📄 i2c.c
字号:
#include "stdlib.h"
#include "config.h"
#include "regmap.h"
#include "bufloc.h"
#include "global.h"
#include "memmap.h"
#include "sio.h"
#include "gpio.h"
#include "func.h"
#include "osdfont.h"
#ifdef SUPPORT_I2C_DEVICE
/************************************************************************
* I2C Subroutine Define *
************************************************************************/
void I2CBusIdle(void);
void I2CBusStart(void);
void I2CBusStop(void);
BYTE I2CWriteByte(BYTE);
BYTE I2CReadByte(BYTE);
/************************************************************************
* I2C Device Address Define *
************************************************************************/
#define I2C_ADDR_24C02 0xA0
#define I2C_TIME_24C02 100
/************************************************************************
* I2C Interface Define *
************************************************************************/
#define I2C_SCL 11
#define I2C_SDA 10
#define I2C_SCL_LOW (GPIO_O_SET(I2C_SCL, 0)); (GPIO_E_SET(I2C_SCL, 1))
#define I2C_SCL_HIGH (GPIO_E_SET(I2C_SCL, 0))
#define I2C_SDA_LOW (GPIO_O_SET(I2C_SDA, 0)); (GPIO_E_SET(I2C_SDA, 1))
#define I2C_SDA_HIGH (GPIO_E_SET(I2C_SDA, 0))
#define I2C_SDA_READ (GPIO_I_GET(I2C_SDA))
/************************************************************************
* I2C Code Start *
************************************************************************/
void I2CInitGPIO()
{
GPIO_M_SET(I2C_SCL, 1);
GPIO_M_SET(I2C_SDA, 1);
GPIO_O_SET(I2C_SCL, 0);
GPIO_O_SET(I2C_SDA, 0);
// Input mode
I2C_SCL_HIGH;
I2C_SDA_HIGH;
}
void I2CBusIdle()
{
I2C_SCL_HIGH;
I2C_SDA_HIGH;
#if 0
MicroDelay(5000);
I2C_SCL_LOW; MicroDelay(2000);
I2C_SCL_HIGH; MicroDelay(2000);
I2C_SCL_LOW; MicroDelay(5000);
I2C_SCL_HIGH;
#else
while (1) {
I2CBusStart();
if (I2CWriteByte(I2C_ADDR_24C02))
break;
I2CBusStop();
}
I2CBusStop();
#endif
}
void I2CBusStart()
{
I2C_SCL_HIGH; MicroDelay(I2C_TIME_24C02);
I2C_SDA_LOW; MicroDelay(I2C_TIME_24C02);
I2C_SCL_LOW;
}
void I2CBusStop()
{
I2C_SDA_LOW; MicroDelay(I2C_TIME_24C02);
I2C_SCL_HIGH; MicroDelay(I2C_TIME_24C02);
I2C_SDA_HIGH;
}
BYTE I2CWriteByte(BYTE Data)
{
BYTE i;
for (i = 0; i < 8; i++) {
MicroDelay(I2C_TIME_24C02);
if (Data & 0x80) {
I2C_SDA_HIGH;
}
else {
I2C_SDA_LOW;
}
MicroDelay(I2C_TIME_24C02);
I2C_SCL_HIGH; MicroDelay(I2C_TIME_24C02);
I2C_SCL_LOW;
Data <<= 1;
}
I2C_SDA_HIGH; MicroDelay(I2C_TIME_24C02);
I2C_SCL_HIGH; MicroDelay(I2C_TIME_24C02);
for (i = 0; i < 200; i++) {
if (!(I2C_SDA_READ)) break;
MicroDelay(10);
}
i = !(I2C_SDA_READ); // Wait ACK signal
I2C_SCL_LOW;
return i;
}
BYTE I2CReadByte(BYTE Ack)
{
BYTE i;
BYTE Data = 0;
for (i = 0; i < 8; i++) {
Data <<= 1; MicroDelay(I2C_TIME_24C02);
I2C_SCL_HIGH;
if (I2C_SDA_READ)
Data |= 0x01;
MicroDelay(I2C_TIME_24C02);
I2C_SCL_LOW;
}
if (Ack) {
I2C_SDA_LOW; // Send ACK signal
}
else {
I2C_SDA_HIGH;
}
MicroDelay(I2C_TIME_24C02);
I2C_SCL_HIGH; MicroDelay(I2C_TIME_24C02);
I2C_SCL_LOW;
I2C_SDA_HIGH;
return Data;
}
void I2CWrite24C02(UINT16 Pos, BYTE Data)
{
BYTE Bank;
BYTE Addr;
Bank = (Pos >> 8) << 1;
Addr = (Pos & 0xFF);
I2CBusIdle();
I2CBusStart();
I2CWriteByte(Bank + I2C_ADDR_24C02);
I2CWriteByte(Addr);
I2CWriteByte(Data);
I2CBusStop();
I2C_SCL_HIGH;
I2C_SDA_HIGH;
}
BYTE I2CRead24C02(UINT16 Pos)
{
BYTE Data;
BYTE Bank;
BYTE Addr;
Bank = (Pos >> 8) << 1;
Addr = (Pos & 0xFF);
I2CBusIdle();
I2CBusStart();
I2CWriteByte(Bank + I2C_ADDR_24C02);
I2CWriteByte(Addr);
I2CBusStop();
I2CBusStart();
I2CWriteByte(Bank + I2C_ADDR_24C02 + 0x01);
Data = I2CReadByte(0);
I2CBusStop();
I2C_SCL_HIGH;
I2C_SDA_HIGH;
return Data;
}
void I2CWrite24C02Array(UINT16 Pos, BYTE *Data, BYTE Len)
{
BYTE Bank;
BYTE Addr;
Bank = (Pos >> 8) << 1;
Addr = (Pos & 0xFF);
I2CBusIdle();
I2CBusStart();
I2CWriteByte(Bank + I2C_ADDR_24C02);
I2CWriteByte(Addr);
while (Len) {
I2CWriteByte(*Data);
Data++;
Len--;
}
I2CBusStop();
I2C_SCL_HIGH;
I2C_SDA_HIGH;
}
void I2CRead24C02Array(UINT16 Pos, BYTE *Data, BYTE Len)
{
BYTE Bank;
BYTE Addr;
Bank = (Pos >> 8) << 1;
Addr = Pos & 0xFF;
I2CBusIdle();
I2CBusStart();
I2CWriteByte(Bank + I2C_ADDR_24C02);
I2CWriteByte(Addr);
I2CBusStop();
I2CBusStart();
I2CWriteByte(Bank + I2C_ADDR_24C02 + 0x01);
while (Len) {
*Data = I2CReadByte(Len != 1);
Data++;
Len--;
}
I2CBusStop();
I2C_SCL_HIGH;
I2C_SDA_HIGH;
}
#define I2C_POS_SELFTEST 0xF8
const BYTE I2CTestStr[] = "Hello TMLH";
BYTE I2CSelfTest()
{
TestI2CBank = 0;
I2CWrite24C02Array(I2C_POS_SELFTEST, (BYTE *)I2CTestStr, 8);
I2CRead24C02Array( I2C_POS_SELFTEST, CalcByteBuffer, 8);
if (memcmp(CalcByteBuffer, (BYTE *)I2CTestStr, 8) != 0)
return 0;
I2CWrite24C02Array(I2C_POS_SELFTEST, (BYTE *)(I2CTestStr + 2), 8);
I2CRead24C02Array( I2C_POS_SELFTEST, CalcByteBuffer, 8);
if (memcmp(CalcByteBuffer, (BYTE *)(I2CTestStr + 2), 8) != 0)
return 0;
I2CRead24C02Array( 0x100 + I2C_POS_SELFTEST, CalcByteBuffer, 8);
if (memcmp(CalcByteBuffer, (BYTE *)(I2CTestStr + 2), 8) == 0) {
// 1-Bank
TestI2CBank = 1;
return 1;
}
I2CWrite24C02Array(0x100 + I2C_POS_SELFTEST, (BYTE *)I2CTestStr, 8);
I2CRead24C02Array( 0x100 + I2C_POS_SELFTEST, CalcByteBuffer, 8);
if (memcmp(CalcByteBuffer, (BYTE *)I2CTestStr, 8) == 0) {
// 2-Bank
TestI2CBank = 2;
}
else {
// 1-Bank
TestI2CBank = 1;
}
return 1;
}
#ifdef SUPPORT_TEST_FUNCTION
#define TEST_I2C_MODE 1
void TestI2C()
{
#if TEST_I2C_MODE == 0
BYTE i;
#else
BYTE Data[8];
#endif
static BYTE Count = 0;
#if TEST_I2C_MODE == 0
for (i = 0; i < 0x20; i++) {
I2CWrite24C02(i, ASC16[i + 16 + Count]);
}
#else
I2CWrite24C02Array(0, (BYTE *)(ASC16 + 16 + Count), 0x08);
I2CRead24C02Array(0, (BYTE *)Data, 0x08);
#endif
psprintf(LineBuffer, "I2C Read : %02x%02x%02x%02x-%02x%02x%02x%02x-%02x",
#if TEST_I2C_MODE == 0
I2CRead24C02(0x00),
I2CRead24C02(0x01),
I2CRead24C02(0x02),
I2CRead24C02(0x03),
I2CRead24C02(0x04),
I2CRead24C02(0x05),
I2CRead24C02(0x06),
I2CRead24C02(0x07),
#else
Data[0x00],
Data[0x01],
Data[0x02],
Data[0x03],
Data[0x04],
Data[0x05],
Data[0x06],
Data[0x07],
#endif
Count++);
MenuPrintMessage(2);
}
#endif
#endif SUPPORT_I2C_DEVICE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -