diff Small_CPU/Src/i2c.c @ 332:39f146ccdb1b

Merged in Ideenmodellierer/ostc4/I2C_Improvment (pull request #30) I2C Improvment
author heinrichsweikamp <bitbucket@heinrichsweikamp.com>
date Thu, 18 Jul 2019 14:26:56 +0000
parents 4fe5400567e7
children
line wrap: on
line diff
--- a/Small_CPU/Src/i2c.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/i2c.c	Thu Jul 18 14:26:56 2019 +0000
@@ -31,39 +31,51 @@
 void HAL_I2C_Send_One_CLOCK(void)
 {
 	HAL_GPIO_WritePin(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN, GPIO_PIN_RESET);
-	HAL_Delay(10);
+	HAL_Delay(1); 
 	HAL_GPIO_WritePin(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN, GPIO_PIN_SET);
-	HAL_Delay(10);
+	HAL_Delay(1);
 }
 
 GPIO_PinState MX_I2C1_TestAndClear(void)
 {
+	GPIO_PinState retval;
+	uint8_t repeatcnt = 3;
+
 	I2C_DeInit();
 	HAL_I2C_ManualControl_MspInit();
-	for(int i=0; i<9;i++)
+	
+/* The SDA line is expected to be HIGH if no com is pending => send dummy clock signals if that is not the case */
+	do
 	{
-		if(HAL_I2C_Read_Data_PIN() == GPIO_PIN_RESET)
-			HAL_I2C_Send_One_CLOCK();
-		else
-			break;
-	}
-	return HAL_I2C_Read_Data_PIN();
+		for(int i=0; i<20;i++)
+		{
+			if(HAL_I2C_Read_Data_PIN() == GPIO_PIN_RESET)
+				HAL_I2C_Send_One_CLOCK();
+			else
+				break;
+		}
+		retval = HAL_I2C_Read_Data_PIN();
+	}while ((repeatcnt-- > 0) && (retval != GPIO_PIN_SET));
+
+	return retval;
 }
 
 HAL_StatusTypeDef MX_I2C1_Init(void)
 {
-	I2cHandle.Instance             = I2Cx;
+  I2cHandle.Instance             = I2Cx;
   I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
-  I2cHandle.Init.ClockSpeed      = 100000;//400000; REDUCED for compatibility with  HMC5583L + MMA8452Q
-  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
-  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
+  I2cHandle.Init.ClockSpeed      = 88000; /* Reduced to avoid behavior described in errata: Mismatch on the “Setup time for a repeated Start condition” */
+  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;				/* don't care if not in fast mode */
   I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
   I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;
-  I2cHandle.Init.OwnAddress1     = 0x01;
+  I2cHandle.Init.OwnAddress1     = 0x01;						/* don't care because of master mode */
+
+/* According to documentation setting filters before I2C initialization is recommended */
+	/* HAL_I2CEx_AnalogFilter_Config(&I2cHandle, I2C_ANALOGFILTER_ENABLED); */
+	HAL_I2CEx_ConfigDigitalFilter(&I2cHandle,0x0F);
 
 	global.I2C_SystemStatus = HAL_I2C_Init(&I2cHandle);
-	HAL_I2CEx_AnalogFilter_Config(&I2cHandle, I2C_ANALOGFILTER_ENABLED);
-	HAL_I2CEx_ConfigDigitalFilter(&I2cHandle,0x0F);
 
 	if(global.dataSendToSlavePending)
 	{
@@ -85,12 +97,13 @@
 	i2c_errors++;
 }
 
+
 HAL_StatusTypeDef I2C_Master_Transmit(  uint16_t DevAddress, uint8_t *pData, uint16_t Size)
 {
 	if(global.I2C_SystemStatus != HAL_OK)
 		return global.I2C_SystemStatus;
 
-	global.I2C_SystemStatus = HAL_I2C_Master_Transmit(&I2cHandle, DevAddress,  pData, Size, 2);
+	global.I2C_SystemStatus = HAL_I2C_Master_Transmit(&I2cHandle, DevAddress,  pData, Size, 10);
 	if(global.I2C_SystemStatus != HAL_OK)
 	{
 		I2C_Error_count();