Filippo Casamassima / Nucleo_blueNRG

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bluenrg_utils.c Source File

bluenrg_utils.c

00001 
00002 #include "hal.h"
00003 #include "hal_types.h"
00004 #include "ble_status.h"
00005 #include "bluenrg_aci.h"
00006 #include "bluenrg_utils.h"
00007 #include "hci.h"
00008 #include "osal.h"
00009 #include "string.h"
00010 //#include "SDK_EVAL_Spi_Driver.h"
00011 
00012 #define SUPPORTED_BOOTLOADER_VERSION_MIN  3
00013 #define SUPPORTED_BOOTLOADER_VERSION_MAX  5
00014 
00015 #define BASE_ADDRESS 0x10010000
00016 
00017 #define FW_OFFSET       (2*1024)  // 2 KB
00018 #define FULL_STACK_SIZE (66*1024) // 66 KB
00019 #define BOOTLOADER_SIZE (2*1024)  // 2 kB
00020 #define DATA_SIZE       64        // 64 bytes
00021 #define SECTOR_SIZE     (2*1024)  // 2 KB
00022 
00023 // x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 +
00024 // x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0
00025 #define CRC_POLY        0x04C11DB7      // the poly without the x**32
00026 
00027 #define IFR_SIZE 192
00028 #define IFR_BASE_ADDRESS 0x10020000
00029 
00030 typedef struct{
00031   uint8_t cold_ana_act_config_table[64];
00032 }cold_table_TypeDef;
00033 
00034 static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes)
00035 {
00036     uint32_t i, j, a1;
00037     uint32_t crc, value;
00038 
00039     crc = 0;
00040     for (i = 0; i < nr_of_bytes; i += 4) {
00041       value = data[i]|((uint32_t)data[i+1]<<8)|((uint32_t)data[i+2]<<16)|((uint32_t)data[i+3]<<24);
00042       
00043         crc = crc ^ value;
00044         for (j = 0; j < 32; j ++) {
00045             a1 = (crc >> 31) & 0x1;
00046             crc = (crc << 1) ^ (a1 * CRC_POLY);
00047         }
00048     }
00049     return crc;
00050 }
00051 
00052 int program_device(const uint8_t *fw_image, uint32_t fw_size, uint8_t skip_bootloader_verif)
00053 {
00054   uint8_t version;
00055   uint8_t verify_from_sector = 0;
00056   uint8_t number_sectors;
00057   uint8_t last_sector[SECTOR_SIZE];
00058   const uint8_t *last_image, *addr_image;
00059   uint16_t last_size;
00060   uint32_t address;
00061   uint32_t crc, crc2;
00062   tBleStatus ret;  
00063   
00064   BlueNRG_HW_Bootloader();
00065   HCI_Process();
00066 
00067   if(aci_get_updater_version(&version))
00068     return BLE_UTIL_ACI_ERROR;
00069   
00070   if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
00071     return BLE_UTIL_UNSUPPORTED_VERSION;
00072   
00073   if(skip_bootloader_verif){
00074     verify_from_sector = 1;
00075   }
00076 
00077   if (fw_size > FULL_STACK_SIZE)
00078     return BLE_UTIL_WRONG_IMAGE_SIZE;
00079 
00080   /***********************************************************************
00081   * Erase BLUE flag
00082   ************************************************************************/
00083   
00084   if(aci_erase_blue_flag()) 
00085     return BLE_UTIL_ACI_ERROR;
00086   
00087   /***********************************************************************
00088   * Erase sectors
00089   ************************************************************************/  
00090   
00091   for(int i = FW_OFFSET; i < FULL_STACK_SIZE; i += SECTOR_SIZE){
00092     ret = aci_updater_erase_sector(BASE_ADDRESS + i);
00093     if(ret) return BLE_UTIL_ACI_ERROR;
00094     HCI_Process();
00095   }
00096   
00097   /***********************************************************************
00098   * Flashing firmware
00099   ************************************************************************/
00100 
00101   /* Calculate the number of sectors necessary to contain the fw image.
00102      If the fw image is the bootloader we need to add a sector because 
00103      the flashing start with an offset of 2 KB 
00104   */
00105   number_sectors = (fw_size / SECTOR_SIZE);
00106   if (skip_bootloader_verif)
00107     number_sectors++;
00108 
00109   for(int i = FW_OFFSET; i < (number_sectors*SECTOR_SIZE); i += DATA_SIZE){
00110     /* If bootloader image we need to subtract the 2KB offset */
00111     if (skip_bootloader_verif)
00112       addr_image = fw_image + i - FW_OFFSET;
00113     else
00114       addr_image = fw_image + i;
00115     ret = aci_updater_program_data_block(BASE_ADDRESS+i, DATA_SIZE, addr_image);
00116     if(ret) return BLE_UTIL_ACI_ERROR;
00117     HCI_Process();
00118   }
00119   
00120   /* If the image is not multiple of a sector size */
00121   if (fw_size % SECTOR_SIZE) {
00122     /* If bootloader image we need to subtract the 2KB offset */
00123     if (skip_bootloader_verif) {
00124       last_image = fw_image + (number_sectors-1) * SECTOR_SIZE;
00125       last_size = fw_size -(number_sectors-1) * SECTOR_SIZE;
00126     } else {
00127       last_image = fw_image + number_sectors * SECTOR_SIZE;
00128       last_size = fw_size - number_sectors * SECTOR_SIZE;
00129     }
00130     memset(last_sector, 0xFF, SECTOR_SIZE);
00131     memcpy (last_sector, last_image, last_size);
00132     address = BASE_ADDRESS + (number_sectors * SECTOR_SIZE);
00133     for(int i = 0; i < SECTOR_SIZE; i += DATA_SIZE){
00134       ret = aci_updater_program_data_block(address+i, DATA_SIZE, last_sector+i);
00135       if(ret) return BLE_UTIL_ACI_ERROR;
00136       HCI_Process();
00137     }
00138   }
00139 
00140   /***********************************************************************
00141   * Verify firmware
00142   ************************************************************************/
00143   
00144   for(int i = (verify_from_sector*SECTOR_SIZE); i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){
00145     address = BASE_ADDRESS + i;
00146     if(aci_updater_calc_crc(address, 1, &crc))
00147       return BLE_UTIL_ACI_ERROR;
00148     
00149     /* If bootloader image we need to subtract the 2KB offset */
00150     if (skip_bootloader_verif) {
00151       crc2 = updater_calc_crc(fw_image+i-FW_OFFSET,SECTOR_SIZE);
00152     } else {
00153       crc2 = updater_calc_crc(fw_image+i,SECTOR_SIZE);
00154     }
00155     
00156     if(crc!=crc2)
00157       return BLE_UTIL_CRC_ERROR;
00158 
00159     HCI_Process();
00160   }
00161 
00162   /* If the image is not multiple of a sector size */
00163   if (fw_size % SECTOR_SIZE) {
00164     address = BASE_ADDRESS + (number_sectors*SECTOR_SIZE);
00165     if(aci_updater_calc_crc(address, 1, &crc))
00166       return BLE_UTIL_ACI_ERROR;
00167     
00168     crc2 = updater_calc_crc(last_sector,SECTOR_SIZE);
00169     
00170     if(crc!=crc2)
00171       return BLE_UTIL_CRC_ERROR;
00172 
00173     HCI_Process();
00174 
00175   }    
00176   
00177   if(aci_reset_blue_flag())
00178     return BLE_UTIL_ACI_ERROR;
00179   
00180   BlueNRG_RST();
00181   
00182   HCI_Process();
00183 
00184   return 0;
00185 }
00186 
00187 int read_IFR(uint8_t *data)
00188 {
00189   uint8_t version;
00190   tBleStatus ret;
00191   
00192   aci_updater_start();
00193   if(aci_get_updater_version(&version))
00194     return BLE_UTIL_ACI_ERROR;
00195   
00196   if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
00197     return BLE_UTIL_UNSUPPORTED_VERSION;
00198   
00199   /***********************************************************************
00200   * Reading last 3 IFR 64-byte blocks
00201   ************************************************************************/
00202   
00203   for(int i = 66*1024 - 3*64; i < 66*1024; i += 64){
00204     ret = aci_updater_read_data_block(BASE_ADDRESS+i, 64, data);
00205     if(ret) return BLE_UTIL_ACI_ERROR;
00206   }
00207   
00208   BlueNRG_RST();
00209 
00210   return 0;
00211   
00212 }
00213 
00214 void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config)
00215 {
00216   IFR_config->stack_mode = data[0];
00217   IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28);
00218   IFR_config->master_sca = data[30];
00219   IFR_config->hs_startup_time = LE_TO_HOST_16(data+32);
00220   IFR_config->year = BCD_TO_INT(data[41]);
00221   IFR_config->month = BCD_TO_INT(data[42]);
00222   IFR_config->day = BCD_TO_INT(data[43]);    
00223 }
00224 
00225 int IFR_validate(IFR_config2_TypeDef *IFR_config)
00226 {
00227   if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3)
00228     return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode
00229   if(IFR_config->master_sca > 7)
00230     return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA
00231   if(IFR_config->month > 12 || IFR_config->month < 1)
00232     return BLE_UTIL_PARSE_ERROR; // Invalid date
00233   if(IFR_config->day > 31 || IFR_config->day < 1)
00234     return BLE_UTIL_PARSE_ERROR; // Invalid date
00235   if(IFR_config->month > 12 || IFR_config->month < 1)
00236     return BLE_UTIL_PARSE_ERROR; // Invalid date
00237   
00238   return 0;
00239 }
00240 
00241 /* TODO: Function to generate data from given options. */
00242 
00243 void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64])
00244 {
00245   data[0] = IFR_config->stack_mode;
00246   HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm);
00247   data[30] = IFR_config->master_sca;
00248   HOST_TO_LE_16(data+32, IFR_config->hs_startup_time);  
00249   data[41] = INT_TO_BCD(IFR_config->year);
00250   data[42] = INT_TO_BCD(IFR_config->month);
00251   data[43] = INT_TO_BCD(IFR_config->day);
00252 }
00253 
00254 
00255 int program_IFR(const IFR_config_TypeDef *ifr_image)
00256 {
00257   uint8_t version;
00258   tBleStatus ret;  
00259   uint8_t ifr_data[2*1024];
00260   
00261   aci_updater_start();
00262   if(aci_get_updater_version(&version))
00263     return BLE_UTIL_ACI_ERROR;
00264   
00265   if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
00266     return BLE_UTIL_UNSUPPORTED_VERSION;
00267   
00268   /***********************************************************************
00269    * READ IFR data
00270    ************************************************************************/  
00271   for(int i = 0; i < (2*1024); i += 64){
00272     ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, 64, ifr_data+i);
00273     if(ret != BLE_STATUS_SUCCESS){
00274       return ret;
00275     }
00276   }
00277   
00278   /***********************************************************************
00279   * Erase IFR sectors
00280   ************************************************************************/  
00281   ret = aci_updater_erase_sector(IFR_BASE_ADDRESS);
00282   if(ret != BLE_STATUS_SUCCESS) 
00283     return BLE_UTIL_ACI_ERROR;
00284   
00285   /***********************************************************************
00286   * Flashing IFR
00287   ************************************************************************/
00288   Osal_MemCpy(&ifr_data[2*1024-IFR_SIZE], ifr_image, IFR_SIZE);
00289   for(int i = 0; i < (2*1024); i += 64){
00290     ret = aci_updater_program_data_block(IFR_BASE_ADDRESS+i, 64, ifr_data+i);
00291     if(ret != BLE_STATUS_SUCCESS) 
00292       return BLE_UTIL_ACI_ERROR;
00293   }
00294 
00295   /***********************************************************************
00296   * Verify IFR
00297   ************************************************************************/  
00298   {
00299     uint8_t ifr_updated[64];
00300     for(int i = 0; i < (2*1024); i += 64){
00301       ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, 64, ifr_updated);
00302       if(ret != BLE_STATUS_SUCCESS){
00303     return ret;
00304       }
00305       if (memcmp(ifr_updated, ifr_data+i, 64) != 0)
00306     return BLE_UTIL_WRONG_VERIFY;
00307     }
00308   }
00309 
00310   BlueNRG_RST();
00311     
00312   return 0;
00313 }
00314 
00315 uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data)
00316 {
00317   uint8_t ifr_updated[64];
00318   uint8_t version, ret;
00319     
00320   aci_updater_start();
00321   if(aci_get_updater_version(&version))
00322     return BLE_UTIL_ACI_ERROR;
00323   for(int i = 0; i < (3*64); i += 64){
00324     ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+2048-IFR_SIZE)+i, 64, ifr_updated);
00325     if(ret != BLE_STATUS_SUCCESS){
00326       return ret;
00327     }
00328     if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, 64) != 0)
00329       return BLE_UTIL_WRONG_VERIFY;
00330   }
00331 
00332   BlueNRG_RST();
00333   
00334   return 0;
00335 }
00336 
00337 uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion)
00338 {
00339   uint8_t status;
00340   uint8_t hci_version, lmp_pal_version;
00341   uint16_t hci_revision, manufacturer_name, lmp_pal_subversion;
00342 
00343   status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, 
00344                      &manufacturer_name, &lmp_pal_subversion);
00345 
00346   if (status == BLE_STATUS_SUCCESS) {
00347     *hwVersion = hci_revision >> 8;
00348     *fwVersion = (hci_revision & 0xFF) << 8;              // Major Version Number
00349     *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number
00350     *fwVersion |= lmp_pal_subversion & 0xF;               // Patch Version Number
00351   }
00352 
00353   HCI_Process();
00354 
00355   return status;
00356 }
00357 
00358 uint8_t getBlueNRGUpdaterVersion(uint8_t *version)
00359 {
00360   HCI_Process();
00361 
00362   BlueNRG_HW_Bootloader();
00363 
00364   HCI_Process();
00365 
00366   if(aci_get_updater_version(version))
00367     return BLE_UTIL_ACI_ERROR;
00368   
00369   if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX)
00370     return BLE_UTIL_UNSUPPORTED_VERSION;
00371 
00372   BlueNRG_RST();
00373 
00374   HCI_Process();
00375 
00376   return BLE_STATUS_SUCCESS;
00377 }
00378