Initialy I used an app_easy_timer to to start a governor every 2s to process any received data and send them via BLE. This governor would use uart_receive() in DMA mode. This worked perfectly, however; I want to increase the program's response time meaning that I want the governor to be always waiting on the uart for data transfer to begin.
I tried the following but the program crashes after reahing the while loop.
volatile bool SOM_RECEIVED = false; static void uart_receive_intr_cb(uint16_t length){ static uint8_t index = 0; static uint8_t temp_length = 0; if (SOM_RECEIVED){ if (index == 1){ temp_length = temp_queue[index]; index ++; return; } else if ((index>1) && (index < temp_length + 3)){ queue[index] = temp_queue[index]; index ++; return; } else if (index == (temp_length+3)){ queue[index] = temp_queue[index]; uart_receive_finished = true; data_received_cnt = length; SOM_RECEIVED = false; index = 0; return; } else{ SOM_RECEIVED = false; index = 0; return; } } else if (temp_queue[index] == SOM_CHAR ){ queue[index] = temp_queue[index]; index ++; SOM_RECEIVED = true; return; } else{ index = 0; SOM_RECEIVED = false; uart_receive_finished = false; data_received_cnt = 0; return; } } void uart_receive_intr_example(uart_t* uart) { uart_receive_finished = false; data_received_cnt = 0; uart_register_rx_cb(uart, uart_receive_intr_cb); uart_receive(uart, (uint8_t *)temp_queue, TEMP_QUEUE_MAX_LENGTH, UART_OP_INTR); while ((!uart_receive_finished)); if (chk_queue(data_received_cnt)) { printf_string(UART2,"B"); for (int8_t i = 0; i < buffer_received_cnt; i++) printf_byte(uart,buffer[i]); process_buffer((uint8_t *)buffer,buffer_received_cnt); } }I'm waiting for a SOM character, length of data and the data itself. That being said; I'm storing these values in queue and after receiving one packet of data I'm changing uart_receive_finished to true.
I have the following questions:
1- Is there a way that the board can be always waiting for data (listening to UART) in the background? The board should be running its normal process (maybe a state machine that checks the current state and whether any data has been received or not) while always waiting and storing the incoming data via UART.
2- I'm guessing that my current code has a problem with the time out (with or without the watchdog the problem still exists!). I've tried modifying the uart_rx_timeout_isr so it would stop the infinite loop but that didn't work. Would you please explain a bit about this interrupt and the timeout?
Regards,
Hamid
That said, After importing some library which were required and enabling dma mode in ble example;我遵循这个过程:
void user_svc1_adc_val_1_cfg_ind_handler(ke_msg_id_t const msgid, struct custs1_val_write_ind const *param, ke_task_id_t const dest_id,ke_task_id_t const src_id){//当中心订阅它时生成指示if (param->value[0]){printf_string(UART2,"用户订阅了ADC特征!\n\r");SendRecSM_op ();}} ke_msg_id_t timer_used_SendRec_SM __SECTION_ZERO("retention_mem_area0");//@RETENTION MEMORY uart_t * uart = UART2; //保留内存 const int READ_CHAR_COUNT = 5; static char buffer_BLE[READ_CHAR_COUNT + 1]; volatile bool uart_receive_finished = false; volatile uint16_t data_received_cnt = 0; //Function Definitions void SendRecSM_op() { //blocking_receive_uart(); intr_receive_uart(); //dma_receive_uart(); app_easy_timer(500,uart_chk_buffer_cb); } static void uart_receive_cb(uint16_t length){ data_received_cnt = length; uart_receive_finished = true; } void dma_receive_uart(){ uart_receive_finished = false; data_received_cnt = 0; uart_register_rx_cb(uart, uart_receive_cb); //Time to ask for data! uart_receive(uart, (uint8_t *)buffer_BLE, READ_CHAR_COUNT, UART_OP_DMA); } void uart_chk_buffer_cb() { arch_printf("\n\rChecking the buffer!\n\r"); if (uart_receive_finished){ buffer_BLE[READ_CHAR_COUNT] = 0; // make it a null terminated string printf_string(uart,buffer_BLE); } } void intr_receive_uart(){ uart_receive_finished = false; data_received_cnt = 0; uart_register_rx_cb(uart, uart_receive_cb); //Time to ask for data! arch_printf("UART is in Interrupt mode!\n\r"); arch_printf("Please input the data!"); uart_receive(uart, (uint8_t *)buffer_BLE, READ_CHAR_COUNT, UART_OP_INTR); } void blocking_receive_uart(){ printf_string(uart,"UART is in Blocking mode!\n\r"); printf_string(uart,"Please input the data!"); uart_receive(uart, (uint8_t *)buffer_BLE, READ_CHAR_COUNT, UART_OP_BLOCKING); buffer_BLE[READ_CHAR_COUNT] = 0; // make it a null terminated string printf_string(uart,buffer_BLE); }In case of blocking recieve, I'm not using the timer. However, If I don't input the data right away, the program crashes due to "while (!uart_data_ready_getf(uart_id));" command in "uart_read_byte()".
In case of interrupted receives, I use the said timer. However, the program runs only once. In other words, it only prints "Checking the buffer!" and regardless of what I would do, everything would freeze.
I wanted to know, what can I do to solve these problems? Is there a something that I haven't configured for the UART? Is there a better way to do this? (except for using codeless or dsps, because they seem extremely hard to modify)