📄 lib_i2c.c
字号:
//*-----------------------------------------------------------------------------
//* File Name : lib_i2c.c
//* Object : I2C driver functions
//*
//* 1.0 29/05/00 EL : Creation
//* 2.0 06/09/00 EL : Clean up
//* 2.1 21/11/00 JPP : Change Timer interrupt in LEVEL
//* 2.2 14/01/02 JPP : Send NACK at for read, and add wait function
//*-----------------------------------------------------------------------------
//* --------------------------- include file ----------------------------------
#include "dtm_v3.h"
#include "dtm.h"
#include "externdef.h"
#define SETSDATOOUTPUT pCPLD[0x0a]=0x03;
#define SETSDATOINPUT pCPLD[0x0a]=0x01;
#define SETSCL gcpCPLDReg[4] |= CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4];
#define CLEARSCL gcpCPLDReg[4] &=~CPLD_IC_CLK; pCPLD[8]=gcpCPLDReg[4];
#define SETSDA gcpCPLDReg[4] |= CPLD_IC_DATA;pCPLD[8]=gcpCPLDReg[4];
#define CLEARSDA gcpCPLDReg[4] &=~CPLD_IC_DATA;pCPLD[8]=gcpCPLDReg[4];
void AT91_I2CDeviceRead(I2Cdesc *I2C_pt);
void AT91_I2CTxSendByte(I2Cdesc *I2C_pt);
void AT91_I2CTxSendBit(I2Cdesc *I2C_pt);
void AT91_I2CSendStartSDA(I2Cdesc *I2C_pt);
void AT91_I2CSendStartSCL(I2Cdesc *I2C_pt);
void AT91_I2CPrepareSTOP(I2Cdesc *I2C_pt);
void AT91_I2CSendStopEND(I2Cdesc *I2C_pt);
void AT91_I2CSendStopSDA(I2Cdesc *I2C_pt);
void AT91_I2CPrepareACK(I2Cdesc *I2C_pt);
void AT91_I2CRxPrepareACK(I2Cdesc *I2C_pt);
void AT91_I2CTxWaitACK(I2Cdesc *I2C_pt);
void AT91_I2CRxDoACK(I2Cdesc *I2C_pt);
void AT91_I2CTxSetSCL(I2Cdesc *I2C_pt);
void AT91_I2CTxClearSCL(I2Cdesc *I2C_pt);
void AT91_I2CRxSetSCL(I2Cdesc *I2C_pt);
void AT91_I2CRxClearSCL(I2Cdesc *I2C_pt);
void AT91_I2CRxReceiveByte(I2Cdesc *I2C_pt);
void AT91_I2CRxReceiveBit(I2Cdesc *I2C_pt);
void AT91_I2CWait(I2Cdesc *I2C_pt);
void I2C_lineHandlerInt(I2Cdesc *I2C_pt);
void AT91_I2C_LineOpen(I2Cdesc *I2C_pt, _DWORD RCValue,_BYTE cChip,_BYTE cI2CType);
void AT91_I2C_LineClose(I2Cdesc *I2C_pt);
void AT91_I2CWrite(I2Cdesc *I2C_pt, _WORD loadAddress, _DWORD nbByte);
void AT91_I2CRead(I2Cdesc *I2C_pt, _WORD loadAddress, _DWORD nbByte);
_DWORD AT91_I2CWaitTime(I2Cdesc *I2C_pt,_DWORD time,_DWORD mcki);
void AT91_I2CTransfertEnd(I2Cdesc *I2C_pt);
void AT91_irq_open(_DWORD irq_id,_DWORD priority,_DWORD src_type,TypeAICHandler handler_pt);
void no_handler_tc (I2Cdesc *I2C_pt);
void AT91_I2CError(I2Cdesc *I2C_pt);
void I2CInitVariable(_DWORD dwSDA, _DWORD dwSCL);
void I2CTransfertEnd(void);
_BYTE I2CWritePage(_WORD wAddress,_DWORD wLength,_BYTE cChip,_BYTE *cpBuf,_BYTE cI2CType);
_BYTE I2CReadPage(_WORD wAddress,_DWORD wLength,_BYTE cChip,_BYTE *cpBuf,_BYTE cI2CType);
_BYTE I2CReadBlock(_WORD wAddress,_DWORD dwLength,_BYTE cChip,_BYTE *cpBlockBuf,_BYTE cI2CType);
_BYTE I2CWriteBlock(_WORD wAddress,_DWORD dwLength,_BYTE cChip,_BYTE *cpBlockBuf,_BYTE cI2CType);
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2C (I2Cdesc *I2C_pt, _WORD loadAddress, _BYTE nbByte)
//* Object : I2C
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* : loadAddress
//* : nbByte
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CDeviceRead (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH) {
MY_PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
MY_PIO_SODR = I2C_pt->SDA_line; //* set SDA line
MY_PIO_SODR = I2C_pt->SCL_line; //* set SCL line
}
else {
SETSDATOOUTPUT
SETSDA
SETSCL
}
//* get byte to transmit
I2C_pt->I2CByte = I2C_pt->DeviceAddress | READ_BIT ;
I2C_pt->mode = DATA_READ; //* next mode
I2C_pt->countBit = 8; //* initialize countBit
//* initialize nb_ACK
I2C_pt->nb_ACK = 10;
//* change interrupt handler to AT91_I2CSendStartSDA
I2C_pt->I2CTCHandler = AT91_I2CSendStartSDA;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CTxSendByte (I2Cdesc *I2C_pt)
//* Object : I2C
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CTxSendByte (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH) {
MY_PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
MY_PIO_SODR = I2C_pt->SDA_line; //* set SDA line
}
else {
SETSDATOOUTPUT
SETSDA
}
switch(I2C_pt->mode) { //* get byte to transmit
case DATA :
I2C_pt->I2CByte = *(I2C_pt->TxEnd++);
I2C_pt->nbI2CByte--;
if(I2C_pt->nbI2CByte == 0) I2C_pt->mode = STOP; //* next mode
break;
case HIGH_ADDRESS_WRITE :
I2C_pt->I2CByte = (_BYTE) (I2C_pt->LoadAddress >> 8);
I2C_pt->mode = LOW_ADDRESS_WRITE; //* next mode
break;
case LOW_ADDRESS_WRITE :
I2C_pt->I2CByte = (_BYTE) I2C_pt->LoadAddress;
I2C_pt->mode = DATA; //* next mode
break;
case HIGH_ADDRESS_READ :
I2C_pt->I2CByte = (_BYTE) (I2C_pt->LoadAddress >> 8);
I2C_pt->mode = LOW_ADDRESS_READ; //* next mode
break;
case LOW_ADDRESS_READ :
I2C_pt->I2CByte = (_BYTE) I2C_pt->LoadAddress;
I2C_pt->mode = DEVICE_READ; //* next mode
break;
}
I2C_pt->countBit = 8; //* initialize countBit
I2C_pt->nb_ACK = 10; //* initialize nb_ACK
//* change interrupt handler to AT91_I2CTxSendBit
I2C_pt->I2CTCHandler = AT91_I2CTxSendBit;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CTxSendBit (I2Cdesc *I2C_pt)
//* Object :
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CTxSendBit (I2Cdesc *I2C_pt)
{
_BYTE bit_val;
if (I2C_pt->I2CType==I2CFLASH) {
MY_PIO_CODR = I2C_pt->SCL_line; //* Clear SCL line
}
else
CLEARSCL
I2C_pt->countBit--; //* decrement countBit
if(I2C_pt->countBit >= 0) { //* if bit counter = 0
bit_val = (I2C_pt->I2CByte >> I2C_pt->countBit) & 1; //* get bit to transfert
if (bit_val) { //* Send 0 or 1
if (I2C_pt->I2CType==I2CFLASH) { //* Set SDA line
MY_PIO_SODR = I2C_pt->SDA_line;
}
else
SETSDA
}
else {
if (I2C_pt->I2CType==I2CFLASH) //* Clear SDA line
MY_PIO_CODR = I2C_pt->SDA_line;
else
CLEARSDA
}
//* change interrupt handler to AT91_I2CTxSetSCL
I2C_pt->I2CTCHandler = AT91_I2CTxSetSCL;
}
else {
if (I2C_pt->I2CType==I2CFLASH) { //* set SDA line as an input
MY_PIO_ODR = I2C_pt->SDA_line;
}
else
SETSDATOINPUT
//* change interrupt handler to AT91_I2CPrepareACK
I2C_pt->I2CTCHandler = AT91_I2CPrepareACK;
}
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CSendStartSDA (I2Cdesc *I2C_pt)
//* Object : clear SDA line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CSendStartSDA (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH) {
MY_PIO_CODR = I2C_pt->SDA_line; //* clear SDA line
}
else
CLEARSDA
//* change interrupt handler to AT91_I2CSendStartSCL
I2C_pt->I2CTCHandler = AT91_I2CSendStartSCL;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CTxSendStart (I2Cdesc *I2C_pt)
//* Object : clear SCL line
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CSendStartSCL (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH)
MY_PIO_CODR = I2C_pt->SCL_line; //* clear SCL line
else
CLEARSCL
//* change interrupt handler to AT91_I2CTxSendBit
I2C_pt->I2CTCHandler = AT91_I2CTxSendBit;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CPrepareSTOP (I2Cdesc *I2C_pt)
//* Object :
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CPrepareSTOP (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH) {
MY_PIO_OER = I2C_pt->SDA_line; //* set SDA line as an output
MY_PIO_CODR = I2C_pt->SDA_line; //* clear SDA line
MY_PIO_SODR = I2C_pt->SCL_line; //* set SCL line
}
else {
SETSDATOOUTPUT
CLEARSDA
SETSCL
}
I2C_pt->I2CTCHandler = AT91_I2CSendStopSDA; //* change interrupt handler to AT91_I2CSendStopSDA
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CSendStopEND (I2Cdesc *I2C_pt)
//* Object : end of transmistion
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CSendStopEND (I2Cdesc *I2C_pt)
{
I2C_pt->timerBase->TC_IDR = TC_CPCS; //* Disable RC compare interrupt
I2C_pt->I2CTCHandler = no_handler_tc; //* change interrupt handler to
I2C_pt->state = OK; //* set the End state
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CSendStopSDA (I2Cdesc *I2C_pt)
//* Object : set SDA and ans load end for stop
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CSendStopSDA (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH)
MY_PIO_SODR = I2C_pt->SDA_line; //* set SDA line
else
SETSDA
I2C_pt->I2CTCHandler = AT91_I2CSendStopEND; //* change interrupt handler to
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CPrepareACK (I2Cdesc *I2C_pt)
//* Object : set SCL line and load AT91_I2CTxWaitACK
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CPrepareACK (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH)
MY_PIO_SODR = I2C_pt->SCL_line; //* set SCL line
else
SETSCL
//* change interrupt handler to AT91_I2CTxWaitACK
I2C_pt->I2CTCHandler = AT91_I2CTxWaitACK;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CRxPrepareACK (I2Cdesc *I2C_pt)
//* Object :
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CRxPrepareACK (I2Cdesc *I2C_pt)
{
if (I2C_pt->I2CType==I2CFLASH)
MY_PIO_SODR = I2C_pt->SCL_line; //* set SCL line
else
SETSCL
if(I2C_pt->mode == STOP)
//* change interrupt handler to
I2C_pt->I2CTCHandler = AT91_I2CPrepareSTOP;
else
//* change interrupt handler to AT91_I2CRxDoACK
I2C_pt->I2CTCHandler = AT91_I2CRxDoACK;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91_I2CTxWaitACK (I2Cdesc *I2C_pt)
//* Object :
//* Input Parameters : <I2C_pt> = I2C Peripheral Descriptor pointer
//* Output Parameters : none
//*-----------------------------------------------------------------------------
void AT91_I2CTxWaitACK (I2Cdesc *I2C_pt)
{
_DWORD dwReadAck;
if (I2C_pt->I2CType==I2CFLASH)
dwReadAck = MY_PIO_PDSR & I2C_pt->SDA_line;
else
dwReadAck = (_DWORD)((pCPLD[8]) & 0x1);
if (dwReadAck == 0) { //* if ACK (SDA = 0)
switch(I2C_pt->mode) {
case STOP :
if (I2C_pt->I2CType==I2CFLASH)
MY_PIO_CODR = I2C_pt->SCL_line; //* clear SCL line
else
CLEARSCL
//* change interrupt handler to
I2C_pt->I2CTCHandler = AT91_I2CPrepareSTOP;
break;
case DEVICE_READ :
if (I2C_pt->I2CType==I2CFLASH)
MY_PIO_CODR = I2C_pt->SCL_line; //* clear SCL line
else
CLEARSCL
//* change interrupt handler to
I2C_pt->I2CTCHandler = AT91_I2CDeviceRead;
break;
case DATA_READ :
//* change interrupt handler to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -