Mercurial > public > ostc4
comparison Small_CPU/Src/spi.c @ 208:9fc06e1e0f66 ImprovmentSPI
Update SPI error display and handling
For easier identification of a communication problem the RX state of Main and RTE is displayed in the debug view.
Also error reactions are now handles based on this state. E.g. RTE resets its DMA incase Main reports a data shift which can not be resolved by Main itself
In addition the timeout for error detection has been decreased to have a faster reaction
author | ideenmodellierer |
---|---|
date | Sun, 24 Mar 2019 22:57:28 +0100 |
parents | ee744c7160ce |
children | e4207f0aaa4b |
comparison
equal
deleted
inserted
replaced
207:b95741467355 | 208:9fc06e1e0f66 |
---|---|
33 #ifdef DEBUG_GPIO | 33 #ifdef DEBUG_GPIO |
34 extern void GPIO_new_DEBUG_LOW(void); | 34 extern void GPIO_new_DEBUG_LOW(void); |
35 extern void GPIO_new_DEBUG_HIGH(void); | 35 extern void GPIO_new_DEBUG_HIGH(void); |
36 #endif | 36 #endif |
37 | 37 |
38 // SPI header by index used for synchronization check (package sequence counter) | |
39 #define SPI_HEADER_INDEX_MASTER 1 | |
40 #define SPI_HEADER_INDEX_SLAVE 2 | |
41 | |
42 uint8_t data_error = 0; | 38 uint8_t data_error = 0; |
43 uint32_t data_error_time = 0; | 39 uint32_t data_error_time = 0; |
44 uint8_t SPIDataRX = 0; /* Flag to signal that SPI RX callback has been triggered */ | 40 uint8_t SPIDataRX = 0; /* Flag to signal that SPI RX callback has been triggered */ |
45 | 41 |
46 extern void HardSyncToSPI(void); | |
47 static void SPI_Error_Handler(void); | 42 static void SPI_Error_Handler(void); |
48 | 43 |
49 /* USER CODE END 0 */ | 44 /* USER CODE END 0 */ |
50 | 45 |
51 static uint8_t SPI_check_header_and_footer_ok(void); | 46 static uint8_t SPI_check_header_and_footer_ok(void); |
320 | 315 |
321 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { | 316 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) { |
322 /* restart SPI */ | 317 /* restart SPI */ |
323 if (hspi == &hspi1) | 318 if (hspi == &hspi1) |
324 { | 319 { |
325 HardSyncToSPI(); | 320 Scheduler_SyncToSPI(); |
326 SPIDataRX = 1; | 321 SPIDataRX = 1; |
327 | 322 |
328 global.check_sync_not_running = 0; | |
329 /* stop data exchange? */ | 323 /* stop data exchange? */ |
330 if (global.mode == MODE_SHUTDOWN) { | 324 if (global.mode == MODE_SHUTDOWN) { |
331 global.mode = MODE_SLEEP; | 325 global.mode = MODE_SLEEP; |
332 global.dataSendToSlavePending = 0; | 326 global.dataSendToSlavePending = 0; |
333 global.dataSendToSlaveIsValid = 1; | 327 global.dataSendToSlaveIsValid = 1; |
336 } | 330 } |
337 } | 331 } |
338 | 332 |
339 void SPI_Evaluate_RX_Data() | 333 void SPI_Evaluate_RX_Data() |
340 { | 334 { |
335 uint8_t resettimeout = 1; | |
336 | |
341 if ((global.mode != MODE_SHUTDOWN) && ( global.mode != MODE_SLEEP) && (SPIDataRX)) | 337 if ((global.mode != MODE_SHUTDOWN) && ( global.mode != MODE_SLEEP) && (SPIDataRX)) |
342 { | 338 { |
343 SPIDataRX = 0; | 339 SPIDataRX = 0; |
344 /* data consistent? */ | 340 /* data consistent? */ |
345 if (SPI_check_header_and_footer_ok()) { | 341 if (SPI_check_header_and_footer_ok()) { |
342 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK; | |
346 // GPIO_new_DEBUG_HIGH(); //For debug. | 343 // GPIO_new_DEBUG_HIGH(); //For debug. |
347 global.dataSendToSlaveIsValid = 1; | 344 global.dataSendToSlaveIsValid = 1; |
348 global.dataSendToSlaveIsNotValidCount = 0; | 345 global.dataSendToSlaveIsNotValidCount = 0; |
349 /* use sequence index from master to indicate correct reception */ | 346 /* Master signal a data shift outside of his control => reset own DMA and resync */ |
350 if(global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_SLAVE] > 0x7F) | 347 if(global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_SHIFTED) |
351 { | 348 { |
352 HAL_SPI_Abort_IT(&hspi1); | 349 HAL_SPI_Abort_IT(&hspi1); |
353 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_SLAVE] = global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_MASTER]; | 350 Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_HARD); |
354 global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_SLAVE] = 0; | |
355 } | 351 } |
356 else | 352 else |
357 { | 353 { |
358 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_SLAVE] = global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_MASTER]; | |
359 } | 354 } |
360 } else { | 355 } |
356 else | |
357 { | |
361 // GPIO_new_DEBUG_LOW(); //For debug. | 358 // GPIO_new_DEBUG_LOW(); //For debug. |
362 global.dataSendToSlaveIsValid = 0; | 359 global.dataSendToSlaveIsValid = 0; |
363 global.dataSendToSlaveIsNotValidCount++; | 360 global.dataSendToSlaveIsNotValidCount++; |
364 if(DataEX_check_header_and_footer_shifted()) | 361 if(DataEX_check_header_and_footer_shifted()) |
365 { | 362 { |
366 if (global.dataSendToSlaveIsNotValidCount == 1) | 363 |
364 /* Reset own DMA */ | |
365 if ((global.dataSendToSlaveIsNotValidCount % 10) == 1) //% 10 | |
367 { | 366 { |
368 HAL_SPI_Abort_IT(&hspi1); /* reset DMA only once */ | 367 HAL_SPI_Abort_IT(&hspi1); /* reset DMA only once */ |
369 } | 368 } |
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 } | |
370 } | 374 } |
371 } | 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 } | |
372 | 381 |
373 global.dataSendToMaster.power_on_reset = 0; | 382 global.dataSendToMaster.power_on_reset = 0; |
374 global.deviceDataSendToMaster.power_on_reset = 0; | 383 global.deviceDataSendToMaster.power_on_reset = 0; |
375 | 384 |
376 //TODO:REMOVE | 385 //TODO:REMOVE |
377 // if ( !global.dataSendToSlaveStopEval ) { | 386 // if ( !global.dataSendToSlaveStopEval ) { |
378 // scheduleSpecial_Evaluate_DataSendToSlave(); | 387 // scheduleSpecial_Evaluate_DataSendToSlave(); |
379 // } | 388 // } |
380 scheduleSpecial_Evaluate_DataSendToSlave(); | 389 scheduleSpecial_Evaluate_DataSendToSlave(); |
381 | 390 |
382 SPI_Start_single_TxRx_with_Master(); //Send data always. | 391 SPI_Start_single_TxRx_with_Master(); |
392 } | |
393 | |
394 if(resettimeout) | |
395 { | |
396 global.check_sync_not_running = 0; | |
383 } | 397 } |
384 } | 398 } |
385 | 399 |
386 static uint8_t SPI_check_header_and_footer_ok(void) { | 400 static uint8_t SPI_check_header_and_footer_ok(void) { |
387 if (global.dataSendToSlave.header.checkCode[0] != 0xBB) | 401 if (global.dataSendToSlave.header.checkCode[0] != 0xBB) |