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.

tm4c-1294xl i2c always NACKs easy light sensor + short code

Hello,

I am trying to communicate with a very easy light sensor via i2c. the light sensor is ts34725. To do this I use a microcontroller which is new for me: tm4c1294xl

So I am trying to get the id of the module to be sure evrything starts well. But already get a NAK there

http://imgur.com/ZIlQ6SB

Can somebody telle me what I am doing wrong in my short piece of software? As you see The 0x44 (which I need) gets transmitted. But My mc sends a nak for some reason. Also when I try to print the data I receive it prints wrong data (mostly 0).

Does anybody know why?

void setupI2c()
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C7);
GPIOPinConfigure(0x00001002);
GPIOPinConfigure(0x00001402);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_5);
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_4);

}

  void getModel() {

int i=0; int k; int data[1]={0};

 int g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_320),  40000000);

I2CMasterInitExpClk( I2C7Master_Base, g_ui32SysClock, false);
I2CMasterSlaveAddrSet(I2C7Master_Base, 0x29, false); //true = read

I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_SEND);
I2CMasterDataPut(I2C7Master_Base, 0x80|0x12); // result register
while(I2CMasterBusy(I2C7Master_Base));

/******************************/
/*for(i=0;i<10000;i++)
{k++;}

/*****************************/
I2CMasterSlaveAddrSet(I2C7Master_Base, 0x29, true); //true = read
for(i=0;i<10000;i++)
{k--;}
I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_RECEIVE);
data[0]=I2CMasterDataGet(I2C7Master_Base);
while(I2CMasterBusy(I2C7Master_Base));


UARTprintf(" model: %x\n", data[0]);

}

  • Hello Li,

    The configuration of the IO's for the I2C7 has not been done. You can refer to one of the sensorlib examples in TivaWare to see how the IO's are to be configured. The only thing that would change is Port and Pin Number corresponding to the I2C7 and can be got from the data sheet.

    Regards
    Amit
  • , sorry I forgot to post this part of the code. But it was already done. Anu other ideas?

  • Hi,

    Can't seem to find any info about your light sensor on the web - care to post a link?

    The reason you get the NAK is that you use I2C_MASTER_CMD_SINGLE_RECEIVE, which incorporates "START + RUN + STOP" commands to the I2C Master module. The protocol states that the master, when receiving data, should send NAK when it no longer wishes to receive additional bytes - the module does this when you give it the STOP command. If you need to transfer more than one byte, you need to look at the _BURST_RECEIVE_ commands - they'll allow you to generate a multi-byte sequence.

  • the datasheet: www.adafruit.com/.../TCS34725.pdf

    Oh ok thank you very much!
    But why then, when I try to print it, do I almost always get something else than 0x44 that s printed. Altough it s 0x44 thats was sent?
  • Probably because the I2C module doesn't always immediately go to the busy state. Try:

    while(!I2CMasterBusy(I2C7Master_Base));
    while(I2CMasterBusy(I2C7Master_Base));

    so that it will first wait for the module to become busy, then wait until it is not.

  • ok i ll quickly try this!
  • it didn't work.

    this is what I tried:


    void getModel()
    {
    int i=0;
    int k;
    int data[1]={0};

    int g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_320), 40000000);

    I2CMasterInitExpClk( I2C7Master_Base, g_ui32SysClock, false);
    I2CMasterSlaveAddrSet(I2C7Master_Base, 0x29, false); //true = read


    I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_SEND);
    I2CMasterDataPut(I2C7Master_Base, 0x80|0x12); // result register
    while(!I2CMasterBusy(I2C7Master_Base));
    while(I2CMasterBusy(I2C7Master_Base));

    I2CMasterSlaveAddrSet(I2C7Master_Base, 0x29, true); //true = read
    I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_RECEIVE);
    data[0]=I2CMasterDataGet(I2C7Master_Base);
    //while(I2CMasterBusy(I2C7Master_Base));
    while(!I2CMasterBusy(I2C7Master_Base));
    while(I2CMasterBusy(I2C7Master_Base));

    UARTprintf(" model: %x\n", data[0]);
    while(1);
    }

  • You read the data before you wait for the module to become non-busy...
  • I don't get what You mean. I even put double busy-statements on two places. Before and after reading.
    Whata did you mean?

  • I meant that if you read the data from the I2C before it has arrived (it arrives while the master is busy), you're not going to get what you expect. Move the I2CMasterDataGet statement right before the UARTprintf, after the notbusy-busy -while loops. I'll leave it at that, but with careful thought into the matter you should be able to get it working - you're already past many obstacles when you have a clear signal going on the bus.
  • Hello Li

    What Veikko implied was

    I2CMasterSlaveAddrSet(I2C7Master_Base, 0x29, true); //true = read
    I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_RECEIVE);
    while(!I2CMasterBusy(I2C7Master_Base));
    while(I2CMasterBusy(I2C7Master_Base));
    data[0]=I2CMasterDataGet(I2C7Master_Base);

    instead of

    I2CMasterSlaveAddrSet(I2C7Master_Base, 0x29, true); //true = read
    I2CMasterControl(I2C7Master_Base, I2C_MASTER_CMD_SINGLE_RECEIVE);
    data[0]=I2CMasterDataGet(I2C7Master_Base);
    while(!I2CMasterBusy(I2C7Master_Base));
    while(I2CMasterBusy(I2C7Master_Base));

    Regards
    Amit