This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

am3359 communicate with TCA9539

Other Parts Discussed in Thread: AM3359

Hi,

I am using the am3359 to communicate with TCA9539 I/O expander by I2C 1. When I send the slave address, then the process stop at this byte every time. No matter what I change the slave address that is no use. So I get the wavefrom form LA that slave is non ack every time. Then I check the things as follow,

(1) VCC in 3.3V, that is correct.

(2) I2C_SDA/ I2C_SCL is connected.

(3) I2C_SDA/ I2C_SCL waveform is correct, just no ack receive

(4) Slave addres is 7-bit address mode

(5) The ISR only enter 2 times

I am afraid that problem is firmware, so have any one advance the issue. Here's my code...

----------------------------------------------------------------------------------------------------------------------------

volatile unsigned int tCount;
volatile unsigned int rCount;
volatile unsigned int flag = 1;
volatile unsigned int numOfBytes;
volatile unsigned char dataToSlave[4];
volatile unsigned char dataFromSlave[50];

int main(void)
{
 /* Enable IRQ in CPSR */
 IntMasterIRQEnable();
 /* Configures AINTC to generate interrupt */
 I2CAINTCConfigure();
 /* Configures I2C to Master mode and speed of 400khz */
 SetupI2C();

 dataToSlave[0] = 0x02;
 dataToSlave[1] = 0xFF;
 dataToSlave[2] = 0xFF;
 tCount = 0;
 rCount = 0;

 // Data Count specifies the number of bytes to be transmitted
 I2CSetDataCount(SOC_I2C_1_REGS, 3);
 numOfBytes = I2CDataCountGet(SOC_I2C_1_REGS);
 // Clear status of all interrupts
 CleanUpInterrupts();
 // Configure I2C controller in Master Transmitter mode
 I2CMasterControl(SOC_I2C_1_REGS, I2C_CFG_MST_TX);
 // Transmit interrupt is enabled
 I2CMasterIntEnableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY|I2C_INT_ADRR_READY_ACESS);
 // Generate Start Condition over I2C bus
 I2CMasterStart(SOC_I2C_1_REGS);
 
 while(I2CMasterBusBusy(SOC_I2C_1_REGS) == 0); // issue: always stop at this line******
 while(tCount != numOfBytes);
 flag = 1;

 // Wait until I2C registers are ready to access
 while(!(I2CMasterIntRawStatus(SOC_I2C_1_REGS) & (I2C_INT_ADRR_READY_ACESS)));
 // Data Count specifies the number of bytes to be received
 I2CSetDataCount(SOC_I2C_1_REGS, 1);
 numOfBytes = I2CDataCountGet(SOC_I2C_1_REGS);
 // Clear status of all interrupts
 CleanUpInterrupts();
 // Configure I2C controller in Master Receiver mode
 I2CMasterControl(SOC_I2C_1_REGS, I2C_CFG_MST_RX);
 // Receive and Stop Condition Interrupts are enabled
 I2CMasterIntEnableEx(SOC_I2C_1_REGS,  I2C_INT_RECV_READY |I2C_INT_STOP_CONDITION);
 // Generate Start Condition over I2C bus
 I2CMasterStart(SOC_I2C_1_REGS);

 while(I2CMasterBusBusy(SOC_I2C_1_REGS) == 0);
 while(flag);
 flag = 1;
}

/* Clear status of all interrupts */
void CleanUpInterrupts(void)
{
    I2CMasterIntEnableEx(SOC_I2C_1_REGS, 0x7FF);
    I2CMasterIntClearEx(SOC_I2C_1_REGS,  0x7FF);
    I2CMasterIntDisableEx(SOC_I2C_1_REGS, 0x7FF);
}

