/*******************************************************************************
*
* DESCRIPTION
* This file defines routines for i2c master with gpio, port from linux kernel
*
******************************************************************************/
*
* DESCRIPTION
* This file defines routines for i2c master with gpio, port from linux kernel
*
******************************************************************************/
#include <pio.h>
#include "sensor.h"
#define TS_SCL_PIO_MASK (0x01UL << SENSOR_I2C_SCL_PIO)
#define TS_SDA_PIO_MASK (0x01UL << SENSOR_I2C_SDA_PIO)
#define TS_SDA_PIO_MASK (0x01UL << SENSOR_I2C_SDA_PIO)
#define CS_H() PioSet(SENSOR_I2C_SCL_PIO, TRUE)
#define CS_L() PioSet(SENSOR_I2C_SCL_PIO, FALSE)
#define SDA_OUT() PioSetDir(SENSOR_I2C_SDA_PIO, TRUE)
#define SDA_IN() PioSetDir(SENSOR_I2C_SDA_PIO, FALSE)
#define SDA_READ() PioGet(SENSOR_I2C_SDA_PIO)
#define SDA_H() PioSet(SENSOR_I2C_SDA_PIO, TRUE)
#define SDA_L() PioSet(SENSOR_I2C_SDA_PIO, FALSE)
#define SCK_H() PioSet(SENSOR_I2C_SCL_PIO, TRUE)
#define SCK_L() PioSet(SENSOR_I2C_SCL_PIO, FALSE)
#define udelay(x) TimeDelayUSec(x)
#define CS_L() PioSet(SENSOR_I2C_SCL_PIO, FALSE)
#define SDA_OUT() PioSetDir(SENSOR_I2C_SDA_PIO, TRUE)
#define SDA_IN() PioSetDir(SENSOR_I2C_SDA_PIO, FALSE)
#define SDA_READ() PioGet(SENSOR_I2C_SDA_PIO)
#define SDA_H() PioSet(SENSOR_I2C_SDA_PIO, TRUE)
#define SDA_L() PioSet(SENSOR_I2C_SDA_PIO, FALSE)
#define SCK_H() PioSet(SENSOR_I2C_SCL_PIO, TRUE)
#define SCK_L() PioSet(SENSOR_I2C_SCL_PIO, FALSE)
#define udelay(x) TimeDelayUSec(x)
/*
* DELAY_TIME is quarter clock cycle of i2c SCL.
* As far as i known, no delay is needed in CSR101x_A05
*/
#ifdef DELAY_TIME
#define DELAY(x) udelay(x)
#else
#define DELAY(x) do{ }while(0)
#endif
* DELAY_TIME is quarter clock cycle of i2c SCL.
* As far as i known, no delay is needed in CSR101x_A05
*/
#ifdef DELAY_TIME
#define DELAY(x) udelay(x)
#else
#define DELAY(x) do{ }while(0)
#endif
static void I2cStart(void)
{
/* assert: scl, sda are high */
DELAY(DELAY_TIME);
SDA_L();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
{
/* assert: scl, sda are high */
DELAY(DELAY_TIME);
SDA_L();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
return;
}
}
static void I2cRestart(void)
{
/* assert: scl is low */
SDA_H();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SDA_L();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
{
/* assert: scl is low */
SDA_H();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SDA_L();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
return;
}
}
static void I2cStop(void)
{
/* assert: scl is low */
SDA_L();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SDA_H();
DELAY(DELAY_TIME<<1);
{
/* assert: scl is low */
SDA_L();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SDA_H();
DELAY(DELAY_TIME<<1);
return;
}
}
static int I2cOutByte(uint8 c)
{
bool ack;
int16 i;
uint8 sb;
SDA_OUT();
for(i=7; i>=0; i--)
{
sb = (c >> i) & 1;
if(sb) SDA_H();
else SDA_L();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
}
{
bool ack;
int16 i;
uint8 sb;
SDA_OUT();
for(i=7; i>=0; i--)
{
sb = (c >> i) & 1;
if(sb) SDA_H();
else SDA_L();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
}
SDA_H();
DELAY(DELAY_TIME);
SDA_IN();
SCK_H();
DELAY(DELAY_TIME<<1);
ack = !SDA_READ();
DELAY(DELAY_TIME);
SDA_IN();
SCK_H();
DELAY(DELAY_TIME<<1);
ack = !SDA_READ();
SCK_L();
DELAY(DELAY_TIME);
SDA_OUT();
DELAY(DELAY_TIME);
SDA_OUT();
return ack;
}
}
static int I2cInByte(void)
{
int16 i;
uint8 indata = 0;
/* assert: scl is low */
SDA_H();
SDA_IN();
DELAY(DELAY_TIME);
for (i = 0; i < 8; i++) {
SCK_H();
DELAY(DELAY_TIME);
{
int16 i;
uint8 indata = 0;
/* assert: scl is low */
SDA_H();
SDA_IN();
DELAY(DELAY_TIME);
for (i = 0; i < 8; i++) {
SCK_H();
DELAY(DELAY_TIME);
indata *= 2;
if (SDA_READ()) indata |= 0x01;
DELAY(DELAY_TIME);
if (SDA_READ()) indata |= 0x01;
DELAY(DELAY_TIME);
SCK_L();
if(i == 7) DELAY(DELAY_TIME);
else DELAY(DELAY_TIME<<1);
}
SDA_OUT();
if(i == 7) DELAY(DELAY_TIME);
else DELAY(DELAY_TIME<<1);
}
SDA_OUT();
return indata;
}
}
static int I2cAckNak(uint16 is_ack)
{
/* assert: sda is high */
if (is_ack) SDA_L(); /* send ack */
else SDA_H();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
return 0;
}
{
/* assert: sda is high */
if (is_ack) SDA_L(); /* send ack */
else SDA_H();
DELAY(DELAY_TIME);
SCK_H();
DELAY(DELAY_TIME<<1);
SCK_L();
DELAY(DELAY_TIME);
return 0;
}
bool TSCWrite(uint8 addr, uint16 reg, uint16 *buf, uint16 size)
{
bool acktemp;
uint16 i;
I2cStart();
acktemp = I2cOutByte(addr);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg&0xff);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg>>8);
if(!acktemp) return acktemp;
for(i=0;i<size;i++)
{
acktemp = I2cOutByte(buf[i]&0xff);
acktemp = I2cOutByte(buf[i]>>8);
}
I2cStop();
return acktemp;
}
{
bool acktemp;
uint16 i;
I2cStart();
acktemp = I2cOutByte(addr);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg&0xff);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg>>8);
if(!acktemp) return acktemp;
for(i=0;i<size;i++)
{
acktemp = I2cOutByte(buf[i]&0xff);
acktemp = I2cOutByte(buf[i]>>8);
}
I2cStop();
return acktemp;
}
bool TSCRead(uint8 addr, uint16 reg, uint16 *buf, uint16 size)
{
bool acktemp;
uint16 i=0;
{
bool acktemp;
uint16 i=0;
I2cStart();
acktemp = I2cOutByte(addr);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg&0xff);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg>>8);
if(!acktemp) return acktemp;
I2cRestart();
acktemp = I2cOutByte(addr + 1);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(addr);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg&0xff);
if(!acktemp) return acktemp;
acktemp = I2cOutByte(reg>>8);
if(!acktemp) return acktemp;
I2cRestart();
acktemp = I2cOutByte(addr + 1);
if(!acktemp) return acktemp;
for(i=0;i<size;i++)
{
buf[i] = I2cInByte();
I2cAckNak(TRUE);
buf[i] |= (I2cInByte())<<8;
I2cAckNak(TRUE);
}
I2cStop();
{
buf[i] = I2cInByte();
I2cAckNak(TRUE);
buf[i] |= (I2cInByte())<<8;
I2cAckNak(TRUE);
}
I2cStop();
return acktemp;
}
}
bool Read_N_Bytes(uint8 dev_addr, uint8 l_data, uint8 h_data, uint8 *buffer, uint16 n)
{
bool acktemp;
uint16 i;
{
bool acktemp;
uint16 i;
I2cStart();
acktemp = I2cOutByte(dev_addr);
acktemp = I2cOutByte(l_data);
acktemp = I2cOutByte(h_data);
I2cRestart();
acktemp = I2cOutByte(dev_addr + 1);
for(i=0; i<n; i++)
{
buffer[i] = I2cInByte();
I2cAckNak(TRUE);
}
I2cStop();
return acktemp;
}
acktemp = I2cOutByte(dev_addr);
acktemp = I2cOutByte(l_data);
acktemp = I2cOutByte(h_data);
I2cRestart();
acktemp = I2cOutByte(dev_addr + 1);
for(i=0; i<n; i++)
{
buffer[i] = I2cInByte();
I2cAckNak(TRUE);
}
I2cStop();
return acktemp;
}