I adding custom code to asset_tracker_v2. Two UARTs are required in my project. The firmware to be added to nRF9160 is already running very well in NRF5340 based UART communication. The UART communication in nRF5340 has been implemented by using both UARTs in UART_ASYNC mode and ring buffers have been used to store incoming data. Now, my problem is how to use same functionality / firmware in asset_tracker_v2 while it needs UART_INTERRUPT for AT commands. Where changes need to be done in configuration, initialization, transmit and receive sections of UART code ? The file with UART_SYNC_API based communication is attached. How to modify it for nRF9160 Asset_tracker_v2 ?
//*******************serial port API ********** #include <sys/ring_buffer.h> #include "serial_api.h" //********************************** BMS ******************** uint8_t bms_double_buffer[2][CONFIG_BMS_UART_BUF_SIZE]; uint8_t *bms_buf_next = bms_double_buffer[1]; volatile int bms_bytes_claimed; K_SEM_DEFINE(bms_tx_done, 1, 1); K_SEM_DEFINE(bms_rx_disabled, 0, 1); static const struct device *bms_uart; bool bms_transmit_done ; struct bms_msg_queue_item bms_incoming_message; // UART TX fifo RING_BUF_DECLARE(bms_tx_fifo, CONFIG_BMS_UART_TX_BUF_SIZE); // UART RX message queue K_MSGQ_DEFINE(bms_rx_msgq, sizeof(struct bms_msg_queue_item), CONFIG_BMS_UART_RX_MSG_QUEUE_SIZE, 2); //****** unsigned int bms_tx_get_from_queue(void) { uint8_t *data_ptr; // Try to claim any available bytes in the FIFO bms_bytes_claimed = ring_buf_get_claim(&bms_tx_fifo, &data_ptr, CONFIG_BMS_UART_TX_BUF_SIZE); if(bms_bytes_claimed > 0) { // Start a UART transmission based on the number of available bytes uart_tx(bms_uart, data_ptr, bms_bytes_claimed, SYS_FOREVER_MS); } return bms_bytes_claimed; } void bms_uart_async_callback(const struct device *uart_dev, struct uart_event *evt, void *user_data) { static struct bms_msg_queue_item bms_new_message; switch (evt->type) { case UART_TX_DONE: // Free up the written bytes in the TX FIFO ring_buf_get_finish(&bms_tx_fifo, bms_bytes_claimed); // If there is more data in the TX fifo, start the transmission if(bms_tx_get_from_queue() == 0) { // Or release the semaphore if the TX fifo is empty k_sem_give(&bms_tx_done); bms_transmit_done = true; } break; case UART_RX_RDY: memcpy(bms_new_message.bytes, evt->data.rx.buf + evt->data.rx.offset, evt->data.rx.len); bms_new_message.length = evt->data.rx.len; if(k_msgq_put(&bms_rx_msgq, &bms_new_message, K_NO_WAIT) != 0){ /*printk("Error: Uart1 RX message queue full!\n");*/ } break; case UART_RX_BUF_REQUEST: uart_rx_buf_rsp(bms_uart, bms_buf_next, CONFIG_BMS_UART_BUF_SIZE); break; case UART_RX_BUF_RELEASED: bms_buf_next = evt->data.rx_buf.buf; break; case UART_RX_DISABLED: k_sem_give(&bms_rx_disabled); break; default: break; } } void bms_uart_init(void) { bms_uart = device_get_binding("UART_1"); if (bms_uart == NULL) { printk("Failed to get UART1 binding\n"); return; } uart_callback_set(bms_uart, bms_uart_async_callback, NULL); uart_rx_enable(bms_uart, bms_double_buffer[0], CONFIG_BMS_UART_BUF_SIZE, BMS_UART_RX_TIMEOUT_MS); } // Function to send UART data, by writing it to a ring buffer (FIFO) in the application // WARNING: This function is not thread safe! If you want to call this function from multiple threads a semaphore should be used unsigned int bms_uart_send(const uint8_t * data_ptr, uint32_t data_len) { while(1) { // Try to move the data into the TX ring buffer uint32_t written_to_buf = ring_buf_put(&bms_tx_fifo, data_ptr, data_len); data_len -= written_to_buf; // In case the UART TX is idle, start transmission if(k_sem_take(&bms_tx_done, K_NO_WAIT) == 0) { bms_tx_get_from_queue(); } // In case all the data was written, exit the loop if(data_len == 0) break; // In case some data is still to be written, sleep for some time and run the loop one more time k_msleep(10); data_ptr += written_to_buf; } return 0; }