changeset 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 b95741467355
children 2de856965c55
files Common/Inc/global_constants.h Discovery/Src/data_exchange_main.c Discovery/Src/tHome.c Small_CPU/Src/spi.c
diffstat 4 files changed, 118 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/Common/Inc/global_constants.h	Sun Mar 24 22:53:17 2019 +0100
+++ b/Common/Inc/global_constants.h	Sun Mar 24 22:57:28 2019 +0100
@@ -40,10 +40,14 @@
 #define SPI_SHOW_SYNC_STATS 0
 #define SPI_MIN_ERROR_SHOW 10
 
-// SPI header by index used for synchronization check (package sequence counter)
-#define SPI_HEADER_INDEX_MASTER 1
-#define SPI_HEADER_INDEX_SLAVE 2
+/* Define INDEX for information exchanged within the header */
+#define SPI_HEADER_INDEX_RX_STATE  (1)
+#define SPI_HEADER_INDEX_FRAME_CNT (2)
 
+#define SPI_RX_STATE_OK 		(0)
+#define SPI_RX_STATE_SHIFTED	(1)
+#define SPI_RX_STATE_OFFLINE	(2)
+#define SPI_RX_STATE_INVALID	(3)
 
 //Text data
 #define TEXT_PRESSURE_UNIT "hPa"
--- a/Discovery/Src/data_exchange_main.c	Sun Mar 24 22:53:17 2019 +0100
+++ b/Discovery/Src/data_exchange_main.c	Sun Mar 24 22:57:28 2019 +0100
@@ -145,8 +145,8 @@
 	memset((void *)&dataOut, 0, sizeof(SDataReceiveFromMaster));
 
 	dataOut.header.checkCode[0] = 0xBB;
-	dataOut.header.checkCode[1] = 0x01;
-	dataOut.header.checkCode[2] = 0x01;
+	dataOut.header.checkCode[1] = SPI_RX_STATE_OK;
+	dataOut.header.checkCode[2] = SPI_RX_STATE_OK;
 	dataOut.header.checkCode[3] = 0xBB;
 
 	dataOut.footer.checkCode[0] = 0xF4;
@@ -258,42 +258,76 @@
 
 uint8_t DataEX_call(void)
 {
+	static uint32_t RTEOfflineCnt = 0;
+	static uint8_t SusppressCom = 0;
+
 	uint8_t SPI_DMA_answer = 0;
 
-	HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
-
-	if(data_old__lost_connection_to_slave_counter_temp >= 3)
+	if(SusppressCom)
 	{
-		data_old__lost_connection_to_slave_counter_temp = 0;
-		if((DataEX_check_header_and_footer_shifted()) && (data_old__lost_connection_to_slave_counter_retry == 0))
-		{
-			HAL_SPI_Abort_IT(&cpu2DmaSpi);
-		}
-		/* reset of own DMA does not work ==> request reset of slave dma */
-		if((DataEX_check_header_and_footer_shifted()) && (data_old__lost_connection_to_slave_counter_retry == 2))
-		{
-			dataOut.header.checkCode[SPI_HEADER_INDEX_SLAVE] = 0xA5;
-		}
-		data_old__lost_connection_to_slave_counter_retry++;
+		SusppressCom--;
 	}
-#if USE_OLD_SYNC_METHOD
-	/* one cycle with NotChipSelect true to clear slave spi buffer */
 	else
 	{
-		HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
-	}
-#endif
+		if(data_old__lost_connection_to_slave_counter_temp >= 2) /* error reaction is triggered whenever communication could not be reestablishen within two cycles */
+		{
+			data_old__lost_connection_to_slave_counter_temp = 0;
+			if(DataEX_check_header_and_footer_shifted())
+			{
+				if(RTEOfflineCnt > 1)		/* RTE restarted communication after a longer silent time => restart error handling to recover */
+				{
+					data_old__lost_connection_to_slave_counter_retry = 0;
+					RTEOfflineCnt = 0;
+				}
 
-	DataEx_call_helper_requests();
+				/* We received shifted data. Step one. Reset DMA to see if the problem is located at main */
+				if (data_old__lost_connection_to_slave_counter_retry == 0)
+				{
+					HAL_SPI_Abort_IT(&cpu2DmaSpi);
+				}
+				/* reset of own DMA does not work ==> request reset of slave dma by indicating shifted receiption */
+				if (data_old__lost_connection_to_slave_counter_retry == 1)
+				{
+					dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_SHIFTED;
+				}
+
+				/* stop communication with RTE to trigger RTE timeout reaction */
+				if (data_old__lost_connection_to_slave_counter_retry == 2)
+				{
+					SusppressCom = 3;
+				}
 
-//HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_RESET); /* only for testing with Oscilloscope */
-
+				data_old__lost_connection_to_slave_counter_retry++;
+			}
+			else
+			{
+				RTEOfflineCnt++;	/* based on footer status the RTE does not seem to provide data in time */
+				dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OFFLINE;
+			}
+		}
+	#if USE_OLD_SYNC_METHOD
+		/* one cycle with NotChipSelect true to clear slave spi buffer */
+		else
+		{
+			HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
+		}
+	#endif
 
-	SPI_DMA_answer = HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)&dataOut, (uint8_t *)&dataIn, EXCHANGE_BUFFERSIZE);
-	if(SPI_DMA_answer != HAL_OK)
-	{
-		DataEX_Error_Handler(SPI_DMA_answer);
-	}		
+		DataEx_call_helper_requests();
+
+	//HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_RESET); /* only for testing with Oscilloscope */
+
+		if(SusppressCom == 0)
+		{
+			HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
+
+			SPI_DMA_answer = HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)&dataOut, (uint8_t *)&dataIn, EXCHANGE_BUFFERSIZE);
+			if(SPI_DMA_answer != HAL_OK)
+			{
+				DataEX_Error_Handler(SPI_DMA_answer);
+			}
+		}
+	}
 //	HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_SET);
 //HAL_Delay(3);
 //HAL_GPIO_WritePin(OSCILLOSCOPE2_GPIO_PORT,OSCILLOSCOPE2_PIN,GPIO_PIN_SET); /* only for testing with Oscilloscope */
@@ -311,7 +345,6 @@
 	return &dataIn;
 }
 
-
 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
 {
 	if(hspi == &cpu2DmaSpi)
@@ -671,6 +704,7 @@
 			data_old__lost_connection_to_slave_counter_retry = 0;
 			data_old__lost_connection_to_slave_counter_temp = 0;
 			stateRealGetPointerWrite()->data_old__lost_connection_to_slave = 0;
+			dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
 		}
 		else
 		{
@@ -757,6 +791,7 @@
 			data_old__lost_connection_to_slave_counter_temp = 0;
 			data_old__lost_connection_to_slave_counter_retry = 0;
 			pStateReal->data_old__lost_connection_to_slave = 0;
+			dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
 		}
 		else
 		{
@@ -771,12 +806,9 @@
 		data_old__lost_connection_to_slave_counter_temp = 0;
 		data_old__lost_connection_to_slave_counter_retry = 0;
 		pStateReal->data_old__lost_connection_to_slave = 0;
+		dataOut.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
 	}
 	
-	/* update SPI communication tokens */
-	dataOut.header.checkCode[SPI_HEADER_INDEX_SLAVE] = dataIn.header.checkCode[SPI_HEADER_INDEX_SLAVE];
-	dataOut.header.checkCode[SPI_HEADER_INDEX_MASTER] = (dataOut.header.checkCode[SPI_HEADER_INDEX_MASTER] + 1) & 0x7F;
-
 	if(getDeviceDataAfterStartOfMainCPU)
 	{
 		getDeviceDataAfterStartOfMainCPU--;
--- a/Discovery/Src/tHome.c	Sun Mar 24 22:53:17 2019 +0100
+++ b/Discovery/Src/tHome.c	Sun Mar 24 22:57:28 2019 +0100
@@ -425,12 +425,15 @@
 
 uint8_t tHome_show_lost_connection_count(GFX_DrawCfgScreen *ScreenToWriteOn)
 {
+	static uint8_t LastKnowRTEState = SPI_RX_STATE_INVALID;
+
 	if(!SPI_MIN_ERROR_SHOW) return 0;
 	if(DataEX_lost_connection_count()>=SPI_MIN_ERROR_SHOW && SPI_SHOW_SYNC_STATS){
 
     char text[64];
 
     SDataExchangeSlaveToMaster* dataIn=get_dataInPointer();
+    SDataReceiveFromMaster* pDataOut = dataOutGetPointer();
 
     snprintf(text,32,"spi err:\002 %i/%i",DataEX_lost_connection_count(),get_num_SPI_CALLBACKS());
     Gfx_write_label_var(ScreenToWriteOn,  100,300, 0,&FontT24,CLUT_ButtonSymbols,text);
@@ -438,7 +441,18 @@
 //    snprintf(text,32,"header:\002%X%X%X%X",dataIn->header.checkCode[0],dataIn->header.checkCode[1],dataIn->header.checkCode[2],dataIn->header.checkCode[3]);
 //    Gfx_write_label_var(ScreenToWriteOn,  350,550, 0,&FontT24,CLUT_ButtonSymbols,text);
 
-    snprintf(text,32,"footer:\002%X%X%X%X",dataIn->footer.checkCode[0],dataIn->footer.checkCode[1],dataIn->footer.checkCode[2],dataIn->footer.checkCode[3]);
+    //snprintf(text,32,"footer:\002%X%X%X%X",dataIn->footer.checkCode[0],dataIn->footer.checkCode[1],dataIn->footer.checkCode[2],dataIn->footer.checkCode[3]);
+
+    /* data shifted => ignore received data */
+    if((pDataOut->header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_SHIFTED) || (pDataOut->header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_OFFLINE))
+    {
+    	dataIn->header.checkCode[SPI_HEADER_INDEX_RX_STATE] = LastKnowRTEState;
+    }
+    else
+    {
+    	LastKnowRTEState =dataIn->header.checkCode[SPI_HEADER_INDEX_RX_STATE];
+    }
+    snprintf(text,32,"RX State M|R:\002%X|%X",pDataOut->header.checkCode[SPI_HEADER_INDEX_RX_STATE], dataIn->header.checkCode[SPI_HEADER_INDEX_RX_STATE] );
     Gfx_write_label_var(ScreenToWriteOn,  600,800, 0,&FontT24,CLUT_ButtonSymbols,text);
     }
 
--- a/Small_CPU/Src/spi.c	Sun Mar 24 22:53:17 2019 +0100
+++ b/Small_CPU/Src/spi.c	Sun Mar 24 22:57:28 2019 +0100
@@ -35,15 +35,10 @@
 extern void GPIO_new_DEBUG_HIGH(void);
 #endif
 
-// SPI header by index used for synchronization check (package sequence counter)
-#define SPI_HEADER_INDEX_MASTER 1
-#define SPI_HEADER_INDEX_SLAVE 2
-
 uint8_t data_error = 0;
 uint32_t data_error_time = 0;
 uint8_t SPIDataRX = 0; /* Flag to signal that SPI RX callback has been triggered */
 
-extern void HardSyncToSPI(void);
 static void SPI_Error_Handler(void);
 
 /* USER CODE END 0 */
@@ -322,10 +317,9 @@
 	/* restart SPI */
 	if (hspi == &hspi1)
 	{
-		HardSyncToSPI();
+		Scheduler_SyncToSPI();
 		SPIDataRX = 1;
 
-		global.check_sync_not_running = 0;
 		/* stop data exchange? */
 		if (global.mode == MODE_SHUTDOWN) {
 			global.mode = MODE_SLEEP;
@@ -338,37 +332,52 @@
 
 void SPI_Evaluate_RX_Data()
 {
+	uint8_t resettimeout = 1;
+
 	if ((global.mode != MODE_SHUTDOWN) && ( global.mode != MODE_SLEEP) && (SPIDataRX))
 	{
 		SPIDataRX = 0;
 		/* data consistent? */
 		if (SPI_check_header_and_footer_ok()) {
+			global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OK;
 	//		GPIO_new_DEBUG_HIGH(); //For debug.
 			global.dataSendToSlaveIsValid = 1;
 			global.dataSendToSlaveIsNotValidCount = 0;
-			/* use sequence index from master to indicate correct reception */
-			if(global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_SLAVE] > 0x7F)
+			/* Master signal a data shift outside of his control => reset own DMA and resync */
+			if(global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_RX_STATE] == SPI_RX_STATE_SHIFTED)
 			{
 				HAL_SPI_Abort_IT(&hspi1);
-				global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_SLAVE] = global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_MASTER];
-				global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_SLAVE] = 0;
+				Scheduler_Request_sync_with_SPI(SPI_SYNC_METHOD_HARD);
 			}
 			 else
 			 {
-				 global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_SLAVE] = global.dataSendToSlave.header.checkCode[SPI_HEADER_INDEX_MASTER];
 			 }
-		} else {
+		}
+		else
+		{
 	//		GPIO_new_DEBUG_LOW(); //For debug.
 				global.dataSendToSlaveIsValid = 0;
 				global.dataSendToSlaveIsNotValidCount++;
 				if(DataEX_check_header_and_footer_shifted())
 				{
-					if (global.dataSendToSlaveIsNotValidCount == 1) 
+
+					/* Reset own DMA */
+					if ((global.dataSendToSlaveIsNotValidCount % 10) == 1)  //% 10
 					{	
 						HAL_SPI_Abort_IT(&hspi1); /* reset DMA only once */
 					}
+					/* Signal problem to master */
+					if ((global.dataSendToSlaveIsNotValidCount ) >= 2)
+					{
+						global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_SHIFTED;
+					}
 				}
-			}
+				else /* handle received data as if no data would have been received */
+				{
+					global.dataSendToMaster.header.checkCode[SPI_HEADER_INDEX_RX_STATE] = SPI_RX_STATE_OFFLINE;
+					resettimeout = 0;
+				}
+		}
 
 		global.dataSendToMaster.power_on_reset = 0;
 		global.deviceDataSendToMaster.power_on_reset = 0;
@@ -379,7 +388,12 @@
 	//		}
 		scheduleSpecial_Evaluate_DataSendToSlave();
 
-		SPI_Start_single_TxRx_with_Master(); //Send data always.
+		SPI_Start_single_TxRx_with_Master();
+	}
+
+	if(resettimeout)
+	{
+			global.check_sync_not_running = 0;
 	}
 }