📄 lib_i2c.c
字号:
MY_PIO_SODR = I2C_pt->SCL_line; //* set SCL line
MY_PIO_SODR = I2C_pt->SDA_line; //* set SDA line
}
else {
SETSDATOOUTPUT
SETSCL
SETSDA
K=(_BYTE)(loadAddress/256);
I2C_line.DeviceAddress = AT24C64_I2C_ADDRESS+2*K;
}
//* get byte to transmit
I2C_pt->I2CByte = I2C_pt->DeviceAddress | WRITE_BIT ;
I2C_pt->LoadAddress = loadAddress; //* get address in Target
I2C_pt->nbI2CByte = nbByte; //* get nb byte to transmit
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* Send Write
I2C_pt->mode = LOW_ADDRESS_WRITE ;// I2C_pt->mode = HIGH_ADDRESS_WRITE; //*
//* change interrupt handler to AT91_I2CSendStartSDA
I2C_pt->I2CTCHandler = AT91_I2CSendStartSDA;
//* Enable RC compare interrupt
I2C_pt->timerBase->TC_IER = TC_CPCS;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CRead (I2Cdesc *I2C_pt, _WORD loadAddress, _BYTE nbByte)
//* Object : I2C RANDOM Read & Sequential Read
//* I2C sequence:
//* start addI2C W ACK loadAddressMSD ACK loadAddressLSB ACK Start addI2C R data NACK stop
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* : loadAddress address of return buffer
//* : nbByte
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CRead (I2Cdesc *I2C_pt, _WORD loadAddress, _DWORD nbByte )
{
_DWORD loop;
_BYTE K;
//* clean the rx buff for shifting byte
for(loop = 0; loop < nbByte ; loop++) {
I2C_pt->RxPtr[loop]=0;
}
//* initialize state
I2C_pt->state = NOK;
if (I2C_pt->I2CType==I2CFLASH) {
MY_PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
MY_PIO_OER = I2C_pt->SCL_line; //* set SCL line as an output
MY_PIO_SODR = I2C_pt->SCL_line; //* set SCL line
MY_PIO_SODR = I2C_pt->SDA_line; //* set SDA line
}
else {
SETSDATOOUTPUT
SETSCL
SETSDA
K=(_BYTE)(loadAddress/256);
I2C_line.DeviceAddress = AT24C64_I2C_ADDRESS+2*K;
}
//* get byte to read
I2C_pt->I2CByte = I2C_pt->DeviceAddress | WRITE_BIT;
I2C_pt->LoadAddress = loadAddress; //* get address
I2C_pt->nbI2CByte = nbByte; //* get nb byte to transmit
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* next mode
I2C_pt->mode = LOW_ADDRESS_READ; //I2C_pt->mode = HIGH_ADDRESS_READ; //
//* change interrupt handler to AT91_I2CSendStartSDA
I2C_pt->I2CTCHandler = AT91_I2CSendStartSDA;
//* Enable RC compare interrupt
I2C_pt->timerBase->TC_IER = TC_CPCS;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CWaitTime
//* Object : I2C
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* loadAddress - Address on slave
//* nbByte - Read to bytes
//* I2C_address - I2C address Divice
//* mcki - MCKI freq in KHz
//* Output Parameters : FALSE if input parameter are out of range
//*-----------------------------------------------------------------------------
_DWORD AT91_I2CWaitTime (I2Cdesc *I2C_pt,_DWORD time,_DWORD mcki)
{
while(I2C_pt->state != OK);
mcki = mcki/2; //* load timer value for 0,2 ms
if ((mcki <= 0x0FFFF ) & ((time ) < 128)) { //* check input value
I2C_pt->timerBase->TC_RC = mcki; //* work in step of 1 ms
I2C_pt->state = NOK; //* initialize state
I2C_pt->countBit = time ; //* initialize countBit time
I2C_pt->I2CTCHandler = AT91_I2CWait; //* change interrupt handler to AT91_I2CWait
I2C_pt->timerBase->TC_RC = mcki; //* load timer value for 1 ms
I2C_pt->timerBase->TC_IER = TC_CPCS; //* Enable RC compare interrupt
I2C_pt->timerBase->TC_CCR = TC_SWTRG; //* Trig the timer
}
else {
return (FALSE);
}
return (TRUE);
}
//*---------------------------------------------------------------------------------------
//* Function Name : AT91_I2CTransfertEnd(I2Cdesc *I2C_pt)
//* Object : Wait the end I2C transfert when I2C_line.state != OK
//* Input Parameters : None
//* Output Parameters : none
//*---------------------------------------------------------------------------------------
void AT91_I2CTransfertEnd(I2Cdesc *I2C_pt)
{
_DWORD i,j;
for(i=0; i<3; i++)
for (j=0;j<MCK/5;j++)
if (I2C_pt->state == OK) break;
if (I2C_pt->state != OK) {
I2C_pt->cRetCode = C_ICTIMEOUT;
I2C_pt->state = OK;
}
}
//*---------------------------------------------------------------------------------------
//* Function Name : AT91_irq_open
//* Object : 开中断
//* Input Parameters : None
//* Output Parameters : none
//*---------------------------------------------------------------------------------------
void AT91_irq_open(_DWORD irq_id,_DWORD priority,_DWORD src_type,TypeAICHandler handler_pt )
{
_DWORD mask ;
mask = 0x1 << irq_id ;
//* Disable the interrupt on the interrupt controller
AIC_BASE->AIC_IDCR = mask ;
//* Save the interrupt handler routine pointer and the interrupt priority
AIC_BASE->AIC_SVR[irq_id] = (_DWORD) handler_pt ;
//* Store the Source Mode Register
AIC_BASE->AIC_SMR[irq_id] = src_type | priority ;
//* Clear the interrupt on the interrupt controller
AIC_BASE->AIC_ICCR = mask ;
//* Enable the interrupt on the interrupt controller
AIC_BASE->AIC_IECR = mask ;
}
//*-----------------------------------------------------------------------------
//* Function Name : no_handler_tc (I2Cdesc *I2C_pt)
//* Object : I2C Error
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void no_handler_tc (I2Cdesc *I2C_pt)
{
AT91_I2C_LineClose(&I2C_line);
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CError(I2Cdesc *I2C_pt)
//* Object : I2C Error
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* : loadAddress Address on slave
//* : nbByte Read to bytes
//* : I2C_address I2C address Divice
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CError(I2Cdesc *I2C_pt)
{
//* change interrupt handler to at91_I2CTxSendStopSDA
I2C_pt->I2CTCHandler = AT91_I2CSendStopSDA;
I2C_line.cRetCode = C_NOTOK;
}
//*--------------------------------------------------------------------------------
//* 函数: I2CInitVariable
//* 功能: 初始化I2C读写使用的全局变量
//* 输入:
//* dwSDA : FLASH读写的SDA引脚的PIO地址
//* dwSCL : FLASH读写的SCL引脚的PIO地址
//* 返回: 无
//*---------------------------------------------------------------------------------
void I2CInitVariable(_DWORD dwSDA, _DWORD dwSCL )
{
/*I2C init */
I2C_line.SDA_line = dwSDA ;
I2C_line.SCL_line = dwSCL ;
// EPROM AT24C512 address
I2C_line.DeviceAddress = AT24C256_CHIP1_ADDRESS;
I2C_line.dwI2CSpeed = I2CICCARDSPEED;
//* Timer 0 Counter field
I2C_line.TCBase = TCB0_BASE;
I2C_line.timerBase = (StructTC *) TCB0_BASE;
I2C_line.channelId = TC0_ID;
//* IRQ field
I2C_line.timerBase->TC_IDR = 0x1FF; //* disable interrupt
I2C_line.AICHandler = tc0_asm_interrupt_handler;
I2C_line.I2CTCHandler = no_handler_tc;
}
//*--------------------------------------------------------------------------------
//* 函数: I2CTransfertEnd
//* 功能: 等待I2C处理结束
//* 输入: 无
//* 返回: 无
//*---------------------------------------------------------------------------------
void I2CTransfertEnd(void)
{
AT91_I2CTransfertEnd(&I2C_line);
}
//*--------------------------------------------------------------------------------
//* 函数: I2CWritePage
//* 功能: 将BUF中的数据写入I2C中
//* 参数: wAddress: 拟写数据在Flash或IC卡中的起始地址
//* cLength: 拟写数据的长度
//* cpBuf: 存放拟写入数据的缓冲区,不超过64个字节
//* cChip: 选择0片还是1片FLASH,只对FLASH有效,对I2C无效
//*--------------------------------------------------------------------------------
_BYTE I2CWritePage(_WORD wAddress,_DWORD wLength,_BYTE cChip,_BYTE *cpBuf,_BYTE cI2CType)
{
//AT91_I2C_LineOpen(&I2C_line,I2C_line.dwI2CSpeed,cChip,cI2CType);
I2C_line.TxEnd = I2C_line.TxPtr = cpBuf; //* set global buffer aadres
I2C_line.cRetCode = C_OK;
I2C_line.state = OK;
I2C_line.timerBase->TC_CCR = TC_SWTRG; //* Trig the timer
AT91_I2CTransfertEnd(&I2C_line); //* write modulo page block
AT91_I2CWrite(&I2C_line,wAddress,wLength);
AT91_I2CTransfertEnd(&I2C_line);
//AT91_I2C_LineClose(&I2C_line);
Delayms(5);
if (I2C_line.cRetCode!=C_OK) return(I2C_line.cRetCode);
return(C_OK);
}
//*--------------------------------------------------------------------------------
//* 函数: I2CReadPage
//* 功能: 从I2C中读取数据到BUF中
//* 参数: wAddress: 拟读取数据在Flash或IC卡中的起始地址
//* cLength: 拟读取数据的长度
//* cpBuf: 存放读取数据的缓冲区,不超过64个字节
//* cChip: 选择0片还是1片FLASH,只对FLASH有效,对I2C无效
//*--------------------------------------------------------------------------------
_BYTE I2CReadPage(_WORD wAddress,_DWORD wLength,_BYTE cChip,_BYTE *cpBuf,_BYTE cI2CType)
{
//AT91_I2C_LineOpen(&I2C_line, I2C_line.dwI2CSpeed,cChip,cI2CType);
I2C_line.RxEnd = I2C_line.RxPtr = cpBuf; //* Set the recivied buffer
I2C_line.cRetCode = C_OK;
I2C_line.timerBase->TC_CCR = TC_SWTRG; //* Trig the timer
AT91_I2CTransfertEnd(&I2C_line);
AT91_I2CRead(&I2C_line,wAddress,wLength);
AT91_I2CTransfertEnd(&I2C_line);
Delayms(5);
//AT91_I2C_LineClose(&I2C_line);
if (I2C_line.cRetCode!=C_OK) return(I2C_line.cRetCode);
return(C_OK);
}
//***********************************************************************************
//读取信息到IC卡中
//其中:
//函数的返回值为C_OK或C_NOTOK
//wAddress:读写或写入信息在IC卡中的起始地址
//wLength:读取或写入信息的长度
//cpBlockBuf:读取或待写入的信息
//***********************************************************************************
_BYTE I2CReadBlock(_WORD wAddress,_DWORD dwLength,_BYTE cChip,_BYTE *cpBlockBuf,_BYTE cI2CType)
{
_BYTE cRetCode;
_WORD wAdd;
_DWORD dwPageLength,dwCurLen;
_WORD wPageSize;
wPageSize = I2C_line.wPageSize;
wAdd=wAddress;
dwCurLen = 0;
while (dwCurLen<dwLength) {
if ((wAdd%wPageSize)==0) { // 一页的起始
dwPageLength = ((dwCurLen+wPageSize>=dwLength)?dwLength-dwCurLen:wPageSize);
}
else { // 一页的中间
dwPageLength = wPageSize - (wAdd%wPageSize); // 本页剩余字节的长度
if (dwCurLen + dwPageLength >dwLength) { // 剩余字节长度不够
dwPageLength = (dwLength - dwCurLen);
}
}
cRetCode = I2CReadPage(wAdd,dwPageLength,cChip,cpBlockBuf,cI2CType);
if (cRetCode!=C_OK) return(cRetCode);
wAdd += (_WORD)dwPageLength;
dwCurLen += dwPageLength;
cpBlockBuf += dwPageLength;
}
return(C_OK);
}
//***********************************************************************************
//写入信息到IC卡中
//其中:
//函数的返回值为C_OK或C_NOTOK
//wAddress:读写或写入信息在IC卡中的起始地址
//wLength:读取或写入信息的长度
//cpBlockBuf:读取或待写入的信息
//***********************************************************************************
_BYTE I2CWriteBlock(_WORD wAddress,_DWORD dwLength,_BYTE cChip,_BYTE *cpBlockBuf,_BYTE cI2CType)
{
_BYTE cRetCode;
_WORD wAdd;
_DWORD dwCurLen,dwPageLength;
_WORD wPageSize;
wPageSize = I2C_line.wPageSize;
wAdd=wAddress;
dwCurLen = 0;
while (dwCurLen<dwLength) {
if ((wAdd%wPageSize)==0) { // 一页的起始
dwPageLength = ((dwCurLen+wPageSize>=dwLength)?dwLength-dwCurLen:wPageSize);
}
else { // 一页的中间
dwPageLength = wPageSize - (wAdd%wPageSize); // 本页剩余字节的长度
if (dwCurLen + dwPageLength >dwLength) { // 剩余字节长度不够
dwPageLength = dwLength - dwCurLen;
}
}
cRetCode = I2CWritePage(wAdd,dwPageLength,cChip,cpBlockBuf,cI2CType);
if (cRetCode!=C_OK) return(cRetCode);
wAdd += dwPageLength;
dwCurLen += dwPageLength;
cpBlockBuf += dwPageLength;
}
return(C_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -