NRF51. Создание проекта с поддержкой BLE

Автор: | 14.02.2019

Сегодня создадим с нуля проект с поддержкой BLE в частности профиля Nordic UART over BLE. Хочу сказать про некоторые оговорки, касающиеся стека BLE. Мне удалось запустить проект только со стеком SoftDevice S130. Этот стек для такой цели избыточен, потому что он поддерживает режим работы устройства, как в режиме хоста, так и слейва. Этот функционал, требует больший размер используемой ОЗУ и ПЗУ контроллера. Программа будет запускаться на отладочной плате BLE400.

Общие сведения про BLE.

Bluetooth Low Energy (Bluetooth Smart) ответвление от протокола Bluetooth Classic, предназначенное для работы в малопотребляющих устройствах. Протокол в целом не предназначен для передачи большого объема данных. В версии BLE 4.0, которую и реализует nrf51, в одном пакете может быть до 39 байт данных. В более поздних стандартах протокола кол-во данных было увеличено. Более подробная статья про BLE и кстати на примере нрф чипа можно почитать тут.

Стек для чипов поставляется в виде скомпилированного бинарного файла, так называемого SoftDevice. В зависимости от функционала он делится на несколько  типов.

S110  — периферийное устройство (наиболее подходящий стек для нашей задачи)

S120 — периферийное или центральное устройство

S130 — периферийное и центральное одновременно

Как я говорил выше, был использован стек S130.

Создание проекта.

Теперь создадим проект в IDE Keil uVision 6.

Создание проекта будет происходить аналогично простому примеру с уартом. Естественно, есть нюансы, но об этом далее. Данный проект основан на примере BLE NUS, но с отключенными кнопками.

В проект потребуется добавить следующие пакеты:

  • Board Support:
    • bsp | default
  • CMSIS
    • CORE.
  • Device:
    • Startup
    • StartupConfig.
  • nRF_BLE:
    • BLE_Modules:
      • ble_advdata
      • ble_advertising
      • ble_common
      • ble_common_params
      • ble_service_common
    • BLE_Services: конкретные BLE сервисы
      • ble_nus — Nordic UART Service (тот самый сервис UART over BLE)
  • nRF_Drivers: драйвера периферии
    • app_uart | Fifo (Fifo — Variant)
    • nrf_delay
    • nrf_drv_common
    • nrf_drv_gpiote
    • nrf_drv_uart
    • nrf_error
    • nrf_gpiote
    • nrf_uart
    • pstorage
  • nRF_Libraries:
    • app_error
    • app_fifo
    • app_timer
    • app_util
    • nordic_common
    • nrf_assert
    • retarget
  • nRF_SoftDevice:
    • s130 | Present_only
    • s130_hex
    • Internal:
      • sd_common | default
      • softdevice_present

Теперь о нюансах т.к. мы уже используем исполняемый файл SoftDevice, который использует часть ПЗУ и ОЗУ — наша программа должна иметь некоторое определенное смещение адресов. Про значение этого смещения можно прочитать в документации на софтдевайс. В нашем случаи оно составляет 0x1B000 для флешь памяти и 0x1F00 для оперативной.

Также должны быть прописаны следующие дефайны: BLE_STACK_SUPPORT_REQD BOARD_CUSTOM S130 NRF_LOG_USES_UART=1 NRF51 SOFTDEVICE_PRESENT.

Описание программы.

Сама программа, как я говорил повторяет пример, но имеет небольшие дополнения в функции nus_data_handler.

static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
{
    for (uint32_t i = 0; i < length; i++)
    {
        while(app_uart_put(p_data[i]) != NRF_SUCCESS);
    }
    while(app_uart_put('\n') != NRF_SUCCESS);
    
    switch(p_data[0])
    {
        case '1': nrf_gpio_pin_toggle(LED_1); break;
        case '2': nrf_gpio_pin_toggle(LED_2); break;
        case '3': nrf_gpio_pin_toggle(LED_3); break;        
        case '4': nrf_gpio_pin_toggle(LED_4); break;
    }
}

В этой функции анализируется буфер приема и зажигается соответствующий светодиод на плате BLE400 в зависимости от принятого символа.  Думаю больше пояснений не требуется, тем более в исходный код проекта содержит много подробных комментариев. На что стоит обратить внимание так это на следующую часть кода.

static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;

    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
            break;
        case BLE_ADV_EVT_IDLE:
            ble_advertising_start(BLE_ADV_MODE_FAST);
            //sleep_mode_enter();
            break;
        default:
            break;
    }
}

Это код обработчик advertising событий. Здесь можно увидеть, что при переходе стека в состояние BLE_ADV_EVT_IDLE  то вызывается функция ble_advertising_start(BLE_ADV_MODE_FAST). Т.е. происходит рестарт режима объявления (Advertasing) стека. Дело в том по истечению времени APP_ADV_TIMEOUT_IN_SECONDS (в нашем случае установлен максимально возможный интервал — 180 секунд) и если никакое устройство не было подключено стек перейдет в состояние IDLE. Если мы не хотим, чтобы наше устройство перешло в сон, а хотим оставаться в активном режиме, то соответственно, нужно перезапустить сервис объявлений.

Для проверки работы программы можно воспользоваться отладочным софтом от Nordic Semiconductor — nRF Connect или nRF Toolbox. Программы доступны в Google Play. Они имеет понятый интерфейс и очень полезны для отладки BLE устройств.

Для конкретики будем использовать nRF Connect. Чтобы получить данные с UART терминала нужно подписаться на характеристику TX, для отправки в терминал нужно писать данные в хар-ку RX.

Пример отправки из терминал строки «123» и получение ее в приложении.

Запись же символов от 1 до 4 в хар-ку RX приведет к включению/отключению светодиодов LED1 — LED4 соответственно.

Код проекта доступен на гитхабе.

Полезный документ по настройки проекта.

NRF51. Создание проекта с поддержкой BLE: 1 комментарий

  1. Артем

    Рабочий ли пример на Гитхабе? Не получается запустить в 5-ом кейле. Софт девайс прошивал разнной версии и ваш 2.0.0.7 alfa и 2.0.1 c сайта нордика. Но трассировка виснет на строке SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);
    Спасибо за статью. Вот бы еше разобраться. 51822 смотрю только старыми sdk поддерживается

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *