Hi,
I have a problem with I2C slave implementation on Stellaris / Tiva.
Im running CC2541 Keyfob as a I2C Master and LM4F120H5QR as a Slave (TM4C123G in final design - I keep in mind differences like I2C1_SLAVE_BASE -> I2C1_BASE). I am using CCS 6.0.0.00190. Because stellaris will maintain some calculations I am using an interrupt for handle I2C.
My goals are:
1. Receive first byte and depending on it (like register address) select next steps in switch().
2. For instance I received 10, so I wanna put one byte I2CSlaveDataPut(I2C1_SLAVE_BASE, someValue), if I received 20 other value and so on.
Thats it! But here comes the problem.
From the LEDS I am using for control occurence of matches I can see that program steps into right cases but the value on the SDA during sending from stellaris is always the same 0x05 as on the picture. It should be the one in case eg 10 but not...
Q1: Why is this happening?
I have tried adding some whiles with I2CSlaveStatus() but without good results.
Q2: How to catch EXACTLY the first byte (not a WRITE request or something else) and then send data depending on received byte?
Speed doesn't matter. Same results when running 533kHz and 33kHz as a CC2541 Master. There must be my bad. Maybe configuration of the slave module.
And i almost forgot... Q3: How by using I2CSlaveACKOverride and I2CSlaveACKValueSet reject request by put NACK during READ (from stellaris slave) cycle? My attempts failed.
Code:
#include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_ints.h" #include "inc/hw_i2c.h" #include "driverlib/debug.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/i2c.h" #include "driverlib/interrupt.h" #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif /* variables, const */ #define SLAVE_OWN_ADDRESS 0x02 volatile unsigned short fir = 0; unsigned short i = 0; unsigned short flag =0; void I2C1SlaveIntHandler(void) { I2CSlaveIntClear(I2C1_SLAVE_BASE); I2CSlaveIntClearEx(I2C1_SLAVE_BASE,I2C_SLAVE_INT_DATA); fir = I2CSlaveDataGet(I2C1_SLAVE_BASE); switch(fir) { case 8: I2CSlaveDataPut(I2C1_SLAVE_BASE, 8); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1); break; case 2: I2CSlaveDataPut(I2C1_SLAVE_BASE, 2); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1); break; case 5: I2CSlaveDataPut(I2C1_SLAVE_BASE, 0xCA); //before here was 0x05 - when picture was captured //GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1); break; case 10: while(I2CSlaveStatus(I2C1_SLAVE_BASE) & I2C_SLAVE_ACT_TREQ) { I2CSlaveDataPut(I2C1_SLAVE_BASE, 255); } GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,GPIO_PIN_3); break; case 20: I2CSlaveDataPut(I2C1_SLAVE_BASE, 20); break; case 30: I2CSlaveDataPut(I2C1_SLAVE_BASE, 30); break; default: //I2CSlaveDataPut(I2C1_SLAVE_BASE, 64); break; } GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2,GPIO_PIN_2); flag = 1; fir = 0; } main(void) { ROM_FPUEnable(); ROM_FPULazyStackingEnable(); SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3); SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); ROM_GPIOPinConfigure(GPIO_PA6_I2C1SCL); ROM_GPIOPinConfigure(GPIO_PA7_I2C1SDA); GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6); GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7); I2CSlaveEnable(I2C1_SLAVE_BASE); I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_OWN_ADDRESS); /* Enable interrupts */ I2CSlaveIntEnable(I2C1_SLAVE_BASE); I2CSlaveIntEnableEx(I2C1_SLAVE_BASE, I2C_SLAVE_INT_DATA); IntEnable(INT_I2C1); IntMasterEnable(); while(1) { if(flag) { flag = 0; GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,0); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2,0); i++; if(i > 5) { i = 0; GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3,0); } } } }
PS. I realized that I have added this post on wrong forum -> LM3 so I have deleted it there and post here. Newbie fail :)
Thanks,
Piotr.