BLE_API wrapper library for STMicroelectronics' BlueNRG Bluetooth Low Energy expansion board shield (Component)
Dependents: Nucleo_Zumo_BLE_IDB04A1 contest_IOT5 contest_IOT6 contest_IOT_10 ... more
Fork of X_NUCLEO_IDB0XA1 by
bluenrg_utils.c
00001 00002 #include "ble_hal.h" 00003 #include "ble_hal_types.h" 00004 #include "ble_status.h" 00005 #include "bluenrg_aci.h" 00006 #include "bluenrg_utils.h" 00007 #include "ble_hci.h" 00008 #include "ble_osal.h" 00009 #include "string.h" 00010 #include "stm32_bluenrg_ble.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 FW_OFFSET_MS 0 00019 #define FULL_STACK_SIZE (66*1024) // 66 KB 00020 #define BOOTLOADER_SIZE (2*1024) // 2 kB 00021 #define SECTOR_SIZE (2*1024) // 2 KB 00022 #define DATA_SIZE 64 // 64 bytes 00023 00024 // x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + 00025 // x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 00026 #define CRC_POLY 0x04C11DB7 // the poly without the x**32 00027 00028 #define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC 00029 00030 #define IFR_SIZE 192 00031 #define IFR_BASE_ADDRESS 0x10020000 00032 #define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data 00033 00034 #if BLUENRG_MS 00035 #define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET 00036 #else 00037 #define IFR_WRITE_OFFSET_BEGIN 0 00038 #endif 00039 00040 00041 #define BLUE_FLAG_OFFSET 0x8C0 00042 #define MAX_ERASE_RETRIES 2 00043 #define MAX_WRITE_RETRIES 2 00044 #define MIN_WRITE_BLOCK_SIZE 4 00045 00046 #define RETRY_COMMAND(func, num_ret, error) \ 00047 { \ 00048 uint8_t num_retries; \ 00049 num_retries = 0; \ 00050 error = 0; \ 00051 while (num_retries++ < num_ret) { \ 00052 if (func == BLE_STATUS_SUCCESS) \ 00053 break; \ 00054 if (num_retries == num_ret) \ 00055 error = BLE_UTIL_ACI_ERROR; \ 00056 } \ 00057 } 00058 00059 typedef struct{ 00060 uint8_t cold_ana_act_config_table[64]; 00061 }cold_table_TypeDef; 00062 00063 /* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, 00064 they are extended with 0xFF until sector size is reached 00065 */ 00066 static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) 00067 { 00068 uint32_t i, j, a1; 00069 uint32_t crc, value; 00070 00071 crc = 0; 00072 for (i = 0; i < SECTOR_SIZE; i += 4) { 00073 uint8_t *dataw = (uint8_t *) &value; 00074 00075 dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; 00076 dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; 00077 dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; 00078 dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; 00079 00080 crc = crc ^ value; 00081 for (j = 0; j < 32; j ++) { 00082 a1 = (crc >> 31) & 0x1; 00083 crc = (crc << 1) ^ (a1 * CRC_POLY); 00084 } 00085 } 00086 00087 return crc; 00088 } 00089 00090 int program_device(const uint8_t *fw_image, uint32_t fw_size) 00091 { 00092 uint8_t version, num_erase_retries=0, status, data_size; 00093 uint8_t number_sectors, module; 00094 uint32_t address, j; 00095 uint32_t crc, crc2, crc_size; 00096 uint32_t fw_offset = FW_OFFSET; 00097 00098 BlueNRG_HW_Bootloader(); 00099 HCI_Process(); // To receive the EVT_INITIALIZED 00100 00101 if(aci_get_updater_version(&version)) 00102 return BLE_UTIL_ACI_ERROR; 00103 00104 if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) 00105 return BLE_UTIL_UNSUPPORTED_VERSION; 00106 00107 if(aci_updater_hw_version(&version)) 00108 return BLE_UTIL_ACI_ERROR; 00109 00110 if(version==0x31){ 00111 // It does not contain bootloader inside first sector. It may contain code. 00112 fw_offset = FW_OFFSET_MS; 00113 } 00114 00115 if (fw_size != FULL_STACK_SIZE) 00116 return BLE_UTIL_WRONG_IMAGE_SIZE; 00117 00118 if (fw_size % MIN_WRITE_BLOCK_SIZE) 00119 return BLE_UTIL_WRONG_IMAGE_SIZE; 00120 00121 /* Calculate the number of sectors necessary to contain the fw image.*/ 00122 number_sectors = ((fw_size + SECTOR_SIZE - 1) / SECTOR_SIZE); 00123 00124 /*********************************************************************** 00125 * Erase BLUE flag 00126 ************************************************************************/ 00127 RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); 00128 if (status != BLE_STATUS_SUCCESS) 00129 return status; 00130 00131 /*********************************************************************** 00132 * Erase and Program sectors 00133 ************************************************************************/ 00134 for(unsigned int i = fw_offset; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) { 00135 num_erase_retries = 0; 00136 while (num_erase_retries++ < MAX_ERASE_RETRIES) { 00137 aci_updater_erase_sector(BASE_ADDRESS + i); 00138 if ((i/SECTOR_SIZE) < (unsigned int)(number_sectors-1)) 00139 data_size = DATA_SIZE; 00140 else 00141 data_size = MIN_WRITE_BLOCK_SIZE; 00142 for (j=i; ((j<SECTOR_SIZE+i)&&(j<fw_size)); j += data_size) { 00143 RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, data_size, fw_image+j), MAX_WRITE_RETRIES, status); 00144 if (status != BLE_STATUS_SUCCESS) 00145 break; 00146 } 00147 if (status == BLE_STATUS_SUCCESS) 00148 break; 00149 } 00150 if (num_erase_retries == MAX_ERASE_RETRIES) 00151 return BLE_UTIL_ACI_ERROR; 00152 } 00153 00154 /*********************************************************************** 00155 * Verify firmware 00156 ************************************************************************/ 00157 module = fw_size % SECTOR_SIZE; 00158 crc_size = SECTOR_SIZE; 00159 for(int i = fw_offset; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){ 00160 address = BASE_ADDRESS + i; 00161 if(aci_updater_calc_crc(address, 1, &crc)) 00162 return BLE_UTIL_ACI_ERROR; 00163 00164 if ((module != 0) && ((i/SECTOR_SIZE) == (number_sectors-1))) 00165 crc_size = module; 00166 00167 crc2 = updater_calc_crc(fw_image+i,crc_size); 00168 if(crc!=crc2) 00169 return BLE_UTIL_CRC_ERROR; 00170 } 00171 00172 /*********************************************************************** 00173 * Write BLUE flag 00174 ************************************************************************/ 00175 RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); 00176 if (status != BLE_STATUS_SUCCESS) 00177 return status; 00178 00179 BlueNRG_RST(); 00180 HCI_Process(); // To receive the EVT_INITIALIZED 00181 00182 return BLE_STATUS_SUCCESS; 00183 } 00184 00185 int read_IFR(uint8_t *data) 00186 { 00187 uint8_t version, offset; 00188 tBleStatus ret; 00189 00190 offset = 0; 00191 aci_updater_start(); 00192 if(aci_get_updater_version(&version)) 00193 return BLE_UTIL_ACI_ERROR; 00194 00195 if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) 00196 return BLE_UTIL_UNSUPPORTED_VERSION; 00197 00198 /*********************************************************************** 00199 * Reading last 3 IFR 64-byte blocks 00200 ************************************************************************/ 00201 for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += DATA_SIZE){ 00202 ret = aci_updater_read_data_block(BASE_ADDRESS+i, DATA_SIZE, (data+offset)); 00203 offset += DATA_SIZE; 00204 if(ret) return BLE_UTIL_ACI_ERROR; 00205 } 00206 00207 BlueNRG_RST(); 00208 HCI_Process(); // To receive the EVT_INITIALIZED 00209 00210 return BLE_STATUS_SUCCESS; 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 BLUENRG_MS 00228 if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 4) 00229 #else 00230 if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) 00231 #endif 00232 return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode 00233 if(IFR_config->master_sca > 7) 00234 return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA 00235 if(IFR_config->month > 12 || IFR_config->month < 1) 00236 return BLE_UTIL_PARSE_ERROR; // Invalid date 00237 if(IFR_config->day > 31 || IFR_config->day < 1) 00238 return BLE_UTIL_PARSE_ERROR; // Invalid date 00239 if(IFR_config->month > 12 || IFR_config->month < 1) 00240 return BLE_UTIL_PARSE_ERROR; // Invalid date 00241 00242 return BLE_STATUS_SUCCESS; 00243 } 00244 00245 /* TODO: Function to generate data from given options. */ 00246 00247 void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) 00248 { 00249 data[0] = IFR_config->stack_mode; 00250 HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); 00251 data[30] = IFR_config->master_sca; 00252 HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); 00253 data[41] = INT_TO_BCD(IFR_config->year); 00254 data[42] = INT_TO_BCD(IFR_config->month); 00255 data[43] = INT_TO_BCD(IFR_config->day); 00256 } 00257 00258 00259 int program_IFR(const IFR_config_TypeDef *ifr_image) 00260 { 00261 uint8_t version, num_erase_retries; 00262 tBleStatus ret; 00263 #if BLUENRG_MS 00264 const uint8_t *ifr_data = (uint8_t *)ifr_image; 00265 #else 00266 uint8_t ifr_data[SECTOR_SIZE]; 00267 #endif 00268 uint8_t hwVersion; 00269 uint16_t fwVersion; 00270 00271 if(getBlueNRGVersion(&hwVersion, &fwVersion)) 00272 return BLE_UTIL_ACI_ERROR; 00273 00274 BlueNRG_HW_Bootloader(); 00275 HCI_Process(); // To receive the EVT_INITIALIZED 00276 00277 if(aci_get_updater_version(&version)) 00278 return BLE_UTIL_ACI_ERROR; 00279 00280 if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) 00281 return BLE_UTIL_UNSUPPORTED_VERSION; 00282 00283 #ifndef BLUENRG_MS 00284 /*********************************************************************** 00285 * READ IFR data 00286 ************************************************************************/ 00287 for(int i = 0; i < SECTOR_SIZE; i += DATA_SIZE){ 00288 ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+i); 00289 if(ret != BLE_STATUS_SUCCESS){ 00290 return ret; 00291 } 00292 } 00293 #endif 00294 00295 /*********************************************************************** 00296 * Erase & Flashing IFR sectors 00297 ************************************************************************/ 00298 #ifndef BLUENRG_MS 00299 Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); 00300 #endif 00301 num_erase_retries = 0; 00302 while (num_erase_retries++ < MAX_ERASE_RETRIES) { 00303 aci_updater_erase_sector(IFR_BASE_ADDRESS); 00304 for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE) { 00305 RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); 00306 if (ret != BLE_STATUS_SUCCESS) 00307 break; 00308 } 00309 if (ret == BLE_STATUS_SUCCESS) 00310 break; 00311 } 00312 if (num_erase_retries == MAX_ERASE_RETRIES) 00313 return BLE_UTIL_ACI_ERROR; 00314 00315 /*********************************************************************** 00316 * Verify IFR 00317 ************************************************************************/ 00318 { 00319 uint8_t ifr_updated[DATA_SIZE]; 00320 for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE){ 00321 ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_updated); 00322 if(ret != BLE_STATUS_SUCCESS){ 00323 return ret; 00324 } 00325 if (memcmp(ifr_updated, ifr_data+j, DATA_SIZE) != 0) 00326 return BLE_UTIL_WRONG_VERIFY; 00327 } 00328 } 00329 00330 BlueNRG_RST(); 00331 HCI_Process(); // To receive the EVT_INITIALIZED 00332 00333 return BLE_STATUS_SUCCESS; 00334 } 00335 00336 uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) 00337 { 00338 uint8_t ifr_updated[DATA_SIZE]; 00339 uint8_t version, ret = BLE_STATUS_SUCCESS; 00340 00341 aci_updater_start(); 00342 if(aci_get_updater_version(&version)) 00343 return BLE_UTIL_ACI_ERROR; 00344 for(int i = 0; i < IFR_SIZE; i += DATA_SIZE){ 00345 ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, DATA_SIZE, ifr_updated); 00346 if(ret != BLE_STATUS_SUCCESS){ 00347 return ret; 00348 } 00349 if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, DATA_SIZE) != 0) 00350 { 00351 ret = BLE_UTIL_WRONG_VERIFY; 00352 break; 00353 } 00354 } 00355 00356 BlueNRG_RST(); 00357 HCI_Process(); // To receive the EVT_INITIALIZED 00358 00359 return ret; 00360 } 00361 00362 uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) 00363 { 00364 uint8_t status; 00365 uint8_t hci_version, lmp_pal_version; 00366 uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; 00367 00368 status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, 00369 &manufacturer_name, &lmp_pal_subversion); 00370 00371 if (status == BLE_STATUS_SUCCESS) { 00372 *hwVersion = hci_revision >> 8; 00373 *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number 00374 *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number 00375 *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number 00376 } 00377 00378 return status; 00379 } 00380 00381 uint8_t getBlueNRGUpdaterVersion(uint8_t *version) 00382 { 00383 00384 BlueNRG_HW_Bootloader(); 00385 HCI_Process(); // To receive the EVT_INITIALIZED 00386 00387 if(aci_get_updater_version(version)) 00388 return BLE_UTIL_ACI_ERROR; 00389 00390 if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) 00391 return BLE_UTIL_UNSUPPORTED_VERSION; 00392 00393 BlueNRG_RST(); 00394 HCI_Process(); // To receive the EVT_INITIALIZED 00395 00396 return BLE_STATUS_SUCCESS; 00397 } 00398 00399 uint8_t getBlueNRGUpdaterHWVersion(uint8_t *version) 00400 { 00401 00402 BlueNRG_HW_Bootloader(); 00403 HCI_Process(); // To receive the EVT_INITIALIZED 00404 00405 if(aci_updater_hw_version(version)) 00406 return BLE_UTIL_ACI_ERROR; 00407 00408 BlueNRG_RST(); 00409 HCI_Process(); // To receive the EVT_INITIALIZED 00410 00411 return BLE_STATUS_SUCCESS; 00412 } 00413 00414 uint8_t isHWBootloader_Patched(void) 00415 { 00416 uint8_t status, version; 00417 uint32_t crc, address = 0x10010000; 00418 00419 if(aci_get_updater_version(&version)) 00420 return BLE_UTIL_ACI_ERROR; 00421 00422 RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); 00423 if (status != BLE_STATUS_SUCCESS) 00424 return 0; 00425 00426 if (crc == BOOTLOADER_CRC_NOT_PATCHED) 00427 return 0; 00428 00429 return 1; 00430 }
Generated on Tue Jul 12 2022 18:15:59 by 1.7.2