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 |