Mercurial > public > ostc4
annotate Discovery/Src/externCPU2bootloader.c @ 319:d8e86af78474 fix-version
bugfix: correct packed main version number in dive header
This fixes a rather mysterious bug. Users report that up to 1.3.5 beta,
a correct version number is shown in libdivecomputer based
applications (like in Subsurface, in the extra data tab). Careful
examining the code in both libdivecomputer and the firmware shows
a subtle error in the bit mask and shift operation to pack a full
X.Y.Z.beta version number in 2 bytes (as is available in the
dive header) in the firmware end (as the libdivecomputer code
looks sane, assuming this is the right way to pack things).
Likely, this bug crept in in the conversion from the closed
source Keil period into the open source GCC setup of
the code base. So its impossible to document the exact
history of this problem here.
Further notice that the main version number is only 1 of 3 version
numbers, denoting the full version of the firmware (besides Font
and RTE).
Finally notice that this way of packing is limited to 2^5 bits
(decimal 32), so we could easily build a 1.4.21, but not a
1.4.55.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Wed, 19 Jun 2019 14:31:50 +0200 |
parents | 5ca177d2df5d |
children | 01f40cb1057e |
rev | line source |
---|---|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
43 static uint8_t boot_sync_frame(void); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
44 static uint8_t boot_ack(void); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
45 static uint8_t boot_get_id(uint8_t *RxBuffer); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
46 static uint8_t boot_get_version(uint8_t *RxBuffer); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
47 static uint8_t boot_write_memory(uint32_t address, uint8_t length_minus_1, uint8_t *data); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
48 static uint8_t boot_erase_memory(void); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
49 static void Bootloader_send_command(uint8_t command); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
50 static void Bootloader_spi_single(uint8_t TxByte); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
51 static void Bootloader_spi(uint16_t lengthData, uint8_t *aTxBuffer, uint8_t *aRxBuffer); |
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
127 static uint8_t boot_sync_frame(void) |
38 | 128 { |
129 Bootloader_spi_single(0x5a); | |
130 return boot_ack(); | |
131 } | |
132 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
133 static uint8_t boot_get_version(uint8_t *RxBuffer) |
38 | 134 { |
135 Bootloader_spi_single(0x5a); | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
144 static uint8_t boot_get_id(uint8_t *RxBuffer) |
38 | 145 { |
146 Bootloader_spi_single(0x5a); | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
215 Bootloader_send_command(0x73); |
38 | 216 if(!boot_ack()) |
217 return 0; | |
218 return boot_ack(); | |
219 } | |
220 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
252 static void Bootloader_spi_single(uint8_t TxByte) |
38 | 253 { |
254 Bootloader_spi(1,&TxByte, 0); | |
255 } | |
256 | |
257 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
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 | |
300
5ca177d2df5d
cleanup: remove commented/unused code, make static
Jan Mulder <jlmulder@xs4all.nl>
parents:
53
diff
changeset
|
289 static void Bootloader_Error_Handler(void) |
38 | 290 { |
291 while(1); | |
292 } |