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
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 "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(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) < (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 16:31:45 by
1.7.2
