BLE shield
Fork of X_NUCLEO_IDB0XA1 by
Embed:
(wiki syntax)
Show/hide line numbers
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