Code flashing successful but not working!

Hello,

I am creating a new project that uses the nRF52810 as my controller, and during the development stage, I am using the PCA10040 nRF52832 development board. (I read somewhere that we can flash the nRF52810 code into the nRF52832 PCA10040 development board). My requirement is a simple LED indicator based on delay commands from an APK that uses the Nordic UART service to send and receive data. I added the timer peripheral to the ble_app_uart example project from the directory nRF5_SDK_17.0.2_d674dde\examples\ble_peripheral\ble_app_uart\pca10040e\s112\ses and flashed the code onto the PCA10040 nRF52832 development board to test it. The code works perfectly.

Then I took an nRF52810 custom PCB and connected the JTAG. The board is able to detect and erase the chip. When I flash the code onto the board, the IDE shows "flash successful," but the board is not working. Are there any other conditions for flashing the code into the nRF52810 custom board? Your response is valuable.

SDK version: 17.0.2
SEGGER Embedded Studio version: 5.42a

Parents
  • Hi,

    If your custom board do not have external 32K crystal, you can try to modify these parameters in sdk_config.h

    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 16
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 2
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
     
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 1
    #endif

  • hi  ,

    I modified the sdk_config file as per the given instructions. Now I am able to debug through RTT Viewer, but the issue still persists. I am still getting a fatal error, Are there any other memory constraints while flashing the code onto the nRF52810 ?.

  • I think the settings is ok. Because you can see the advertising of your device.

    Call stack contents shows the error is from uart_event_handler.

    Can you use break point to check the error is from case APP_UART_DATA_READY or other case?

  • hi ,  , , Sorry for the late response. When debugging the code, I am checking the error code before a fatal error. The log indicates error code 4. Is it related to a memory issue? How can I solve this?

  • Hi,

    Yes, it's no memory error code. But there are many functions will return this error code.

    You should put the break points in the uart_event_handler and find which function returns this error code.

  • hi  , ,


    I am having trouble debugging the code. Sometimes it gets stuck for a while. i think this function app_fifo_put(), which returns NRF_ERROR_NO_MEM. What is the reason for this function returning 'no memory'?

    
         static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
    {
        app_uart_evt_t app_uart_event;
        uint32_t err_code;
        NRF_LOG_INFO(" UART EVENT HANDLER \n");
        switch (p_event->type)
        {
            case NRF_DRV_UART_EVT_RX_DONE:
                // If 0, then this is a RXTO event with no new bytes.
                if(p_event->data.rxtx.bytes == 0)
                {
                   // A new start RX is needed to continue to receive data
                   (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
                   break;
                }
    
                // Write received byte to FIFO.
                err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]);
                NRF_LOG_INFO(" app_fifo_put : %d\n",err_code);
                if (err_code != NRF_SUCCESS)
                {
                    
                    app_uart_event.evt_type          = APP_UART_FIFO_ERROR;
                    app_uart_event.data.error_code   = err_code;
                    m_event_handler(&app_uart_event);
                }
                // Notify that there are data available.
                else if (FIFO_LENGTH(m_rx_fifo) != 0)
                {
                    app_uart_event.evt_type = APP_UART_DATA_READY;
                    m_event_handler(&app_uart_event);
                }
    
                // Start new RX if size in buffer.
                if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask)
                {
                    (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
                }
                else
                {
                    // Overflow in RX FIFO.
                    m_rx_ovf = true;
                }
    
                break;
    
            case NRF_DRV_UART_EVT_ERROR:
                NRF_LOG_INFO("  NRF_DRV_UART_EVT_ERROR \n");
                app_uart_event.evt_type                 = APP_UART_COMMUNICATION_ERROR;
                app_uart_event.data.error_communication = p_event->data.error.error_mask;
                (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
                m_event_handler(&app_uart_event);
                break;
    
            case NRF_DRV_UART_EVT_TX_DONE:
                // Get next byte from FIFO.
                if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
                {
                    (void)nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
                }
                else
                {
                    NRF_LOG_INFO(" else NRF_DRV_UART_EVT_TX_DONE \n");
                    // Last byte from FIFO transmitted, notify the application.
                    app_uart_event.evt_type = APP_UART_TX_EMPTY;
                    m_event_handler(&app_uart_event);
                }
                break;
    
            default:
                break;
        }
    }
    
    //________________________________________________________________//
    
    uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte)
    {
        if (FIFO_LENGTH() <= p_fifo->buf_size_mask)
        {
            fifo_put(p_fifo, byte);
            return NRF_SUCCESS;
        }
    
        return NRF_ERROR_NO_MEM;
    }

  • hi ,  , ,I apologize for the previous incorrect response. The debug terminal shows that the code enters this specific case. The issue is actually occurring within the UART event handler. What could be causing this?

    case NRF_DRV_UART_EVT_ERROR:
    NRF_LOG_INFO(" NRF_DRV_UART_EVT_ERROR \n");
    app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
    app_uart_event.data.error_communication = p_event->data.error.error_mask;
    (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
    m_event_handler(&app_uart_event);
    break;

Reply
  • hi ,  , ,I apologize for the previous incorrect response. The debug terminal shows that the code enters this specific case. The issue is actually occurring within the UART event handler. What could be causing this?

    case NRF_DRV_UART_EVT_ERROR:
    NRF_LOG_INFO(" NRF_DRV_UART_EVT_ERROR \n");
    app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
    app_uart_event.data.error_communication = p_event->data.error.error_mask;
    (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
    m_event_handler(&app_uart_event);
    break;

Children
  • Hi,

    You can set break point in app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;

    And check UART register's ERRORSRC.

    This document shows error root casue.

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/uart.html?cp=5_2_0_49_9_3#register.ERRORSRC

    typedef struct
    {
        app_uart_evt_type_t evt_type; /**< Type of event. */
        union
        {
            uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */
            uint32_t error_code;          /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
            uint8_t  value;               /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
        } data;
    } app_uart_evt_t;

  • hi ,  , , 

    When I put a breakpoint here and start debugging the code, it never stops at the given breakpoint. The code execution continues until a fatal error occurs.

    When I check the ERRORSRC register, I am attaching an image of the ERRORSRC register values.

  • Hi,

    Please refer to spec :

    Break condition

    The serial data input is '0' for longer than the length of a data frame. (The data frame length is 10 bits without parity bit, and 11 bits with parity bit.).

    If you have logic analyzer or oscilloscope, you can measure the waveform of 52810 RX pin.

  • Hi, sorry for the delayed response. solved the issue by changing the UART RX, TX, CTS, and RTS pin numbers. The previously used pin numbers were connected to a motion sensor on the custom PCB via the SPI peripheral. Now the board is able to advertise, send commands, and trigger timer intervals based on the delay command from the APK. I really appreciate your efforts in providing this level of support for our development.

Related