📄 i2c.c
字号:
#include "globaldefs.h"
#include "gen_macros.h"
//#define I2C_WINDRIVER 1
//#define I2C_USB 1
#ifdef I2C_WINDRIVER
#include "status_strings.h"
#else
#ifdef I2C_USB
#include "stusb.h"
#else
#ifdef _CVI_
#include <utility.h>
#else
#include <dlportio.h>
#define inp DlPortReadPortUchar
#define outp DlPortWritePortUchar
#endif
#endif
#endif
#include <cvirte.h>
#include "stdio.h"
#include "i2c.h"
#define LOW 0
#define HIGH 1
#define SDABIT 0x80 /* write = not bit 7 of data port, read = bit 7 of status port */
#define SCLBIT 0x08 /* write = bit 4 of control port , read = bit 4 of status port */
static U16 SppDataPort, /* Address of SPP Data port */
SppStatusPort, /* Address of SPP Status port */
SppControlPort; /* Address of SPP Control port */
static U32 I2cBitTempoValue = 0; /* temporization for I2C bits */
#ifdef I2C_WINDRIVER
HANDLE hWD; /* global Windriver handle */
WD_CARD_REGISTER cardReg; /* Global card handle */
WD_TRANSFER trns[30]; /* transfert structure table for 30 events (10bits*3)*/
#endif
#ifdef I2C_USB
typedef enum
{
I2CREQ_READ,
I2CREQ_WRITE,
I2CREQ_WRITE_READ
}I2C_ReqMsgType_t; /* I2c message type */
typedef struct
{
U8 Type;
U8 Address;
U8 NbWrData;
U8 NbRdData;
U8 Data[20];
}I2C_RequestMsg_t; /* I2c request message */
typedef enum
{
I2CERR_OK,
I2CERR_NACK
}I2C_Error_t;
typedef struct
{
U8 Error;
U8 NbRdData;
U8 Data[20];
}I2C_AnswerMsg_t; /* I2c answer message */
HANDLE hUsb;
I2C_RequestMsg_t req;
I2C_AnswerMsg_t ans;
#endif
#ifndef I2C_USB
/*****************************************************
**FUNCTION :: I2cTempo
**ACTION :: Wait loop used to slow down the I2C communication
**PARAMS IN :: I2cTempoValue global -> Number of loops
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cTempo(U32 TempoValue)
{
unsigned int i;
for ( i=0 ; i<TempoValue ;i++ );
}
#ifdef I2C_WINDRIVER
/*****************************************************
**FUNCTION :: I2cSetBit
**ACTION :: Send a bit to the slave
**PARAMS IN :: level -> HIGH or LOW
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cSetBit(int bitIndex,int level)
{
trns[bitIndex].cmdTrans = WP_BYTE;
trns[bitIndex].dwPort = SppDataPort;
trns[bitIndex].Data.Byte = level ? 0x00 : SDABIT; /* Set SDA to level */
trns[bitIndex+1].cmdTrans = WP_BYTE;
trns[bitIndex+1].dwPort = SppControlPort;
trns[bitIndex+1].Data.Byte = SCLBIT; /* Set SCL to HIGH */
trns[bitIndex+2].cmdTrans = WP_BYTE;
trns[bitIndex+2].dwPort = SppControlPort;
trns[bitIndex+2].Data.Byte = 0x00; /* Set SCL to LOW */
}
/*****************************************************
**FUNCTION :: I2cGetBit
**ACTION :: get a bit from slave
**PARAMS IN :: level -> HIGH or LOW
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cGetBit(int bitIndex)
{
trns[bitIndex].cmdTrans = WP_BYTE;
trns[bitIndex].dwPort = SppControlPort;
trns[bitIndex].Data.Byte = SCLBIT; /* Set SCL to HIGH */
trns[bitIndex+1].cmdTrans = RP_BYTE;
trns[bitIndex+1].dwPort = SppStatusPort; /* Get SDA level */
trns[bitIndex+2].cmdTrans = WP_BYTE;
trns[bitIndex+2].dwPort = SppControlPort;
trns[bitIndex+2].Data.Byte = 0x00; /* Set SCL to LOW */
}
#else
/*****************************************************
**FUNCTION :: I2cSetSDA
**ACTION :: Set the state of the SDAT line
**PARAMS IN :: level -> HIGH or LOW
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cSetSDA(int level)
{
outp(SppDataPort,level ? 0x00 : SDABIT); /* D7 of data port is inverted ? */
}
/*****************************************************
**FUNCTION :: I2cGetSDA
**ACTION :: Get the state of the SDAT line
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: HIGH or LOW
*****************************************************/
unsigned char I2cGetSDA(void)
{
return (inp(SppStatusPort) & SDABIT) ? 1 : 0;
}
/*****************************************************
**FUNCTION :: I2cSetSCL
**ACTION :: Set the state of the SCLK line
**PARAMS IN :: level -> HIGH or LOW
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cSetSCL(int level)
{
outp(SppControlPort,level ? SCLBIT : 0x00);
I2cTempo(I2cBitTempoValue);
}
/*****************************************************
**FUNCTION :: I2cGetSCL
**ACTION :: Get the state of the SCLK line
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: HIGH or LOW
*****************************************************/
unsigned char I2cGetSCL(void)
{
return (inp(SppStatusPort) & SCLBIT) ? 1 : 0;
}
/*****************************************************
**FUNCTION :: I2cWriteBit
**ACTION :: Send a bit to the slave
**PARAMS IN :: level -> HIGH or LOW
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
void I2cWriteBit(int level)
{
I2cSetSDA(level);
I2cSetSCL(HIGH);
I2cSetSCL(LOW);
}
/*****************************************************
**FUNCTION :: I2cReadBit
**ACTION :: Read a bit from the slave
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: HIGH or LOW
*****************************************************/
unsigned char I2cReadBit(void)
{
unsigned char bit;
I2cSetSCL(HIGH);
bit=I2cGetSDA();
I2cSetSCL(LOW);
return bit;
}
#endif
/*****************************************************
**FUNCTION :: I2cStart
**ACTION :: Send a start sequence on the I2C bus (Falling edge on SDAT while SCLK is HIGH)
**PARAMS IN :: NONE
**PARAMS OUT:: NONE
**RETURN :: bus status
*****************************************************/
I2C_RESULT I2cStart (void)
{
U8 sda,scl;
#ifdef I2C_WINDRIVER
trns[0].cmdTrans = WP_BYTE;
trns[0].dwPort = SppDataPort;
trns[0].Data.Byte = 0x00; /* Set SDA to HIGH */
trns[1].cmdTrans = WP_BYTE;
trns[1].dwPort = SppControlPort;
trns[1].Data.Byte = SCLBIT; /* Set SCL to HIGH */
trns[2].cmdTrans = WP_BYTE;
trns[2].dwPort = SppDataPort;
trns[2].Data.Byte = SDABIT; /* Set SDA to LOW */
trns[3].cmdTrans = WP_BYTE;
trns[3].dwPort = SppControlPort;
trns[3].Data.Byte = 0x00; /* Set SCL to LOW */
trns[4].cmdTrans = RP_BYTE;
trns[4].dwPort = SppStatusPort; /* Get SDA & SCL level */
WD_MultiTransfer(hWD,trns,5);
sda = (trns[4].Data.Byte & SDABIT) ? 1 : 0;
scl = (trns[4].Data.Byte & SCLBIT) ? 1 : 0;
#else
I2cSetSDA(HIGH);
I2cSetSCL(HIGH);
I2cSetSDA(LOW);
I2cSetSCL(LOW);
sda = I2cGetSDA();
scl = I2cGetSCL();
#endif
return (scl<<1) + sda;
}
/*****************************************************
**FUNCTION :: I2cWriteByte
**ACTION :: Send a byte to the slave
**PARAMS IN :: data -> the byte to be send
**PARAMS OUT:: NONE
**RETURN :: NONE
*****************************************************/
unsigned char I2cWriteByte(unsigned char data )
{
unsigned char i,bit,nbevents=0;
/* Write 8 bits Data */
#ifdef I2C_WINDRIVER
for (i=0 ;i<8 ;i++)
{
I2cSetBit(nbevents,(data<<i) & 0x80);
nbevents+=3;
}
trns[nbevents].cmdTrans = WP_BYTE;
trns[nbevents].dwPort = SppDataPort;
trns[nbevents].Data.Byte = 0x00; /* Set SDA to HIGH for acknowledge test*/
nbevents++;
I2cGetBit(nbevents);
nbevents+=3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -