BLE Hands on Beacon Solution - joe-possum/IoT-Developer-Boot-Camp GitHub Wiki

The following is my entire "app.c" which can be dropped in to Bluetooth - SoC Empty. It requires the Bluetooth Feature Legacy Advertiser and Platform Driver TEMPDRV.

#include "em_common.h"
#include "app_assert.h"
#include "sl_bluetooth.h"
#include "gatt_db.h"
#include "app.h"
#include "tempdrv.h"

// The advertising set handle allocated from Bluetooth stack.
static uint8_t advertising_set_handle = 0xff;

// Structure for Eddystone TLM beacon --- contains big-endian fields
struct __attribute__((packed)) {
  uint8_t len_serviceList, type_serviceList;
  uint16_t serviceList[1];
  uint8_t len_serviceData, type_serviceData;
  uint16_t id;
  uint8_t frameType, version;
  uint16_t be_mvBattery;
  int16_t be_temperature;
  uint32_t be_pduCount, be_time;
} advData = { .len_serviceList = 3,
    .type_serviceList = 3,
    .serviceList = { 0xfeaa },
    .len_serviceData = 0x11,
    .type_serviceData = 0x16,
    .id = 0xfeaa,
    .frameType = 0x20,
    .version = 0,
    .be_mvBattery = 0,
};

// Flag to indicate AdvData should be updated in app_process_action()
bool update_advData = false;

// Running counter for advertisement packets
uint32_t advCount;

void setAdvData(void) {
  sl_status_t sc;
  uint16_t tx_packets, rx_packets, crc_errors, failures;
  int16_t temperature = TEMPDRV_GetTemp() << 8;
  uint32_t time = 10*sl_sleeptimer_get_tick_count64()/sl_sleeptimer_get_timer_frequency();
  sc = sl_bt_system_get_counters(1, &tx_packets, &rx_packets, &crc_errors, &failures);
  app_assert_status(sc);
  advCount += rx_packets;
  advData.be_temperature = __builtin_bswap16((int16_t) temperature);
  advData.be_pduCount = __builtin_bswap32(advCount);
  advData.be_time = __builtin_bswap32(time);
  sc = sl_bt_legacy_advertiser_set_data(advertising_set_handle, 0, 22, (uint8_t*)&advData);
  app_assert_status(sc);
}

void app_init(void)
{
  app_assert(22 == sizeof(advData));
  TEMPDRV_Init();
  advCount = 0;
}

SL_WEAK void app_process_action(void)
{
  if(update_advData) setAdvData();
}

void sl_bt_on_event(sl_bt_msg_t *evt)
{
  sl_status_t sc;

  switch (SL_BT_MSG_ID(evt->header)) {
    case sl_bt_evt_system_boot_id:

      // Create an advertising set.
      sc = sl_bt_advertiser_create_set(&advertising_set_handle);
      app_assert_status(sc);

      // Set advertising interval to 100ms.
      sc = sl_bt_advertiser_set_timing(
        advertising_set_handle,
        160, // min. adv. interval (milliseconds * 1.6)
        160, // max. adv. interval (milliseconds * 1.6)
        0,   // adv. duration
        0);  // max. num. adv. events
      app_assert_status(sc);

      // Set initial data before starting advertisement
      setAdvData();

      // Start advertising
      sc = sl_bt_legacy_advertiser_start(advertising_set_handle,
                                         sl_bt_advertiser_non_connectable);
      app_assert_status(sc);
      update_advData = true;
      break;

    // Default event handler.
    default:
      app_assert("No other events expected");
      break;
  }
}
⚠️ **GitHub.com Fallback** ⚠️