UART Configuration in DFU nRF52840

Hi,

I have recently migrated by code from the nRF52832 to the nRF52840 on a custom board. This board uses UART to an STMH7 for the DFU.

When trying to do a DFU in the bootloader I get the UART error 12 = 0x1100 which are frame and block mask bits as far as I understand it. After this error the module just restarts the Bootloader

 

00> <error> app: p_event->type 2
00> <error> app: NRF_DRV_UART_EVT_ERROR
00> <error> app: UART_DFU_Mng_EventHandler p_event->data.error.error_mask 12
00> <error> app: ./Components/Middleware/UART_DFU_Mng/UART_DFU_Mng_Md0.c:168

I am using the following configuration (relevant extraits):

// <e> NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver
//==========================================================
#ifndef NRFX_UARTE_ENABLED
#define NRFX_UARTE_ENABLED 1
#endif
// <o> NRFX_UARTE0_ENABLED - Enable UARTE0 instance
#ifndef NRFX_UARTE0_ENABLED
#define NRFX_UARTE0_ENABLED 0
#endif

// <o> NRFX_UARTE_DEFAULT_CONFIG_HWFC  - Hardware Flow Control

// <0=> Disabled
// <1=> Enabled

#ifndef NRFX_UARTE_DEFAULT_CONFIG_HWFC
#define NRFX_UARTE_DEFAULT_CONFIG_HWFC 0
#endif

// <o> NRFX_UARTE_DEFAULT_CONFIG_PARITY  - Parity

// <0=> Excluded
// <14=> Included

#ifndef NRFX_UARTE_DEFAULT_CONFIG_PARITY
#define NRFX_UARTE_DEFAULT_CONFIG_PARITY 0
#endif

// <o> NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate

// <323584=> 1200 baud
// <643072=> 2400 baud
// <1290240=> 4800 baud
// <2576384=> 9600 baud
// <3862528=> 14400 baud
// <5152768=> 19200 baud
// <7716864=> 28800 baud
// <8388608=> 31250 baud
// <10289152=> 38400 baud
// <15007744=> 56000 baud
// <15400960=> 57600 baud
// <20615168=> 76800 baud
// <30801920=> 115200 baud
// <61865984=> 230400 baud
// <67108864=> 250000 baud
// <121634816=> 460800 baud
// <251658240=> 921600 baud
// <268435456=> 1000000 baud

#ifndef NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE
#define NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE 251658240
#endif

// <o> NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority

// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7

#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY
#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif

// <e> NRFX_UARTE_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED
#define NRFX_UARTE_CONFIG_LOG_ENABLED 0
#endif
// <o> NRFX_UARTE_CONFIG_LOG_LEVEL  - Default Severity level

// <0=> Off
// <1=> Error
// <2=> Warning
// <3=> Info
// <4=> Debug

#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL
#define NRFX_UARTE_CONFIG_LOG_LEVEL 3
#endif

// <o> NRFX_UARTE_CONFIG_INFO_COLOR  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRFX_UARTE_CONFIG_INFO_COLOR
#define NRFX_UARTE_CONFIG_INFO_COLOR 0
#endif

// <o> NRFX_UARTE_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRFX_UARTE_CONFIG_DEBUG_COLOR
#define NRFX_UARTE_CONFIG_DEBUG_COLOR 0
#endif

// </e>

// </e>

// <e> NRFX_UART_ENABLED - nrfx_uart - UART peripheral driver
//==========================================================
#ifndef NRFX_UART_ENABLED
#define NRFX_UART_ENABLED 1
#endif
// <o> NRFX_UART0_ENABLED - Enable UART0 instance
#ifndef NRFX_UART0_ENABLED
#define NRFX_UART0_ENABLED 0
#endif

// <o> NRFX_UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control

// <0=> Disabled
// <1=> Enabled

#ifndef NRFX_UART_DEFAULT_CONFIG_HWFC
#define NRFX_UART_DEFAULT_CONFIG_HWFC 0
#endif

// <o> NRFX_UART_DEFAULT_CONFIG_PARITY  - Parity

// <0=> Excluded
// <14=> Included

#ifndef NRFX_UART_DEFAULT_CONFIG_PARITY
#define NRFX_UART_DEFAULT_CONFIG_PARITY 0
#endif

// <o> NRFX_UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate

// <323584=> 1200 baud
// <643072=> 2400 baud
// <1290240=> 4800 baud
// <2576384=> 9600 baud
// <3866624=> 14400 baud
// <5152768=> 19200 baud
// <7729152=> 28800 baud
// <8388608=> 31250 baud
// <10309632=> 38400 baud
// <15007744=> 56000 baud
// <15462400=> 57600 baud
// <20615168=> 76800 baud
// <30924800=> 115200 baud
// <61845504=> 230400 baud
// <67108864=> 250000 baud
// <123695104=> 460800 baud
// <247386112=> 921600 baud
// <268435456=> 1000000 baud

#ifndef NRFX_UART_DEFAULT_CONFIG_BAUDRATE
#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE 247386112
#endif

// <o> NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority

// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7

#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY
#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif

// <e> NRFX_UART_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef NRFX_UART_CONFIG_LOG_ENABLED
#define NRFX_UART_CONFIG_LOG_ENABLED 0
#endif
// <o> NRFX_UART_CONFIG_LOG_LEVEL  - Default Severity level

// <0=> Off
// <1=> Error
// <2=> Warning
// <3=> Info
// <4=> Debug

#ifndef NRFX_UART_CONFIG_LOG_LEVEL
#define NRFX_UART_CONFIG_LOG_LEVEL 3
#endif

// <o> NRFX_UART_CONFIG_INFO_COLOR  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRFX_UART_CONFIG_INFO_COLOR
#define NRFX_UART_CONFIG_INFO_COLOR 0
#endif

// <o> NRFX_UART_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.

// <0=> Default
// <1=> Black
// <2=> Red
// <3=> Green
// <4=> Yellow
// <5=> Blue
// <6=> Magenta
// <7=> Cyan
// <8=> White

#ifndef NRFX_UART_CONFIG_DEBUG_COLOR
#define NRFX_UART_CONFIG_DEBUG_COLOR 0
#endif

// </e>

// </e>

// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
//==========================================================
#ifndef UART_ENABLED
#define UART_ENABLED 1
#endif
// <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control

// <0=> Disabled
// <1=> Enabled

#ifndef UART_DEFAULT_CONFIG_HWFC
#define UART_DEFAULT_CONFIG_HWFC 0
#endif

// <o> UART_DEFAULT_CONFIG_PARITY  - Parity

// <0=> Excluded
// <14=> Included

#ifndef UART_DEFAULT_CONFIG_PARITY
#define UART_DEFAULT_CONFIG_PARITY 0
#endif

// <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate

// <323584=> 1200 baud
// <643072=> 2400 baud
// <1290240=> 4800 baud
// <2576384=> 9600 baud
// <3862528=> 14400 baud
// <5152768=> 19200 baud
// <7716864=> 28800 baud
// <10289152=> 38400 baud
// <15400960=> 57600 baud
// <20615168=> 76800 baud
// <30801920=> 115200 baud
// <61865984=> 230400 baud
// <67108864=> 250000 baud
// <121634816=> 460800 baud
// <251658240=> 921600 baud
// <268435456=> 1000000 baud

#ifndef UART_DEFAULT_CONFIG_BAUDRATE
#define UART_DEFAULT_CONFIG_BAUDRATE 251658240
#endif

// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority


// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7

#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif

// <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA


#ifndef UART_EASY_DMA_SUPPORT
#define UART_EASY_DMA_SUPPORT 1
#endif

// <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode


#ifndef UART_LEGACY_SUPPORT
#define UART_LEGACY_SUPPORT 0
#endif

// <e> UART0_ENABLED - Enable UART0 instance
//==========================================================
#ifndef UART0_ENABLED
#define UART0_ENABLED 1
#endif
// <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA


#ifndef UART0_CONFIG_USE_EASY_DMA
#define UART0_CONFIG_USE_EASY_DMA 1
#endif

I have used this configuration and it worked fine with the nRF52832 but somehow now I am getting errors.

My questions are:

- Is there specific requirements for DMA or similar when switching to the nRF52840? eg I have seen this line in nrf_drv_uart_init:

#ifdef NRF52840_XXAA
    NRF_LOG_ERROR("NRF52840_XXAA");
    if (inst_idx == 1)
    {
        ASSERT(p_config->use_easy_dma);
    }
#endif

- What exactly is the difference between NRFX_UART(E)_ENABLED and UART_ENABLED?

- when should I use UART_LEGACY_SUPPORT?

The initialization in the code looks like this:

   nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;

   uart_config.pselrxd   = RX_PIN_NUMBER_MDBT50Q;
   uart_config.pseltxd   = TX_PIN_NUMBER_MDBT50Q;
   uart_config.pselcts   = CTS_PIN_NUMBER_MDBT50Q;
   uart_config.pselrts   = RTS_PIN_NUMBER_MDBT50Q;

   uart_config.hwfc      = NRF_DFU_SERIAL_UART_USES_HWFC ?
         NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
   uart_config.p_context = &m_serial;


   err_code =  nrf_drv_uart_init(&m_uart, &uart_config, UART_DFU_Mng_EventHandler);

Parents
  • Hello,

    Is there specific requirements for DMA or similar when switching to the nRF52840? eg I have seen this line in nrf_drv_uart_init:

    The 52840 has 2x UARTE instances and one UART instance instead of 1x UARTE and 1x UART like on the 52832. The assert is simply to warn users if they try to use UART1 which does not exist. 

    What exactly is the difference between NRFX_UART(E)_ENABLED and UART_ENABLED?

    The main difference is that UARTE has easyDMA support. However, it does not make much of a difference for the UART DFU transport as it only allocates 1 byte for its DMA buffer.

    when should I use UART_LEGACY_SUPPORT?

    I cannot think of any reasons for using the UART_LEGACY_SUPPORT (i.e. use UART instead of UARTE). The reason we included the UART peripheral in the first place was to ease porting of existing code from the nRF51 series (Migrating from the nRF51 Series to the nRF52 Series) 

    Can you include your UART pin assignments? Also, is the NRF_DRV_UART_EVT_ERROR event raised before or after the transfer is started? 

    Best regards,

    Vidar

  • Thank you for the prompt reply!

    My pin assignments and init function are the following:

    #define RX_PIN_NUMBER_MDBT50Q  	8	    /**< UART RX pin number.  */
    #define TX_PIN_NUMBER_MDBT50Q  	6       /**< UART TX pin number.  */
    #define CTS_PIN_NUMBER_MDBT50Q 	7       /**< UART CTS pin number. */
    #define RTS_PIN_NUMBER_MDBT50Q 	5      /**< UART RTS pin number. */
    
    UINT32_T UART_DFU_Mng_TransportInit(nrf_dfu_observer_t observer)
    {
       ERROR_T ERROR_RetVal = E_OK;
       ret_code_t err_code = NRF_SUCCESS;
    
       BOOL_ProcessingDone = TRUE;
    
    
       if (BOOL_IsActive)
       {
          return err_code;
       }
    
    //   NRF_LOG_DEBUG("serial_dfu_transport_init()");
    
       m_observer = observer;
    
       m_serial.rsp_func           = UART_DFU_Mng_ResponseSend;
       m_serial.payload_free_func  = UART_DFU_Mng_PayloadFree;
       m_serial.mtu                = UART_SERIALPRTC_MTU;
       m_serial.p_rsp_buf          = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SERIALPRTC -
                                                NRF_SERIAL_MAX_RESPONSE_SIZE];
       m_serial.p_low_level_transport = &m_uart_dfu_transport;
    
       nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
    
       uart_config.pselrxd   = RX_PIN_NUMBER_MDBT50Q;
       uart_config.pseltxd   = TX_PIN_NUMBER_MDBT50Q;
       uart_config.pselcts   = CTS_PIN_NUMBER_MDBT50Q;
       uart_config.pselrts   = RTS_PIN_NUMBER_MDBT50Q;
    
       uart_config.hwfc      = NRF_DFU_SERIAL_UART_USES_HWFC ?
             NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
       uart_config.p_context = &m_serial;
    
       NRF_LOG_ERROR("nrf_drv_uart_init");
    
    
       err_code =  nrf_drv_uart_init(&m_uart, &uart_config, UART_DFU_Mng_EventHandler);
       if (err_code != NRF_SUCCESS)
       {
          NRF_LOG_ERROR("UART_DFU_Mng_TransportInit Failed initializing uart %d", err_code);
          return err_code;
       }
    
       err_code = nrf_drv_uart_rx(&m_uart, &UINT8_RxByte, 1);
       if (err_code != NRF_SUCCESS)
       {
    //      NRF_LOG_ERROR("Failed initializing rx");
       }
    
    //   NRF_LOG_DEBUG("serial_dfu_transport_init() completed");
    
       BOOL_IsActive = true;
    
       if (m_observer)
       {
          m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
       }
    
    //todo enable dfu notify send, here or redefine nrf_dfu_init_user(), or send from app
    
       if(FALSE == _BOOL_SysEvtSent)
       {
          _BOOL_SysEvtSent = TRUE;
          ERROR_Check(ERROR_RetVal, UART_DFU_Mng_SysEventDfuNotify());
       }
    
       return err_code;
    }

    The error only shows up once the update/transfer from the STM32H7 is started.

    The main difference is that UARTE has easyDMA support. However, it does not make much of a difference for the UART DFU transport as it only allocates 1 byte for its DMA buffer.

    And what is the difference between NRFX_UART_ENABLED and UART_ENABLED?

    Once the App is running on the nRF and STM32 uC somehow the USART communication seems to be working. So it must be something BL specific on uC or nRF side.

