Hello everyone,
I'm trying to interface a NiceRF LN610 LoRaWAN chip to nRF52840 via UART. Initially, I tried communicating with the chip using CP2102 USB-to-TTL module and RealTerm in a Windows 10 PC and manually entering the commands there (after configuring the port properly). The LN610 chip responds and I get the required values to operate the LoRaWAN chip (see attached image, manual commands in green, chip response in yellow)
I then connected the LN610 TX & RX pins to nRF52840 GPIO pins P1.13 & P1.14, respectively, and then used the UART, SERIAL, and LIBUARTE peripheral examples in SDK16 to communicate with the LN610 chip but I failed to get any response from LN610 in each of the examples.
1. uart peripheral example files
#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include "app_uart.h" #include "app_error.h" #include "nrf_delay.h" #include "nrf.h" #include "bsp.h" #if defined (UART_PRESENT) #include "nrf_uart.h" #endif #if defined (UARTE_PRESENT) #include "nrf_uarte.h" #endif #define MAX_TEST_DATA_BYTES (15U) /**< max number of test bytes to be used for tx and rx. */ #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ #define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */ void uart_error_handle(app_uart_evt_t * p_event) { switch (p_event->evt_type) { case APP_UART_COMMUNICATION_ERROR: APP_ERROR_HANDLER(p_event->data.error_communication); break; case APP_UART_FIFO_ERROR: APP_ERROR_HANDLER(p_event->data.error_code); break; case APP_UART_DATA_READY: printf("APP_UART_DATA_READY"); break; case APP_UART_TX_EMPTY: printf("APP_UART_TX_EMPTY"); printf("An event indicating that UART has completed transmission of all available data in the TX FIFO."); app_uart_flush(); break; case APP_UART_DATA: printf("APP_UART_DATA"); printf("An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured."); break; default: break; } } /* When UART is used for communication with the host do not use flow control.*/ #define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED /** * @brief Function for main application entry. */ int main(void) { uint32_t err_code; uint32_t i = 0; bsp_board_init(BSP_INIT_LEDS); const app_uart_comm_params_t comm_params = { 14, /* UART RX <-> LN610 TX */ 13, /* UART TX <-> LN610 RX */ UART_PIN_DISCONNECTED, UART_PIN_DISCONNECTED, UART_HWFC, false, #if defined (UART_PRESENT) NRF_UART_BAUDRATE_9600 #else NRF_UARTE_BAUDRATE_9600 #endif }; APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, uart_error_handle, APP_IRQ_PRIORITY_LOWEST, err_code); APP_ERROR_CHECK(err_code); /* Test */ uint8_t tx_data[4] = { 0x24, 0x01, 0x00, 0x25 }; uint8_t rx_data = 0; uint8_t buff[255]; // Start sending one byte for (i = 0; i < 4; i++) { app_uart_put(tx_data[i]); } // Receive data i = 0; while (true) { app_uart_get(&rx_data); buff[i++] = rx_data; if (i % 255) break; } return 0; }
2. serial peripheral example files
/** * Copyright (c) 2016 - 2019, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include <stdint.h> #include <stdbool.h> #include <stddef.h> #include "nrf.h" #include "nrf_drv_clock.h" #include "nrf_gpio.h" #include "nrf_delay.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_drv_power.h" #include "nrf_serial.h" #include "app_timer.h" #include "app_error.h" #include "app_util.h" #include "boards.h" /** @file * @defgroup nrf_serial_example main.c * @{ * @ingroup nrf_serial_example * @brief Example of @ref nrf_serial usage. Simple loopback. * */ #define OP_QUEUES_SIZE 3 #define APP_TIMER_PRESCALER NRF_SERIAL_APP_TIMER_PRESCALER static void sleep_handler(void) { __WFE(); __SEV(); __WFE(); } NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config, 14, /* UART RX <-> LN610 TX */ 13, /* UART TX <-> LN610 RX */ NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED, NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED, NRF_UART_BAUDRATE_9600, UART_DEFAULT_CONFIG_IRQ_PRIORITY); #define SERIAL_FIFO_TX_SIZE 32 #define SERIAL_FIFO_RX_SIZE 1 NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE); #define SERIAL_BUFF_TX_SIZE 32 #define SERIAL_BUFF_RX_SIZE 1 NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE); NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_DMA, &serial_queues, &serial_buffs, NULL, sleep_handler); NRF_SERIAL_UART_DEF(serial_uart, 0); int main(void) { ret_code_t ret; ret = nrf_drv_clock_init(); APP_ERROR_CHECK(ret); ret = nrf_drv_power_init(NULL); APP_ERROR_CHECK(ret); nrf_drv_clock_lfclk_request(NULL); ret = app_timer_init(); APP_ERROR_CHECK(ret); // Initialize LEDs and buttons. bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS); ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config); APP_ERROR_CHECK(ret); static uint8_t tx_message[] = { 0x24, 0x01, 0x00, 0x25 }; uint8_t response = 0; uint8_t buff[255] = {0}; size_t bytes_read; ret = nrf_serial_write(&serial_uart, tx_message, 4, NULL, 500); APP_ERROR_CHECK(ret); (void)nrf_serial_flush(&serial_uart, 0); /* nrf_serial_uninit(&serial_uart); nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config); nrf_delay_us(1000); */ uint32_t i = 0; while (true) { uint8_t c; nrf_serial_read(&serial_uart, &c, sizeof(c), &bytes_read, 1000); if (bytes_read) { buff[i++] = c; if ((i % 255) == 0) break; } } return 0; } /** @} */
3. libuarte example files
/** * Copyright (c) 2018 - 2019, Nordic Semiconductor ASA * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form, except as embedded into a Nordic * Semiconductor ASA integrated circuit in a product or a software update for * such product, must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * 3. Neither the name of Nordic Semiconductor ASA nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * 4. This software, with or without modification, must only be used with a * Nordic Semiconductor ASA integrated circuit. * * 5. Any software provided in binary form under this license must not be reverse * engineered, decompiled, modified and/or disassembled. * * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /** @file * @defgroup libuarte_example_main main.c * @{ * @ingroup libuarte_example * @brief Libuarte Example Application main file. * * This file contains the source code for a sample application using libuarte. * */ #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include "nrf_libuarte_async.h" #include "nrf_drv_clock.h" #include <bsp.h> #include "nrf_log_ctrl.h" #include "nrf_log_default_backends.h" #include "nrf_queue.h" NRF_LIBUARTE_ASYNC_DEFINE(libuarte0, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3); static volatile bool m_loopback_phase; typedef struct { uint8_t * p_data; uint32_t length; } buffer_t; NRF_QUEUE_DEF(buffer_t, m_buf_queue, 10, NRF_QUEUE_MODE_NO_OVERFLOW); void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt) { nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context; ret_code_t ret; switch (p_evt->type) { case NRF_LIBUARTE_ASYNC_EVT_ERROR: bsp_board_led_invert(0); break; case NRF_LIBUARTE_ASYNC_EVT_RX_DATA: /*ret = nrf_libuarte_async_tx(p_libuarte,p_evt->data.rxtx.p_data, p_evt->data.rxtx.length); if (ret == NRF_ERROR_BUSY) { buffer_t buf = { .p_data = p_evt->data.rxtx.p_data, .length = p_evt->data.rxtx.length, }; ret = nrf_queue_push(&m_buf_queue, &buf); APP_ERROR_CHECK(ret); } else { APP_ERROR_CHECK(ret); }*/ bsp_board_led_invert(1); m_loopback_phase = true; break; case NRF_LIBUARTE_ASYNC_EVT_TX_DONE: if (m_loopback_phase) { nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data, p_evt->data.rxtx.length); if (!nrf_queue_is_empty(&m_buf_queue)) { buffer_t buf; ret = nrf_queue_pop(&m_buf_queue, &buf); APP_ERROR_CHECK(ret); UNUSED_RETURN_VALUE(nrf_libuarte_async_tx(p_libuarte, buf.p_data, buf.length)); } } bsp_board_led_invert(2); break; default: break; } } /** * @brief Function for main application entry. */ int main(void) { bsp_board_init(BSP_INIT_LEDS); ret_code_t ret = nrf_drv_clock_init(); APP_ERROR_CHECK(ret); nrf_drv_clock_lfclk_request(NULL); ret_code_t err_code /*= NRF_LOG_INIT(app_timer_cnt_get); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT()*/; /* UARTE 0 */ static uint8_t text[] = { 0x24, 0x01, 0x00, 0x25 }; static uint8_t text_size = sizeof(text); nrf_libuarte_async_config_t nrf_libuarte_async_config0 = { .tx_pin = 13, /* UART TX <-> LN610 RX */ .rx_pin = 14, /* UART RX <-> LN610 TX */ .baudrate = NRF_UARTE_BAUDRATE_9600, .parity = NRF_UARTE_PARITY_EXCLUDED, .hwfc = NRF_UARTE_HWFC_DISABLED, .timeout_us = 100, .int_prio = APP_IRQ_PRIORITY_LOW }; err_code = nrf_libuarte_async_init(&libuarte0, &nrf_libuarte_async_config0, uart_event_handler, (void *)&libuarte0); APP_ERROR_CHECK(err_code); nrf_libuarte_async_enable(&libuarte0); err_code = nrf_libuarte_async_tx(&libuarte0, text, text_size); APP_ERROR_CHECK(err_code); while (true) { NRF_LOG_FLUSH(); } } /** @} */
Also tried using UARTE directly from this instruction from Hung Buihttps://devzone.nordicsemi.com/f/nordic-q-a/58740/data-throughput-between-nrf52810-ble-uart
https://github.com/andenore/NordicSnippets/blob/master/examples/uart/main.c
#include <nrf.h> #define PIN_TXD (13) #define PIN_RXD (14) int main(void) { uint8_t hello_world[] = /*"Hello World!\n"*/ { 0x24, 0x01, 0x00, 0x25 }; uint8_t hi_there = 0 /*[255] = { 0 }*/; // Configure the UARTE with no flow control, one parity bit and 115200 baud rate NRF_UARTE0->CONFIG = (UART_CONFIG_HWFC_Disabled << UART_CONFIG_HWFC_Pos) | (UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos); NRF_UARTE0->BAUDRATE = UARTE_BAUDRATE_BAUDRATE_Baud4800 << UARTE_BAUDRATE_BAUDRATE_Pos; // Select TX and RX pins NRF_UARTE0->PSEL.TXD = PIN_TXD; NRF_UARTE0->PSEL.RXD = PIN_RXD; /*TX*/ // Enable the UART (starts using the TX/RX pins) NRF_UARTE0->ENABLE = UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos; // Configure transmit buffer and start the transfer NRF_UARTE0->TXD.MAXCNT = sizeof(hello_world); NRF_UARTE0->TXD.PTR = (uint32_t)&hello_world[0]; NRF_UARTE0->TASKS_STARTTX = 1; // Wait until the transfer is complete while (NRF_UARTE0->EVENTS_ENDTX == 0) { } // Stop the UART TX NRF_UARTE0->TASKS_STOPTX = 1; // Wait until we receive the stopped event while (NRF_UARTE0->EVENTS_TXSTOPPED == 0); // Disable the UARTE (pins are now available for other use) //NRF_UARTE0->ENABLE = UARTE_ENABLE_ENABLE_Disabled << UARTE_ENABLE_ENABLE_Pos; /*RX*/ // Enable the UART (starts using the TX/RX pins) //NRF_UARTE0->ENABLE = UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos; // Enable the UART RXDRDY interrupt NRF_UARTE0->INTENSET = UARTE_INTENSET_RXDRDY_Enabled << UARTE_INTENSET_RXDRDY_Pos; // Enable the UART RXTO interrupt NRF_UARTE0->INTENSET = UARTE_INTENSET_RXTO_Enabled << UARTE_INTENSET_RXTO_Pos; // Configure receive buffer and start receiving NRF_UARTE0->RXD.MAXCNT = /*sizeof(hi_there)*/ 1; NRF_UARTE0->RXD.PTR = (uint32_t)&hi_there/*[0]*/; NRF_UARTE0->TASKS_STARTRX = 1; // Wait until the receive is started while (NRF_UARTE0->EVENTS_RXSTARTED == UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_NotGenerated) { } // Wait until a data is received while ( (NRF_UARTE0->EVENTS_RXDRDY == UARTE_EVENTS_RXDRDY_EVENTS_RXDRDY_NotGenerated) || (NRF_UARTE0->EVENTS_ENDRX == UARTE_EVENTS_ENDRX_EVENTS_ENDRX_NotGenerated)) { if (NRF_UART0->EVENTS_RXTO == UARTE_EVENTS_RXTO_EVENTS_RXTO_Generated) break; } // Stop the UART TX NRF_UARTE0->TASKS_STOPRX = 1; // Wait until we receive the stopped event while (NRF_UARTE0->EVENTS_RXTO == 0); // Disable the UARTE (pins are now available for other use) NRF_UARTE0->ENABLE = UARTE_ENABLE_ENABLE_Disabled << UARTE_ENABLE_ENABLE_Pos; while (1) { __WFE(); } }
Would appreciate if someone could point me on what could possibly be wrong with my UART usage?
Thank you,
Carlos