BLE_API wrapper library for STMicroelectronics' BlueNRG Bluetooth Low Energy expansion board shield
Fork of X_NUCLEO_IDB0XA1 by
Revision 232:f2a7da5d24e1, committed 2016-06-17
- Comitter:
- avilei
- Date:
- Fri Jun 17 16:07:05 2016 +0000
- Parent:
- 231:b94d080127c7
- Commit message:
- Add firmware update capabilities
Changed in this revision
diff -r b94d080127c7 -r f2a7da5d24e1 source/BlueNRGDevice.cpp --- a/source/BlueNRGDevice.cpp Thu Jun 16 12:08:19 2016 +0000 +++ b/source/BlueNRGDevice.cpp Fri Jun 17 16:07:05 2016 +0000 @@ -108,6 +108,13 @@ nCS_ = 1; wait_us(500); + + // Set the interrupt handler for the device + irq_.mode(PullDown); // set irq mode + irq_.rise(&HCI_Isr); + + // Prepare communication between the host and the BTLE HW device + btleInitHW(); } /**************************************************************************/ @@ -119,6 +126,37 @@ { } +/** + * @brief Get BlueNRG HW updater version + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t BlueNRGDevice::getUpdaterHardwareVersion(uint8_t *upd_hw_version) +{ + uint8_t status; + + status = btleGetUpdaterHWVersion(upd_hw_version); + + return (status); +} + +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int BlueNRGDevice::updateFirmware(const uint8_t *fw_image, uint32_t fw_size) +{ + int status = btleUpdateFirmware(fw_image, fw_size); + + return (status); +} + /** @brief Initialises anything required to start using BLE @@ -135,14 +173,11 @@ callback.call(&context); return BLE_ERROR_ALREADY_INITIALIZED; } - - // Set the interrupt handler for the device - irq_.mode(PullDown); // betzw: set irq mode - irq_.rise(&HCI_Isr); /* ToDo: Clear memory contents, reset the SD, etc. */ + // Start the BlueNRG/BlueNRG-MS stack // By default, we set the device GAP role to PERIPHERAL - btleInit(BlueNRGGap::getInstance().getIsSetAddress(), GAP_PERIPHERAL_ROLE_IDB04A1); + btleStart(BlueNRGGap::getInstance().getIsSetAddress(), GAP_PERIPHERAL_ROLE_IDB04A1); isInitialized = true; BLE::InitializationCompleteCallbackContext context = {
diff -r b94d080127c7 -r f2a7da5d24e1 source/bluenrg-hci/hci/controller/bluenrg_utils.c --- a/source/bluenrg-hci/hci/controller/bluenrg_utils.c Thu Jun 16 12:08:19 2016 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_utils.c Fri Jun 17 16:07:05 2016 +0000 @@ -15,6 +15,7 @@ #define BASE_ADDRESS 0x10010000 #define FW_OFFSET (2*1024) // 2 KB +#define FW_OFFSET_MS 0 #define FULL_STACK_SIZE (66*1024) // 66 KB #define BOOTLOADER_SIZE (2*1024) // 2 kB #define SECTOR_SIZE (2*1024) // 2 KB @@ -92,6 +93,7 @@ uint8_t number_sectors, module; uint32_t address, j; uint32_t crc, crc2, crc_size; + uint32_t fw_offset = FW_OFFSET; BlueNRG_HW_Bootloader(); HCI_Process(); // To receive the EVT_INITIALIZED @@ -102,6 +104,14 @@ if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) return BLE_UTIL_UNSUPPORTED_VERSION; + if(aci_updater_hw_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version==0x31){ + // It does not contain bootloader inside first sector. It may contain code. + fw_offset = FW_OFFSET_MS; + } + if (fw_size != FULL_STACK_SIZE) return BLE_UTIL_WRONG_IMAGE_SIZE; @@ -121,11 +131,11 @@ /*********************************************************************** * Erase and Program sectors ************************************************************************/ - for(unsigned int i = FW_OFFSET; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) { + for(int i = fw_offset; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) { num_erase_retries = 0; while (num_erase_retries++ < MAX_ERASE_RETRIES) { aci_updater_erase_sector(BASE_ADDRESS + i); - if ((i/SECTOR_SIZE) < (unsigned int)(number_sectors-1)) + if ((i/SECTOR_SIZE) < (number_sectors-1)) data_size = DATA_SIZE; else data_size = MIN_WRITE_BLOCK_SIZE; @@ -146,7 +156,7 @@ ************************************************************************/ module = fw_size % SECTOR_SIZE; crc_size = SECTOR_SIZE; - for(int i = SECTOR_SIZE; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){ + for(int i = fw_offset; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){ address = BASE_ADDRESS + i; if(aci_updater_calc_crc(address, 1, &crc)) return BLE_UTIL_ACI_ERROR; @@ -214,8 +224,12 @@ int IFR_validate(IFR_config2_TypeDef *IFR_config) { - if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) - return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode +#if BLUENRG_MS + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) +#else + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) +#endif + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode if(IFR_config->master_sca > 7) return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA if(IFR_config->month > 12 || IFR_config->month < 1) @@ -360,9 +374,7 @@ *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number } - - HCI_Process(); // To receive the BlueNRG EVT - + return status; } @@ -384,6 +396,21 @@ return BLE_STATUS_SUCCESS; } +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_updater_hw_version(version)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + uint8_t isHWBootloader_Patched(void) { uint8_t status, version;
diff -r b94d080127c7 -r f2a7da5d24e1 source/platform/btle.cpp --- a/source/platform/btle.cpp Thu Jun 16 12:08:19 2016 +0000 +++ b/source/platform/btle.cpp Fri Jun 17 16:07:05 2016 +0000 @@ -88,17 +88,69 @@ /**************************************************************************/ /*! - @brief Initialises BTLE and the underlying HW/Device - @param isSetAddress boolean if address has been set - @param mosi MOSI Pin - @param miso MISO Pin - @param sclk clock Pin + @brief Prepare communication between the host and the BTLE HW device @returns void */ /**************************************************************************/ -void btleInit(bool isSetAddress, uint8_t role) +void btleInitHW(void) +{ + PRINTF("btleInitHW>>\n\r"); + + /* Delay needed only to be able to acces the JTAG interface after reset + if it will be disabled later. */ + //Clock_Wait(500); FIXME: // check if I can remove this + + /* Initialize the BlueNRG HCI */ + HCI_Init(); +} + +/**************************************************************************/ +/*! + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +/**************************************************************************/ + +int btleUpdateFirmware(const uint8_t *fw_image, uint32_t fw_size) { - PRINTF("btleInit>>\n\r"); + int status = program_device(fw_image, fw_size); + + return (status); +} + +/**************************************************************************/ +/*! + * @brief Get BlueNRG HW updater version + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +/**************************************************************************/ +uint8_t btleGetUpdaterHWVersion(uint8_t *upd_hw_version) +{ + uint8_t status; + + status = getBlueNRGUpdaterHWVersion(upd_hw_version); + + return (status); +} + + +/**************************************************************************/ +/*! + @brief Start the BTLE stack with the specified role + @param isSetAddress boolean if address has been set + @param role The device role + @returns void +*/ +/**************************************************************************/ +void btleStart(bool isSetAddress, uint8_t role) +{ /* Avoid compiler warnings about unused variables. */ (void)isSetAddress; @@ -107,13 +159,6 @@ uint16_t fwVersion; uint16_t service_handle, dev_name_char_handle, appearance_char_handle; - /* Delay needed only to be able to acces the JTAG interface after reset - if it will be disabled later. */ - Clock_Wait(500); - - /* Initialize the BlueNRG HCI */ - HCI_Init(); - /* Reset BlueNRG SPI interface */ BlueNRG_RST();
diff -r b94d080127c7 -r f2a7da5d24e1 source/platform/stm32_bluenrg_ble.cpp --- a/source/platform/stm32_bluenrg_ble.cpp Thu Jun 16 12:08:19 2016 +0000 +++ b/source/platform/stm32_bluenrg_ble.cpp Fri Jun 17 16:07:05 2016 +0000 @@ -122,8 +122,11 @@ */ void BlueNRG_HW_Bootloader(void) { - // FIXME: this is not implemented yet - while (1); + // Reset BlueNRG SPI interface + BlueNRG_RST(); + + // Send an ACI command to reboot BlueNRG in bootloader mode + aci_updater_start(); } /**
diff -r b94d080127c7 -r f2a7da5d24e1 x-nucleo-idb0xa1/BlueNRGDevice.h --- a/x-nucleo-idb0xa1/BlueNRGDevice.h Thu Jun 16 12:08:19 2016 +0000 +++ b/x-nucleo-idb0xa1/BlueNRGDevice.h Fri Jun 17 16:07:05 2016 +0000 @@ -81,6 +81,8 @@ return isInitialized; } + uint8_t getUpdaterHardwareVersion(uint8_t *upd_hw_version); + int updateFirmware(const uint8_t *fw_image, uint32_t fw_size); bool dataPresent(); int32_t spiRead(uint8_t *buffer, uint8_t buff_size); int32_t spiWrite(uint8_t* data1, uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2);
diff -r b94d080127c7 -r f2a7da5d24e1 x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h --- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h Thu Jun 16 12:08:19 2016 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h Fri Jun 17 16:07:05 2016 +0000 @@ -182,6 +182,13 @@ uint8_t getBlueNRGUpdaterVersion(uint8_t *version); /** + * @brief Get BlueNRG HW updater version + * @param version This parameter returns the updater HW version. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version); + +/** * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on * the HW bootloader related to the 32 MHz external crystal oscillator. * @retval TRUE if the HW bootloader is already patched, FALSE otherwise
diff -r b94d080127c7 -r f2a7da5d24e1 x-nucleo-idb0xa1/platform/btle.h --- a/x-nucleo-idb0xa1/platform/btle.h Thu Jun 16 12:08:19 2016 +0000 +++ b/x-nucleo-idb0xa1/platform/btle.h Fri Jun 17 16:07:05 2016 +0000 @@ -37,8 +37,11 @@ extern uint16_t g_gap_service_handle; extern uint16_t g_appearance_char_handle; extern uint16_t g_device_name_char_handle; - -void btleInit(bool isSetAddress, uint8_t role); + +void btleInitHW(void); +uint8_t btleGetUpdaterHWVersion(uint8_t *upd_hw_version); +int btleUpdateFirmware(const uint8_t *fw_image, uint32_t fw_size); +void btleStart(bool isSetAddress, uint8_t role); void SPI_Poll(void); void User_Process(void); void setConnectable(void);