/* I2C Interrupt Service Routine */
void I2CIsr(void)
{
    unsigned int status = 0;

    /* Get only Enabled interrupt status */
    status = I2CMasterIntStatus(SOC_I2C_1_REGS);
    /* Clear interrupt status except receive ready and transmit ready interrupt status */
    I2CMasterIntClearEx(SOC_I2C_1_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_1_REGS);
     /* Clear receive ready interrupt status */
        I2CMasterIntClearEx(SOC_I2C_1_REGS,  I2C_INT_RECV_READY);

        if(rCount == numOfBytes)
        {
         /* Disable the receive ready interrupt */
         I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_RECV_READY);
         /* Generate a STOP */
         I2CMasterStop(SOC_I2C_1_REGS);
        }
    }

    if (status & I2C_INT_TRANSMIT_READY)
    {
     /* Put data to data transmit register of i2c */
        I2CMasterDataPut(SOC_I2C_1_REGS, dataToSlave[tCount++]);
        /* Clear Transmit interrupt status */
        I2CMasterIntClearEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY);

        if(tCount == numOfBytes)
        {
         /* Disable the transmit ready interrupt */
         I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY);
        }
    }

    if (status & I2C_INT_STOP_CONDITION)
    {
       /* Disable transmit data ready and receive data read interupt */
        I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY |
            I2C_INT_RECV_READY     |
            I2C_INT_STOP_CONDITION);
        flag = 0;
    }

    if(status & I2C_INT_NO_ACK)
    {
  I2CMasterIntDisableEx(SOC_I2C_1_REGS, I2C_INT_TRANSMIT_READY  |
            I2C_INT_RECV_READY      |
            I2C_INT_NO_ACK          |
            I2C_INT_STOP_CONDITION);
  // Generate a STOP
  I2CMasterStop(SOC_I2C_1_REGS);

  printf("Data no ack\n");
  flag = 0;
    }
}

static void SetupI2C(void)
{
    /* Enable the clock for I2C1 */
 I2C1ModuleClkConfig();
    I2CPinMux1Setup();
    /* Put i2c in reset/disabled state */
    I2CMasterDisable(SOC_I2C_1_REGS);
    /* Disable auto Idle functionality */
    I2CAutoIdleDisable(SOC_I2C_1_REGS);
    /* Configure i2c bus speed to 400khz */
    I2CMasterInitExpClk(SOC_I2C_1_REGS, 48000000, 12000000, 400000);
    /* Set i2c slave address */
    I2CMasterSlaveAddrSet(SOC_I2C_1_REGS, 0x74);
    /* Bring I2C out of reset */
    I2CMasterEnable(SOC_I2C_1_REGS);
}

/* Configures AINTC to generate interrupt */
void I2CAINTCConfigure(void)
{
    /* Intialize the ARM Interrupt Controller(AINTC) */
    IntAINTCInit();
    /* Registering the Interrupt Service Routine(ISR). */
    IntRegister(SYS_INT_I2C1INT, I2CIsr);
    /* Setting the priority for the system interrupt in AINTC. */
    IntPrioritySet(SYS_INT_I2C1INT, 0, AINTC_HOSTINT_ROUTE_IRQ );
    /* Enabling the system interrupt in AINTC. */
    IntSystemEnable(SYS_INT_I2C1INT);
}

/* Configures I2C1 pin mux */
void I2CPinMux1Setup(void)
{
 HWREG(SOC_CONTROL_REGS + CONTROL_CONF_SPI0_D1)  =
  (CONTROL_CONF_SPI0_D1_CONF_SPI0_D1_PUTYPESEL |
  CONTROL_CONF_SPI0_D1_CONF_SPI0_D1_RXACTIVE  |
  CONTROL_CONF_SPI0_D1_CONF_SPI0_D1_SLEWCTRL  |
  CONTROL_CONF_MUXMODE(2));

 HWREG(SOC_CONTROL_REGS + CONTROL_CONF_SPI0_CS0) =
  (CONTROL_CONF_SPI0_CS0_CONF_SPI0_CS0_PUTYPESEL |
  CONTROL_CONF_SPI0_CS0_CONF_SPI0_CS0_RXACTIVE  |
  CONTROL_CONF_SPI0_D1_CONF_SPI0_D1_SLEWCTRL    |
  CONTROL_CONF_MUXMODE(2));
}

----------------------------------------------------------------------------------------------------------------------------

So, have any idea?