Reply
  • Thank you for the prompt reply!

    My pin assignments and init function are the following:

    #define RX_PIN_NUMBER_MDBT50Q  	8	    /**< UART RX pin number.  */
    #define TX_PIN_NUMBER_MDBT50Q  	6       /**< UART TX pin number.  */
    #define CTS_PIN_NUMBER_MDBT50Q 	7       /**< UART CTS pin number. */
    #define RTS_PIN_NUMBER_MDBT50Q 	5      /**< UART RTS pin number. */
    
    UINT32_T UART_DFU_Mng_TransportInit(nrf_dfu_observer_t observer)
    {
       ERROR_T ERROR_RetVal = E_OK;
       ret_code_t err_code = NRF_SUCCESS;
    
       BOOL_ProcessingDone = TRUE;
    
    
       if (BOOL_IsActive)
       {
          return err_code;
       }
    
    //   NRF_LOG_DEBUG("serial_dfu_transport_init()");
    
       m_observer = observer;
    
       m_serial.rsp_func           = UART_DFU_Mng_ResponseSend;
       m_serial.payload_free_func  = UART_DFU_Mng_PayloadFree;
       m_serial.mtu                = UART_SERIALPRTC_MTU;
       m_serial.p_rsp_buf          = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SERIALPRTC -
                                                NRF_SERIAL_MAX_RESPONSE_SIZE];
       m_serial.p_low_level_transport = &m_uart_dfu_transport;
    
       nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
    
       uart_config.pselrxd   = RX_PIN_NUMBER_MDBT50Q;
       uart_config.pseltxd   = TX_PIN_NUMBER_MDBT50Q;
       uart_config.pselcts   = CTS_PIN_NUMBER_MDBT50Q;
       uart_config.pselrts   = RTS_PIN_NUMBER_MDBT50Q;
    
       uart_config.hwfc      = NRF_DFU_SERIAL_UART_USES_HWFC ?
             NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
       uart_config.p_context = &m_serial;
    
       NRF_LOG_ERROR("nrf_drv_uart_init");
    
    
       err_code =  nrf_drv_uart_init(&m_uart, &uart_config, UART_DFU_Mng_EventHandler);
       if (err_code != NRF_SUCCESS)
       {
          NRF_LOG_ERROR("UART_DFU_Mng_TransportInit Failed initializing uart %d", err_code);
          return err_code;
       }
    
       err_code = nrf_drv_uart_rx(&m_uart, &UINT8_RxByte, 1);
       if (err_code != NRF_SUCCESS)
       {
    //      NRF_LOG_ERROR("Failed initializing rx");
       }
    
    //   NRF_LOG_DEBUG("serial_dfu_transport_init() completed");
    
       BOOL_IsActive = true;
    
       if (m_observer)
       {
          m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
       }
    
    //todo enable dfu notify send, here or redefine nrf_dfu_init_user(), or send from app
    
       if(FALSE == _BOOL_SysEvtSent)
       {
          _BOOL_SysEvtSent = TRUE;
          ERROR_Check(ERROR_RetVal, UART_DFU_Mng_SysEventDfuNotify());
       }
    
       return err_code;
    }

    The error only shows up once the update/transfer from the STM32H7 is started.

    The main difference is that UARTE has easyDMA support. However, it does not make much of a difference for the UART DFU transport as it only allocates 1 byte for its DMA buffer.

    And what is the difference between NRFX_UART_ENABLED and UART_ENABLED?

    Once the App is running on the nRF and STM32 uC somehow the USART communication seems to be working. So it must be something BL specific on uC or nRF side.

Children
Related