I have used the UART example up and got it working. So i can send and receive data using it.
However i wanted to modify it so as to run with the current RTOS environment. So i generated a task:
static void tb_uart_task(void* p_params) { uint8_t cr; tb_uart_evt_t event = TB_UART_EVT_INVALID; while(1) { //wait forever for an event if(xQueueReceive(m_tb_uart_evt_queue, &event, portMAX_DELAY)) { //NRF_LOG_DEBUG("tb_uart_evt: %d\n", event); handle_uart_evt(event); } } } static void init_queues(void) { m_tb_uart_evt_queue = xQueueCreate(TB_UART_EVT_QUEUE_LENGTH, sizeof(tb_uart_evt_t)); if(m_tb_uart_evt_queue==NULL) { APP_ERROR_CHECK(NRF_ERROR_NO_MEM); } } void tb_uart_send_event(tb_uart_evt_t evt) { //queue the event if(xQueueSendToBack(m_tb_uart_evt_queue,&evt,UART_QUEUE_WAIT_TICKS) == pdFAIL) { APP_ERROR_CHECK(NRF_ERROR_NO_MEM); } } static void handle_uart_evt(tb_uart_evt_t evt){ switch(evt) { case TB_UART_BYTE_REC: uart_putstring("Received\r"); break; case TB_UART_EVT_INVALID: break; default: break; } }
In the task section if i invoke a tb_uart_send_event(TB_UART_BYTE_REC) with a push button input, the system will output "Received" as expected, so the task works. However, i cannot get it to retrieve data from the UART no matter what i attempt to do through the task system. The only way i can get the UART to read upon receiving is to modify the tb_uart_task method.
static void tb_uart_task(void* p_params) { uint8_t cr; tb_uart_evt_t event = TB_UART_EVT_INVALID; while(1) { //wait forever for an event while(app_uart_get(&cr) != NRF_SUCCESS); while(app_uart_put(cr) != NRF_SUCCESS); } }
ultimately what i would like to be able to do is this:
oid uart_init(void){ uint32_t err_code; nrf_gpio_cfg_input(RX_PIN, NRF_GPIO_PIN_PULLUP); nrf_gpio_cfg_output(TX_PIN); uart_received = false; APP_UART_FIFO_INIT(&comm_params, RX_BUF_SIZE, TX_BUF_SIZE, uart_evt_callback, UART_IRQ_PRIORITY, err_code); } void uart_evt_callback(app_uart_evt_t * uart_evt) { switch (uart_evt->evt_type) { uint8_t cr; case APP_UART_DATA: //Data is ready on the UART break; case APP_UART_DATA_READY: //Data is ready on the UART FIFO tb_uart_send_event(TB_UART_BYTE_REC); break; case APP_UART_TX_EMPTY: //Data has been successfully transmitted on the UART break; default: break; } } static void handle_uart_evt(tb_uart_evt_t evt){ uint8_t cr; uint32_t err_code; uint8_t str[50]; str[0] = '\0'; switch(evt) { case TB_UART_BYTE_REC: uart_getstring(str, 50); uart_putstring(str); break; case TB_UART_EVT_INVALID: break; default: break; } } void uart_getstring(char* c, int size){ int i; uint32_t err_code; for(i = 0; i < size - 1; i++){ err_code = app_uart_get(&c[i]); if(err_code == NRF_ERROR_NOT_FOUND) break; nrf_delay_us(1250); } c[i] = (char)0; }
However, when i try and get the UART to receive data from within a task scenario like that it not only fails to receive the byte but seems to freeze the system. Is there something that is special about how tasks operate and the way UART is operate that makes them incompatible in the way i want to use them?
More testing: I tried to go back to test just the callback function. so i modified the following:
int main(void) { uart_init(); while (true) { } if(pdPASS != xTaskCreate(tb_uart_task_init, // Function that implements the task "UART_INIT", // Text name (for debug only) TASK_STACK_SIZE_LARGE, // Stack size NULL, // Parameter (not used...) 3, // Task priority (highestintern_softdevice_events_execute) &m_tb_uart_task)) // Handle { APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } /* Activate deep sleep mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Start FreeRTOS scheduler */ vTaskStartScheduler(); /* should never get here, task scheduler takes over */ while (true) { APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN); } } static void uart_evt_callback(app_uart_evt_t * uart_evt) { uint8_t cr; switch (uart_evt->evt_type) { case APP_UART_DATA: //Data is ready on the UART break; case APP_UART_DATA_READY: //Data is ready on the UART FIFO while(app_uart_get(&cr) != NRF_SUCCESS); while(app_uart_put(cr) != NRF_SUCCESS); break; case APP_UART_TX_EMPTY: //Data has been successfully transmitted on the UART break; default: break; } }
Just trying to use the callback function does not work. I did move the code to case APP_UART_DATA section and it works once or twice to print the incoming data but ultimately locks up.
My test rig is just sending "T\r" every 5 second from an arduino, and it then outputs to the arduino so i can read the data.
SDK: 12.2