Michaël Nagels / project_bachproef2

Fork of X_NUCLEO_IDB0XA1 by ST

Committer:
mjnagels
Date:
Sat Mar 05 09:49:47 2016 +0000
Revision:
213:edfc72290462
Parent:
132:51056160fa4a
used bikeservice

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wolfgang Betz 132:51056160fa4a 1
Wolfgang Betz 132:51056160fa4a 2 #include "hal.h"
Wolfgang Betz 132:51056160fa4a 3 #include "hal_types.h"
Wolfgang Betz 132:51056160fa4a 4 #include "ble_status.h"
Wolfgang Betz 132:51056160fa4a 5 #include "bluenrg_aci.h"
Wolfgang Betz 132:51056160fa4a 6 #include "bluenrg_utils.h"
Wolfgang Betz 132:51056160fa4a 7 #include "hci.h"
Wolfgang Betz 132:51056160fa4a 8 #include "osal.h"
Wolfgang Betz 132:51056160fa4a 9 #include "string.h"
Wolfgang Betz 132:51056160fa4a 10 #include "stm32_bluenrg_ble.h"
Wolfgang Betz 132:51056160fa4a 11
Wolfgang Betz 132:51056160fa4a 12 #define SUPPORTED_BOOTLOADER_VERSION_MIN 3
Wolfgang Betz 132:51056160fa4a 13 #define SUPPORTED_BOOTLOADER_VERSION_MAX 5
Wolfgang Betz 132:51056160fa4a 14
Wolfgang Betz 132:51056160fa4a 15 #define BASE_ADDRESS 0x10010000
Wolfgang Betz 132:51056160fa4a 16
Wolfgang Betz 132:51056160fa4a 17 #define FW_OFFSET (2*1024) // 2 KB
Wolfgang Betz 132:51056160fa4a 18 #define FULL_STACK_SIZE (66*1024) // 66 KB
Wolfgang Betz 132:51056160fa4a 19 #define BOOTLOADER_SIZE (2*1024) // 2 kB
Wolfgang Betz 132:51056160fa4a 20 #define SECTOR_SIZE (2*1024) // 2 KB
Wolfgang Betz 132:51056160fa4a 21 #define DATA_SIZE 64 // 64 bytes
Wolfgang Betz 132:51056160fa4a 22
Wolfgang Betz 132:51056160fa4a 23 // x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 +
Wolfgang Betz 132:51056160fa4a 24 // x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0
Wolfgang Betz 132:51056160fa4a 25 #define CRC_POLY 0x04C11DB7 // the poly without the x**32
Wolfgang Betz 132:51056160fa4a 26
Wolfgang Betz 132:51056160fa4a 27 #define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC
Wolfgang Betz 132:51056160fa4a 28
Wolfgang Betz 132:51056160fa4a 29 #define IFR_SIZE 192
Wolfgang Betz 132:51056160fa4a 30 #define IFR_BASE_ADDRESS 0x10020000
Wolfgang Betz 132:51056160fa4a 31 #define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data
Wolfgang Betz 132:51056160fa4a 32
Wolfgang Betz 132:51056160fa4a 33 #if BLUENRG_MS
Wolfgang Betz 132:51056160fa4a 34 #define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET
Wolfgang Betz 132:51056160fa4a 35 #else
Wolfgang Betz 132:51056160fa4a 36 #define IFR_WRITE_OFFSET_BEGIN 0
Wolfgang Betz 132:51056160fa4a 37 #endif
Wolfgang Betz 132:51056160fa4a 38
Wolfgang Betz 132:51056160fa4a 39
Wolfgang Betz 132:51056160fa4a 40 #define BLUE_FLAG_OFFSET 0x8C0
Wolfgang Betz 132:51056160fa4a 41 #define MAX_ERASE_RETRIES 2
Wolfgang Betz 132:51056160fa4a 42 #define MAX_WRITE_RETRIES 2
Wolfgang Betz 132:51056160fa4a 43 #define MIN_WRITE_BLOCK_SIZE 4
Wolfgang Betz 132:51056160fa4a 44
Wolfgang Betz 132:51056160fa4a 45 #define RETRY_COMMAND(func, num_ret, error) \
Wolfgang Betz 132:51056160fa4a 46 { \
Wolfgang Betz 132:51056160fa4a 47 uint8_t num_retries; \
Wolfgang Betz 132:51056160fa4a 48 num_retries = 0; \
Wolfgang Betz 132:51056160fa4a 49 error = 0; \
Wolfgang Betz 132:51056160fa4a 50 while (num_retries++ < num_ret) { \
Wolfgang Betz 132:51056160fa4a 51 if (func == BLE_STATUS_SUCCESS) \
Wolfgang Betz 132:51056160fa4a 52 break; \
Wolfgang Betz 132:51056160fa4a 53 if (num_retries == num_ret) \
Wolfgang Betz 132:51056160fa4a 54 error = BLE_UTIL_ACI_ERROR; \
Wolfgang Betz 132:51056160fa4a 55 } \
Wolfgang Betz 132:51056160fa4a 56 }
Wolfgang Betz 132:51056160fa4a 57
Wolfgang Betz 132:51056160fa4a 58 typedef struct{
Wolfgang Betz 132:51056160fa4a 59 uint8_t cold_ana_act_config_table[64];
Wolfgang Betz 132:51056160fa4a 60 }cold_table_TypeDef;
Wolfgang Betz 132:51056160fa4a 61
Wolfgang Betz 132:51056160fa4a 62 /* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size,
Wolfgang Betz 132:51056160fa4a 63 they are extended with 0xFF until sector size is reached
Wolfgang Betz 132:51056160fa4a 64 */
Wolfgang Betz 132:51056160fa4a 65 static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes)
Wolfgang Betz 132:51056160fa4a 66 {
Wolfgang Betz 132:51056160fa4a 67 uint32_t i, j, a1;
Wolfgang Betz 132:51056160fa4a 68 uint32_t crc, value;
Wolfgang Betz 132:51056160fa4a 69
Wolfgang Betz 132:51056160fa4a 70 crc = 0;
Wolfgang Betz 132:51056160fa4a 71 for (i = 0; i < SECTOR_SIZE; i += 4) {
Wolfgang Betz 132:51056160fa4a 72 uint8_t *dataw = (uint8_t *) &value;
Wolfgang Betz 132:51056160fa4a 73
Wolfgang Betz 132:51056160fa4a 74 dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF;
Wolfgang Betz 132:51056160fa4a 75 dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF;
Wolfgang Betz 132:51056160fa4a 76 dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF;
Wolfgang Betz 132:51056160fa4a 77 dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF;
Wolfgang Betz 132:51056160fa4a 78
Wolfgang Betz 132:51056160fa4a 79 crc = crc ^ value;
Wolfgang Betz 132:51056160fa4a 80 for (j = 0; j < 32; j ++) {
Wolfgang Betz 132:51056160fa4a 81 a1 = (crc >> 31) & 0x1;
Wolfgang Betz 132:51056160fa4a 82 crc = (crc << 1) ^ (a1 * CRC_POLY);
Wolfgang Betz 132:51056160fa4a 83 }
Wolfgang Betz 132:51056160fa4a 84 }
Wolfgang Betz 132:51056160fa4a 85
Wolfgang Betz 132:51056160fa4a 86 return crc;
Wolfgang Betz 132:51056160fa4a 87 }
Wolfgang Betz 132:51056160fa4a 88
Wolfgang Betz 132:51056160fa4a 89 int program_device(const uint8_t *fw_image, uint32_t fw_size)
Wolfgang Betz 132:51056160fa4a 90 {
Wolfgang Betz 132:51056160fa4a 91 uint8_t version, num_erase_retries=0, status, data_size;
Wolfgang Betz 132:51056160fa4a 92 uint8_t number_sectors, module;
Wolfgang Betz 132:51056160fa4a 93 uint32_t address, j;
Wolfgang Betz 132:51056160fa4a 94 uint32_t crc, crc2, crc_size;
Wolfgang Betz 132:51056160fa4a 95
Wolfgang Betz 132:51056160fa4a 96 BlueNRG_HW_Bootloader();
Wolfgang Betz 132:51056160fa4a 97 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 98
Wolfgang Betz 132:51056160fa4a 99 if(aci_get_updater_version(&version))
Wolfgang Betz 132:51056160fa4a 100 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 101
Wolfgang Betz 132:51056160fa4a 102 if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
Wolfgang Betz 132:51056160fa4a 103 return BLE_UTIL_UNSUPPORTED_VERSION;
Wolfgang Betz 132:51056160fa4a 104
Wolfgang Betz 132:51056160fa4a 105 if (fw_size != FULL_STACK_SIZE)
Wolfgang Betz 132:51056160fa4a 106 return BLE_UTIL_WRONG_IMAGE_SIZE;
Wolfgang Betz 132:51056160fa4a 107
Wolfgang Betz 132:51056160fa4a 108 if (fw_size % MIN_WRITE_BLOCK_SIZE)
Wolfgang Betz 132:51056160fa4a 109 return BLE_UTIL_WRONG_IMAGE_SIZE;
Wolfgang Betz 132:51056160fa4a 110
Wolfgang Betz 132:51056160fa4a 111 /* Calculate the number of sectors necessary to contain the fw image.*/
Wolfgang Betz 132:51056160fa4a 112 number_sectors = ((fw_size + SECTOR_SIZE - 1) / SECTOR_SIZE);
Wolfgang Betz 132:51056160fa4a 113
Wolfgang Betz 132:51056160fa4a 114 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 115 * Erase BLUE flag
Wolfgang Betz 132:51056160fa4a 116 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 117 RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status);
Wolfgang Betz 132:51056160fa4a 118 if (status != BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 119 return status;
Wolfgang Betz 132:51056160fa4a 120
Wolfgang Betz 132:51056160fa4a 121 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 122 * Erase and Program sectors
Wolfgang Betz 132:51056160fa4a 123 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 124 for(unsigned int i = FW_OFFSET; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) {
Wolfgang Betz 132:51056160fa4a 125 num_erase_retries = 0;
Wolfgang Betz 132:51056160fa4a 126 while (num_erase_retries++ < MAX_ERASE_RETRIES) {
Wolfgang Betz 132:51056160fa4a 127 aci_updater_erase_sector(BASE_ADDRESS + i);
Wolfgang Betz 132:51056160fa4a 128 if ((i/SECTOR_SIZE) < (unsigned int)(number_sectors-1))
Wolfgang Betz 132:51056160fa4a 129 data_size = DATA_SIZE;
Wolfgang Betz 132:51056160fa4a 130 else
Wolfgang Betz 132:51056160fa4a 131 data_size = MIN_WRITE_BLOCK_SIZE;
Wolfgang Betz 132:51056160fa4a 132 for (j=i; ((j<SECTOR_SIZE+i)&&(j<fw_size)); j += data_size) {
Wolfgang Betz 132:51056160fa4a 133 RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, data_size, fw_image+j), MAX_WRITE_RETRIES, status);
Wolfgang Betz 132:51056160fa4a 134 if (status != BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 135 break;
Wolfgang Betz 132:51056160fa4a 136 }
Wolfgang Betz 132:51056160fa4a 137 if (status == BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 138 break;
Wolfgang Betz 132:51056160fa4a 139 }
Wolfgang Betz 132:51056160fa4a 140 if (num_erase_retries == MAX_ERASE_RETRIES)
Wolfgang Betz 132:51056160fa4a 141 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 142 }
Wolfgang Betz 132:51056160fa4a 143
Wolfgang Betz 132:51056160fa4a 144 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 145 * Verify firmware
Wolfgang Betz 132:51056160fa4a 146 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 147 module = fw_size % SECTOR_SIZE;
Wolfgang Betz 132:51056160fa4a 148 crc_size = SECTOR_SIZE;
Wolfgang Betz 132:51056160fa4a 149 for(int i = SECTOR_SIZE; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){
Wolfgang Betz 132:51056160fa4a 150 address = BASE_ADDRESS + i;
Wolfgang Betz 132:51056160fa4a 151 if(aci_updater_calc_crc(address, 1, &crc))
Wolfgang Betz 132:51056160fa4a 152 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 153
Wolfgang Betz 132:51056160fa4a 154 if ((module != 0) && ((i/SECTOR_SIZE) == (number_sectors-1)))
Wolfgang Betz 132:51056160fa4a 155 crc_size = module;
Wolfgang Betz 132:51056160fa4a 156
Wolfgang Betz 132:51056160fa4a 157 crc2 = updater_calc_crc(fw_image+i,crc_size);
Wolfgang Betz 132:51056160fa4a 158 if(crc!=crc2)
Wolfgang Betz 132:51056160fa4a 159 return BLE_UTIL_CRC_ERROR;
Wolfgang Betz 132:51056160fa4a 160 }
Wolfgang Betz 132:51056160fa4a 161
Wolfgang Betz 132:51056160fa4a 162 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 163 * Write BLUE flag
Wolfgang Betz 132:51056160fa4a 164 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 165 RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status);
Wolfgang Betz 132:51056160fa4a 166 if (status != BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 167 return status;
Wolfgang Betz 132:51056160fa4a 168
Wolfgang Betz 132:51056160fa4a 169 BlueNRG_RST();
Wolfgang Betz 132:51056160fa4a 170 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 171
Wolfgang Betz 132:51056160fa4a 172 return BLE_STATUS_SUCCESS;
Wolfgang Betz 132:51056160fa4a 173 }
Wolfgang Betz 132:51056160fa4a 174
Wolfgang Betz 132:51056160fa4a 175 int read_IFR(uint8_t *data)
Wolfgang Betz 132:51056160fa4a 176 {
Wolfgang Betz 132:51056160fa4a 177 uint8_t version, offset;
Wolfgang Betz 132:51056160fa4a 178 tBleStatus ret;
Wolfgang Betz 132:51056160fa4a 179
Wolfgang Betz 132:51056160fa4a 180 offset = 0;
Wolfgang Betz 132:51056160fa4a 181 aci_updater_start();
Wolfgang Betz 132:51056160fa4a 182 if(aci_get_updater_version(&version))
Wolfgang Betz 132:51056160fa4a 183 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 184
Wolfgang Betz 132:51056160fa4a 185 if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
Wolfgang Betz 132:51056160fa4a 186 return BLE_UTIL_UNSUPPORTED_VERSION;
Wolfgang Betz 132:51056160fa4a 187
Wolfgang Betz 132:51056160fa4a 188 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 189 * Reading last 3 IFR 64-byte blocks
Wolfgang Betz 132:51056160fa4a 190 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 191 for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += DATA_SIZE){
Wolfgang Betz 132:51056160fa4a 192 ret = aci_updater_read_data_block(BASE_ADDRESS+i, DATA_SIZE, (data+offset));
Wolfgang Betz 132:51056160fa4a 193 offset += DATA_SIZE;
Wolfgang Betz 132:51056160fa4a 194 if(ret) return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 195 }
Wolfgang Betz 132:51056160fa4a 196
Wolfgang Betz 132:51056160fa4a 197 BlueNRG_RST();
Wolfgang Betz 132:51056160fa4a 198 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 199
Wolfgang Betz 132:51056160fa4a 200 return BLE_STATUS_SUCCESS;
Wolfgang Betz 132:51056160fa4a 201
Wolfgang Betz 132:51056160fa4a 202 }
Wolfgang Betz 132:51056160fa4a 203
Wolfgang Betz 132:51056160fa4a 204 void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config)
Wolfgang Betz 132:51056160fa4a 205 {
Wolfgang Betz 132:51056160fa4a 206 IFR_config->stack_mode = data[0];
Wolfgang Betz 132:51056160fa4a 207 IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28);
Wolfgang Betz 132:51056160fa4a 208 IFR_config->master_sca = data[30];
Wolfgang Betz 132:51056160fa4a 209 IFR_config->hs_startup_time = LE_TO_HOST_16(data+32);
Wolfgang Betz 132:51056160fa4a 210 IFR_config->year = BCD_TO_INT(data[41]);
Wolfgang Betz 132:51056160fa4a 211 IFR_config->month = BCD_TO_INT(data[42]);
Wolfgang Betz 132:51056160fa4a 212 IFR_config->day = BCD_TO_INT(data[43]);
Wolfgang Betz 132:51056160fa4a 213 }
Wolfgang Betz 132:51056160fa4a 214
Wolfgang Betz 132:51056160fa4a 215 int IFR_validate(IFR_config2_TypeDef *IFR_config)
Wolfgang Betz 132:51056160fa4a 216 {
Wolfgang Betz 132:51056160fa4a 217 if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3)
Wolfgang Betz 132:51056160fa4a 218 return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode
Wolfgang Betz 132:51056160fa4a 219 if(IFR_config->master_sca > 7)
Wolfgang Betz 132:51056160fa4a 220 return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA
Wolfgang Betz 132:51056160fa4a 221 if(IFR_config->month > 12 || IFR_config->month < 1)
Wolfgang Betz 132:51056160fa4a 222 return BLE_UTIL_PARSE_ERROR; // Invalid date
Wolfgang Betz 132:51056160fa4a 223 if(IFR_config->day > 31 || IFR_config->day < 1)
Wolfgang Betz 132:51056160fa4a 224 return BLE_UTIL_PARSE_ERROR; // Invalid date
Wolfgang Betz 132:51056160fa4a 225 if(IFR_config->month > 12 || IFR_config->month < 1)
Wolfgang Betz 132:51056160fa4a 226 return BLE_UTIL_PARSE_ERROR; // Invalid date
Wolfgang Betz 132:51056160fa4a 227
Wolfgang Betz 132:51056160fa4a 228 return BLE_STATUS_SUCCESS;
Wolfgang Betz 132:51056160fa4a 229 }
Wolfgang Betz 132:51056160fa4a 230
Wolfgang Betz 132:51056160fa4a 231 /* TODO: Function to generate data from given options. */
Wolfgang Betz 132:51056160fa4a 232
Wolfgang Betz 132:51056160fa4a 233 void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64])
Wolfgang Betz 132:51056160fa4a 234 {
Wolfgang Betz 132:51056160fa4a 235 data[0] = IFR_config->stack_mode;
Wolfgang Betz 132:51056160fa4a 236 HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm);
Wolfgang Betz 132:51056160fa4a 237 data[30] = IFR_config->master_sca;
Wolfgang Betz 132:51056160fa4a 238 HOST_TO_LE_16(data+32, IFR_config->hs_startup_time);
Wolfgang Betz 132:51056160fa4a 239 data[41] = INT_TO_BCD(IFR_config->year);
Wolfgang Betz 132:51056160fa4a 240 data[42] = INT_TO_BCD(IFR_config->month);
Wolfgang Betz 132:51056160fa4a 241 data[43] = INT_TO_BCD(IFR_config->day);
Wolfgang Betz 132:51056160fa4a 242 }
Wolfgang Betz 132:51056160fa4a 243
Wolfgang Betz 132:51056160fa4a 244
Wolfgang Betz 132:51056160fa4a 245 int program_IFR(const IFR_config_TypeDef *ifr_image)
Wolfgang Betz 132:51056160fa4a 246 {
Wolfgang Betz 132:51056160fa4a 247 uint8_t version, num_erase_retries;
Wolfgang Betz 132:51056160fa4a 248 tBleStatus ret;
Wolfgang Betz 132:51056160fa4a 249 #if BLUENRG_MS
Wolfgang Betz 132:51056160fa4a 250 const uint8_t *ifr_data = (uint8_t *)ifr_image;
Wolfgang Betz 132:51056160fa4a 251 #else
Wolfgang Betz 132:51056160fa4a 252 uint8_t ifr_data[SECTOR_SIZE];
Wolfgang Betz 132:51056160fa4a 253 #endif
Wolfgang Betz 132:51056160fa4a 254 uint8_t hwVersion;
Wolfgang Betz 132:51056160fa4a 255 uint16_t fwVersion;
Wolfgang Betz 132:51056160fa4a 256
Wolfgang Betz 132:51056160fa4a 257 if(getBlueNRGVersion(&hwVersion, &fwVersion))
Wolfgang Betz 132:51056160fa4a 258 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 259
Wolfgang Betz 132:51056160fa4a 260 BlueNRG_HW_Bootloader();
Wolfgang Betz 132:51056160fa4a 261 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 262
Wolfgang Betz 132:51056160fa4a 263 if(aci_get_updater_version(&version))
Wolfgang Betz 132:51056160fa4a 264 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 265
Wolfgang Betz 132:51056160fa4a 266 if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX)
Wolfgang Betz 132:51056160fa4a 267 return BLE_UTIL_UNSUPPORTED_VERSION;
Wolfgang Betz 132:51056160fa4a 268
Wolfgang Betz 132:51056160fa4a 269 #ifndef BLUENRG_MS
Wolfgang Betz 132:51056160fa4a 270 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 271 * READ IFR data
Wolfgang Betz 132:51056160fa4a 272 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 273 for(int i = 0; i < SECTOR_SIZE; i += DATA_SIZE){
Wolfgang Betz 132:51056160fa4a 274 ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+i);
Wolfgang Betz 132:51056160fa4a 275 if(ret != BLE_STATUS_SUCCESS){
Wolfgang Betz 132:51056160fa4a 276 return ret;
Wolfgang Betz 132:51056160fa4a 277 }
Wolfgang Betz 132:51056160fa4a 278 }
Wolfgang Betz 132:51056160fa4a 279 #endif
Wolfgang Betz 132:51056160fa4a 280
Wolfgang Betz 132:51056160fa4a 281 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 282 * Erase & Flashing IFR sectors
Wolfgang Betz 132:51056160fa4a 283 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 284 #ifndef BLUENRG_MS
Wolfgang Betz 132:51056160fa4a 285 Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE);
Wolfgang Betz 132:51056160fa4a 286 #endif
Wolfgang Betz 132:51056160fa4a 287 num_erase_retries = 0;
Wolfgang Betz 132:51056160fa4a 288 while (num_erase_retries++ < MAX_ERASE_RETRIES) {
Wolfgang Betz 132:51056160fa4a 289 aci_updater_erase_sector(IFR_BASE_ADDRESS);
Wolfgang Betz 132:51056160fa4a 290 for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE) {
Wolfgang Betz 132:51056160fa4a 291 RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret);
Wolfgang Betz 132:51056160fa4a 292 if (ret != BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 293 break;
Wolfgang Betz 132:51056160fa4a 294 }
Wolfgang Betz 132:51056160fa4a 295 if (ret == BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 296 break;
Wolfgang Betz 132:51056160fa4a 297 }
Wolfgang Betz 132:51056160fa4a 298 if (num_erase_retries == MAX_ERASE_RETRIES)
Wolfgang Betz 132:51056160fa4a 299 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 300
Wolfgang Betz 132:51056160fa4a 301 /***********************************************************************
Wolfgang Betz 132:51056160fa4a 302 * Verify IFR
Wolfgang Betz 132:51056160fa4a 303 ************************************************************************/
Wolfgang Betz 132:51056160fa4a 304 {
Wolfgang Betz 132:51056160fa4a 305 uint8_t ifr_updated[DATA_SIZE];
Wolfgang Betz 132:51056160fa4a 306 for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE){
Wolfgang Betz 132:51056160fa4a 307 ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_updated);
Wolfgang Betz 132:51056160fa4a 308 if(ret != BLE_STATUS_SUCCESS){
Wolfgang Betz 132:51056160fa4a 309 return ret;
Wolfgang Betz 132:51056160fa4a 310 }
Wolfgang Betz 132:51056160fa4a 311 if (memcmp(ifr_updated, ifr_data+j, DATA_SIZE) != 0)
Wolfgang Betz 132:51056160fa4a 312 return BLE_UTIL_WRONG_VERIFY;
Wolfgang Betz 132:51056160fa4a 313 }
Wolfgang Betz 132:51056160fa4a 314 }
Wolfgang Betz 132:51056160fa4a 315
Wolfgang Betz 132:51056160fa4a 316 BlueNRG_RST();
Wolfgang Betz 132:51056160fa4a 317 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 318
Wolfgang Betz 132:51056160fa4a 319 return BLE_STATUS_SUCCESS;
Wolfgang Betz 132:51056160fa4a 320 }
Wolfgang Betz 132:51056160fa4a 321
Wolfgang Betz 132:51056160fa4a 322 uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data)
Wolfgang Betz 132:51056160fa4a 323 {
Wolfgang Betz 132:51056160fa4a 324 uint8_t ifr_updated[DATA_SIZE];
Wolfgang Betz 132:51056160fa4a 325 uint8_t version, ret = BLE_STATUS_SUCCESS;
Wolfgang Betz 132:51056160fa4a 326
Wolfgang Betz 132:51056160fa4a 327 aci_updater_start();
Wolfgang Betz 132:51056160fa4a 328 if(aci_get_updater_version(&version))
Wolfgang Betz 132:51056160fa4a 329 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 330 for(int i = 0; i < IFR_SIZE; i += DATA_SIZE){
Wolfgang Betz 132:51056160fa4a 331 ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, DATA_SIZE, ifr_updated);
Wolfgang Betz 132:51056160fa4a 332 if(ret != BLE_STATUS_SUCCESS){
Wolfgang Betz 132:51056160fa4a 333 return ret;
Wolfgang Betz 132:51056160fa4a 334 }
Wolfgang Betz 132:51056160fa4a 335 if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, DATA_SIZE) != 0)
Wolfgang Betz 132:51056160fa4a 336 {
Wolfgang Betz 132:51056160fa4a 337 ret = BLE_UTIL_WRONG_VERIFY;
Wolfgang Betz 132:51056160fa4a 338 break;
Wolfgang Betz 132:51056160fa4a 339 }
Wolfgang Betz 132:51056160fa4a 340 }
Wolfgang Betz 132:51056160fa4a 341
Wolfgang Betz 132:51056160fa4a 342 BlueNRG_RST();
Wolfgang Betz 132:51056160fa4a 343 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 344
Wolfgang Betz 132:51056160fa4a 345 return ret;
Wolfgang Betz 132:51056160fa4a 346 }
Wolfgang Betz 132:51056160fa4a 347
Wolfgang Betz 132:51056160fa4a 348 uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion)
Wolfgang Betz 132:51056160fa4a 349 {
Wolfgang Betz 132:51056160fa4a 350 uint8_t status;
Wolfgang Betz 132:51056160fa4a 351 uint8_t hci_version, lmp_pal_version;
Wolfgang Betz 132:51056160fa4a 352 uint16_t hci_revision, manufacturer_name, lmp_pal_subversion;
Wolfgang Betz 132:51056160fa4a 353
Wolfgang Betz 132:51056160fa4a 354 status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version,
Wolfgang Betz 132:51056160fa4a 355 &manufacturer_name, &lmp_pal_subversion);
Wolfgang Betz 132:51056160fa4a 356
Wolfgang Betz 132:51056160fa4a 357 if (status == BLE_STATUS_SUCCESS) {
Wolfgang Betz 132:51056160fa4a 358 *hwVersion = hci_revision >> 8;
Wolfgang Betz 132:51056160fa4a 359 *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number
Wolfgang Betz 132:51056160fa4a 360 *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number
Wolfgang Betz 132:51056160fa4a 361 *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number
Wolfgang Betz 132:51056160fa4a 362 }
Wolfgang Betz 132:51056160fa4a 363
Wolfgang Betz 132:51056160fa4a 364 HCI_Process(); // To receive the BlueNRG EVT
Wolfgang Betz 132:51056160fa4a 365
Wolfgang Betz 132:51056160fa4a 366 return status;
Wolfgang Betz 132:51056160fa4a 367 }
Wolfgang Betz 132:51056160fa4a 368
Wolfgang Betz 132:51056160fa4a 369 uint8_t getBlueNRGUpdaterVersion(uint8_t *version)
Wolfgang Betz 132:51056160fa4a 370 {
Wolfgang Betz 132:51056160fa4a 371
Wolfgang Betz 132:51056160fa4a 372 BlueNRG_HW_Bootloader();
Wolfgang Betz 132:51056160fa4a 373 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 374
Wolfgang Betz 132:51056160fa4a 375 if(aci_get_updater_version(version))
Wolfgang Betz 132:51056160fa4a 376 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 377
Wolfgang Betz 132:51056160fa4a 378 if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX)
Wolfgang Betz 132:51056160fa4a 379 return BLE_UTIL_UNSUPPORTED_VERSION;
Wolfgang Betz 132:51056160fa4a 380
Wolfgang Betz 132:51056160fa4a 381 BlueNRG_RST();
Wolfgang Betz 132:51056160fa4a 382 HCI_Process(); // To receive the EVT_INITIALIZED
Wolfgang Betz 132:51056160fa4a 383
Wolfgang Betz 132:51056160fa4a 384 return BLE_STATUS_SUCCESS;
Wolfgang Betz 132:51056160fa4a 385 }
Wolfgang Betz 132:51056160fa4a 386
Wolfgang Betz 132:51056160fa4a 387 uint8_t isHWBootloader_Patched(void)
Wolfgang Betz 132:51056160fa4a 388 {
Wolfgang Betz 132:51056160fa4a 389 uint8_t status, version;
Wolfgang Betz 132:51056160fa4a 390 uint32_t crc, address = 0x10010000;
Wolfgang Betz 132:51056160fa4a 391
Wolfgang Betz 132:51056160fa4a 392 if(aci_get_updater_version(&version))
Wolfgang Betz 132:51056160fa4a 393 return BLE_UTIL_ACI_ERROR;
Wolfgang Betz 132:51056160fa4a 394
Wolfgang Betz 132:51056160fa4a 395 RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status);
Wolfgang Betz 132:51056160fa4a 396 if (status != BLE_STATUS_SUCCESS)
Wolfgang Betz 132:51056160fa4a 397 return 0;
Wolfgang Betz 132:51056160fa4a 398
Wolfgang Betz 132:51056160fa4a 399 if (crc == BOOTLOADER_CRC_NOT_PATCHED)
Wolfgang Betz 132:51056160fa4a 400 return 0;
Wolfgang Betz 132:51056160fa4a 401
Wolfgang Betz 132:51056160fa4a 402 return 1;
Wolfgang Betz 132:51056160fa4a 403 }