Other Parts Discussed in Thread: TM4C129ENCPDT
Hi,
I'm writing code for TM4C129ENCPDT and I'm having trouble reading from an I2C bus expander PCAL9555A.
This code is ported from Cortex LM3S9B96.
From the scope captures it seems that there is only 1/2 of the clock pulsed on the SCL line and the data that is read back is always "0"
uint32_t gSysCtlClock; //the system clock
uint8_t endPointAddress = 0x77; //I2C bus address
uint8_t data[2]; //data to read
#define I2C_WRITE_DIRECTION 0x00
#define I2C_READ_DIRECTION 0x01
#define I2C_MASTER_MAX_RETRIES 1000 // Number of retries
void main() {
clockInit();
GPIO_Init();
I2C_Init();
while(1) {
//Write the command
I2CMasterSlaveAddrSet( I2C2_BASE,
endPointAddress, //7-bit slave address
I2C_WRITE_DIRECTION); //write
I2CMasterDataPut(I2C2_BASE, 0x00); //cmd = read registers
if(I2CMasterBusBusyTimeOut(I2C2_BASE)) return BUSY;
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_START);
if(I2CMasterBusyTimeOut(I2C2_BASE)) {
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_STOP);
return FAIL;
}
//read 1th word
I2CMasterSlaveAddrSet( I2C2_BASE,
endPointAddress, //7-bit slave address
I2C_READ_DIRECTION); //read
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);
if(I2CMasterBusyTimeOut(I2C2_BASE)) {
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_SEND_STOP);
return FAIL;
}
data_p[i++] = I2CMasterDataGet(I2C2_BASE);
I2CMasterControl(I2C2_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
if(I2CMasterBusyTimeOut(I2C2_BASE)) {
return FAIL;
}
//read the last word
data_p[i] = I2CMasterDataGet(I2C2_BASE);
}//while(1)
}//main
//wait for the bus to be ready
uint16_t I2CMasterBusBusyTimeOut(unsigned long ulBase){
uint16_t i;
//wait for the bus to be idle
for(i = 0; i < I2C_MASTER_MAX_RETRIES; i++) {
if(!I2CMasterBusBusy(ulBase)) return FALSE;
SysCtlDelay(gSysCtlClock * 10e-6); //wait 10us
}
if(I2CMasterBusBusy(ulBase)) return TRUE;
else return FALSE;
}
void I2C_Init(void) {
// Initialize the I2C master.
I2CMasterInitExpClk(I2C2_BASE,
gSysCtlClock,
true); //400 kbps
I2CMasterEnable( I2C2_BASE); //set as master
}
void clockInit() {
SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ);
gSysCtlClock = SysCtlClockFreqSet(
SYSCTL_USE_PLL |
SYSCTL_OSC_MAIN |
SYSCTL_XTAL_25MHZ |
SYSCTL_CFG_VCO_400,
120000000); //desired system frequency
}
void GPIO_Init(void) {
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2); //I2C: bus expander
SysCtlPeripheralReset(SYSCTL_PERIPH_I2C2);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOL);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
SysCtlPeripheralReset(SYSCTL_PERIPH_GPION);
GPIOPinConfigure(GPIO_PL1_I2C2SCL); //I2C2 SCL
GPIOPinConfigure(GPIO_PN4_I2C2SDA); //I2C2 SDA
GPIOPinTypeI2CSCL(GPIO_PORTL_BASE, GPIO_PIN_1); //I2C2 SCL
GPIOPinTypeI2C (GPIO_PORTN_BASE, GPIO_PIN_4); //I2C2 SDA
}
