Quantcast
Viewing all articles
Browse latest Browse all 25965

Forum Post: RE: Something wrong with Interaction between SYS/BIOS and interrupts

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;
}

Viewing all articles
Browse latest Browse all 25965

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>