38
+ − 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
+ − 39 /* Private variables ---------------------------------------------------------*/
+ − 40
+ − 41 /* Private function prototypes -----------------------------------------------*/
+ − 42
300
+ − 43 static uint8_t boot_sync_frame(void);
+ − 44 static uint8_t boot_ack(void);
+ − 45 static uint8_t boot_get_id(uint8_t *RxBuffer);
+ − 46 static uint8_t boot_get_version(uint8_t *RxBuffer);
+ − 47 static uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data);
+ − 48 static uint8_t boot_erase_memory(void);
+ − 49 static void Bootloader_send_command(uint8_t command);
+ − 50 static void Bootloader_spi_single(uint8_t TxByte);
+ − 51 static void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer);
699
+ − 52 //static void Bootloader_Error_Handler(void);
38
+ − 53
+ − 54 /* Exported functions --------------------------------------------------------*/
+ − 55
+ − 56 uint8_t extCPU2bootloader_start(uint8_t *version, uint16_t *chipID)
+ − 57 {
+ − 58 uint8_t aRxBuffer[256] = { 0 };
+ − 59
+ − 60 HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
+ − 61
+ − 62 boot_sync_frame();
+ − 63 boot_get_version(aRxBuffer);
+ − 64 *version = aRxBuffer[1];
+ − 65 HAL_Delay(10);
+ − 66 boot_get_id(aRxBuffer);
+ − 67 *chipID = ((uint16_t)aRxBuffer[2]) << 8;
+ − 68 *chipID += (uint16_t)aRxBuffer[3];
+ − 69 HAL_Delay(10);
+ − 70 if((*chipID == 0x431) && (*version > 10) && (*version < 32))
+ − 71 return 1;
+ − 72 else
+ − 73 return 0;
+ − 74 }
+ − 75
+ − 76
53
+ − 77 uint8_t extCPU2bootloader_internal(uint8_t* buffer, uint32_t length, char* display_text)
38
+ − 78 {
+ − 79 uint8_t version = 0;
+ − 80 uint16_t chipID = 0;
300
+ − 81
38
+ − 82 if(!extCPU2bootloader_start(&version,&chipID))
+ − 83 return 0;
+ − 84 if(!boot_erase_memory())
+ − 85 return 0;
+ − 86 HAL_Delay(100);
+ − 87 uint16_t i=0;
53
+ − 88 uint32_t lengthsave = length;
38
+ − 89 uint8_t percent = 0;
+ − 90
+ − 91 while(length)
+ − 92 {
+ − 93 percent = (100 * (i * 256)) /lengthsave;
+ − 94 tComm_verlauf(percent);
+ − 95
+ − 96 if(length > 256)
+ − 97 {
+ − 98 if( !boot_write_memory(0x08000000 + (i * 256), 255, &buffer[i * 256]) )
+ − 99 return 0;;
+ − 100 length -= 256;
+ − 101
+ − 102 }
+ − 103 else
+ − 104 {
+ − 105 if(!boot_write_memory(0x08000000 + (i * 256), length - 1, &buffer[i * 256]))
+ − 106 return 0;
+ − 107 length = 0;
+ − 108 }
+ − 109 i++;
+ − 110 }
+ − 111 return 2;
+ − 112 }
+ − 113
+ − 114
53
+ − 115 uint8_t extCPU2bootloader(uint8_t* buffer, uint32_t length, char* display_text)
38
+ − 116 {
+ − 117 uint8_t result = 0;
+ − 118
+ − 119 MX_SmallCPU_Reset_To_Boot();
+ − 120 result = extCPU2bootloader_internal(buffer,length,display_text);
+ − 121 MX_SmallCPU_Reset_To_Standard();
+ − 122 return result;
+ − 123 }
+ − 124
+ − 125 /* Private functions --------------------------------------------------------*/
+ − 126
300
+ − 127 static uint8_t boot_sync_frame(void)
38
+ − 128 {
+ − 129 Bootloader_spi_single(0x5a);
+ − 130 return boot_ack();
+ − 131 }
+ − 132
300
+ − 133 static uint8_t boot_get_version(uint8_t *RxBuffer)
38
+ − 134 {
+ − 135 Bootloader_spi_single(0x5a);
300
+ − 136 Bootloader_send_command(0x01);
38
+ − 137 if(!boot_ack())
+ − 138 return 0;
+ − 139 Bootloader_spi(3, NULL, RxBuffer);
+ − 140 return boot_ack();
+ − 141 }
+ − 142
+ − 143
300
+ − 144 static uint8_t boot_get_id(uint8_t *RxBuffer)
38
+ − 145 {
+ − 146 Bootloader_spi_single(0x5a);
300
+ − 147 Bootloader_send_command(0x02);
38
+ − 148 if(!boot_ack())
+ − 149 return 0;
+ − 150 Bootloader_spi(5, NULL, RxBuffer);
+ − 151 return boot_ack();
+ − 152 }
+ − 153
+ − 154
+ − 155 uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data)
+ − 156 {
+ − 157 uint8_t addressNew[4];
+ − 158 uint8_t checksum = 0;
+ − 159 uint16_t length;
+ − 160
+ − 161 Bootloader_spi_single(0x5a);
300
+ − 162 Bootloader_send_command(0x31);
38
+ − 163 if(!boot_ack())
+ − 164 return 1;
+ − 165 HAL_Delay(5);
+ − 166 addressNew[0] = (uint8_t)((address >> 24) & 0xFF);
+ − 167 addressNew[1] = (uint8_t)((address >> 16) & 0xFF);
+ − 168 addressNew[2] = (uint8_t)((address >> 8) & 0xFF);
+ − 169 addressNew[3] = (uint8_t)((address >> 0) & 0xFF);
+ − 170 Bootloader_spi(4, addressNew, NULL);
+ − 171 checksum = 0;
+ − 172 checksum ^= addressNew[0];
+ − 173 checksum ^= addressNew[1];
+ − 174 checksum ^= addressNew[2];
+ − 175 checksum ^= addressNew[3];
+ − 176 Bootloader_spi_single(checksum);
+ − 177 if(!boot_ack())
+ − 178 return 0;
+ − 179 HAL_Delay(1);
+ − 180 Bootloader_spi_single(length_minus_1);
+ − 181 length = ((uint16_t)length_minus_1) + 1;
+ − 182 Bootloader_spi(length, data, NULL);
+ − 183 HAL_Delay(26);
+ − 184 checksum = 0;
+ − 185 checksum ^= length_minus_1;
+ − 186 for(int i=0;i<length;i++)
+ − 187 checksum ^= data[i];
+ − 188 Bootloader_spi_single(checksum);
+ − 189
+ − 190 if(!boot_ack())
+ − 191 return 0;
+ − 192 HAL_Delay(1);
+ − 193 return 1;
+ − 194 }
+ − 195
300
+ − 196 static uint8_t boot_erase_memory(void)
38
+ − 197 {
+ − 198 uint8_t special_erase_with_checksum[3] = {0xFF, 0xFF, 0x00};
+ − 199
+ − 200 Bootloader_spi_single(0x5a);
300
+ − 201 Bootloader_send_command(0x44);
38
+ − 202 if(!boot_ack())
+ − 203 return 0;
+ − 204 Bootloader_spi(3, special_erase_with_checksum, NULL);
+ − 205 HAL_Delay(11000); /* 5.5 to 11 seconds */
+ − 206 if(!boot_ack())
+ − 207 return 0;
+ − 208 return 1;
+ − 209 }
+ − 210
+ − 211 /* write unprotect does reset the system !! */
+ − 212 uint8_t boot_write_unprotect(void)
+ − 213 {
+ − 214 Bootloader_spi_single(0x5a);
300
+ − 215 Bootloader_send_command(0x73);
38
+ − 216 if(!boot_ack())
+ − 217 return 0;
+ − 218 return boot_ack();
+ − 219 }
+ − 220
300
+ − 221 static uint8_t boot_ack(void)
38
+ − 222 {
+ − 223 uint8_t answer = 0;
+ − 224
+ − 225 Bootloader_spi_single(0x00);
+ − 226 for(int i=0; i< 1000; i++)
+ − 227 {
+ − 228 Bootloader_spi(1, NULL, &answer);
+ − 229 if((answer == 0x79) || (answer == 0x1F))
+ − 230 {
+ − 231 Bootloader_spi_single(0x79);
+ − 232 break;
+ − 233 }
+ − 234 HAL_Delay(10);
+ − 235 }
+ − 236 if(answer == 0x79)
+ − 237 return 1;
+ − 238 else
+ − 239 return 0;
+ − 240 }
+ − 241
300
+ − 242 static void Bootloader_send_command(uint8_t command)
38
+ − 243 {
+ − 244 uint8_t send[2];
+ − 245 uint8_t receive[2];
+ − 246
+ − 247 send[0] = command;
+ − 248 send[1] = 0xFF ^ command;
+ − 249 Bootloader_spi(2, send, receive);
+ − 250 }
+ − 251
300
+ − 252 static void Bootloader_spi_single(uint8_t TxByte)
38
+ − 253 {
+ − 254 Bootloader_spi(1,&TxByte, 0);
+ − 255 }
+ − 256
+ − 257
300
+ − 258 static void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer)
38
+ − 259 {
+ − 260 uint8_t dummy[256] = { 0 };
+ − 261 uint8_t *tx_data;
+ − 262 uint8_t *rx_data;
+ − 263
+ − 264 tx_data = aTxBuffer;
+ − 265 rx_data = aRxBuffer;
+ − 266
+ − 267 if(aTxBuffer == NULL)
+ − 268 tx_data = dummy;
+ − 269 if(aRxBuffer == NULL)
+ − 270 rx_data = dummy;
+ − 271
+ − 272 //HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_RESET); // only for testing with Oscilloscope
+ − 273
+ − 274
+ − 275 HAL_SPI_TransmitReceive(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData,1000);
+ − 276 /*
+ − 277 if(HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData) != HAL_OK)
+ − 278 if(HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)tx_data, (uint8_t *)rx_data, (uint16_t)lengthData) != HAL_OK)
+ − 279 Bootloader_Error_Handler();
+ − 280
+ − 281 while (HAL_SPI_GetState(&cpu2DmaSpi) != HAL_SPI_STATE_READY)// only for testing with Oscilloscope
+ − 282 {
+ − 283 }
+ − 284 HAL_GPIO_WritePin(OSCILLOSCOPE_GPIO_PORT,OSCILLOSCOPE_PIN,GPIO_PIN_SET); // only for testing with Oscilloscope
+ − 285 */
+ − 286 }
+ − 287
+ − 288
699
+ − 289 /*
300
+ − 290 static void Bootloader_Error_Handler(void)
38
+ − 291 {
+ − 292 while(1);
+ − 293 }
699
+ − 294 */