Mercurial > public > ostc4
comparison Discovery/Src/externCPU2bootloader.c @ 38:5f11787b4f42
include in ostc4 repository
| author | heinrichsweikamp |
|---|---|
| date | Sat, 28 Apr 2018 11:52:34 +0200 |
| parents | |
| children | f64cf099a7f5 |
comparison
equal
deleted
inserted
replaced
| 37:ccc45c0e1ea2 | 38:5f11787b4f42 |
|---|---|
| 1 /** | |
| 2 ****************************************************************************** | |
| 3 * @file externCPU2bootloader.c Template | |
| 4 * @author heinrichs weikamp gmbh | |
| 5 * @version V0.0.1 | |
| 6 * @date 23-Oct-2014 | |
| 7 * @version V0.0.1 | |
| 8 * @since 23-Oct-2014 | |
| 9 * @brief Main Template to communicate with the second CPU in bootloader mode | |
| 10 * bootloader ROM build by ST and defined in AN4286 | |
| 11 * | |
| 12 @verbatim | |
| 13 ============================================================================== | |
| 14 ##### How to use ##### | |
| 15 ============================================================================== | |
| 16 @endverbatim | |
| 17 ****************************************************************************** | |
| 18 * @attention | |
| 19 * | |
| 20 * <h2><center>© COPYRIGHT(c) 2016 heinrichs weikamp</center></h2> | |
| 21 * | |
| 22 ****************************************************************************** | |
| 23 */ | |
| 24 | |
| 25 /* Includes ------------------------------------------------------------------*/ | |
| 26 #include "stm32f4xx_hal.h" | |
| 27 #include "stdio.h" | |
| 28 #include "ostc.h" | |
| 29 #include "settings.h" | |
| 30 #include "externCPU2bootloader.h" | |
| 31 #include "externLogbookFlash.h" | |
| 32 #include "tComm.h" | |
| 33 | |
| 34 | |
| 35 /* Exported variables --------------------------------------------------------*/ | |
| 36 | |
| 37 /* Private types -------------------------------------------------------------*/ | |
| 38 #define BOOTLOADSPITIMEOUT 5000 | |
| 39 | |
| 40 /* Private variables ---------------------------------------------------------*/ | |
| 41 | |
| 42 /* Private function prototypes -----------------------------------------------*/ | |
| 43 | |
| 44 uint8_t boot_sync_frame(void); | |
| 45 uint8_t boot_ack(void); | |
| 46 uint8_t boot_get(uint8_t *RxBuffer); | |
| 47 uint8_t boot_get_id(uint8_t *RxBuffer); | |
| 48 uint8_t boot_get_version(uint8_t *RxBuffer); | |
| 49 //uint8_t boot_go(uint32_t address); | |
| 50 uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data); | |
| 51 //uint8_t boot_erase_memory(uint16_t data_frame, uint16_t *page_numbers); | |
| 52 uint8_t boot_erase_memory(void); | |
| 53 uint8_t boot_write_protect(uint8_t number_of_sectors_minus_one, uint8_t *sector_codes); | |
| 54 /* | |
| 55 uint8_t boot_write_unprotect(void); | |
| 56 uint8_t boot_readout_protect(void); | |
| 57 uint8_t boot_readout_unprotect(void); | |
| 58 */ | |
| 59 void Bootoader_send_command(uint8_t command); | |
| 60 void Bootloader_spi_single(uint8_t TxByte); | |
| 61 void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer); | |
| 62 void Bootloader_Error_Handler(void); | |
| 63 | |
| 64 /* Exported functions --------------------------------------------------------*/ | |
| 65 | |
| 66 uint8_t extCPU2bootloader_start(uint8_t *version, uint16_t *chipID) | |
| 67 { | |
| 68 // uint8_t aTxBuffer[256] = { 0 }; | |
| 69 uint8_t aRxBuffer[256] = { 0 }; | |
| 70 | |
| 71 HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET); | |
| 72 | |
| 73 boot_sync_frame(); | |
| 74 boot_get_version(aRxBuffer); | |
| 75 *version = aRxBuffer[1]; | |
| 76 HAL_Delay(10); | |
| 77 boot_get_id(aRxBuffer); | |
| 78 *chipID = ((uint16_t)aRxBuffer[2]) << 8; | |
| 79 *chipID += (uint16_t)aRxBuffer[3]; | |
| 80 HAL_Delay(10); | |
| 81 if((*chipID == 0x431) && (*version > 10) && (*version < 32)) | |
| 82 return 1; | |
| 83 else | |
| 84 return 0; | |
| 85 } | |
| 86 | |
| 87 | |
| 88 uint8_t extCPU2bootloader_internal(uint8_t* buffer, uint16_t length, char* display_text) | |
| 89 { | |
| 90 uint8_t version = 0; | |
| 91 uint16_t chipID = 0; | |
| 92 // uint8_t ret; | |
| 93 if(!extCPU2bootloader_start(&version,&chipID)) | |
| 94 return 0; | |
| 95 if(!boot_erase_memory()) | |
| 96 return 0; | |
| 97 HAL_Delay(100); | |
| 98 uint16_t i=0; | |
| 99 uint16_t lengthsave = length; | |
| 100 uint8_t percent = 0; | |
| 101 | |
| 102 while(length) | |
| 103 { | |
| 104 percent = (100 * (i * 256)) /lengthsave; | |
| 105 tComm_verlauf(percent); | |
| 106 | |
| 107 if(length > 256) | |
| 108 { | |
| 109 if( !boot_write_memory(0x08000000 + (i * 256), 255, &buffer[i * 256]) ) | |
| 110 return 0;; | |
| 111 length -= 256; | |
| 112 | |
| 113 } | |
| 114 else | |
| 115 { | |
| 116 if(!boot_write_memory(0x08000000 + (i * 256), length - 1, &buffer[i * 256])) | |
| 117 return 0; | |
| 118 length = 0; | |
| 119 } | |
| 120 i++; | |
| 121 } | |
| 122 return 2; | |
| 123 } | |
| 124 | |
| 125 | |
| 126 uint8_t extCPU2bootloader(uint8_t* buffer, uint16_t length, char* display_text) | |
| 127 { | |
| 128 uint8_t result = 0; | |
| 129 | |
| 130 MX_SmallCPU_Reset_To_Boot(); | |
| 131 result = extCPU2bootloader_internal(buffer,length,display_text); | |
| 132 MX_SmallCPU_Reset_To_Standard(); | |
| 133 return result; | |
| 134 } | |
| 135 | |
| 136 /* Private functions --------------------------------------------------------*/ | |
| 137 | |
| 138 uint8_t boot_sync_frame(void) | |
| 139 { | |
| 140 Bootloader_spi_single(0x5a); | |
| 141 return boot_ack(); | |
| 142 } | |
| 143 | |
| 144 | |
| 145 uint8_t boot_get(uint8_t *RxBuffer) | |
| 146 { | |
| 147 Bootloader_spi_single(0x5a); | |
| 148 Bootoader_send_command(0x00); | |
| 149 if(!boot_ack()) | |
| 150 return 0; | |
| 151 Bootloader_spi(14, NULL, RxBuffer); | |
| 152 return boot_ack(); | |
| 153 } | |
| 154 | |
| 155 | |
| 156 uint8_t boot_get_version(uint8_t *RxBuffer) | |
| 157 { | |
| 158 Bootloader_spi_single(0x5a); | |
| 159 Bootoader_send_command(0x01); | |
| 160 if(!boot_ack()) | |
| 161 return 0; | |
| 162 Bootloader_spi(3, NULL, RxBuffer); | |
| 163 return boot_ack(); | |
| 164 } | |
| 165 | |
| 166 | |
| 167 uint8_t boot_get_id(uint8_t *RxBuffer) | |
| 168 { | |
| 169 Bootloader_spi_single(0x5a); | |
| 170 Bootoader_send_command(0x02); | |
| 171 if(!boot_ack()) | |
| 172 return 0; | |
| 173 Bootloader_spi(5, NULL, RxBuffer); | |
| 174 return boot_ack(); | |
| 175 } | |
| 176 | |
| 177 /* | |
| 178 uint8_t boot_go(uint32_t address) | |
| 179 { | |
| 180 | |
| 181 } | |
| 182 */ | |
| 183 | |
| 184 | |
| 185 uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data) | |
| 186 { | |
| 187 uint8_t addressNew[4]; | |
| 188 uint8_t checksum = 0; | |
| 189 uint16_t length; | |
| 190 | |
| 191 Bootloader_spi_single(0x5a); | |
| 192 Bootoader_send_command(0x31); | |
| 193 if(!boot_ack()) | |
| 194 return 1; | |
| 195 HAL_Delay(5); | |
| 196 addressNew[0] = (uint8_t)((address >> 24) & 0xFF); | |
| 197 addressNew[1] = (uint8_t)((address >> 16) & 0xFF); | |
| 198 addressNew[2] = (uint8_t)((address >> 8) & 0xFF); | |
| 199 addressNew[3] = (uint8_t)((address >> 0) & 0xFF); | |
| 200 Bootloader_spi(4, addressNew, NULL); | |
| 201 checksum = 0; | |
| 202 checksum ^= addressNew[0]; | |
| 203 checksum ^= addressNew[1]; | |
| 204 checksum ^= addressNew[2]; | |
| 205 checksum ^= addressNew[3]; | |
| 206 Bootloader_spi_single(checksum); | |
| 207 if(!boot_ack()) | |
| 208 return 0; | |
| 209 HAL_Delay(1); | |
| 210 Bootloader_spi_single(length_minus_1); | |
| 211 length = ((uint16_t)length_minus_1) + 1; | |
| 212 Bootloader_spi(length, data, NULL); | |
| 213 HAL_Delay(26); | |
| 214 checksum = 0; | |
| 215 checksum ^= length_minus_1; | |
| 216 for(int i=0;i<length;i++) | |
| 217 checksum ^= data[i]; | |
| 218 Bootloader_spi_single(checksum); | |
| 219 | |
| 220 if(!boot_ack()) | |
| 221 return 0; | |
| 222 HAL_Delay(1); | |
| 223 return 1; | |
| 224 } | |
| 225 | |
| 226 //uint8_t boot_erase_memory(uint16_t data_frame, uint16_t *page_numbers) | |
| 227 uint8_t boot_erase_memory(void) | |
| 228 { | |
| 229 uint8_t special_erase_with_checksum[3] = {0xFF, 0xFF, 0x00}; | |
| 230 | |
| 231 Bootloader_spi_single(0x5a); | |
| 232 Bootoader_send_command(0x44); | |
| 233 if(!boot_ack()) | |
| 234 return 0; | |
| 235 Bootloader_spi(3, special_erase_with_checksum, NULL); | |
| 236 HAL_Delay(11000); /* 5.5 to 11 seconds */ | |
| 237 if(!boot_ack()) | |
| 238 return 0; | |
| 239 return 1; | |
| 240 } | |
| 241 | |
| 242 /* write unprotect does reset the system !! */ | |
| 243 uint8_t boot_write_unprotect(void) | |
| 244 { | |
| 245 Bootloader_spi_single(0x5a); | |
| 246 Bootoader_send_command(0x73); | |
| 247 if(!boot_ack()) | |
| 248 return 0; | |
| 249 return boot_ack(); | |
| 250 } | |
| 251 | |
| 252 /* | |
| 253 uint8_t boot_write_protect(uint8_t number_of_sectors_minus_one, uint8_t *sector_codes) | |
| 254 { | |
| 255 | |
| 256 } | |
| 257 | |
| 258 uint8_t boot_readout_protect(void) | |
| 259 { | |
| 260 | |
| 261 } | |
| 262 | |
| 263 uint8_t boot_readout_unprotect(void) | |
| 264 { | |
| 265 | |
| 266 } | |
| 267 */ | |
| 268 | |
| 269 uint8_t boot_ack(void) | |
| 270 { | |
| 271 uint8_t answer = 0; | |
| 272 | |
| 273 Bootloader_spi_single(0x00); | |
| 274 for(int i=0; i< 1000; i++) | |
| 275 { | |
| 276 Bootloader_spi(1, NULL, &answer); | |
| 277 if((answer == 0x79) || (answer == 0x1F)) | |
| 278 { | |
| 279 Bootloader_spi_single(0x79); | |
| 280 break; | |
| 281 } | |
| 282 HAL_Delay(10); | |
| 283 } | |
| 284 if(answer == 0x79) | |
| 285 return 1; | |
| 286 else | |
| 287 return 0; | |
| 288 } | |
| 289 | |
| 290 void Bootoader_send_command(uint8_t command) | |
| 291 { | |
| 292 uint8_t send[2]; | |
| 293 uint8_t receive[2]; | |
| 294 | |
| 295 send[0] = command; | |
| 296 send[1] = 0xFF ^ command; | |
| 297 Bootloader_spi(2, send, receive); | |
| 298 } | |
| 299 | |
| 300 void Bootloader_spi_single(uint8_t TxByte) | |
| 301 { | |
| 302 Bootloader_spi(1,&TxByte, 0); | |
| 303 } | |
| 304 | |
| 305 | |
| 306 void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer) | |
| 307 { | |
| 308 uint8_t dummy[256] = { 0 }; | |
| 309 uint8_t *tx_data; | |
| 310 uint8_t *rx_data; | |
| 311 | |
| 312 tx_data = aTxBuffer; | |
| 313 rx_data = aRxBuffer; | |
| 314 | |
| 315 if(aTxBuffer == NULL) | |
| 316 tx_data = dummy; | |
| 317 if(aRxBuffer == NULL) | |
| 318 rx_data = dummy; | |
| 319 | |
| 320 //HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_RESET); // only for testing with Oscilloscope | |
| 321 | |
| 322 | |
| 323 HAL_SPI_TransmitReceive(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData,1000); | |
| 324 /* | |
| 325 if(HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData) != HAL_OK) | |
| 326 if(HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData) != HAL_OK) | |
| 327 Bootloader_Error_Handler(); | |
| 328 | |
| 329 while (HAL_SPI_GetState(&cpu2DmaSpi) != HAL_SPI_STATE_READY)// only for testing with Oscilloscope | |
| 330 { | |
| 331 } | |
| 332 HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_SET); // only for testing with Oscilloscope | |
| 333 */ | |
| 334 } | |
| 335 | |
| 336 | |
| 337 void Bootloader_Error_Handler(void) | |
| 338 { | |
| 339 while(1); | |
| 340 } | |
| 341 | |
| 342 | |
| 343 |
