Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
--- 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 = {
--- 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;
--- 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();
--- 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(); } /**
--- 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);
--- 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
--- 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);