BLE_API wrapper library for STMicroelectronics' BlueNRG Bluetooth Low Energy expansion board shield

Fork of X_NUCLEO_IDB0XA1 by ST Expansion SW Team

Files at this revision

API Documentation at this revision

Comitter:
avilei
Date:
Fri Jun 17 16:07:05 2016 +0000
Parent:
231:b94d080127c7
Commit message:
Add firmware update capabilities

Changed in this revision

source/BlueNRGDevice.cpp Show annotated file Show diff for this revision Revisions of this file
source/bluenrg-hci/hci/controller/bluenrg_utils.c Show annotated file Show diff for this revision Revisions of this file
source/platform/btle.cpp Show annotated file Show diff for this revision Revisions of this file
source/platform/stm32_bluenrg_ble.cpp Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/BlueNRGDevice.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h Show annotated file Show diff for this revision Revisions of this file
x-nucleo-idb0xa1/platform/btle.h Show annotated file Show diff for this revision Revisions of this file
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);