📄 i2cint.c
字号:
/****************************************Copyright (c)**************************************************
** File:i2cint
** Created By: zhangacai
** Created date: 2008-05-28
** Version: v1.0
** Descriptions: i2c function
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "hw_i2c.h"
#include "gpio.h"
#include "sysctl.h"
#include "i2c.h"
#include "interrupt.h"
#include "define.c"
/******************************************************************************************
** Delays (dly)
** About 1 seconds while dly==35
******************************************************************************************/
void Delays (ulong dly)
{
int i,j;
for (; dly>0; dly--)
{
for (i=0; i<150; i++)
for (j=0; j<255; j++)HWREG(WATCHDOG_BASE + WDT_O_ICR) = WDT_INT_TIMEOUT;
}
}
/***********************************************************************************************
** I2CInit()
** I2C port initialize
** spd speed (100000 or 400000)
** pri INT priority (0~7)
** Return ture or false
*************************************************************************************************/
int I2CInit(ulong spd, uchar pri)
{
if ((spd == 400000) || (spd == 100000))
{
//SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
// Set port pin
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
// Initialize master
if(spd == 400000)
I2CMasterInit(I2C_MASTER_BASE, true);
else
I2CMasterInit(I2C_MASTER_BASE, false);
// Enable master
IntMasterEnable();
// Enable I2C INT
IntEnable(INT_I2C);
// Enable I2C master INT
I2CMasterIntEnable(I2C_MASTER_BASE);
// Set INT priority
IntPrioritySet(INT_I2C, (pri << 5));
return(true);
}
else
return(false);
}
/*******************************************************************************************
** I2C_ISR()
** I2C INT process
*******************************************************************************************/
void I2C_ISR (void)
{
I2CMasterIntClear(I2C_MASTER_BASE); // Clear I2C INT flag
switch(I2C_state)
{
// Free state
case STATE_IDLE:
{
break;
}
// After sent one byte
case STATE_WRITE_ONE:
{
I2C_state = STATE_IDLE;
break;
}
// Send next data
case STATE_WRITE_NEXT:
{
// Send next data to register
if(I2C_suba_num != 0)
{
I2C_suba_num--;
I2CMasterDataPut(I2C_MASTER_BASE,
(I2C_suba >> (8 * I2C_suba_num)));
if((I2C_suba_num == 0) && I2C_opt == 1)
{
if(I2C_num == 1)
I2C_state = STATE_READ_ONE;
else
I2C_state = STATE_READ_FIRST;
}
}
else
{
I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf++);
I2C_num--;
if(I2C_num == 1)
{
I2C_state = STATE_WRITE_FINAL;
}
}
// Countinuing block send
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
break;
}
// Send last data
case STATE_WRITE_FINAL:
{
I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf);
I2C_num--;
// Stop send
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
// Will complete next block send
I2C_state= STATE_IDLE;
break;
}
// Read one byte
case STATE_READ_ONE:
{
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
I2C_state= STATE_READ_WAIT;
break;
}
// Start read muti bytes
case STATE_READ_FIRST:
{
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);
I2CMasterControl(I2C_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_START);
if(I2C_num == 2)
I2C_state = STATE_READ_FINAL;
else
I2C_state = STATE_READ_NEXT;
break;
}
// Read next byte
case STATE_READ_NEXT:
{
*I2C_buf++ = I2CMasterDataGet(I2C_MASTER_BASE);
I2C_num--;
I2CMasterControl(I2C_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_CONT);
if(I2C_num == 2)
I2C_state = STATE_READ_FINAL;
break;
}
// Read the last byte
case STATE_READ_FINAL:
{
*I2C_buf++ = I2CMasterDataGet(I2C_MASTER_BASE);
I2C_num--;
I2CMasterControl(I2C_MASTER_BASE,
I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
I2C_state= STATE_READ_WAIT;
break;
}
// Wait for read a byte
case STATE_READ_WAIT:
{
*I2C_buf++ = I2CMasterDataGet(I2C_MASTER_BASE);
I2C_num--;
I2C_state= STATE_IDLE;
break;
}
}
}
/*
*********************************************************************************************************
** ISendByte()
** Send one Byte to device with no subaddress
** sla:device slave address
** c:The data will be sent
** Return ture or false
*********************************************************************************************************
*/
int ISendByte(uchar sla, uchar c)
{
I2C_sla = sla >> 1;
I2C_buf = &c;
I2C_state = STATE_WRITE_ONE;
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);
I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf);
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_SEND);
Delays(1);
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C_MASTER_BASE))
return (false);
else
return (true);
}
/**********************************************************************************************
** ISendStr()**
** sla;Device slave address
** suba:Subaddress
** suba_type:Subaddress type, 8+X,one byte,two byte,three byte
** s;Pointer
** no:Data number
** Return ture or false
************************************************************************************************/
int ISendStr(uchar sla, ulong suba, uchar sub_type, uchar *s, ulong no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
I2C_suba = suba;
switch(sub_type)
{
// “8+x”
case 0:
I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
I2C_suba_num = 1;
break;
// one byte
case 1:
I2C_suba_num = 1;
break;
// two byte
case 2:
I2C_suba_num = 2;
break;
// three byte
case 3:
I2C_suba_num = 3;
break;
default: break;
}
if((no == 1) && (I2C_suba_num == 1))
I2C_state = STATE_WRITE_FINAL; // one byte or 8+X subaddress send one byte data
else
I2C_state = STATE_WRITE_NEXT; // Muti byte subaddress send multi byte data
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);
I2C_suba_num--;
I2CMasterDataPut(I2C_MASTER_BASE,
(I2C_suba >> (8 * I2C_suba_num))); // send subaddress HI byte
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
Delays(1);
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C_MASTER_BASE))
return (true);
else
return (true);
}
/*
*********************************************************************************************************
** ISendStrExt()
** send muti data to device with no subaddress
** sla:Device slave address
** s:pointer
** no: Byte number will be sent
** Return ture or false
*********************************************************************************************************
*/
int ISendStrExt(uchar sla, uchar *s, uchar no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
if (no > 1)
{
if(no == 2)
I2C_state = STATE_WRITE_FINAL;
else
I2C_state = STATE_WRITE_NEXT;
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);
I2CMasterDataPut(I2C_MASTER_BASE, *I2C_buf++);
I2C_num--;
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
Delays(1);
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C_MASTER_BASE))
return (false);
else
return (true);
}
else
return(false);
}
/*
*********************************************************************************************************
** IRcvByte()
** Read one byte from device with no subaddress
** sla:Device slave address
** c:pointer
** Return ture or false
*********************************************************************************************************
*/
int IRcvByte(uchar sla, uchar *c)
{
I2C_sla = sla >> 1;
I2C_buf = c;
I2C_state = STATE_READ_WAIT;
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true); // 主机读操作
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);// 启动单次读取
Delays(1);
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C_MASTER_BASE))
return (false);
else
return (true);
}
/**********************************************************************************************
** IRcvStr()
** Read N byte data from device with subaddress
** sla:Device slave address
** suba_type:8+X,one byte, two bytes, three bytes
** suba:Subaddress
** s:pointer
** no;Data number
** Return ture or false
***********************************************************************************************/
int IRcvStr(uchar sla, ulong suba, uchar sub_type, uchar *s, uchar no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
I2C_suba = suba;
I2C_opt = 1;
switch(sub_type)
{
// 8+X
case 0:
I2C_sla = I2C_sla | ((suba >> 8) & 0x07);
I2C_suba_num = 1;
break;
// 1 byte
case 1:
I2C_suba_num = 1;
break;
//2 bytes
case 2:
I2C_suba_num = 2;
break;
// 3 bytes
case 3:
I2C_suba_num = 3;
break;
default: break;
}
if(I2C_suba_num == 1)
{
if(I2C_num == 1)
I2C_state = STATE_READ_ONE;
else
I2C_state = STATE_READ_FIRST;
}
else
I2C_state = STATE_WRITE_NEXT;
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, false);
I2C_suba_num--;
I2CMasterDataPut(I2C_MASTER_BASE,
(I2C_suba >> (8 * I2C_suba_num))); // Send Hi byte of subaddress
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
Delays(1);
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C_MASTER_BASE))
return (false);
else
return (true);
}
/***********************************************************************************************
** IRvcStrExt()
** Read N bytes data from devices with no subaddress
** sla: Device slave address
** s: Pointer
** no: Data number
** Return true or false
************************************************************************************************/
int IRvcStrExt(uchar sla, uchar *s, uchar no)
{
I2C_sla = sla >> 1;
I2C_buf = s;
I2C_num = no;
if(I2C_num > 1)
{
if(I2C_num == 2)
I2C_state = STATE_READ_FINAL;
else
I2C_state = STATE_READ_NEXT;
I2CMasterSlaveAddrSet(I2C_MASTER_BASE, I2C_sla, true);
I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
Delays(1);
while(I2C_state != STATE_IDLE);
if(true == I2CMasterBusy(I2C_MASTER_BASE))
return (false);
else
return (true);
}
else
return (false);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -