Browse Source

update:扩展I2C读写功能

alienwalker 3 years ago
parent
commit
19a96dad98

+ 9 - 2
application/src/luat_i2c_air105.c

@@ -50,14 +50,21 @@ int luat_i2c_close(int id) {
 }
 
 int luat_i2c_send(int id, int addr, void* buff, size_t len, uint8_t stop) {
-	if (!stop) I2C_SetTxStopFlag(id);
 	return I2C_BlockWrite(id, addr, (const uint8_t *)buff, len, 100, NULL, NULL);
     // I2C_Prepare(id, addr, 1, NULL, NULL);
     // I2C_MasterXfer(id, I2C_OP_WRITE, 0, buff, len, 20);
 }
 
 int luat_i2c_recv(int id, int addr, void* buff, size_t len) {
-	return I2C_BlockRead(id, addr, 0, (uint8_t *)buff, len, 100, NULL, NULL);
+	return I2C_BlockRead(id, addr, 0, 0, (uint8_t *)buff, len, 100, NULL, NULL);
     // I2C_Prepare(id, addr, 1, NULL, NULL);
     // I2C_MasterXfer(id, I2C_OP_READ, 0, buff, len, 20);
 }
+
+int luat_i2c_xfer(int id, int addr, uint8_t *reg, size_t reg_len, uint8_t *buff, size_t len) {
+	if (reg && reg_len) {
+		return I2C_BlockRead(id, addr, reg, reg_len, (uint8_t *)buff, len, 100, NULL, NULL);
+	} else {
+		return I2C_BlockWrite(id, addr, (const uint8_t *)buff, len, 100, NULL, NULL);
+	}
+}

+ 2 - 0
bsp/air105/hal/core_flash.c

@@ -412,6 +412,7 @@ int32_t Flash_Program(uint32_t Address, const uint8_t *pBuf, uint32_t Len)
 	return ERROR_NONE;
 }
 
+#if 0
 int Flash_EraseSector(uint32_t address, uint8_t NeedCheck)
 {
 	uint8_t buf[__FLASH_PAGE_SIZE__];
@@ -472,3 +473,4 @@ int Flash_ProgramData(uint32_t address, uint32_t *Data, uint32_t Len, uint8_t Ne
 	}
 	return 0;
 }
+#endif

+ 43 - 140
bsp/air105/hal/core_i2c.c

@@ -43,22 +43,18 @@ typedef struct
 	const I2C_TypeDef *RegBase;
 	const int IrqLine;
 	Buffer_Struct DataBuf;
+	Buffer_Struct RegBuf;
 	Timer_t *ToTimer;
 	CBFuncEx_t Callback;
 	void *pParam;
 	HANDLE Sem;
-	I2C_CommonRegDataStruct *RegQueue;
-	uint32_t TotalQueueNum;
-	uint32_t CurQueuePos;
 	int32_t Result;
 	uint16_t TimeoutMs;
 	uint16_t ChipAddress;
 	uint8_t ChipAddressLen;
-	uint8_t RegAddress;
 	uint8_t State;
 	uint8_t IsBusy;
 	uint8_t IsBlockMode;
-	uint8_t no_stop_end;
 }I2C_CtrlStruct;
 static I2C_CtrlStruct prvI2C = {
 		I2C0,
@@ -71,7 +67,6 @@ static void prvI2C_Done(uint8_t I2CID, int32_t Result)
 	prvI2C.State = I2C_STATE_FREE;
 	prvI2C.Result = Result;
 	prvI2C.IsBusy = 0;
-	prvI2C.no_stop_end = 0;
 #ifdef __BUILD_OS__
 	if (prvI2C.IsBlockMode) OS_MutexRelease(prvI2C.Sem);
 #endif
@@ -128,14 +123,8 @@ static void I2C_IrqHandle(int32_t IrqLine, void *pData)
 			}
 			else
 			{
-				if (!prvI2C.no_stop_end)
-				{
-					I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[prvI2C.DataBuf.Pos]|I2C_IC_DATA_CMD_STOP;
-				}
-				else
-				{
-					I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[prvI2C.DataBuf.Pos];
-				}
+
+				I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[prvI2C.DataBuf.Pos]|I2C_IC_DATA_CMD_STOP;
 			}
 			prvI2C.DataBuf.Pos++;
 		}
@@ -144,16 +133,33 @@ static void I2C_IrqHandle(int32_t IrqLine, void *pData)
 		if (State & I2C_IT_TXE)
 		{
 			Timer_StartMS(prvI2C.ToTimer, prvI2C.TimeoutMs, 0);
-			prvI2C.State = I2C_STATE_READ_ADDRESS_RD;
-			if ((prvI2C.DataBuf.MaxLen - prvI2C.DataBuf.Pos) > 1)
+			if (prvI2C.RegBuf.Pos >= prvI2C.RegBuf.MaxLen)
 			{
-				I2C->IC_DATA_CMD = I2C_IC_DATA_CMD_CMD;
+				prvI2C.State = I2C_STATE_READ_ADDRESS_RD;
+				if ((prvI2C.DataBuf.MaxLen - prvI2C.DataBuf.Pos) > 1)
+				{
+					I2C->IC_DATA_CMD = I2C_IC_DATA_CMD_CMD;
+				}
+				else
+				{
+					I2C->IC_DATA_CMD = I2C_IC_DATA_CMD_CMD|I2C_IC_DATA_CMD_STOP;
+				}
+				I2C->IC_INTR_MASK = I2C_IC_INTR_MASK_M_RX_FULL|I2C_IC_INTR_MASK_M_STOP_DET|I2C_IC_INTR_MASK_M_TX_ABRT;
 			}
 			else
 			{
-				I2C->IC_DATA_CMD = I2C_IC_DATA_CMD_CMD|I2C_IC_DATA_CMD_STOP;
+				if ((prvI2C.RegBuf.MaxLen - prvI2C.RegBuf.Pos) > 1)
+				{
+					I2C->IC_DATA_CMD = prvI2C.RegBuf.Data[prvI2C.RegBuf.Pos];
+
+				}
+				else
+				{
+
+					I2C->IC_DATA_CMD = prvI2C.RegBuf.Data[prvI2C.RegBuf.Pos]|I2C_IC_DATA_CMD_RESTART;
+				}
+				prvI2C.RegBuf.Pos++;
 			}
-			I2C->IC_INTR_MASK = I2C_IC_INTR_MASK_M_RX_FULL|I2C_IC_INTR_MASK_M_STOP_DET|I2C_IC_INTR_MASK_M_TX_ABRT;
 		}
 		break;
 	case I2C_STATE_READ_ADDRESS_RD:
@@ -189,57 +195,6 @@ I2C_DONE:
 	prvI2C_Done(0, result);
 }
 
-static void I2C_IrqHandleRegQueue(int32_t IrqLine, void *pData)
-{
-	int32_t result = ERROR_NONE;
-	I2C_TypeDef *I2C = prvI2C.RegBase;
-	uint32_t Source = I2C->IC_TX_ABRT_SOURCE;
-	uint32_t State = I2C->IC_RAW_INTR_STAT;
-	uint32_t RegValue = I2C->IC_CLR_INTR;
-
-	if (Source & 0x0000ffff)
-	{
-//		DBG("error stop state %d, result 0x%x", prvI2C.State, Source);
-		result = -ERROR_OPERATION_FAILED;
-		goto I2C_DONE;
-	}
-
-	if (State & I2C_IT_TXE)
-	{
-		Timer_StartMS(prvI2C.ToTimer, prvI2C.TimeoutMs, 0);
-		if (prvI2C.DataBuf.Pos >= prvI2C.DataBuf.MaxLen)
-		{
-			prvI2C.CurQueuePos++;
-			if (prvI2C.CurQueuePos >= prvI2C.TotalQueueNum)
-			{
-				goto I2C_DONE;
-			}
-			else
-			{
-				Buffer_StaticInit(&prvI2C.DataBuf, prvI2C.RegQueue[prvI2C.CurQueuePos].Data, 2);
-				I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[0];
-				prvI2C.DataBuf.Pos++;
-				I2C->IC_INTR_MASK = I2C_IC_INTR_MASK_M_TX_EMPTY|I2C_IC_INTR_MASK_M_STOP_DET;
-			}
-
-		}
-		else if ((prvI2C.DataBuf.MaxLen - prvI2C.DataBuf.Pos) > 1)
-		{
-			I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[prvI2C.DataBuf.Pos];
-		}
-		else
-		{
-			I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[prvI2C.DataBuf.Pos]|I2C_IC_DATA_CMD_STOP;
-		}
-		prvI2C.DataBuf.Pos++;
-	}
-	return;
-I2C_DONE:
-	Timer_Stop(prvI2C.ToTimer);
-	I2C->IC_INTR_MASK = 0;
-	prvI2C_Done(0, result);
-}
-
 void I2C_GlobalInit(void)
 {
 	prvI2C.ToTimer = Timer_Create(prvI2C_TimerUpCB, NULL, NULL);
@@ -310,7 +265,7 @@ void I2C_Prepare(uint8_t I2CID, uint16_t ChipAddress, uint8_t ChipAddressLen, CB
 	prvI2C.pParam = pParam;
 }
 
-void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t RegAddress, uint8_t *Data, uint32_t Len, uint16_t Toms)
+void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t *RegAddress, uint32_t RegLen, uint8_t *Data, uint32_t Len, uint16_t Toms)
 {
 	I2C_TypeDef *I2C = prvI2C.RegBase;
 	uint32_t RegValue;
@@ -337,15 +292,22 @@ void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t RegAddress, uint8_t
 		prvI2C.TimeoutMs = 50;
 	}
 	Buffer_StaticInit(&prvI2C.DataBuf, Data, Len);
-	prvI2C.RegQueue = NULL;
+	Buffer_StaticInit(&prvI2C.RegBuf, RegAddress, RegLen);
 	RegValue = I2C->IC_CLR_INTR;
 	Timer_StartMS(prvI2C.ToTimer, prvI2C.TimeoutMs, 0);
 	switch(Operate)
 	{
 	case I2C_OP_READ_REG:
-
 		prvI2C.State = I2C_STATE_READ_ADDRESS_WR;
-		I2C->IC_DATA_CMD = I2C_IC_DATA_CMD_RESTART|RegAddress;
+		if (RegLen > 1)
+		{
+			I2C->IC_DATA_CMD = prvI2C.RegBuf.Data[0];
+		}
+		else
+		{
+			I2C->IC_DATA_CMD = I2C_IC_DATA_CMD_RESTART|prvI2C.RegBuf.Data[0];
+		}
+		prvI2C.RegBuf.Pos = 1;
 		I2C->IC_INTR_MASK = I2C_IC_INTR_MASK_M_TX_EMPTY|I2C_IC_INTR_MASK_M_STOP_DET|I2C_IC_INTR_MASK_M_TX_ABRT;
 		break;
 	case I2C_OP_READ:
@@ -368,14 +330,8 @@ void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t RegAddress, uint8_t
 		}
 		else
 		{
-			if (!prvI2C.no_stop_end)
-			{
-				I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[0]|I2C_IC_DATA_CMD_STOP;
-			}
-			else
-			{
-				I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[0];
-			}
+
+			I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[0]|I2C_IC_DATA_CMD_STOP;
 		}
 		prvI2C.DataBuf.Pos++;
 		I2C->IC_INTR_MASK = I2C_IC_INTR_MASK_M_TX_EMPTY|I2C_IC_INTR_MASK_M_STOP_DET|I2C_IC_INTR_MASK_M_TX_ABRT;
@@ -391,53 +347,6 @@ void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t RegAddress, uint8_t
 	ISR_OnOff(prvI2C.IrqLine, 1);
 }
 
-int32_t I2C_MasterWriteRegQueue(uint8_t I2CID, I2C_CommonRegDataStruct *RegQueue, uint32_t TotalNum, uint16_t Toms, uint8_t IsBlock)
-{
-	I2C_TypeDef *I2C = prvI2C.RegBase;
-	uint32_t RegValue;
-	int32_t Result;
-	I2C->IC_INTR_MASK = 0;
-	ISR_OnOff(prvI2C.IrqLine, 0);
-	if (prvI2C.IsBusy)
-	{
-		Timer_Stop(prvI2C.ToTimer);
-		I2C->IC_ENABLE |= I2C_IC_ENABLE_ABORT;
-		prvI2C.IsBusy = 0;
-		prvI2C.Result = -ERROR_OPERATION_FAILED;
-		prvI2C.Callback(I2C_ID0, prvI2C.pParam);
-		while(I2C->IC_ENABLE & I2C_IC_ENABLE_ABORT){;}
-	}
-    ISR_SetHandler(prvI2C.IrqLine, I2C_IrqHandleRegQueue, NULL);
-	prvI2C.IsBusy = 1;
-	if (Toms)
-	{
-		prvI2C.TimeoutMs = Toms;
-	}
-	else
-	{
-		prvI2C.TimeoutMs = 50;
-	}
-	prvI2C.RegQueue = RegQueue;
-	prvI2C.TotalQueueNum = TotalNum;
-	prvI2C.CurQueuePos = 0;
-	RegValue = I2C->IC_CLR_INTR;
-	Timer_StartMS(prvI2C.ToTimer, prvI2C.TimeoutMs, 0);
-	Buffer_StaticInit(&prvI2C.DataBuf, prvI2C.RegQueue[prvI2C.CurQueuePos].Data, 2);
-	I2C->IC_DATA_CMD = prvI2C.DataBuf.Data[0];
-	prvI2C.DataBuf.Pos++;
-	I2C->IC_INTR_MASK = I2C_IC_INTR_MASK_M_TX_EMPTY|I2C_IC_INTR_MASK_M_STOP_DET;
-	ISR_OnOff(prvI2C.IrqLine, 1);
-	if (IsBlock)
-	{
-		while(!I2C_WaitResult(I2CID, &Result)) {;}
-		return Result;
-	}
-	else
-	{
-		return 0;
-	}
-}
-
 
 int I2C_WaitResult(uint8_t I2CID, int32_t *Result)
 {
@@ -452,7 +361,7 @@ int32_t I2C_BlockWrite(uint8_t I2CID, uint8_t ChipAddress, const uint8_t *Data,
 	while(!I2C_WaitResult(I2CID, &Result)) {;}
 	prvI2C.IsBlockMode = !OS_CheckInIrq();
 	I2C_Prepare(I2CID, ChipAddress, 1, CB, pParam);
-	I2C_MasterXfer(I2CID, I2C_OP_WRITE, 0, Data, Len, Toms);
+	I2C_MasterXfer(I2CID, I2C_OP_WRITE, NULL, 0, Data, Len, Toms);
 #ifdef __BUILD_OS__
 	if (!OS_CheckInIrq())
 	{
@@ -463,19 +372,19 @@ int32_t I2C_BlockWrite(uint8_t I2CID, uint8_t ChipAddress, const uint8_t *Data,
 	return Result;
 }
 
-int32_t I2C_BlockRead(uint8_t I2CID, uint8_t ChipAddress, uint8_t *Reg, uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam)
+int32_t I2C_BlockRead(uint8_t I2CID, uint8_t ChipAddress, uint8_t *Reg, uint32_t RegLen, uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam)
 {
 	int32_t Result;
 	while(!I2C_WaitResult(I2CID, &Result)) {;}
 	prvI2C.IsBlockMode = !OS_CheckInIrq();
 	I2C_Prepare(I2CID, ChipAddress, 1, CB, pParam);
-	if (Reg)
+	if (Reg && RegLen)
 	{
-		I2C_MasterXfer(I2CID, I2C_OP_READ_REG, *Reg, Data, Len, Toms);
+		I2C_MasterXfer(I2CID, I2C_OP_READ_REG, Reg, RegLen, Data, Len, Toms);
 	}
 	else
 	{
-		I2C_MasterXfer(I2CID, I2C_OP_READ, 0, Data, Len, Toms);
+		I2C_MasterXfer(I2CID, I2C_OP_READ, NULL, 0, Data, Len, Toms);
 	}
 #ifdef __BUILD_OS__
 	if (!OS_CheckInIrq())
@@ -487,12 +396,6 @@ int32_t I2C_BlockRead(uint8_t I2CID, uint8_t ChipAddress, uint8_t *Reg, uint8_t
 	return Result;
 }
 
-void I2C_SetTxStopFlag(uint8_t I2CID)
-{
-	int32_t Result;
-	while(!I2C_WaitResult(I2CID, &Result)) {;}
-	prvI2C.no_stop_end = 1;
-}
 #ifdef __BUILD_APP__
 INIT_HW_EXPORT(I2C_GlobalInit, "1");
 #endif

+ 4 - 3
bsp/air105/include/core_i2c.h

@@ -53,12 +53,13 @@ void I2C_Prepare(uint8_t I2CID, uint16_t ChipAddress, uint8_t ChipAddressLen, CB
  *  I2C_OP_READ_REG = 0,	//i2c通用读寄存器,一写一读,自动带start信号
 	I2C_OP_READ,		//i2c通用读,只读
 	I2C_OP_WRITE,		//i2c通用写,只写
- * @param RegAddress 寄存器地址,在通用读写时忽略
+ * @param RegAddress 寄存器地址的数据缓存,在通用读写时忽略
+ * @param RegLen 寄存器地址长度,在通用读写时忽略
  * @param Data 读写数据缓存,直接使用用户的空间,在完成前不可以释放空间
  * @param Len 读写数据长度
  * @param Toms 传输单个字节超时时间,单位ms
  */
-void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t RegAddress, uint8_t *Data, uint32_t Len, uint16_t Toms);
+void I2C_MasterXfer(uint8_t I2CID, uint8_t Operate, uint8_t *RegAddress, uint32_t RegLen, uint8_t *Data, uint32_t Len, uint16_t Toms);
 
 /**
  * @brief i2c主机传输,多个单一寄存器写入
@@ -83,5 +84,5 @@ int I2C_WaitResult(uint8_t I2CID, int32_t *Result);
 
 int32_t I2C_BlockWrite(uint8_t I2CID, uint8_t ChipAddress, const uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam);
 
-int32_t I2C_BlockRead(uint8_t I2CID, uint8_t ChipAddress, uint8_t *Reg, uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam);
+int32_t I2C_BlockRead(uint8_t I2CID, uint8_t ChipAddress, uint8_t *Reg, uint32_t RegLen, uint8_t *Data, uint32_t Len, uint16_t Toms, CBFuncEx_t CB, void *pParam);
 #endif

+ 3 - 3
bsp/air105/test/test_camera.c

@@ -737,7 +737,7 @@ void GC032A_TestInit(void)
 	Data[1] = 0x10;
 
 	I2C_BlockWrite(I2C_ID0, GC032A_I2C_ADDRESS, Data, 2, 10, NULL, 0);
-	I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, Data, 2, 10, NULL, 0);
+	I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, 1, Data, 2, 10, NULL, 0);
 	if ((0x23 == Data[0]) && (0x2a == Data[1]))
 	{
 		DBG("识别到GC032A控制芯片");
@@ -751,7 +751,7 @@ void GC032A_TestInit(void)
 	Data[1] = 0x00;
 	Reg = 0x44;
 	I2C_BlockWrite(I2C_ID0, GC032A_I2C_ADDRESS, Data, 2, 10, NULL, 0);
-	I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, Data, 2, 10, NULL, 0);
+	I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, 1, Data, 2, 10, NULL, 0);
 	DBG("%x,%x", Data[0], Data[1]);
 	for(i = 0; i < sizeof(GC032A_InitRegQueue)/sizeof(I2C_CommonRegDataStruct); i++)
 	{
@@ -806,7 +806,7 @@ void OV2640_TestInit(void)
 	Data[1] = 0x01;
 
 	I2C_BlockWrite(I2C_ID0, OV2640_I2C_ADDRESS, Data, 2, 10, NULL, 0);
-	I2C_BlockRead(I2C_ID0, OV2640_I2C_ADDRESS, &Reg, Data, 2, 10, NULL, 0);
+	I2C_BlockRead(I2C_ID0, OV2640_I2C_ADDRESS, &Reg, 1, Data, 2, 10, NULL, 0);
 	if ((0x7F == Data[0]) && (0xA2 == Data[1]))
 	{
 		DBG("识别到OV2640控制芯片");

+ 1 - 1
bsp/air105/test/test_sht30.c

@@ -85,7 +85,7 @@ void SHT30_GetResult(CBFuncEx_t CB, void *pParam)
 	float vTemp = 0.00;
 
 	Reg[0] = 0;
-	if (!I2C_BlockRead(I2CID, SHT30_ADDR, Reg, Data, 6, 100, CB, pParam))
+	if (!I2C_BlockRead(I2CID, SHT30_ADDR, Reg, 1, Data, 6, 100, CB, pParam))
 	{
 		T = BytesGetBe16(Data);
 		H = BytesGetBe16(Data + 3);

+ 1 - 1
bsp/air105/test/test_zbar.c

@@ -547,7 +547,7 @@ void DecodeQR_TestInit(void)
 	Data[1] = 0x10;
 
 	I2C_BlockWrite(I2C_ID0, GC032A_I2C_ADDRESS, Data, 2, 10, NULL, 0);
-	I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, Data, 2, 10, NULL, 0);
+	I2C_BlockRead(I2C_ID0, GC032A_I2C_ADDRESS, &Reg, 1, Data, 2, 10, NULL, 0);
 	if ((0x23 == Data[0]) && (0x2a == Data[1]))
 	{
 		DBG("识别到GC032A控制芯片");