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

Sending messages to PC

Hi

I am using the SDK_16.0.0 and SDK_for_mesh_4.0.

Board: PCA10056, nRF52840.

1) I try to send strings to from the nRF to PC and then, using a python script, poll messages from the COM-Port.

I tried the UART example from the SDK16 and it worked. All the messages i send with printf() are received from my python script. 

Now I'm trying to use this printf() function in my main.c file in the experimental_lpn example from the SDK_for_mesh_4.0. The code looks like this:

static void button_event_handler(uint32_t button_number)
{
    switch(button_number)
    {
        case 0:
            send_app_state(!hal_led_pin_get(BSP_LED_0));
            printf("\r\nUART example started.\r\n");        //this does not work
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "test\n", button_number);
            ERROR_CHECK(app_timer_start(m_state_on_timer,
                                        HAL_MS_TO_RTC_TICKS(APP_STATE_ON_TIMEOUT_MS),
                                        NULL));
            break;

    }
}

if i don't include anything else in this main.c file, the program runs on the DevKit. However when i press the button_0, the LED goes on and my program then gets stuck in the printf() function. When I remove the printf() function, I can toggle the LED0 with button_0.

2) I then tried to edit the sdk_config.h file in experimental_lpn/include/sdk_config.h and set all the ENABLE_UART to 1. 

#ifndef NRFX_UART_ENABLED
#define NRFX_UART_ENABLED 1
#endif

#ifndef UART_ENABLED
#define UART_ENABLED 1
#endif

sdk_config.h

it should look similar to the sdk_config.h from the uart example. This did however not change anything in functionality.

3) Then I thought i should just include everything that's also included in the uart example:

#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

when i tried to build and run my code now, i get the error: Fatal error: can't create build/lpn_nrf52840_xxAA_s140_7.0.1_Debug/obj/lpn.o: Permission denied

my final main.c looks like this:

/* Copyright (c) 2010 - 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 <string.h>
#include <stdio.h>
#include <stdbool.h>

/* HAL */
#include "boards.h"
#include "simple_hal.h"
#include "app_timer.h"

/* Core */
#include "nrf_mesh_configure.h"
#include "nrf_mesh.h"
#include "mesh_stack.h"
#include "device_state_manager.h"
#include "access_config.h"
#include "proxy.h"

/* LPN */
#include "mesh_lpn.h"
#include "mesh_friendship_types.h"

/* Provisioning and configuration */
#include "mesh_provisionee.h"
#include "mesh_app_utils.h"

/* Models */
#include "generic_onoff_client.h"

/* Logging and RTT */
#include "nrf_log.h"
#include "log.h"
#include "rtt_input.h"

/* Example specific includes */
#include "app_config.h"
#include "nrf_mesh_config_examples.h"
#include "example_common.h"
#include "ble_softdevice_support.h"
#include "ble_dfu_support.h"

/* nRF5 SDK */
#include "nrf_soc.h"
#include "nrf_pwr_mgmt.h"

/* UART */
#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

/** The maximum duration to scan for incoming Friend Offers. */
#define FRIEND_REQUEST_TIMEOUT_MS (MESH_LPN_FRIEND_REQUEST_TIMEOUT_MAX_MS)
/** The upper limit for two subsequent Friend Polls. */
#define POLL_TIMEOUT_MS (SEC_TO_MS(10))
/** The time between LPN sending a request and listening for a response. */
#define RECEIVE_DELAY_MS (100)

#define APP_STATE_OFF                   0
#define APP_STATE_ON                    1

/** The time before state ON is switched to OFF */
#define APP_STATE_ON_TIMEOUT_MS         (SEC_TO_MS(5))

#define APP_UNACK_MSG_REPEAT_COUNT      2
#define STATIC_AUTH_DATA                {0x6E, 0x6F, 0x72, 0x64, 0x69, 0x63, 0x5F, 0x65, \
                                         0x78, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x5F, 0x31}

static generic_onoff_client_t m_client;
static bool                   m_device_provisioned;

/** The timer emulates an occupancy sensor by turning lights off after a certain interval,
 * when no activity is detected. The timer starts after an On State message is sent
 * and sends an Off State message after the timeout @ref APP_STATE_ON_TIMEOUT_MS. */
APP_TIMER_DEF(m_state_on_timer);

/* Forward declaration */
static void app_gen_onoff_client_publish_interval_cb(access_model_handle_t handle, void * p_self);
static void app_generic_onoff_client_status_cb(const generic_onoff_client_t * p_self,
                                               const access_message_rx_meta_t * p_meta,
                                               const generic_onoff_status_params_t * p_in);
static void app_mesh_core_event_cb (const nrf_mesh_evt_t * p_evt);
static void send_app_state(bool is_state_on);

static nrf_mesh_evt_handler_t m_mesh_core_event_handler = { .evt_cb = app_mesh_core_event_cb };

static const generic_onoff_client_callbacks_t client_cbs =
{
    .onoff_status_cb = app_generic_onoff_client_status_cb,
    .ack_transaction_status_cb = NULL,
    .periodic_publish_cb = app_gen_onoff_client_publish_interval_cb
};

static void device_identification_start_cb(uint8_t attention_duration_s)
{
#if SIMPLE_HAL_LEDS_ENABLED
    hal_led_mask_set(LEDS_MASK, false);
    hal_led_blink_ms(BSP_LED_2_MASK  | BSP_LED_3_MASK,
                     LED_BLINK_ATTENTION_INTERVAL_MS,
                     LED_BLINK_ATTENTION_COUNT(attention_duration_s));
#endif
}

static void provisioning_aborted_cb(void)
{
#if SIMPLE_HAL_LEDS_ENABLED
    hal_led_blink_stop();
#endif
}

static void provisioning_complete_cb(void)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Successfully provisioned\n");

    /* Restores the application parameters after switching from the Provisioning
     * service to the Proxy  */
    gap_params_init();
    conn_params_init();

#if BLE_DFU_SUPPORT_ENABLED
    ble_dfu_support_service_init();
#endif

    dsm_local_unicast_address_t node_address;
    dsm_local_unicast_addresses_get(&node_address);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Node Address: 0x%04x \n", node_address.address_start);

#if SIMPLE_HAL_LEDS_ENABLED
    hal_led_blink_stop();
    hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_PROV);
#endif
}

/* This callback is called periodically if model is configured for periodic publishing */
static void app_gen_onoff_client_publish_interval_cb(access_model_handle_t handle, void * p_self)
{
     __LOG(LOG_SRC_APP, LOG_LEVEL_WARN, "Publish desired message here.\n");
}

/* Generic OnOff client model interface: Process the received status message in this callback */
static void app_generic_onoff_client_status_cb(const generic_onoff_client_t * p_self,
                                               const access_message_rx_meta_t * p_meta,
                                               const generic_onoff_status_params_t * p_in)
{
    if (p_in->remaining_time_ms > 0)
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "OnOff server: 0x%04x, Present OnOff: %d, Target OnOff: %d, Remaining Time: %d ms\n",
              p_meta->src.value, p_in->present_on_off, p_in->target_on_off, p_in->remaining_time_ms);
    }
    else
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "OnOff server: 0x%04x, Present OnOff: %d\n",
              p_meta->src.value, p_in->present_on_off);
    }
}

static void state_on_timer_handler(void *p_unused)
{
    UNUSED_VARIABLE(p_unused);

    /* Send state off */
    send_app_state(APP_STATE_OFF);
}

static void node_reset(void)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- Node reset  -----\n");

#if SIMPLE_HAL_LEDS_ENABLED
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_RESET);
#endif

    /* This function may return if there are ongoing flash operations. */
    mesh_stack_device_reset();
}

static void config_server_evt_cb(const config_server_evt_t * p_evt)
{
    if (p_evt->type == CONFIG_SERVER_EVT_NODE_RESET)
    {
        node_reset();
    }
}

static void send_app_state(bool is_state_on)
{
    uint32_t status = NRF_SUCCESS;
    generic_onoff_set_params_t set_params;
    model_transition_t transition_params;
    static uint8_t tid = 0;

    set_params.on_off = is_state_on;
    set_params.tid = tid++;
    transition_params.delay_ms = APP_CONFIG_ONOFF_DELAY_MS;
    transition_params.transition_time_ms = APP_CONFIG_ONOFF_TRANSITION_TIME_MS;
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Sending msg: ONOFF SET %d\n", set_params.on_off);

    /* Demonstrate un-acknowledged transaction, using the client model instance */
    /* In this examples, users will not be blocked if the model is busy */
    status = generic_onoff_client_set_unack(&m_client,
                                            &set_params,
                                            &transition_params,
                                            APP_UNACK_MSG_REPEAT_COUNT);

    switch (status)
    {
        case NRF_SUCCESS:
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_pin_set(BSP_LED_0, set_params.on_off);
#endif
            break;

        case NRF_ERROR_NO_MEM:
        case NRF_ERROR_BUSY:
        case NRF_ERROR_INVALID_STATE:
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Cannot send the message\n");
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_NO_REPLY);
#endif
            break;

        case NRF_ERROR_INVALID_PARAM:
            /* Publication not enabled for this client. One (or more) of the following is wrong:
             * - An application key is missing, or there is no application key bound to the model
             * - The client does not have its publication state set
             *
             * It is the provisioner that adds an application key, binds it to the model and sets
             * the model's publication state.
             */
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Publication not configured\n");
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_ERROR);
#endif
            break;

        default:
            ERROR_CHECK(status);
            break;
    }
}

static void initiate_friendship()
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initiating the friendship establishment procedure.\n");

    mesh_lpn_friend_request_t freq;
    freq.friend_criteria.friend_queue_size_min_log = MESH_FRIENDSHIP_MIN_FRIEND_QUEUE_SIZE_16;
    freq.friend_criteria.receive_window_factor = MESH_FRIENDSHIP_RECEIVE_WINDOW_FACTOR_1_0;
    freq.friend_criteria.rssi_factor = MESH_FRIENDSHIP_RSSI_FACTOR_2_0;
    freq.poll_timeout_ms = POLL_TIMEOUT_MS;
    freq.receive_delay_ms = RECEIVE_DELAY_MS;

    uint32_t status = mesh_lpn_friend_request(freq, FRIEND_REQUEST_TIMEOUT_MS);
    switch (status)
    {
        case NRF_SUCCESS:
            break;

        case NRF_ERROR_INVALID_STATE:
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Already in an active friendship\n");
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_ERROR);
#endif
            break;

        case NRF_ERROR_INVALID_PARAM:
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Friend request parameters outside of valid ranges.\n");
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_ERROR);
#endif
            break;

        default:
            ERROR_CHECK(status);
            break;
    }
}

static void terminate_friendship()
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Terminating the active friendship\n");

    uint32_t status = mesh_lpn_friendship_terminate();
    switch (status)
    {
        case NRF_SUCCESS:
            break;

        case NRF_ERROR_INVALID_STATE:
            __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR, "Not in an active friendship\n");
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_ERROR);
#endif
            break;

        default:
            ERROR_CHECK(status);
            break;
    }
}

static void button_event_handler(uint32_t button_number)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Button %u pressed\n", button_number);

    if (!mesh_stack_is_device_provisioned())
    {
        __LOG(LOG_SRC_APP, LOG_LEVEL_WARN, "The device is not provisioned.\n");
        return;
    }

    ERROR_CHECK(app_timer_stop(m_state_on_timer));

    switch(button_number)
    {
        case 0:
            send_app_state(!hal_led_pin_get(BSP_LED_0));
            printf("\r\nUART example started.\r\n");
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Blyyyat\n", button_number);
            ERROR_CHECK(app_timer_start(m_state_on_timer,
                                        HAL_MS_TO_RTC_TICKS(APP_STATE_ON_TIMEOUT_MS),
                                        NULL));
            break;

        case 1:
            send_app_state(APP_STATE_OFF);
            break;

        case 2:
        {
            if (!mesh_lpn_is_in_friendship())
            {
                initiate_friendship();
            }
            else /* In a friendship */
            {
                terminate_friendship();
            }
            break;
        }

        /* Initiate node reset */
        case 3:
        {
            /* Clear all the states to reset the node. */
            (void) proxy_stop();
            mesh_stack_config_clear();
            node_reset();
            break;
        }
    }
}

#if RTT_INPUT_ENABLED
static void rtt_input_handler(int key)
{
    if (key >= '0' && key <= '3')
    {
        uint32_t button_number = key - '0';
        button_event_handler(button_number);
    }
}
#endif

static void app_mesh_core_event_cb(const nrf_mesh_evt_t * p_evt)
{
    /* USER_NOTE: User can insert mesh core event proceesing here */
    switch (p_evt->type)
    {
        case NRF_MESH_EVT_LPN_FRIEND_OFFER:
        {
            const nrf_mesh_evt_lpn_friend_offer_t *p_offer = &p_evt->params.friend_offer;

            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
                  "Received friend offer from 0x%04X\n",
                  p_offer->src);

            uint32_t status = mesh_lpn_friend_accept(p_offer);
            switch (status)
            {
                case NRF_SUCCESS:
                    break;

                case NRF_ERROR_INVALID_STATE:
                case NRF_ERROR_INVALID_PARAM:
                case NRF_ERROR_NULL:
                    __LOG(LOG_SRC_APP, LOG_LEVEL_ERROR,
                          "Cannot accept friendship: %d\n",
                          status);
#if SIMPLE_HAL_LEDS_ENABLED
                    hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS,
                                     LED_BLINK_CNT_ERROR);
#endif
                    break;

                default:
                    ERROR_CHECK(status);
                    break;
            }

            break;
        }

        case NRF_MESH_EVT_LPN_FRIEND_POLL_COMPLETE:
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Friend poll procedure complete\n");
            break;

        case NRF_MESH_EVT_LPN_FRIEND_REQUEST_TIMEOUT:
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Friend Request timed out\n");
#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_blink_ms(LEDS_MASK, LED_BLINK_SHORT_INTERVAL_MS, LED_BLINK_CNT_ERROR);
#endif
            break;

        case NRF_MESH_EVT_FRIENDSHIP_ESTABLISHED:
        {
            const nrf_mesh_evt_friendship_established_t *p_est =
                    &p_evt->params.friendship_established;
            (void) p_est;

            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
                  "Friendship established with: 0x%04X\n",
                  p_est->friend_src);

#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_pin_set(BSP_LED_1, true);
#endif
            break;
        }

        case NRF_MESH_EVT_FRIENDSHIP_TERMINATED:
        {
            const nrf_mesh_evt_friendship_terminated_t *p_term = &p_evt->params.friendship_terminated;
            UNUSED_VARIABLE(p_term);

            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO,
                  "Friendship with 0x%04X terminated. Reason: %d\n",
                  p_term->friend_src, p_term->reason);

#if SIMPLE_HAL_LEDS_ENABLED
            hal_led_pin_set(BSP_LED_1, false);
#endif

            ERROR_CHECK(app_timer_stop(m_state_on_timer));
            break;
        }

        default:
            break;
    }
}

static void models_init_cb(void)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Initializing and adding models\n");

    m_client.settings.p_callbacks = &client_cbs;
    m_client.settings.timeout = 0;
    m_client.settings.force_segmented = false;
    m_client.settings.transmic_size = APP_CONFIG_MIC_SIZE;

    ERROR_CHECK(generic_onoff_client_init(&m_client, 1));
}

static void mesh_init(void)
{
    mesh_stack_init_params_t init_params =
    {
        .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
        .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
        .core.p_uuid             = NULL,
        .models.models_init_cb   = models_init_cb,
        .models.config_server_cb = config_server_evt_cb
    };

    uint32_t status = mesh_stack_init(&init_params, &m_device_provisioned);
    switch (status)
    {
        case NRF_ERROR_INVALID_DATA:
            __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Data in the persistent memory was corrupted. Device starts as unprovisioned.\n");
            break;
        case NRF_SUCCESS:
            break;
        default:
            ERROR_CHECK(status);
    }

    /* Register event handler to receive LPN and friendship events. */
    nrf_mesh_evt_handler_add(&m_mesh_core_event_handler);
}

#if BLE_DFU_SUPPORT_ENABLED
/** Initializes Power Management. Required for BLE DFU. */
static void power_management_init(void)
{
    uint32_t err_code = nrf_pwr_mgmt_init();
    APP_ERROR_CHECK(err_code);
}
#endif

static void initialize(void)
{
    __LOG_INIT(LOG_SRC_APP | LOG_SRC_ACCESS, LOG_LEVEL_INFO, LOG_CALLBACK_DEFAULT);
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "----- BLE Mesh LPN Demo -----\n");

    ERROR_CHECK(app_timer_init());

#if SIMPLE_HAL_LEDS_ENABLED
    hal_leds_init();
#endif

#if BUTTON_BOARD
    ERROR_CHECK(hal_buttons_init(button_event_handler));
#endif

#if BLE_DFU_SUPPORT_ENABLED
    ble_dfu_support_init();
    power_management_init();
#endif

    ble_stack_init();
    gap_params_init();
    conn_params_init();

#if BLE_DFU_SUPPORT_ENABLED
    ble_dfu_support_service_init();
#endif

    mesh_init();
    ERROR_CHECK(sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE));

    mesh_lpn_init();
}

static void start(void)
{
#if RTT_INPUT_ENABLED
    rtt_input_enable(rtt_input_handler, RTT_INPUT_POLL_PERIOD_MS);
#endif

    ERROR_CHECK(app_timer_create(&m_state_on_timer, APP_TIMER_MODE_SINGLE_SHOT,
                                 state_on_timer_handler));

    if (!m_device_provisioned)
    {
        static const uint8_t static_auth_data[NRF_MESH_KEY_SIZE] = STATIC_AUTH_DATA;
        mesh_provisionee_start_params_t prov_start_params =
        {
            .p_static_data    = static_auth_data,
            .prov_complete_cb = provisioning_complete_cb,
            .prov_device_identification_start_cb = device_identification_start_cb,
            .prov_device_identification_stop_cb = NULL,
            .prov_abort_cb = provisioning_aborted_cb,
            .p_device_uri = EX_URI_LPN
        };
        ERROR_CHECK(mesh_provisionee_prov_start(&prov_start_params));
    }

    mesh_app_uuid_print(nrf_mesh_configure_device_uuid_get());

    ERROR_CHECK(mesh_stack_start());

#if SIMPLE_HAL_LEDS_ENABLED
    hal_led_mask_set(LEDS_MASK, LED_MASK_STATE_OFF);
    hal_led_blink_ms(LEDS_MASK, LED_BLINK_INTERVAL_MS, LED_BLINK_CNT_START);
#endif
}

int main(void)
{
    initialize();
    start();

    for (;;)
    {
        (void)sd_app_evt_wait();
    }
}

I have no idea how to proceed now. All i want is to send some strings from my LPN to my PC and read it using python (I have a functioning script to read a COM-Port).

Is there some easier way to do this where I don't have to include a hundred different .h files?

Thank you.

BR.

  • Hi Brocc, 


    If you want to be able to printout on UART you need to implement the uart module. This include all the .c files of the libraries and retarget.c also must be included. You can't just use printf() without the uart library. 

  • Hi Hung,

    A co-worker told me that it should be sufficient to just include the the paths to the .h files which i include in the main.c. It should then inlude the .c files automatically.

    I did this in the project optins/user defined libraries and added all the relative paths needed (I basically copied the paths from the uart example). For example, i have #include "bsp.h" in my main.c, so I added the path ../../../../nRF5_SDK_16/components/libraries/bsp to the project path. However, I now have the error message "app_button.h: No such file or directory", which is inside the app_uart.h file, so I would need to include this file as well. This would go on forever.

    In the uart example, those subfiles are nowhere declared and it still works. Am I doing this wrong?

    Thanks

  • Okay I found the answer to this problem; from the uart example, right click on the project->options->dropdown common->preprocessor->Preprocessor definitions-> copy all the entries and past them in the Preprocessor definitions of my project. These definitions disable the #include "bsp.h".

    now the only problem is that in the nrf_drv_uart.h file there are #defines that should be grayed out, which are not. 

    #include <nrfx.h>
    
    #if defined(UARTE_PRESENT) && NRFX_CHECK(NRFX_UARTE_ENABLED)
        #define NRF_DRV_UART_WITH_UARTE
    #endif

    this code should not be grayedd out, but it is for me. This means that NRFX_UARTE_ENABLED should be defined. this is defined in the apply_old_config.h. 

    #if defined(UART_ENABLED)
    
    #undef NRFX_UART_ENABLED
    #define NRFX_UART_ENABLED   (UART_ENABLED && NRFX_UART0_ENABLED)
    #undef NRFX_UARTE_ENABLED
    #define NRFX_UARTE_ENABLED  (UART_ENABLED && (NRFX_UARTE0_ENABLED || NRFX_UARTE1_ENABLED))
    So UART_ENABLED has to be defined for this to work.

    I did define UART_ENABLED in my sdk_config.h: 

    // <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
    //==========================================================
    #ifndef UART_ENABLED
    #define UART_ENABLED 1  // was o in server example
    #endif

    but it still doesn't work. 

    Any help? Thanks

  • I got everything working, I now have UART support on my mesh light_switch example and can use the printf(). I will quickly describe what I did if anyone else comes across this post:

    1) open the UART example from the SDK16\examples\peripheral\uart\pca10056\blank\ses.

    Also open the lightswitch example from nRF5_SDK_Mesh_4\examples\light_switch\server.

    2) From UART example, right click on Project 'uart_pca10056' and got to options. On the Dropdown window, select Common. On the left side, select 'Preprocessor'. From 'Preprocessor Definitions' and 'User include Directories', copy everything and paste them in the corresponding lightswitch example. You will have to adjust the paths for the 'User Include Directories' in the light_switch example. It will look something like this:

    include
    ../include
    ../../common/include
    ../../../external/rtt/include
    ../../../../nRF5_SDK_16/components/libraries/uart
    ../../../../nRF5_SDK_16/components/libraries/bsp
    ../../../../nRF5_SDK_16/components/ble/common
    ../../../../nRF5_SDK_16/components/softdevice/common
    ../../../../nRF5_SDK_16/components/libraries/strerror
    ../../../../nRF5_SDK_16/components/libraries/atomic
    ../../../models/foundation/config/include
    ../../../models/foundation/health/include
    ../../../models/model_spec/generic_onoff/include
    ../../../models/model_spec/common/include
    ../../../mesh/friend/api
    ../../../mesh/friend/include
    ../../../mesh/bearer/api
    ../../../mesh/bearer/include
    ../../../mesh/stack/api
    ../../../mesh/core/api
    ../../../mesh/core/include
    ../../../mesh/access/api
    ../../../mesh/access/include
    ../../../mesh/dfu/api
    ../../../mesh/dfu/include
    ../../../mesh/prov/api
    ../../../mesh/prov/include
    ../../../mesh/gatt/api
    ../../../mesh/gatt/include
    ../../../../nRF5_SDK_16/components/softdevice/s140/headers/
    ../../../../nRF5_SDK_16/components/softdevice/s140/headers/nrf52/
    ../../../../nRF5_SDK_16/modules/nrfx
    ../../../../nRF5_SDK_16/modules/nrfx/mdk
    ../../../../nRF5_SDK_16/modules/nrfx/hal
    ../../../../nRF5_SDK_16/components/toolchain/cmsis/include
    ../../../../nRF5_SDK_16/components/toolchain/gcc
    ../../../../nRF5_SDK_16/components/toolchain/cmsis/dsp/GCC
    ../../../../nRF5_SDK_16/components/boards
    ../../../../nRF5_SDK_16/integration/nrfx
    ../../../../nRF5_SDK_16/components/libraries/util
    ../../../../nRF5_SDK_16/components/libraries/timer
    ../../../../nRF5_SDK_16/components/libraries/log
    ../../../../nRF5_SDK_16/components/libraries/log/src
    ../../../../nRF5_SDK_16/components/libraries/experimental_section_vars
    ../../../../nRF5_SDK_16/components/libraries/delay
    ../../../external/micro-ecc
    ../../../mesh/core/include
    ../../../../nRF5_SDK_16/components
    ../../../../nRF5_SDK_16/components/boards
    ../../../../nRF5_SDK_16/components/drivers_nrf/nrf_soc_nosd
    ../../../../nRF5_SDK_16/components/libraries/atomic
    ../../../../nRF5_SDK_16/components/libraries/balloc
    ../../../../nRF5_SDK_16/components/libraries/delay
    ../../../../nRF5_SDK_16/components/libraries/experimental_section_vars
    ../../../../nRF5_SDK_16/components/libraries/fifo
    ../../../../nRF5_SDK_16/components/libraries/log
    ../../../../nRF5_SDK_16/components/libraries/log/src
    ../../../../nRF5_SDK_16/components/libraries/memobj
    ../../../../nRF5_SDK_16/components/libraries/ringbuf
    ../../../../nRF5_SDK_16/components/libraries/strerror
    ../../../../nRF5_SDK_16/components/libraries/uart
    ../../../../nRF5_SDK_16/components/libraries/util
    ../../../../nRF5_SDK_16/components/toolchain/cmsis/include
    ../../../../nRF5_SDK_16/external/fprintf
    ../../../../nRF5_SDK_16/integration/nrfx
    ../../../../nRF5_SDK_16/integration/nrfx/legacy
    ./../../../nRF5_SDK_16/modules/nrfx
    ../../../../nRF5_SDK_16/modules/nrfx/drivers/include
    ../../../../nRF5_SDK_16/modules/nrfx/hal
    ../../../../nRF5_SDK_16/modules/nrfx/mdk

    The 'Preprocessor Definitions' of my light_switch example looks like this:

    NO_VTOR_CONFIG
    USE_APP_CONFIG
    CONFIG_APP_IN_CORE
    NRF52_SERIES
    NRF52840
    NRF52840_XXAA
    S140
    SOFTDEVICE_PRESENT
    NRF_SD_BLE_API_VERSION=7
    BOARD_PCA10056
    CONFIG_GPIO_AS_PINRESET
    BOARD_PCA10056
    BSP_DEFINES_ONLY
    CONFIG_GPIO_AS_PINRESET
    FLOAT_ABI_HARD
    INITIALIZE_USER_SECTIONS
    NO_VTOR_CONFIG
    NRF52840_XXAA

    3) in the UART project, there are alot of .c files that are not included in the light_switch example. I'm not sure if you do have to manually include them into you light_switch example, but here is what I did:

    On the UART project, I right-click the .c file, e.g. the nrf_drv_uart.c, and press 'select in Folder explorer'. I then drag-and-drop this file in my light_switch project (you might want to create a new Folder in the Project to drop your Files in). I did this with almost all files, but make sure to not copy anything that is already in your light_switch example.

    4) Most important part: configure the sdk_config.h file in nRF5_SDK_Mesh_4\examples\light_switch\server\include.

    this is the tricky part. What I did first is to compare the sdk_config.h from the UART example with the sdk_config.h from the light_switch example. user the Website https://www.diffchecker.com/ for this. I then copied the #defines from the UART config that are not in the light_switch config and pasted them at the bottom (before the #dif)  of the light_switch config: 

    //==========================================================
    // START Changes from USER - enable UART
    //==========================================================
    
    // <e> NRFX_PRS_ENABLED - nrfx_prs - Peripheral Resource Sharing module
    //==========================================================
    #ifndef NRFX_PRS_ENABLED
    #define NRFX_PRS_ENABLED 1
    #endif
    // <q> NRFX_PRS_BOX_0_ENABLED  - Enables box 0 in the module.
     
    #ifndef NRFX_PRS_BOX_0_ENABLED
    #define NRFX_PRS_BOX_0_ENABLED 0
    #endif
    // <q> NRFX_PRS_BOX_1_ENABLED  - Enables box 1 in the module.
     
    #ifndef NRFX_PRS_BOX_1_ENABLED
    #define NRFX_PRS_BOX_1_ENABLED 0
    #endif
    // <q> NRFX_PRS_BOX_2_ENABLED  - Enables box 2 in the module.
     
    #ifndef NRFX_PRS_BOX_2_ENABLED
    #define NRFX_PRS_BOX_2_ENABLED 0
    #endif
    // <q> NRFX_PRS_BOX_3_ENABLED  - Enables box 3 in the module.
     
    #ifndef NRFX_PRS_BOX_3_ENABLED
    #define NRFX_PRS_BOX_3_ENABLED 0
    #endif
    // <q> NRFX_PRS_BOX_4_ENABLED  - Enables box 4 in the module.
     
    #ifndef NRFX_PRS_BOX_4_ENABLED
    #define NRFX_PRS_BOX_4_ENABLED 1
    #endif
    // <e> NRFX_PRS_CONFIG_LOG_ENABLED - Enables logging in the module.
    //==========================================================
    #ifndef NRFX_PRS_CONFIG_LOG_ENABLED
    #define NRFX_PRS_CONFIG_LOG_ENABLED 0
    #endif
    // <o> NRFX_PRS_CONFIG_LOG_LEVEL  - Default Severity level
     
    // <0=> Off 
    // <1=> Error 
    // <2=> Warning 
    // <3=> Info 
    // <4=> Debug 
    #ifndef NRFX_PRS_CONFIG_LOG_LEVEL
    #define NRFX_PRS_CONFIG_LOG_LEVEL 3
    #endif
    // <o> NRFX_PRS_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_PRS_CONFIG_INFO_COLOR
    #define NRFX_PRS_CONFIG_INFO_COLOR 0
    #endif
    // <o> NRFX_PRS_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_PRS_CONFIG_DEBUG_COLOR
    #define NRFX_PRS_CONFIG_DEBUG_COLOR 0
    #endif
    
    
    #ifndef NRFX_PRS_BOX_4_ENABLED
    #define NRFX_PRS_BOX_4_ENABLED 1
    #endif
    
    #ifndef NRFX_PRS_CONFIG_DEBUG_COLOR
    #define NRFX_PRS_CONFIG_DEBUG_COLOR 0
    #endif
    
    // <o> NRFX_UARTE1_ENABLED - Enable UARTE1 instance 
    #ifndef NRFX_UARTE1_ENABLED
    #define NRFX_UARTE1_ENABLED 0
    #endif
    
    // <e> UART1_ENABLED - Enable UART1 instance
    //==========================================================
    #ifndef UART1_ENABLED
    #define UART1_ENABLED 0
    #endif
    //==========================================================
    // <q> APP_FIFO_ENABLED  - app_fifo - Software FIFO implementation
     
    #ifndef APP_FIFO_ENABLED
    #define APP_FIFO_ENABLED 1
    #endif
    
    // <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
    
    // <q> RETARGET_ENABLED  - retarget - Retargeting stdio functions
    #ifndef RETARGET_ENABLED
    #define RETARGET_ENABLED 1
    #endif
    //==========================================================
    // END Changes from USER - enable UART
    //=============================================

    I then enabled everything in my light_switch config that was also enabled in the UART config. What did mess up my project was the #define UART_LEGACY_SUPPORT. This is set to 1 in the UART example, I had to set it to 0 for my project to work. In short, here's my config file: 0724.sdk_config.h

    5) to enable the UART in the light_switch example, copy some code from the UART main.c to the light_switch main.c, to be more precice, paste this at the top of your light_switch main.c file: 

    /* UART stuff */
    #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 ENABLE_LOOPBACK_TEST  /**< if defined, then this example will be a loopback test, which means that TX should be connected to RX to get data loopback. */
    
    #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 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);
        }
    }
    
    /* When UART is used for communication with the host do not use flow control.*/
    #define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED

    and paste this inside the main function in the main.c:

        uint32_t err_code;
    
        bsp_board_init(BSP_INIT_LEDS);
    
        const app_uart_comm_params_t comm_params =
          {
              RX_PIN_NUMBER,
              TX_PIN_NUMBER,
              RTS_PIN_NUMBER,
              CTS_PIN_NUMBER,
              UART_HWFC,
              false,
    #if defined (UART_PRESENT)
              NRF_UART_BAUDRATE_115200
    #else
              NRF_UARTE_BAUDRATE_115200
    #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);
    

    6) Now you can user the printf() function wherever you want in your main.c file and read it on your PC with HTerm or Putty.

Related