Hi,I'm using C6472, CCS3.3, and I would like to write a simple I2C read routine.
I tried the example code that came with the CSL library and it worked fine (write and read back in loopback mode).
I need a simple read. I tried to modify the example code with no success. I tried other examples from the web with no success either.
Here is partial code. I removed many of the status return checks to simplify the reading.
My problem is that the read register (RRDY bit) is never ready! Do I have to start by transmitting the slave address, or its is sent automatically? Please help.
void I2C_init(void) {
CSL_Status status;
CSL_I2cObj i2cObj;
CSL_I2cHwSetup hwSetup;
hwSetup.mode = CSL_I2C_MODE_MASTER;
hwSetup.dir = CSL_I2C_DIR_TRANSMIT;
hwSetup.addrMode = CSL_I2C_ADDRSZ_SEVEN; //7bits addressing mode
hwSetup.sttbyteen = CSL_I2C_STB_DISABLE; //DISABLE == disable start byte (Normal mode)
hwSetup.ownaddr = CSL_I2C_SLAVE_ADDR; //address used to talk to this DSP chip
hwSetup.ackMode = CSL_I2C_ACK_ENABLE;
hwSetup.runMode = CSL_I2C_FREE_MODE_DISABLE; //DISABLE == stop at breakpoint
hwSetup.repeatMode = CSL_I2C_REPEAT_MODE_DISABLE;//DISABLE == no repeat mode
hwSetup.loopBackMode = CSL_I2C_DLB_DISABLE; //DISABLE == digital loopback mode is disabled
hwSetup.freeDataFormat = CSL_I2C_FDF_DISABLE; //DISABLE == use 7/10bits addressing mode
hwSetup.resetMode = CSL_I2C_IRS_ENABLE; //ENABLE == put in reset
hwSetup.bcm = CSL_I2C_BCM_DISABLE; //DISABLE == disable back compatibility
hwSetup.inten = 0x00; //interrupt enable mask
hwSetup.clksetup = &clksetup; //prescaler and clock setup
CSL_i2cInit(NULL);
sI2C_Handle = CSL_i2cOpen(&i2cObj, CSL_I2C, NULL, &status);
CSL_i2cHwSetup(sI2C_Handle, &hwSetup);
CSL_i2cHwControl(sI2C_Handle, CSL_I2C_CMD_OUTOFRESET, NULL);
}
uint16_t I2C_read(uint16_t endPoint, uint8_t *data_p, uint16_t length) {
int16_t timecount, timeout = 0x1000;
CSL_Status status = CSL_SOK;
uint16_t response;
uint32_t BbResponse; //busy bit
uint32_t cmd_arg;
uint8_t endPointAddress;
// set address of the slave device
endPointAddress == 0x40;
CSL_i2cHwControl(sI2C_Handle, CSL_I2C_CMD_SET_SLAVE_ADDR, &endPointAddress);
CSL_i2cHwControl(sI2C_Handle, CSL_I2C_CMD_SET_DATA_COUNT,&length);
// Configure Options for Receiving - Master Reciever mode
// CSL_i2cHwControl(sI2C_Handle, CSL_I2C_MODE_MASTER,NULL); //master
CSL_i2cHwControl(sI2C_Handle, CSL_I2C_CMD_DIR_RECEIVE,NULL); //receive
CSL_i2cHwControl(sI2C_Handle, CSL_I2C_CMD_ENABLE,NULL); //enable
CSL_i2cHwControl(sI2C_Handle, CSL_I2C_CMD_START,NULL); //start
// Wait for the transfer to start
do {
CSL_i2cGetBusBusy(sI2C_Handle,&BbResponse);
} while(BbResponse != 1);
while(length) { //receive all data words
CSL_i2cGetHwStatus(sI2C_Handle, CSL_I2C_QUERY_NACKSNT, &response); //check NACK
if ( response != 0x0001 ) {
CSL_i2cGetHwStatus(sI2C_Handle, CSL_I2C_QUERY_ACS_RDY, &response); //check ARDY
if (response != CSL_I2C_ACS_READY ) { //we still have more data to read
CSL_i2cGetHwStatus(sI2C_Handle, CSL_I2C_QUERY_RX_RDY, &response); //check RRDY (can't get past this point)
if ( response == CSL_I2C_RX_READY ) {
CSL_i2cRead(sI2C_Handle,data_p++); //Read Data
length --;
// Clear Receive Ready field
do{
cmd_arg=CSL_I2C_CLEAR_RRDY;
CSL_i2cHwControl(sI2C_Handle,CSL_I2C_CMD_CLEAR_STATUS,&cmd_arg);
CSL_i2cGetHwStatus(sI2C_Handle, CSL_I2C_QUERY_RX_RDY, &response);
}while(response==CSL_I2C_RX_READY);
}//if Rx ready
}//if ARDY: we still have data to read
// Check for Arbitration Lost
CSL_i2cGetHwStatus(sI2C_Handle,CSL_I2C_QUERY_AL, &response);
if ( response == CSL_I2C_ARBITRATION_LOST ) {
return 1001;
}
/* Check for NACK */
CSL_i2cGetHwStatus(sI2C_Handle,CSL_I2C_QUERY_NACKSNT, &response);
if ( response == 0x0001 ) return 1002;
/* Check for Register Access Ready - Good Condition */
CSL_i2cGetHwStatus(sI2C_Handle,CSL_I2C_QUERY_ACS_RDY, &response);//why ARDY!=1?
if ( response == CSL_I2C_ACS_READY ) {
do{
cmd_arg=CSL_I2C_CLEAR_ARDY;
CSL_i2cHwControl(sI2C_Handle,CSL_I2C_CMD_CLEAR_STATUS,&cmd_arg);
CSL_i2cGetHwStatus(sI2C_Handle,CSL_I2C_QUERY_ACS_RDY, &response);
}while(response == CSL_I2C_ACS_READY);
return 0;
}
} // if NACK
} //for all data
// I2C Timeout
return 2002;
}