This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How do I redirect printf in ble_template_app?

So I'm trying to start off development of my project using the PCA10040 development board. I have downloaded the SDK16 and built a couple of examples no problem using SES. Now I have started using the ble_app_template  - which builds fine and seems just right to base development on.

Until I try to use the UART. I've searched & tried dozens of things, none of which work and often break the project. Often the Googled answer to a question is just "please look at the UART example" which doesn't help with modifying another example. After two days of trying to get this one simple thing working I've finally decided to ask here..

It looks like the printf redirect is the simplest option, but there isn't any option in the sdconfig.h which is incomplete.

So what do I need to do to turn off the debug logging and to output to the UART?

Thanks!

Parents
  • Hi,

    To enable retargeting of the STDIO functions, you need to include the source file into the project:

    nRF5_SDK_16.0.0_684aa2c\components\libraries\uart\retarget.c

    And enable it in your sdk_config.h file (add the lines yourself if they are not there):

    // <q> RETARGET_ENABLED  - retarget - Retargeting stdio functions
    
    #ifndef RETARGET_ENABLED
    #define RETARGET_ENABLED 1
    #endif

    This uses the app_uart library, so you need to include and initialize this as well, similar to how it is done in the UART peripheral example.

    Also, make sure that the UART backend is disabled for NRF_LOG module, otherwise, you may get errors when initializing logger (if you want to keep logging over RTT, etc.):

    // <e> NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend
    //==========================================================
    #ifndef NRF_LOG_BACKEND_UART_ENABLED
    #define NRF_LOG_BACKEND_UART_ENABLED 0
    #endif

    Best regards,
    Jørgen

  • First of all, you should use app_uart_fifo.c and not app_uart.c. The latter does not support sending/receiving multiple bytes. You also need to enable the module in your sdk_config.h file:

    // <e> APP_UART_ENABLED - app_uart - UART driver
    //==========================================================
    #ifndef APP_UART_ENABLED
    #define APP_UART_ENABLED 1
    #endif
    // <o> APP_UART_DRIVER_INSTANCE  - UART instance used
     
    // <0=> 0 
    
    #ifndef APP_UART_DRIVER_INSTANCE
    #define APP_UART_DRIVER_INSTANCE 0
    #endif
    
    // </e>

    Then you need to setup and initialize the app_uart library in your application before you can use printf():

    #include "app_uart.h"
    
    #define UART_TX_BUF_SIZE 256                         /**< UART TX buffer size. */
    #define UART_RX_BUF_SIZE 256                         /**< UART RX buffer size. */
    
    void uart_error_handle(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }
    
    static void uart_init(void)
    {
    	ret_code_t err_code;
    
        const app_uart_comm_params_t comm_params =
          {
              RX_PIN_NUMBER,
              TX_PIN_NUMBER,
              RTS_PIN_NUMBER,
              CTS_PIN_NUMBER,
              APP_UART_FLOW_CONTROL_DISABLED,
              false,
              NRF_UARTE_BAUDRATE_115200
          };
    
        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);
    }
    
    
    int main(void)
    {
    	...
    	
        uart_init();
        printf("\r\nUART initialized\r\n");
    
    	...
    }

    There may also be other libraries that need to be included (source file) and enabled (in sdk_config.h), for instance, app_fifo, nrf_drv_uart/nrfx_uart/nrfx_uarte, etc. You should then get undefined references when building.

  • After several build fails Finally I have something from the uart! But I have to say it has NOT been a very friendly user experience Disappointed I think half my problems have been things haven't been enabled in sdconfig.h - and the examples don't have complete sdconfig.h so they aren't there to check. It's nice having examples to get started but when one needs to use more than one feature it gets messy. (my application needs BLE GATT, GPIO interrupts, timers and UART)

    Anyway, firstly it complains about NRF_UARTE_BAUDRATE_115200 so I replaced it with UARTE_BAUDRATE_BAUDRATE_Baud115200 for now

    Now I get some output. But there is a strange artifact which means I get the first character repeated 

        uart_init();
        printf("Hello World\r\n");
        printf("Line2\r\n");

    HHello World
    Line2

    I could mask that by changing to printf("\rHello World\r\n") but that won't work for the actual application (the uart won't be for a user interface)

    Any ideas now?

    Thanks

Reply
  • After several build fails Finally I have something from the uart! But I have to say it has NOT been a very friendly user experience Disappointed I think half my problems have been things haven't been enabled in sdconfig.h - and the examples don't have complete sdconfig.h so they aren't there to check. It's nice having examples to get started but when one needs to use more than one feature it gets messy. (my application needs BLE GATT, GPIO interrupts, timers and UART)

    Anyway, firstly it complains about NRF_UARTE_BAUDRATE_115200 so I replaced it with UARTE_BAUDRATE_BAUDRATE_Baud115200 for now

    Now I get some output. But there is a strange artifact which means I get the first character repeated 

        uart_init();
        printf("Hello World\r\n");
        printf("Line2\r\n");

    HHello World
    Line2

    I could mask that by changing to printf("\rHello World\r\n") but that won't work for the actual application (the uart won't be for a user interface)

    Any ideas now?

    Thanks

Children
No Data
Related