Mercurial > public > ostc4
annotate Small_CPU/Src/spi.c @ 240:625d20070261 div-fixes-5
Improvement SPI stability/recoverability
The core part of this commit comes from careful code reading. The core is the
swap of Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_SOFT) and
SPI_Start_single_TxRx_with_Master(). This code is sitting in an if-clause
that is triggered on SPI comms failure. Instead of blindly trying to
communicate again (which will very likely fail again), first try to reset
the comms link, and then try to communicate again. That simply makes
more sense in this case.
This is heavily tested, on 2 simple dives, and 5 very long deco schedules
from the simulator (10+ hour deco's), and a lot of small simulated dives
(upto 2h runtime). Of all these tests, only one long session failed after
9 out of 11h runtime. Analyzing that one failure, suggests that the
RTE is looping in some error handler, which (obviously) results in
a SPI comms failure as a result. I consider this not part of this change.
Additionally, some more cleanup is done in this code.
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
author | Jan Mulder <jlmulder@xs4all.nl> |
---|---|
date | Mon, 08 Apr 2019 11:49:13 +0200 |
parents | e4207f0aaa4b |
children | b3685fbada3b |
rev | line source |
---|---|
38 | 1 /** |
89 | 2 ****************************************************************************** |
3 * @file spi.c | |
4 * @author heinrichs weikamp gmbh | |
5 * @version V0.0.1 | |
6 * @date 16-Sept-2014 | |
7 * @brief Source code for spi control | |
8 * | |
9 @verbatim | |
10 ============================================================================== | |
11 ##### How to use ##### | |
12 ============================================================================== | |
13 @endverbatim | |
14 ****************************************************************************** | |
15 * @attention | |
16 * | |
17 * <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2> | |
18 * | |
19 ****************************************************************************** | |
20 */ | |
38 | 21 |
22 /* Includes ------------------------------------------------------------------*/ | |
143 | 23 |
24 #include "global_constants.h" | |
38 | 25 #include "spi.h" |
120 | 26 #include "dma.h" |
143 | 27 |
38 | 28 //#include "gpio.h" |
29 | |
30 /* USER CODE BEGIN 0 */ | |
31 #include "scheduler.h" | |
32 | |
120 | 33 #ifdef DEBUG_GPIO |
38 | 34 extern void GPIO_new_DEBUG_LOW(void); |
35 extern void GPIO_new_DEBUG_HIGH(void); | |
120 | 36 #endif |
38 | 37 |
89 | 38 uint8_t data_error = 0; |
39 uint32_t data_error_time = 0; | |
143 | 40 uint8_t SPIDataRX = 0; /* Flag to signal that SPI RX callback has been triggered */ |
38 | 41 |
42 static void SPI_Error_Handler(void); | |
43 | |
44 /* USER CODE END 0 */ | |
45 | |
46 static uint8_t SPI_check_header_and_footer_ok(void); | |
143 | 47 static uint8_t DataEX_check_header_and_footer_shifted(void); |
38 | 48 |
49 SPI_HandleTypeDef hspi1; | |
50 SPI_HandleTypeDef hspi3; | |
51 | |
52 DMA_HandleTypeDef hdma_tx; | |
53 DMA_HandleTypeDef hdma_rx; | |
54 | |
55 // SPI3 init function | |
89 | 56 void MX_SPI3_Init(void) { |
57 hspi3.Instance = SPI3; | |
58 hspi3.Init.Mode = SPI_MODE_MASTER; | |
59 hspi3.Init.Direction = SPI_DIRECTION_2LINES; | |
60 hspi3.Init.DataSize = SPI_DATASIZE_8BIT; | |
61 hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH; | |
62 hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; | |
63 hspi3.Init.NSS = SPI_NSS_SOFT; | |
64 hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; | |
65 hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; | |
66 hspi3.Init.TIMode = SPI_TIMODE_DISABLED; | |
67 hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; | |
68 hspi3.Init.CRCPolynomial = 7; | |
69 HAL_SPI_Init(&hspi3); | |
38 | 70 } |
71 | |
89 | 72 void MX_SPI3_DeInit(void) { |
73 HAL_SPI_DeInit(&hspi3); | |
38 | 74 } |
75 | |
89 | 76 uint8_t SPI3_ButtonAdjust(uint8_t *arrayInput, uint8_t *arrayOutput) { |
38 | 77 HAL_StatusTypeDef status; |
78 uint8_t answer[10]; | |
79 uint8_t rework[10]; | |
80 | |
81 rework[0] = 0xFF; | |
89 | 82 for (int i = 0; i < 3; i++) { |
38 | 83 // limiter |
89 | 84 if (arrayInput[i] == 0xFF) |
38 | 85 arrayInput[i] = 0xFE; |
89 | 86 if (arrayInput[i] >= 15) { |
82 | 87 // copy - ausl�se-schwelle |
89 | 88 rework[i + 1] = arrayInput[i]; |
38 | 89 // wieder-scharf-schalte-schwelle |
89 | 90 rework[i + 3 + 1] = arrayInput[i] - 10; |
91 } else if (arrayInput[i] >= 10) { | |
82 | 92 // copy - ausl�se-schwelle |
89 | 93 rework[i + 1] = arrayInput[i]; |
38 | 94 // wieder-scharf-schalte-schwelle |
89 | 95 rework[i + 3 + 1] = arrayInput[i] - 5; |
96 } else { | |
82 | 97 // copy - ausl�se-schwelle |
89 | 98 rework[i + 1] = 7; |
38 | 99 // wieder-scharf-schalte-schwelle |
89 | 100 rework[i + 3 + 1] = 6; |
38 | 101 } |
102 } | |
103 | |
104 status = HAL_OK; /* = 0 */ | |
89 | 105 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET); |
106 for (int i = 0; i < 7; i++) { | |
107 HAL_Delay(10); | |
108 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET); | |
63 | 109 HAL_Delay(10); |
89 | 110 status += HAL_SPI_TransmitReceive(&hspi3, &rework[i], &answer[i], 1, |
111 20); | |
63 | 112 HAL_Delay(10); |
89 | 113 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET); |
38 | 114 } |
89 | 115 |
116 if (status == HAL_OK) { | |
117 for (int i = 0; i < 3; i++) { | |
118 arrayOutput[i] = answer[i + 2]; // first not, return of 0xFF not | |
119 } | |
38 | 120 return 1; |
89 | 121 } else |
122 | |
38 | 123 return 0; |
124 } | |
125 | |
126 // SPI5 init function | |
89 | 127 void MX_SPI1_Init(void) { |
128 hspi1.Instance = SPI1; | |
129 hspi1.Init.Mode = SPI_MODE_SLAVE; | |
130 hspi1.Init.Direction = SPI_DIRECTION_2LINES; | |
131 hspi1.Init.DataSize = SPI_DATASIZE_8BIT; | |
132 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; | |
133 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; | |
134 hspi1.Init.NSS = SPI_NSS_HARD_INPUT; //SPI_NSS_SOFT; | |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
143
diff
changeset
|
135 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; |
89 | 136 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; |
137 hspi1.Init.TIMode = SPI_TIMODE_DISABLED; | |
138 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED; //_DISABLED; _ENABLED; | |
139 hspi1.Init.CRCPolynomial = 7; | |
140 HAL_SPI_Init(&hspi1); | |
38 | 141 } |
142 | |
89 | 143 void MX_SPI_DeInit(void) { |
144 HAL_SPI_DeInit(&hspi1); | |
38 | 145 } |
146 | |
89 | 147 void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { |
38 | 148 |
89 | 149 GPIO_InitTypeDef GPIO_InitStruct; |
38 | 150 |
89 | 151 if (hspi->Instance == SPI1) { |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
143
diff
changeset
|
152 SPIDataRX = 0; |
89 | 153 // Peripheral clock enable |
154 __SPI1_CLK_ENABLE(); | |
155 __GPIOA_CLK_ENABLE(); | |
38 | 156 //SPI1 GPIO Configuration |
157 //PA4 ------> SPI1_CS | |
158 //PA5 ------> SPI1_SCK | |
159 //PA6 ------> SPI1_MISO | |
160 //PA7 ------> SPI1_MOSI | |
89 | 161 |
162 GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; | |
38 | 163 // GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; |
89 | 164 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; |
165 GPIO_InitStruct.Pull = GPIO_PULLUP; | |
124
4b355396557a
Change GPIO speed for SPI communication as recommended by STM32 Errata
Ideenmodellierer
parents:
120
diff
changeset
|
166 GPIO_InitStruct.Speed = GPIO_SPEED_FAST; /* Decision is based on errata which recommends FAST for GPIO at 90Mhz */ |
89 | 167 GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; |
168 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); | |
38 | 169 |
170 //##-3- Configure the DMA streams ########################################## | |
171 // Configure the DMA handler for Transmission process | |
89 | 172 hdma_tx.Instance = DMA2_Stream3; |
173 hdma_tx.Init.Channel = DMA_CHANNEL_3; | |
174 hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; | |
175 hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; | |
176 hdma_tx.Init.MemInc = DMA_MINC_ENABLE; | |
38 | 177 hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; |
89 | 178 hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; |
179 hdma_tx.Init.Mode = DMA_NORMAL; | |
180 hdma_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH; | |
181 hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; | |
182 hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; | |
183 hdma_tx.Init.MemBurst = DMA_MBURST_INC4; | |
184 hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4; | |
185 | |
186 HAL_DMA_Init(&hdma_tx); | |
187 | |
38 | 188 // Associate the initialized DMA handle to the the SPI handle |
189 __HAL_LINKDMA(hspi, hdmatx, hdma_tx); | |
89 | 190 |
38 | 191 // Configure the DMA handler for Transmission process |
89 | 192 hdma_rx.Instance = DMA2_Stream0; |
193 hdma_rx.Init.Channel = DMA_CHANNEL_3; | |
194 hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; | |
195 hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; | |
196 hdma_rx.Init.MemInc = DMA_MINC_ENABLE; | |
38 | 197 hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; |
89 | 198 hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; |
199 hdma_rx.Init.Mode = DMA_NORMAL; | |
200 hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; | |
201 hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; | |
202 hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; | |
203 hdma_rx.Init.MemBurst = DMA_MBURST_INC4; | |
204 hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4; | |
38 | 205 |
206 HAL_DMA_Init(&hdma_rx); | |
89 | 207 |
208 // Associate the initialized DMA handle to the the SPI handle | |
209 __HAL_LINKDMA(hspi, hdmarx, hdma_rx); | |
38 | 210 |
89 | 211 //##-4- Configure the NVIC for DMA ######################################### |
212 //NVIC configuration for DMA transfer complete interrupt (SPI3_RX) | |
213 HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 0); | |
214 HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); | |
215 | |
216 // NVIC configuration for DMA transfer complete interrupt (SPI1_TX) | |
217 HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 1, 1); | |
218 HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); | |
219 } else if (hspi->Instance == SPI3) { | |
220 __GPIOC_CLK_ENABLE(); | |
221 __SPI3_CLK_ENABLE(); | |
38 | 222 |
223 //SPI1 GPIO Configuration | |
224 //PC10 ------> SPI3_SCK | |
225 //PC11 ------> SPI3_MISO | |
226 //PC12 ------> SPI3_MOSI | |
227 //PA15 ------> SPI3_NSS (official) | |
228 //PC9 ------> SPI3_NSS (hw) | |
89 | 229 |
230 GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; | |
231 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; | |
232 GPIO_InitStruct.Pull = GPIO_PULLUP; | |
233 GPIO_InitStruct.Speed = GPIO_SPEED_FAST; | |
234 GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; | |
235 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); | |
38 | 236 |
237 GPIO_InitStruct.Pin = GPIO_PIN_9; | |
238 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; | |
239 GPIO_InitStruct.Pull = GPIO_PULLUP; | |
240 GPIO_InitStruct.Speed = GPIO_SPEED_LOW; | |
89 | 241 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); |
38 | 242 |
89 | 243 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET); |
38 | 244 } |
245 } | |
246 | |
89 | 247 void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) { |
248 if (hspi->Instance == SPI1) { | |
38 | 249 __SPI1_FORCE_RESET(); |
250 __SPI1_RELEASE_RESET(); | |
251 | |
252 //SPI1 GPIO Configuration | |
253 //PA5 ------> SPI1_SCK | |
254 //PA6 ------> SPI1_MISO | |
255 //PA7 ------> SPI1_MOSI | |
89 | 256 |
257 HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); | |
38 | 258 |
259 HAL_DMA_DeInit(&hdma_tx); | |
260 HAL_DMA_DeInit(&hdma_rx); | |
89 | 261 |
38 | 262 HAL_NVIC_DisableIRQ(DMA2_Stream3_IRQn); |
263 HAL_NVIC_DisableIRQ(DMA2_Stream0_IRQn); | |
89 | 264 } else if (hspi->Instance == SPI3) { |
38 | 265 __SPI3_FORCE_RESET(); |
266 __SPI3_RELEASE_RESET(); | |
267 | |
268 //SPI1 GPIO Configuration | |
269 //PC10 ------> SPI3_SCK | |
270 //PC11 ------> SPI3_MISO | |
271 //PC12 ------> SPI3_MOSI | |
272 //PA15 ------> SPI3_NSS (official) | |
273 //PC9 ------> SPI3_NSS (hw) | |
89 | 274 HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12); |
38 | 275 } |
276 } | |
277 | |
89 | 278 void SPI_synchronize_with_Master(void) { |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
143
diff
changeset
|
279 #ifdef USE_OLD_SYNC_METHOD |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
280 GPIO_InitTypeDef GPIO_InitStruct; |
89 | 281 // |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
282 __GPIOA_CLK_ENABLE(); |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
283 /**SPI1 GPIO Configuration |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
284 PA5 ------> SPI1_SCK |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
285 */ |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
286 GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5; |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
287 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
288 GPIO_InitStruct.Pull = GPIO_PULLUP; |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
143
diff
changeset
|
289 GPIO_InitStruct.Speed = GPIO_SPEED_FAST; |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
290 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); |
89 | 291 // |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
292 HAL_Delay(10); |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
293 while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == 0); |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
294 HAL_Delay(10); |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
295 while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == 1); |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
143
diff
changeset
|
296 HAL_Delay(50); |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
297 #endif |
38 | 298 } |
299 | |
89 | 300 void SPI_Start_single_TxRx_with_Master(void) { |
38 | 301 uint8_t * pOutput; |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
302 HAL_StatusTypeDef retval; |
38 | 303 |
89 | 304 if (global.dataSendToSlave.getDeviceDataNow) { |
38 | 305 global.dataSendToSlave.getDeviceDataNow = 0; |
89 | 306 pOutput = (uint8_t*) &(global.deviceDataSendToMaster); |
307 } else { | |
308 pOutput = (uint8_t*) &(global.dataSendToMaster); | |
38 | 309 } |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
310 retval = HAL_SPI_TransmitReceive_DMA(&hspi1, pOutput,(uint8_t*) &(global.dataSendToSlave), EXCHANGE_BUFFERSIZE); |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
311 if ( retval!= HAL_OK) { |
38 | 312 SPI_Error_Handler(); |
313 } | |
314 } | |
315 | |
89 | 316 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { |
317 /* restart SPI */ | |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
318 if (hspi == &hspi1) |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
319 { |
208 | 320 Scheduler_SyncToSPI(); |
143 | 321 SPIDataRX = 1; |
322 | |
89 | 323 /* stop data exchange? */ |
324 if (global.mode == MODE_SHUTDOWN) { | |
325 global.mode = MODE_SLEEP; | |
326 global.dataSendToSlavePending = 0; | |
327 global.dataSendToSlaveIsValid = 1; | |
328 global.dataSendToSlaveIsNotValidCount = 0; | |
329 } | |
143 | 330 } |
331 } | |
82 | 332 |
143 | 333 void SPI_Evaluate_RX_Data() |
334 { | |
208 | 335 uint8_t resettimeout = 1; |
336 | |
143 | 337 if ((global.mode != MODE_SHUTDOWN) && ( global.mode != MODE_SLEEP) && (SPIDataRX)) |
338 { | |
339 SPIDataRX = 0; | |
89 | 340 /* data consistent? */ |
341 if (SPI_check_header_and_footer_ok()) { | |
208 | 342 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK; |
143 | 343 // GPIO_new_DEBUG_HIGH(); //For debug. |
89 | 344 global.dataSendToSlaveIsValid = 1; |
345 global.dataSendToSlaveIsNotValidCount = 0; | |
208 | 346 /* Master signal a data shift outside of his control => reset own DMA and resync */ |
347 if(global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_SHIFTED) | |
143 | 348 { |
349 HAL_SPI_Abort_IT(&hspi1); | |
208 | 350 Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_HARD); |
143 | 351 } |
352 else | |
353 { | |
354 } | |
208 | 355 } |
356 else | |
357 { | |
143 | 358 // GPIO_new_DEBUG_LOW(); //For debug. |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
359 global.dataSendToSlaveIsValid = 0; |
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
360 global.dataSendToSlaveIsNotValidCount++; |
143 | 361 if(DataEX_check_header_and_footer_shifted()) |
362 { | |
208 | 363 |
364 /* Reset own DMA */ | |
365 if ((global.dataSendToSlaveIsNotValidCount % 10) == 1) //% 10 | |
143 | 366 { |
367 HAL_SPI_Abort_IT(&hspi1); /* reset DMA only once */ | |
368 } | |
208 | 369 /* Signal problem to master */ |
370 if ((global.dataSendToSlaveIsNotValidCount ) >= 2) | |
371 { | |
372 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_SHIFTED; | |
373 } | |
143 | 374 } |
208 | 375 else /* handle received data as if no data would have been received */ |
376 { | |
377 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OFFLINE; | |
378 resettimeout = 0; | |
379 } | |
380 } | |
143 | 381 |
89 | 382 global.dataSendToMaster.power_on_reset = 0; |
383 global.deviceDataSendToMaster.power_on_reset = 0; | |
384 | |
143 | 385 scheduleSpecial_Evaluate_DataSendToSlave(); |
136
6ae8ba5683d6
Introduces abort of communication in case of a out of sync DMA transfer
Ideenmodellierer
parents:
124
diff
changeset
|
386 |
208 | 387 SPI_Start_single_TxRx_with_Master(); |
388 } | |
389 | |
390 if(resettimeout) | |
391 { | |
392 global.check_sync_not_running = 0; | |
143 | 393 } |
38 | 394 } |
395 | |
89 | 396 static uint8_t SPI_check_header_and_footer_ok(void) { |
397 if (global.dataSendToSlave.header.checkCode[0] != 0xBB) | |
38 | 398 return 0; |
148
ee744c7160ce
Use SPI TX callback to synchronize to main CPU
Ideenmodellierer
parents:
143
diff
changeset
|
399 #ifdef USE_OLD_HEADER_FORMAT |
89 | 400 if (global.dataSendToSlave.header.checkCode[1] != 0x01) |
38 | 401 return 0; |
89 | 402 if (global.dataSendToSlave.header.checkCode[2] != 0x01) |
38 | 403 return 0; |
143 | 404 #endif |
89 | 405 if (global.dataSendToSlave.header.checkCode[3] != 0xBB) |
38 | 406 return 0; |
89 | 407 if (global.dataSendToSlave.footer.checkCode[0] != 0xF4) |
38 | 408 return 0; |
89 | 409 if (global.dataSendToSlave.footer.checkCode[1] != 0xF3) |
38 | 410 return 0; |
89 | 411 if (global.dataSendToSlave.footer.checkCode[2] != 0xF2) |
38 | 412 return 0; |
89 | 413 if (global.dataSendToSlave.footer.checkCode[3] != 0xF1) |
38 | 414 return 0; |
415 | |
416 return 1; | |
417 } | |
418 | |
143 | 419 |
420 /* Check if there is an empty frame providec by RTE (all 0) or even no data provided by RTE (all 0xFF) | |
421 * If that is not the case the DMA is somehow not in sync | |
422 */ | |
423 uint8_t DataEX_check_header_and_footer_shifted() | |
424 { | |
425 uint8_t ret = 1; | |
426 if((global.dataSendToSlave.footer.checkCode[0] == 0x00) | |
427 && (global.dataSendToSlave.footer.checkCode[1] == 0x00) | |
428 && (global.dataSendToSlave.footer.checkCode[2] == 0x00) | |
429 && (global.dataSendToSlave.footer.checkCode[3] == 0x00)) { ret = 0; } | |
430 | |
431 if((global.dataSendToSlave.footer.checkCode[0] == 0xff) | |
432 && (global.dataSendToSlave.footer.checkCode[1] == 0xff) | |
433 && (global.dataSendToSlave.footer.checkCode[2] == 0xff) | |
434 && (global.dataSendToSlave.footer.checkCode[3] == 0xff)) { ret = 0; } | |
435 | |
436 return ret; | |
437 } | |
438 | |
89 | 439 static void SPI_Error_Handler(void) { |
82 | 440 //The device is locks. Hard to recover. |
441 // while(1) | |
442 // { | |
443 // } | |
38 | 444 } |
445 | |
446 /** | |
89 | 447 * @} |
448 */ | |
38 | 449 |
450 /** | |
89 | 451 * @} |
452 */ | |
38 | 453 |
454 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |