/** * @brief This function send device address and register address to I2C slave. * @param DeviceAddr: I2C slave address * @param RegAddr: slave device's register address, usually before read/write slave device's register, * i2c master should first send it. * @return * @arg TRUE: success * @arg FALSE:fail */ bool I2cSendAddr(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t RwFlag) { I2cStart(I2cMasterHandle); if(!I2cWriteByte(I2cMasterHandle, SlaveAddr)) { /* Retry */ I2cStart(I2cMasterHandle); if(!I2cWriteByte(I2cMasterHandle, SlaveAddr)) { I2cStop(I2cMasterHandle); return FALSE; } } if(!I2cWriteByte(I2cMasterHandle, RegAddr)) { I2cStop(I2cMasterHandle); return FALSE; } if(RwFlag == IIC_READ) { I2cStart(I2cMasterHandle); if(!I2cWriteByte(I2cMasterHandle, SlaveAddr | IIC_READ)) { I2cStop(I2cMasterHandle); return FALSE; } } return TRUE; }
/** * @brief This function read multiple bytes to I2C slave with address * @param Buf: Buffer pointer to the data to be send * @param Len: Data Length to be send in byte uint * @return * @arg TRUE: success * @arg FALSE: fail */ bool I2cReadNByte(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t* Buf, uint8_t Len) { if(I2cSendAddr(I2cMasterHandle, SlaveAddr, RegAddr, IIC_READ)) { I2cReadBytes(I2cMasterHandle, Buf, Len); I2cStop(I2cMasterHandle); return TRUE; } I2cStop(I2cMasterHandle); return FALSE; }
/** * @brief This function send multiple bytes to I2C slave with address * @param Buf: Buffer pointer to the data to be send * @param Len: Data Length to be send in byte uint * @return * @arg TRUE: success * @arg FALSE:fail */ bool I2cWriteNByte(void* I2cMasterHandle, uint8_t SlaveAddr, uint8_t RegAddr, uint8_t* Buf, uint8_t Len) { if(I2cSendAddr(I2cMasterHandle, SlaveAddr, RegAddr, IIC_WRITE)) { if(I2cWriteBytes(I2cMasterHandle, Buf, Len)) { I2cStop(I2cMasterHandle); return TRUE; } } I2cStop(I2cMasterHandle); return FALSE; }
/*--------------------------------------------------------------------------------------------------*/ unsigned char GLAM_EEPROMReadBytes(unsigned char reg_start, unsigned char bytes, unsigned char *buffer){ unsigned char data, i; signed char error=0; if( reg_start+bytes >128 ) return (2); cli(); error += I2cStartWait(); /* send I2C start with deley */ error += I2cWriteWait(GLAM_EEPROM_ADDRESS); /* send 24AA01 address byte */ error += I2cWriteWait(reg_start); /* write first address byte for miltiple read */ error += I2cStartWait(); /* send I2C start with deley */ error += I2cWriteWait(GLAM_EEPROM_ADDRESS|0x01);/* send 24AA01 address byte and ¸read bit */ for(i=0 ; i<bytes ; i++){ /* read number of bytes */ error += I2cRead(&data); /* read one byte */ *(buffer+i) = data; /* store one byte */ if((i+1) == bytes){ error += I2cSendNak(); /* send NAK to 24AA01 to finish read */ I2cStop(); /* send stop to 24AA01 */ break; /* break for */ } else error += I2cSendAck(); /* send ACK to 24AA01 slave to read next byte */ } sei(); if(error) /* error occurred? */ return (1); /* return error (1) -> communication failed */ return (0); /* return successfully */ }
uint32_t I2cEngine(uint8_t module) { i2c_bus[module].master_state = I2C_IDLE; i2c_bus[module].read_index = 0; i2c_bus[module].write_index = 0; if(I2cStart(module) != TRUE) { I2cStop(module); return (FALSE); } while(i2c_bus[module].master_state != DATA_NACK) { continue; } I2cStop(module); return (TRUE); }
/*检测I2C设备是否忙*/ BYTE I2cDeviceBusy(BYTE bySlave) { BYTE byBusy = 1; int i = 0; while((byBusy != 0) && (i < 100)) { i2cStart(); I2cWriteByte(bySlave); byBusy=I2cReadBit(); if(byBusy) I2cStop(); i++; } #ifdef I2C_DEBUG if(byBusy == 1) printf("\nThe device is busy\n"); else printf("\nThe device is free\n"); #endif /* I2C_DEBUG */ return byBusy; }
/*--------------------------------------------------------------------------------------------------*/ unsigned char GLAM_EEPROMWriteBytes(unsigned char reg_start, unsigned char bytes, unsigned char *buffer){ unsigned char i; signed char error=0; if( reg_start+bytes >120) return (2); /* it is not allowed modify configuration data */ cli(); error += I2cStart(); /* send I2C start with deley */ error += I2cWrite(GLAM_EEPROM_ADDRESS); /* send 24AA01 address byte and write bit */ error += I2cWrite(reg_start); /* write first address byte for miltiple read */ for(i=0 ; i<bytes ; i++){ /* read number of bytes */ error += I2cWrite(*(buffer+i)); /* read one byte */ if((i+1) == bytes){ I2cStop(); /* send stop to 24AA01 */ break; /* break for */ } } sei(); if(error) /* error occurred? */ return (1); /* return error (1) -> communication failed */ return (0); /* return successfully */ }
/*============================================================================*/ GERR I2cReadWrite(BOOL mode, BYTE ChipAddress, BYTE *Data, DWORD NbData) { #if 0 BYTE i=0, ack; I2cStart(); /* Start the I2C sequence */ I2cByteWrite( (BYTE)(ChipAddress+(mode==READ)) ); /* Send Slave chip address */ ack = I2cAckGet(); /* Read Acknowledge bit */ while((i < NbData) && ack) { if(mode==READ) { Data[i] = I2cByteRead(); /* Read data from the slave*/ I2cAckSet(i==(NbData-1)); /* Write Acknowledge bit */ } else { I2cByteWrite(Data[i]); /* Write data to the salve */ ack=I2cAckGet(); /* Read Acknowledge bit */ } i++; } I2cStop(); /* Stop the I2C sequence */ if(!ack) { if (mode==READ) for (i=0; i<NbData; i++) Data[i]=0xFF; return -1; } else return 0; #else GERR ferr; char readData[4]; char data[2]; #ifdef PN2020WT_2 if (mode == READ) { ferr = GD_I2C_Read(&pData->handleI2C, ChipAddress, readReg, 1, Data, NbData); if (ferr != GD_OK) { return GD_ERR_FE_I2C; } } else { ferr = GD_I2C_Write(&pData->handleI2C, ChipAddress, Data, NbData); if (ferr != GD_OK) { return GD_ERR_FE_I2C; } readReg[0] = Data[0]; } return GD_OK; #else if (mode == READ) { ferr = GD_I2C_Read(&pgData->handleI2C, ChipAddress, readReg, 1, Data, NbData); if (ferr != GD_OK) { return GD_ERR_FE_I2C; } } else { ferr = GD_I2C_Write(&pgData->handleI2C, ChipAddress, Data, NbData); if (ferr != GD_OK) { return GD_ERR_FE_I2C; } readReg[0] = Data[0]; } return GD_OK; #endif #endif }
SDWORD I2cReadTest(BYTE byIicPort, BYTE bySlave, DWORD dwAddr) { BYTE byData = 0; volatile BYTE i2c_bw_ctrl; /* I2C write control */ volatile BYTE i2c_br_ctrl; /* I2C read control */ volatile BYTE i2c_addr_00; /* I2C address (0) */ STATUS semStatus; /*i2c同步信号量*/ semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/ if(ERROR == semStatus) { logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0); return; } if(0 == byIicPort) { sCurI2cPort.byClkPin = IICCLK0; sCurI2cPort.byDataPin = IICDATA0; } else if(1 == byIicPort) { sCurI2cPort.byClkPin = IICCLK1; sCurI2cPort.byDataPin = IICDATA1; } #ifdef I2C_DEBUG printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr); #endif /* I2C_DEBUG */ i2c_ack_stat=0x0; i2c_bw_ctrl = bySlave | I2C_WRITE; i2c_br_ctrl = bySlave | I2C_READ; /*i2c_addr_01 = I2C_W1_ADDR(addr);*/ i2c_addr_00 = I2C_W0_ADDR(dwAddr); if(1) { i2cStart(); I2cWriteByte(i2c_bw_ctrl); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x1; I2C_DELAY(CLOCK_LOW_TIME*3); /*I2cWriteByte(i2c_addr_01);*/ /*ack1=I2cReadBit();*/ /*read ack from slave*/ /*if(ack1!=0) i2c_ack_stat |= 0x2; */ I2cWriteByte(i2c_addr_00); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x2; i2cStart(); I2C_DELAY(CLOCK_LOW_TIME*3); I2cWriteByte(i2c_br_ctrl); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x3; I2C_DELAY(CLOCK_LOW_TIME*3); byData = I2cReadByte(); I2cStop(); } #ifdef I2C_DEBUG if(i2c_ack_stat!=0) printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat); #endif printf("byData: %x \n", byData); semGive(semI2cLock); /*释放信号量*/ if(0 != i2c_ack_stat) { return SYS_ERROR; } return SYS_OK; }
SDWORD TestCpld(void) { BYTE byData[5] = {0}; BYTE bySlave = 0xca; BYTE i2c_br_ctrl = 0; /* I2C read control */ BYTE byIicPort = 0; STATUS semStatus; /*i2c同步信号量*/ if (0==I2Cisinit) { dev_I2cInit( ); } semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/ if(ERROR == semStatus) { logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0); return; } if(0 == byIicPort) { sCurI2cPort.byClkPin = IICCLK0; sCurI2cPort.byDataPin = IICDATA0; } else if(1 == byIicPort) { sCurI2cPort.byClkPin = IICCLK1; sCurI2cPort.byDataPin = IICDATA1; } #ifdef I2C_DEBUG /* printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);*/ #endif /* I2C_DEBUG */ i2c_ack_stat=0x0; i2c_br_ctrl = bySlave | I2C_READ; if(1)/*0 == I2cDeviceBusy(bySlave))*/ { i2cStart(); I2cWriteByte(i2c_br_ctrl); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x3; I2C_DELAY(CLOCK_LOW_TIME*3); byData[0] = I2cReadByte(); I2cWriteBit(0x0); /*send ack*/ I2cData(HIGH); byData[1] = I2cReadByte(); I2cWriteBit(0x0); /*send ack*/ I2cData(HIGH); byData[2] = I2cReadByte(); I2cWriteBit(0x00); /*send ack*/ I2cData(HIGH); byData[3] = I2cReadByte(); I2cWriteBit(0x00); /*send ack*/ I2cData(HIGH); byData[4] = I2cReadByte(); I2cWriteBit(0x80); /*send ack*/ I2cData(HIGH); I2cStop(); } #ifdef I2C_DEBUG if(i2c_ack_stat!=0) printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat); #endif printf("\Data[0] = 0x%2x, Data[1] = 0x%2x, Data[2] = 0x%2d, Data[3] = 0x%2d, Data[4] = 0x%2d\n", byData[0], byData[1], byData[2], byData[3], byData[4]); semGive(semI2cLock); /*释放信号量*/ if(0 != i2c_ack_stat) { return SYS_ERROR; } return SYS_OK; }
SDWORD I2cReadCpld(BYTE *pbyData, BYTE byDataNum) { BYTE bySlave = I2C_CPLDID; BYTE i2c_br_ctrl = 0; /* I2C read control */ BYTE byIicPort = I2C_CPLDPORT; static BYTE *pCpldData = (BYTE *)0x20000020; STATUS semStatus; /*i2c同步信号量*/ if (0==I2Cisinit) { dev_I2cInit( ); } semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/ if(ERROR == semStatus) { logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0); return; } if(0 == byIicPort) { sCurI2cPort.byClkPin = IICCLK0; sCurI2cPort.byDataPin = IICDATA0; } else if(1 == byIicPort) { sCurI2cPort.byClkPin = IICCLK1; sCurI2cPort.byDataPin = IICDATA1; } #ifdef I2C_DEBUG /* printf("\n i2cRead() slave address is 0x%08x, addr: 0x%08x", bySlave, dwAddr);*/ #endif /* I2C_DEBUG */ i2c_ack_stat=0x0; i2c_br_ctrl = bySlave | I2C_READ; if(1) { i2cStart(); I2cWriteByte(i2c_br_ctrl); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x3; I2C_DELAY(CLOCK_LOW_TIME*3); pbyData[0] = I2cReadByte(); I2cWriteBit(0x0); /*send ack*/ I2cData(HIGH); pbyData[1] = I2cReadByte(); I2cWriteBit(0x0); /*send ack*/ I2cData(HIGH); pbyData[2] = I2cReadByte(); I2cWriteBit(0x80); /*send ack*/ I2cData(HIGH); I2cStop(); } #ifdef I2C_DEBUG if(i2c_ack_stat!=0) printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat); #endif /* printf("\nbyData[0] =%d, byData[1] =%d,byData[2] =%d\n",pbyData[0], pbyData[1], pbyData[2]);*/ if (0x20000030 > pCpldData) { *pCpldData++ = pbyData[0]; *pCpldData++ = pbyData[1]; *pCpldData++ = pbyData[2]; } semGive(semI2cLock); /*释放信号量*/ if(0 != i2c_ack_stat) { return SYS_ERROR; } return SYS_OK; }
/*return: SYS_OK SYS_ERR */ SDWORD I2cWritePage(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE *pbyData, DWORD dwCount) { int i; volatile BYTE i2c_bw_ctrl; /* I2C write control */ volatile BYTE i2c_addr_00; /* I2C address (0) */ STATUS semStatus; /*i2c同步信号量*/ semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/ if(ERROR == semStatus) { logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0); return; } if(0 == byIicPort) { sCurI2cPort.byClkPin = IICCLK0; sCurI2cPort.byDataPin = IICDATA0; } else if(1 == byIicPort) { sCurI2cPort.byClkPin = IICCLK1; sCurI2cPort.byDataPin = IICDATA1; } i2c_ack_stat=0x0; i2c_bw_ctrl = bySlave | I2C_WRITE; /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/ i2c_addr_00 = I2C_W0_ADDR(dwAddr); for(i=0;i<dwCount;i++) if(dwCount>16) dwCount=16; if(0 == I2cDeviceBusy(bySlave)) { i2cStart(); I2cWriteByte(i2c_bw_ctrl); ack1=I2cReadBit(); if(ack1!=0) i2c_ack_stat |= 0x2; /*I2cWriteByte(i2c_addr_01); ack1=I2cReadBit(); if(ack1!=0) i2c_ack_stat |= 0x2;*/ I2cWriteByte(i2c_addr_00); ack1=I2cReadBit(); if(ack1!=0) i2c_ack_stat |= 0x2; for(i=0;i<dwCount;i++) { I2cWriteByte(pbyData[i]); ack2=I2cReadBit(); if(ack2!=0) i2c_ack_stat |= 0x8; } I2cStop(); } semGive(semI2cLock); /*释放信号量*/ if(0 != i2c_ack_stat) { return SYS_ERROR; } return SYS_OK; }
SDWORD I2cWrite(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE byData) { volatile BYTE i2c_bw_ctrl; /* I2C write control */ volatile BYTE i2c_addr_00; /* I2C address (0) */ STATUS semStatus; /*i2c同步信号量*/ semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/ if(ERROR == semStatus) { logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0); return; } if(0 == byIicPort) { sCurI2cPort.byClkPin = IICCLK0; sCurI2cPort.byDataPin = IICDATA0; } else if(1 == byIicPort) { sCurI2cPort.byClkPin = IICCLK1; sCurI2cPort.byDataPin = IICDATA1; } i2c_ack_stat=0x0; i2c_bw_ctrl = bySlave | I2C_WRITE; /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/ i2c_addr_00 = I2C_W0_ADDR(dwAddr); if(1)/*0 == I2cDeviceBusy(bySlave))*/ { i2cStart(); I2cWriteByte(i2c_bw_ctrl); ack1=I2cReadBit(); if(ack1!=0) i2c_ack_stat |= 0x2; I2C_DELAY(CLOCK_LOW_TIME*3); /*I2cWriteByte(i2c_addr_01); ack1=I2cReadBit(); if(ack1!=0) i2c_ack_stat |= 0x2;*/ I2cWriteByte(i2c_addr_00); ack1=I2cReadBit(); if(ack1!=0) i2c_ack_stat |= 0x2; I2C_DELAY(CLOCK_LOW_TIME*3); I2cWriteByte(byData); ack2=I2cReadBit(); if(ack2!=0) i2c_ack_stat |= 0x8; I2C_DELAY(CLOCK_LOW_TIME*3); I2cStop(); } semGive(semI2cLock); /*释放信号量*/ if(0 != i2c_ack_stat) { printf("\nError in write, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat); return SYS_ERROR; } return SYS_OK; }
/*I2C读字符串 功能暂时不提供 //input : byIicPort I2C端口号为 0 ~ 1 // bySlave 设备号 // dwAddr 命令地址 // dwCount 命令长度 //output: pbyData 命令值 return: SYS_OK SYS_ERR */ SDWORD I2cReadSeq(BYTE byIicPort, BYTE bySlave, DWORD dwAddr, BYTE *pbyData, DWORD dwCount) { volatile BYTE i2c_bw_ctrl; /* I2C write control */ volatile BYTE i2c_br_ctrl; /* I2C read control */ volatile BYTE i2c_addr_00; /* I2C address (0) */ int i; STATUS semStatus; /*i2c同步信号量*/ if (0 == dwCount) { return SYS_ERROR; } semStatus = semTake(semI2cLock, WAIT_FOREVER); /*获得信号量*/ if(ERROR == semStatus) { logMsg("i2c semTake ERROR\n", 0, 0, 0, 0, 0, 0); return; } if(0 == byIicPort) { sCurI2cPort.byClkPin = IICCLK0; sCurI2cPort.byDataPin = IICDATA0; } else if(1 == byIicPort) { sCurI2cPort.byClkPin = IICCLK1; sCurI2cPort.byDataPin = IICDATA1; } #ifdef I2C_DEBUG printf("\n i2cReadSeq() slave address is 0x%x", bySlave); #endif /* I2C_DEBUG */ i2c_ack_stat=0x0; i2c_bw_ctrl = bySlave | I2C_WRITE; i2c_br_ctrl = bySlave | I2C_READ; /*i2c_addr_01 = I2C_W1_ADDR(dwAddr);*/ i2c_addr_00 = I2C_W0_ADDR(dwAddr); if(1) { i2cStart(); I2cWriteByte(i2c_bw_ctrl); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x1; I2cWriteByte(i2c_addr_00); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x2; i2cStart(); I2cWriteByte(i2c_br_ctrl); ack1=I2cReadBit(); /*read ack from slave*/ if(ack1!=0) i2c_ack_stat |= 0x3; for(i=0;i<dwCount;i++) { pbyData[i] = I2cReadByte(); if(i != (dwCount-1)) I2cWriteBit(0x0); /*send ack*/ else I2cWriteBit(0x80); /*send nack after reading the last byte*/ I2cData(HIGH); } I2cStop(); } if(i2c_ack_stat!=0) printf("\nError in read, ack not recd, i2c_ack_stat=0x%x\n",i2c_ack_stat); semGive(semI2cLock); /*释放信号量*/ if(0 != i2c_ack_stat) { return SYS_ERROR; } return SYS_OK; }