/********************************** (C) COPYRIGHT ******************************* * File Name : IIC.c * Author : * Version : V1.0 * Date : 2018/12/12 * Description : I2C 读写 *******************************************************************************/ /********************************************************************* * INCLUDES */ #include "TouchCommon.h" #include "iic.h" #include "driver_gpio.h" /* DATA ADDRESS Length Definition */ #define Address_8bit 0 #define Address_16bit 1 #define Address_32bit 2 #define CHECK_TIMES (25) #define IIC_TIMEOUT 50 #define IIC_SPEED_400 10 void NOP_DELAY(UINT16 num) { while(num--) { asm("nop"); } } void Touch_IIC_Init() { gpio_init_typedef gpio_init_structure; gpio_init_structure.gpio_dir = GPIO_DIR_INPUT; gpio_init_structure.gpio_fen = GPIO_FEN_GPIO; gpio_init_structure.gpio_fdir = GPIO_FDIR_SELF; gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL; gpio_init_structure.gpio_pupd = GPIO_PUPD_PU10K; gpio_init_structure.gpio_drv = GPIO_DRV_6MA; gpio_init_structure.gpio_pin = IIC_SCL; gpio_init(GPIOA_REG, &gpio_init_structure); gpio_init_structure.gpio_pin = IIC_SDA; gpio_init(GPIOA_REG, &gpio_init_structure); gpio_reset_bits(GPIOA_REG, IIC_SCL); gpio_reset_bits(GPIOA_REG, IIC_SDA); } #define SCL_IN() (gpio_read_data(GPIOA_REG)&IIC_SCL) #define SCL_HIGH() gpio_set_input(GPIOA_REG, IIC_SCL) #define SCL_LOW() gpio_set_out(GPIOA_REG, IIC_SCL) #define SDA_IN() (gpio_read_data(GPIOA_REG)&IIC_SDA) #define SDA_HIGH() gpio_set_input(GPIOA_REG, IIC_SDA) #define SDA_LOW() gpio_set_out(GPIOA_REG, IIC_SDA) #define IIC_START() {\ SDA_HIGH();\ SCL_HIGH();\ NOP_DELAY(IIC_SPEED_400);\ SDA_LOW();\ NOP_DELAY(IIC_SPEED_400);\ SCL_LOW();\ } #define IIC_STOP() {\ SDA_LOW();\ SCL_LOW();\ NOP_DELAY(IIC_SPEED_400);\ SCL_HIGH();\ NOP_DELAY(IIC_SPEED_400);\ SDA_HIGH();\ } BOOL I2C_WaitForSclRelease(void) { s8 nTryTimes = IIC_TIMEOUT; while( SCL_IN() == 0 && nTryTimes!=0) { --nTryTimes; NOP_DELAY(IIC_SPEED_400); } if(nTryTimes==0) return 0; return 1; } BOOL IIC_WRITE_DATA(UINT8 dat) { BOOL nak; UINT8 bit_off = 0x80; do { if(bit_off & dat) { SDA_HIGH(); } else { SDA_LOW(); } NOP_DELAY(IIC_SPEED_400); SCL_HIGH(); NOP_DELAY(IIC_SPEED_400); bit_off >>= 1; SCL_LOW(); } while (bit_off); NOP_DELAY(IIC_SPEED_400); SDA_HIGH(); SCL_HIGH(); NOP_DELAY(IIC_SPEED_400); nak = SDA_IN(); SCL_LOW(); return nak==0; } BOOL IIC_READ_DATA(UINT8* dat, BOOL nack) { UINT8 bit_off = 0x80; SDA_HIGH(); SCL_HIGH(); NOP_DELAY(IIC_SPEED_400); if(!I2C_WaitForSclRelease()) { return 0; } while(1) { if(SDA_IN()) { *dat |= bit_off; } else { *dat &= ~bit_off; } SCL_LOW(); NOP_DELAY(IIC_SPEED_400); bit_off >>= 1; if(bit_off) { SCL_HIGH(); NOP_DELAY(IIC_SPEED_400); continue; } break; }; if(nack) { SDA_HIGH(); } else { SDA_LOW(); } SCL_HIGH(); NOP_DELAY(IIC_SPEED_400 + 2); SCL_LOW(); return 1; } BOOL GT_Check_I2C_Address(UINT8 Address) { BOOL nack; IIC_START(); nack = IIC_WRITE_DATA(Address); IIC_STOP(); return nack; } BOOL WriteAddress(UINT32 dwAddr) { if(isBerlinSeries || bIsJDSeries) { IIC_WRITE_DATA((UINT8)(dwAddr>>24) ); IIC_WRITE_DATA((UINT8)(dwAddr>>16) ); } IIC_WRITE_DATA((UINT8)(dwAddr>>8) ); IIC_WRITE_DATA((UINT8)(dwAddr) ); return 1; } u8 IICReadOneByte(UINT32 ReadAddr) { UINT8 temp=0; IIC_START(); IIC_WRITE_DATA(GT_CMD_WR); if(!WriteAddress(ReadAddr)) return 0; NOP_DELAY(4); IIC_START(); IIC_WRITE_DATA(GT_CMD_RD); NOP_DELAY(4); IIC_READ_DATA(&temp, 1); IIC_STOP(); return temp; } BOOL IICReadBytes(UINT32 ReadAddr,UINT8 *pBuffer,UINT16 Length) { BOOL ret = 1; IIC_START(); if(!IIC_WRITE_DATA(GT_CMD_WR)) return 0; if(!WriteAddress(ReadAddr)) return 0; NOP_DELAY(4); IIC_START(); IIC_WRITE_DATA(GT_CMD_RD); for(; Length > 1; --Length) { NOP_DELAY(4); ret = IIC_READ_DATA(pBuffer, 0); if(!ret) { break; } pBuffer++; } if(ret) { NOP_DELAY(4); IIC_READ_DATA(pBuffer, 1); } IIC_STOP(); return ret; } BOOL IICWriteOneByte(UINT32 WriteAddr,UINT8 DataToWrite) { BOOL ret; IIC_START(); ret = IIC_WRITE_DATA(GT_CMD_WR); if(ret) { if(!WriteAddress(WriteAddr)) return 0; ret = IIC_WRITE_DATA(DataToWrite); } IIC_STOP(); return ret; } BOOL IICWriteBytes(UINT32 WriteAddr,UINT8 *pBuffer,UINT16 Length) { BOOL ret; IIC_START(); ret = IIC_WRITE_DATA(GT_CMD_WR); if(ret) { if(!WriteAddress(WriteAddr)) return 0; while (Length--) { IIC_WRITE_DATA(*pBuffer); pBuffer++; } } IIC_STOP(); return ret; } /********************************************************************* *********************************************************************/