drv_i2c.c
来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 214 行
C
214 行
/*************************************************************************
*
* Used with ICCARM and AARM.
*
* (c) Copyright IAR Systems 2007
*
* File name : drv_i2c.c
* Description : The iMX21 I2C driver
*
* History :
* 1. Date : 14 May 2007
* Author : Stanimir Bonev
* Description : Create
*
* $Revision: 1.0 $
**************************************************************************/
#include "drv_i2c.h"
static volatile I2C_Ctrl_t I2C_Ctrl;
/*************************************************************************
* Function Name: I2C_Handler
* Parameters: none
*
* Return: none
*
* Description: I2C interrupts handler
*
*************************************************************************/
void I2C_Handler (void)
{
volatile Int8U Dummy;
// Clear interrupt flag
I2SR_bit.IIF = 0;
// Arbitration lost check
if(!I2SR_bit.IAL)
{
switch (I2C_Ctrl.State)
{
case I2cSlaveAdd:
if(I2SR_bit.RXAK)
{
I2C_Ctrl.Status = I2cNak;
break;
}
I2DR_bit.DATA = I2C_Ctrl.Add;
if(I2C_Ctrl.SlaveAdd & 1)
{
// Receive
I2C_Ctrl.State = I2cRepeatedStart;
}
else
{
// Transmit
++I2C_Ctrl.State;
}
break;
case I2cSend:
if(I2C_Ctrl.DataSize--)
{
I2DR_bit.DATA = *I2C_Ctrl.pData++;
}
else
{
// Transmit complete
I2C_Ctrl.Status = I2cComplete;
}
break;
case I2cRepeatedStart:
I2CR_bit.RSTA = 1;
I2DR_bit.DATA = I2C_Ctrl.SlaveAdd;
++I2C_Ctrl.State;
break;
case I2cRepeatedSlaveAdd:
if(I2SR_bit.RXAK)
{
I2C_Ctrl.Status = I2cNak;
break;
}
if(I2C_Ctrl.DataSize == 1)
{
// Receive without akn
I2CR_bit.TXAK = 1;
}
else
{
// Receive with akn
I2CR_bit.TXAK = 0;
}
// Receive mode
I2CR_bit.MTX = 0;
// Dummy read
Dummy = I2DR_bit.DATA;
++I2C_Ctrl.State;
break;
case I2cReceive:
if(--I2C_Ctrl.DataSize == 0)
{
// Receive complete
I2C_Ctrl.Status = I2cComplete;
// The stop condition must be generate before
// reading of the last received byte
I2CR_bit.MSTA = 0;
}
else if (I2C_Ctrl.DataSize == 1)
{
// Receive without akn
I2CR_bit.TXAK = 1;
}
*I2C_Ctrl.pData++ = I2DR_bit.DATA;
}
}
else
{
// Arbitration is lost
I2SR_bit.IAL = 0;
if(I2C_Ctrl.State)
{
I2C_Ctrl.Status = I2cArbLost;
}
}
if(I2C_Ctrl.Status != I2cBusy)
{
// Stop condition
I2CR_bit.MSTA = 0;
I2C_Ctrl.State = I2cIdle;
}
}
/*************************************************************************
* Function Name: I2C_init
* Parameters: none
*
* Return: none
*
* Description: Init I2C module
*
*************************************************************************/
void I2C_Init (void)
{
// Init variables
I2C_Ctrl.State = I2cIdle;
// Enable a clock
PCCR0_bit.I2C_EN = 1;
// Disable I2C module (reset module)
I2CR_bit.IEN = 0;
// Enable I2C module
I2CR_bit.IEN = 1;
if(I2SR_bit.IBB)
{
I2CR_bit.MSTA = 0;
}
// The pins assign to the I2C module
PTD_GIUS_bit.PIN17 = PTD_GIUS_bit.PIN18 = 0;
// I2C speed init ~100kHz/IPCLK 66.5MHz
IFDR_bit.IC = 0x38;
I2SR_bit.IIF=0;
I2CR_bit.IIEN = 1;
// Init AITC
AITC_SetupIntr(I2C_Handler,FALSE,INT_I2C,0);
AITC_EnableIntSource(INT_I2C);
}
/*************************************************************************
* Function Name: I2C_Transfer
* Parameters: Int8U SlaveAdd, Int8U Add,
* pInt8U pData, Int32U DataSize
*
* Return: Boolean
* TRUE - OK
* FALSE - Fault
*
* Description: Init I2C module
*
*************************************************************************/
Boolean I2C_Transfer(Int8U SlaveAdd, Int8U Add, pInt8U pData, Int32U DataSize)
{
// Parameters check
if((DataSize == 0) && (pData == NULL))
{
return I2cParametersError;
}
// I2C Transfer init
I2C_Ctrl.DataSize = DataSize;
I2C_Ctrl.Status = I2cBusy;
I2C_Ctrl.State = I2cSlaveAdd;
I2C_Ctrl.SlaveAdd = SlaveAdd;
I2C_Ctrl.pData = pData;
I2C_Ctrl.Add = Add;
// Wait bus Idle state
while(I2SR_bit.IBB);
// Transmit mode
I2CR_bit.MTX = 1;
// Send Start condition
I2CR_bit.MSTA = 1;
// Wait until Busy set
while(!I2SR_bit.IBB);
// Load Slave address and direction
I2SR_bit.IIF=0;
I2DR_bit.DATA = I2C_Ctrl.SlaveAdd & 0xFE;
I2CR_bit.IIEN = 1;
// Wait until complete the data transfer
while(I2C_Ctrl.Status == I2cBusy);
if(I2C_Ctrl.Status == I2cArbLost)
{
I2C_Init();
}
I2CR_bit.IIEN = 0;
// I2C status
return I2C_Ctrl.Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?