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