Hi everyone,
I am controlling an external DAC by I2C from the TMS320F28027F. I am able to communicate to it, buy since I will connect several DAC chips to the I2C bus, I want to implement an I2C scan function, which detects if the DAC associated to some address is present or not.
Just writing the address byte and a second byte (command for the DAC) the external DAC, if present, sets the ACK in the bus and the MASTER (MCU) can set the STOP condition and BB bit is set again to 0. However when the DAC is not present is not setting the ACK to the bus and the master remains alwasy with BB=1 and never sets the STOP condition, so the BUS is not free.
This is how I init the I2C:
void i2ca_init(void) { I2caRegs.I2CSAR =0x0C; //0x00001100 DAC address by default I2caRegs.I2CMDR.bit.IRS=0; //Take I2C to reset prior to set the clock I2caRegs.I2CPSC.all = 6; // Prescaler - Fmod need 7-12 Mhz on module clk --> I2C Fmod=(SYSCLKOUT) /(I2CPSC+1)=60/(9+1)=6MHz I2caRegs.I2CCLKL = 38; // Master CLOCK period Tmas=1/Fmod*(I2CCLKL+5+I2CCLKH+5)-->Fmat=100kHz I2caRegs.I2CCLKH = 38; // NOTE: must be non zero I2caRegs.I2CIER.all = 0x0; // Disable interrupts I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset // Stop I2C when suspended }
Inmediately after the initialitation I execute the next function for scanning, where address is the address to scan in the bus, and the funtion should return 1 if the device is present or 0 if not present:
char I2C_scan_AD5675(char address) { static long i=0; static char device_present=0; //Select DAC address I2caRegs.I2CSAR =address; //0x00001100 DAC address for channels 0-7 // Send start as master transmitter //I2caRegs.I2CMDR.all = 0x6E20; I2caRegs.I2CMDR.bit.FREE = 1; //When 1 the I2C module can run even after a breakpoint I2caRegs.I2CMDR.bit.MST = 1; //as master I2caRegs.I2CMDR.bit.TRX = 1; //Transmit I2caRegs.I2CMDR.bit.IRS = 1; //to Reset I2C bus. I2caRegs.I2CCNT = 1; //I2C_NUMBYTES ; //on confi I2caRegs.I2CMDR.bit.STT = 1; // Only when MAster, when 1 the Master generates a START condition As soon as you start the Start Bit the BB == 1 becomes busy again. I2caRegs.I2CMDR.bit.STP = 1; // Only when Master, when 1 generates a stop condition after I2CCNt=0 will free the BUS thus turning the BB == 0. I2caRegs.I2CDXR=0x00; //DAC command for (i = 0; i < 10000; i++) {} //delay loop if (I2caRegs.I2CSTR.bit.BB == 1) { device_present=0; } else { device_present=1; } return device_present; }
This is the I2C bus snapshot when the DAC is present:
And when the DAC is not present:
The main problem is that after scan a DAC not present (not present I2C address), the I2C peripheral remains block even if I run the initatilation routine again.
Any ideas?
Thanks in advance.
Best regards