Part Number:TMS320F28379D
Tool/software: Code Composer Studio
Hi. I am trying to communicate with magnetometer through I2C. I learned how to initialize I2C peripheral and some I2C standard functions used in example i2c_ex2_eeprom.c and i2c_ex1_loopback.c. Now I try to make my own I2C functions based on those examples to build up my sensor library. As I saw in example, to read and write to I2C, we follow this procedure (assumed all initializations have been done):
To write to I2C:
- set slave address
- set register address to be written
- put data ready to be sent
- send start condition
- send stop condition
To read I2C
- set slave address
- set register address to be read
- send start condition
- wait for I2C_INTSRC_REG_ACCESS_RDY to be triggered and then, send stop condition inside ISR
- set number of bytes to be read
- read data using I2C_getData()
I follow this procedure and make some function as shown below. But I have some problem with read function ( write function seemed to be ok)
- I2C_INTSRC_REG_ACCESS_RDY was not triggered so stop condition could not be sent to end the setting up address process
- the program stuck in while(I2C_getStopConditionStatus(base)!=0). But it stuck in the second statement not the first one which I found weird since stop condition cant be sent inside ISR
Please give me some advice. Thanks in advance
void initI2C(uint32_t base) { I2C_disableModule(base); // I2C configuration. Use a 400KHz I2C clock with a 33% duty cycle I2C_initMaster(base, DEVICE_SYSCLK_FREQ, 400000, I2C_DUTYCYCLE_33); I2C_setBitCount(base, I2C_BITCOUNT_8); // I2C_setSlaveAddress(base, slaveAddr); I2C_setEmulationMode(base,I2C_EMULATION_FREE_RUN); // enable stop condition and register-access-ready interrupts I2C_enableInterrupt(base,I2C_INT_STOP_CONDITION | I2C_INT_REG_ACCESS_RDY); // FIFO configuration I2C_enableFIFO(base); I2C_clearInterruptStatus(base,I2C_INT_RXFF | I2C_INT_TXFF); I2C_enableModule(base); } int16_t i2cRead(uint32_t base, uint16_t slaveAddr,uint16_t regAddr,uint16_t *data,uint16_t data_length) { uint16_t count; if(I2C_getStopConditionStatus(base)) { return ERROR_STOP_NOT_READY; } I2C_setSlaveAddress(base, slaveAddr); I2C_setDataCount(base, 1); I2C_putData(base, regAddr); I2C_setConfig(base, I2C_MASTER_SEND_MODE); I2C_sendStartCondition(base); // I2C_sendStopCondition(base); while(I2C_getStopConditionStatus(base)!=0); I2C_setDataCount(base,data_length); I2C_setConfig(base,I2C_MASTER_RECEIVE_MODE); I2C_sendStartCondition(base); I2C_sendStopCondition(base); while(I2C_getStopConditionStatus(base)!=0); // this is where the program stuck // while(data_ready_flag==0); for(count=0;count<data_length;count++) { //while(I2C_getRxFIFOStatus(base)==I2C_FIFO_RXEMPTY); *(data+count) = I2C_getData(base); } return SUCCESS; } int16_t i2cWrite(uint32_t base,uint16_t slaveAddr, uint16_t regAddr, uint16_t data) { if(I2C_getStopConditionStatus(base)) { return ERROR_STOP_NOT_READY; } I2C_setSlaveAddress(base, slaveAddr); if(I2C_isBusBusy(I2CB_BASE)) { return(ERROR_BUS_BUSY); } I2C_setDataCount(base,2); I2C_putData(base,regAddr); I2C_putData(base, data); I2C_setConfig(base,I2C_MASTER_SEND_MODE); I2C_sendStartCondition(base); I2C_sendStopCondition(base); return SUCCESS; } int16_t i2cWriteMulti(uint32_t base,uint16_t slaveAddr, uint16_t regAddr, uint16_t *data,uint16_t data_length) { uint16_t i; if(I2C_getStopConditionStatus(base)) { return ERROR_STOP_NOT_READY; } I2C_setSlaveAddress(base, slaveAddr); if(I2C_isBusBusy(I2CB_BASE)) { return(ERROR_BUS_BUSY); } I2C_setDataCount(base,data_length+1); I2C_putData(base,regAddr); for(i=0; i<data_length;i++) { I2C_putData(base, *(data+i)); } I2C_setConfig(base,I2C_MASTER_SEND_MODE); I2C_sendStartCondition(base); I2C_sendStopCondition(base); return SUCCESS; } __interrupt void i2cISR() { count++; intSource = I2C_getInterruptSource(I2CB_BASE); switch(intSource) { case I2C_INTSRC_STOP_CONDITION: { } break; case I2C_INTSRC_REG_ACCESS_RDY: { if((I2C_getStatus(I2CB_BASE)&I2C_STS_NO_ACK)!=0) { I2C_sendStopCondition(I2CB_BASE); I2C_clearStatus(I2CB_BASE, I2C_STS_NO_ACK); } } break; } Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8); }