Write an article today to explain a problem that puzzles some engineers when using le5010 chip
In the SDK, why don't we create a while loop and implement some of our logic in it? Where is our user code implemented?
- With these two questions, let me briefly introduce the background of this chip. What is the difference between Bluetooth chip and ordinary MCU? In fact, there is only one more ble. We can understand it as a peripheral with an MCU, but this peripheral has high requirements for timing, because there is complex logic in the Bluetooth protocol stack. However, the most important thing is timing, when to do what, and what consequences will be caused if it times out, which are related to timing, At this time, we will deal with the problem of interrupt priority. When setting the priority, the chip sets the level of ble to the highest, which can also reflect the importance of Bluetooth in the whole system. For example, "chestnut": there will be an action to maintain the connection during Bluetooth interaction, that is, after Bluetooth is connected, How can it not be disconnected without sending and receiving data? At this time, there needs to be a "hello" action between the master and slave: "send empty packets". If the master and slave do not interact with data and send empty packets within the set timeout, the connection will be disconnected at this time, and the reason for disconnecting is that they are disconnected due to timeout. In this example, we can see that if we do not do the specified things within the specified time, some problems will occur, and the connection will be disconnected directly in this example.
- In the above example, you just see the result. What are the reasons for this result? In fact, there are many reasons for this, both in software and hardware. Generally, there will be no problem only if it is operated in strict accordance with the suggestions of the bosses of the original factory.
- Let me take this situation of my customers as an example to give you a reference:
Software: the priority of interrupt in the code is very important. In this case, we must see whether our Bluetooth interrupt is interrupted by other interrupts, which will affect the timing of Bluetooth.
- Describe how to modify the interrupt priority:
/**This function is in platform.c. do not modify this file when you are not sure**/ static void irq_priority() { __NVIC_SetPriority(SVCall_IRQn,2); NVIC->IP[0] = IRQ_NVIC_PRIO(EXTI_IRQn,3) | IRQ_NVIC_PRIO(WWDT_IRQn,3) | IRQ_NVIC_PRIO(LPWKUP_IRQn,3) | IRQ_NVIC_PRIO(BLE_IRQn,1); NVIC->IP[1] = IRQ_NVIC_PRIO(RTC_IRQn,3) | IRQ_NVIC_PRIO(DMA_IRQn,3) | IRQ_NVIC_PRIO(QSPI_IRQn,3) | IRQ_NVIC_PRIO(ECC_IRQn,3); NVIC->IP[2] = IRQ_NVIC_PRIO(CACHE_IRQn,3) | IRQ_NVIC_PRIO(TRNG_IRQn,3) | IRQ_NVIC_PRIO(IWDT_IRQn,3) | IRQ_NVIC_PRIO(CRYPT_IRQn,3); NVIC->IP[3] = IRQ_NVIC_PRIO(PDM_IRQn,3) | IRQ_NVIC_PRIO(BLE_WKUP_IRQn,1) | IRQ_NVIC_PRIO(ADC_IRQn,3) | IRQ_NVIC_PRIO(ADTIM1_IRQn,3); NVIC->IP[4] = IRQ_NVIC_PRIO(BSTIM1_IRQn,3) | IRQ_NVIC_PRIO(GPTIMA1_IRQn,3) | IRQ_NVIC_PRIO(GPTIMB1_IRQn,3) | IRQ_NVIC_PRIO(BLE_ERR_IRQn,1); NVIC->IP[5] = IRQ_NVIC_PRIO(LVD33_IRQn,3) | IRQ_NVIC_PRIO(GPTIMC1_IRQn,3) | IRQ_NVIC_PRIO(LPTIM_IRQn,3) | IRQ_NVIC_PRIO(I2C1_IRQn,3); NVIC->IP[6] = IRQ_NVIC_PRIO(I2C2_IRQn,3) | IRQ_NVIC_PRIO(SPI1_IRQn,3) | IRQ_NVIC_PRIO(SPI2_IRQn,3) | IRQ_NVIC_PRIO(UART1_IRQn,3); NVIC->IP[7] = IRQ_NVIC_PRIO(UART2_IRQn,3) | IRQ_NVIC_PRIO(UART3_IRQn,3) | IRQ_NVIC_PRIO(BLE_FIFO_IRQn,1) | IRQ_NVIC_PRIO(BLE_CRYPT_IRQn,1); }
Above with BLE All prefixes are ble This is the interrupt that controls our protocol stack.
- Addition of user code
- Register a user in the protocol stack_ Event timer
/**Scheduling interval**/ #USER_EVENT_PERIOD 20 // 20ms (min_value >=10ms and min_unit=1ms)
- Register a user with the protocol stack_ Event timer
#include "builtin_timer.h" static void ls_user_event_timer_init(void); static void ls_user_event_timer_cb(void *param); static struct builtin_timer *user_event_timer_inst = NULL; static void ls_user_event_timer_init(void) { user_event_timer_inst =builtin_timer_create(ls_user_event_timer_cb); builtin_timer_start(user_event_timer_inst, USER_EVENT_PERIOD, NULL); }
- Handle the relevant application layer code in the callback function of the timer
static void ls_user_event_timer_cb(void *param) { /** user_code */ builtin_timer_start(user_event_timer_inst, USER_EVENT_PERIOD, NULL); }
- user_event_timer initial function add location
- Because user_event_timer is registered with the protocol stack, so the initialization of the protocol stack is required, otherwise it is invalid. This causes the function to have certain position constraints. The earliest setting positions are as follows:
static void dev_manager_callback(enum dev_evt_type type,union dev_evt_u *evt) { switch(type) { case STACK_READY: { ls_user_event_timer_init(); } } }
- The user's code can be added in this way, which is to play a software timer, but this timer will not interfere with the operation of ble, so you can replace the while loop.
Hardware: Bluetooth also has high requirements for hardware. In general, if you are careless in hardware design, you will be shot. Let me show you some board error examples of several customers:
- Because the board is very small, it is difficult to modify it. However, it still needs to be modified, because three points that must be paid attention to in this design are not taken into account.
① The antenna must have a clearance area, and the size of the clearance area will affect your signal quality, and the antenna wiring shall be as short and straight as possible. No 90 ° angle is allowed.
② No line can be taken under the crystal oscillator.
③ All power supplies entering the chip must first pass through the capacitor and then enter the chip. It can't be bypassed. That won't work. The power supply after passing through the capacitor will directly enter the chip. Don't go through the hole into the chip, and you can't route under it. Keep it short and straight as far as possible.