Ashish,
Thank you again.
When I read the API that was not clear.
One more item...
We have a collection of peripherals on the I2C. I created this generic I2C interface from TI's examples. But, it seems to be intermittent I suspect that now that the cache an all is working the timing of the examples may not be correct.
Would you mine looking at this since you spotted my startware/SYSBIOS conflicts before? (see below)
Thanks,
Aaron
--- i2c_utils.c----
#include <ti/sysbios/family/arm/a8/intcps/Hwi.h>
#include "hsi2c.h"
#include "gpio_v2.h"
#include "interrupt.h"
#include "soc_AM335x.h"
#include "consoleUtils.h"
#include "evmAM335x.h"
#include "delay.h"
#include "i2c_utils.h"
#define I2C_SYSTEM_CLOCK 48000000
#define I2C_INTERNAL_CLOCK 12000000
#define I2C_OUTPUT_CLOCK 100000
#define I2C_CLEAR_ALL_INTERRUPTS 0x7FF
static volatile unsigned char dataFromSlave[12];
static volatile unsigned char dataToSlave[12];
static volatile unsigned int numOfBytes;
static volatile unsigned int flag = 1;
static volatile unsigned int tCount;
static volatile unsigned int rCount;
static void I2CAintcConfigure(void);
void cleanupInterrupts(void)
{
I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_CLEAR_ALL_INTERRUPTS);
}
/* Configures AINTC to generate interrupt */
static void I2CAintcConfigure(void)
{
IntMasterIRQEnable();
IntAINTCInit();
Hwi_Params hwiParams;
Hwi_Params_init(&hwiParams);
hwiParams.priority = 1;
hwiParams.enableInt = TRUE;
Hwi_create(SYS_INT_I2C0INT, (ti_sysbios_interfaces_IHwi_FuncPtr)I2CIsr, &hwiParams, NULL);
}
/*
** Configures i2c bus frequency and slave address.
** It also enable the clock for i2c module and
** does pinmuxing for the i2c.
*/
void SetupI2C(void)
{
/* Enable IRQ in CPSR */
IntMasterIRQEnable();
/* Configures AINTC to generate interrupt */
I2CAintcConfigure();
I2C0ModuleClkConfig();
I2CPinMuxSetup(0);
/* Put i2c in reset/disabled state */
I2CMasterDisable(SOC_I2C_0_REGS);
/* Auto Idle functionality is disabled */
I2CAutoIdleDisable(SOC_I2C_0_REGS);
/* Configure i2c bus speed to 100khz */
I2CMasterInitExpClk(SOC_I2C_0_REGS, I2C_SYSTEM_CLOCK, I2C_INTERNAL_CLOCK,
I2C_OUTPUT_CLOCK);
/* Bring I2C module out of reset */
I2CMasterEnable(SOC_I2C_0_REGS);
}
/*
** Transmits data over I2C bus
*/
void i2cWrite(unsigned char i2c_address, unsigned char *data, unsigned int dcount)
{
tCount = 0;
/* Set i2c slave address */
I2CMasterSlaveAddrSet(SOC_I2C_0_REGS, i2c_address);
memcpy( (void *)&dataToSlave, (void *)data, dcount);
/* Data Count specifies the number of bytes to be transmitted */
I2CSetDataCount(SOC_I2C_0_REGS, dcount);
numOfBytes = I2CDataCountGet(SOC_I2C_0_REGS);
/* Configure I2C controller in Master Transmitter mode */
I2CMasterControl(SOC_I2C_0_REGS, I2C_CFG_MST_TX | I2C_CFG_STOP);
/* Transmit and Stop condition interrupt is enabled */
I2CMasterIntEnableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_STOP_CONDITION );
/* Generate Start Condition over I2C bus */
I2CMasterStart(SOC_I2C_0_REGS);
while (flag);
flag = 1;
/* Wait until I2C registers are ready to access */
while(!(I2CMasterIntRawStatus(SOC_I2C_0_REGS) & (I2C_INT_ADRR_READY_ACESS)));
}
void i2cWriteByte(unsigned char i2c_address, unsigned char i2c_reg,
unsigned char byte)
{
unsigned char txdata[2];
txdata[0] = i2c_reg; // register
txdata[1] = byte;
i2cWrite(
i2c_address,
txdata,
sizeof(txdata));
}
/*
** Receives data over I2C bus
*/
void i2cRead(unsigned char i2c_address, unsigned char *wdata, unsigned int wdcount,
unsigned char *rdata, unsigned int rdcount)
{
rCount = 0;
tCount = 0;
/* Set i2c slave address */
I2CMasterSlaveAddrSet(SOC_I2C_0_REGS, i2c_address);
memcpy( (void *)&dataToSlave, (void *)wdata, wdcount);
/* Data Count specifies the number of bytes to be transmitted */
I2CSetDataCount(SOC_I2C_0_REGS, wdcount);
numOfBytes = I2CDataCountGet(SOC_I2C_0_REGS);
/* Configure I2C controller in Master Transmitter mode */
I2CMasterControl(SOC_I2C_0_REGS, I2C_CFG_MST_TX);
/* Transmit and Stop condition interrupt is enabled */
I2CMasterIntEnableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY);
/* Generate Start Condition over I2C bus */
I2CMasterStart(SOC_I2C_0_REGS);
while (tCount != numOfBytes);
flag = 1;
/* Wait until I2C registers are ready to access */
while(!(I2CMasterIntRawStatus(SOC_I2C_0_REGS) & (I2C_INT_ADRR_READY_ACESS)));
/* Data Count specifies the number of bytes to be received */
I2CSetDataCount(SOC_I2C_0_REGS, rdcount);
numOfBytes = I2CDataCountGet(SOC_I2C_0_REGS);
cleanupInterrupts();
/* Configure I2C controller in Master Receiver mode */
I2CMasterControl(SOC_I2C_0_REGS, I2C_CFG_MST_RX);
/* Receive and Stop Condition Interrupts are enabled */
I2CMasterIntEnableEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY |
I2C_INT_STOP_CONDITION);
/* Generate Start Condition over I2C bus */
I2CMasterStart(SOC_I2C_0_REGS);
while(I2CMasterBusBusy(SOC_I2C_0_REGS) == 0);
while (flag);
flag = 1;
memcpy((void *)rdata, (void *)&dataFromSlave[0], rdcount);
}
unsigned char i2cReadByte(unsigned char i2c_address, unsigned char i2c_reg)
{
unsigned char rx_wdata[1];
unsigned char rx_rdata[1];
rx_wdata[0] = i2c_reg; // register
i2cRead(
i2c_address,
rx_wdata,
sizeof(rx_wdata),
rx_rdata,
1
);
return rx_rdata[0];
}
/*
** I2C Interrupt Service Routine. This function will read and write
** data through I2C bus.
*/
void I2CIsr(void)
{
unsigned int status = 0;
status = I2CMasterIntStatus(SOC_I2C_0_REGS);
I2CMasterIntClearEx(SOC_I2C_0_REGS,
(status & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY)));
if(status & I2C_INT_RECV_READY)
{
/* Receive data from data receive register */
dataFromSlave[rCount++] = I2CMasterDataGet(SOC_I2C_0_REGS);
I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY);
if(rCount == numOfBytes)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_RECV_READY);
/* Generate a STOP */
I2CMasterStop(SOC_I2C_0_REGS);
}
}
if (status & I2C_INT_TRANSMIT_READY)
{
/* Put data to data transmit register of i2c */
I2CMasterDataPut(SOC_I2C_0_REGS, dataToSlave[tCount++]);
I2CMasterIntClearEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY);
if(tCount == numOfBytes)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY);
}
}
if (status & I2C_INT_STOP_CONDITION)
{
/* Disable transmit data ready and receive data read interupt */
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_RECV_READY |
I2C_INT_STOP_CONDITION);
flag = 0;
}
if(status & I2C_INT_NO_ACK)
{
I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
I2C_INT_RECV_READY |
I2C_INT_NO_ACK |
I2C_INT_STOP_CONDITION);
/* Generate a STOP */
I2CMasterStop(SOC_I2C_0_REGS);
flag = 0;
}
}
int i2c_write(unsigned char slave_addr,
unsigned char reg_addr,
unsigned char length,
unsigned char const *data)
{
unsigned char temp_data[16];
temp_data[0] = reg_addr;
memcpy(&temp_data[1], data, length);
i2cWrite(slave_addr, temp_data, length+1);
return 0;
}
int i2c_read(unsigned char slave_addr,
unsigned char reg_addr,
unsigned char length,
unsigned char *data)
{
unsigned char temp_wdata[16];
temp_wdata[0] = reg_addr;
i2cRead(slave_addr, temp_wdata, 1, data, length);
return 0;
}