This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I'm trying to send data to a DAC chip using i2c port of C28 but it fails, I'm able to send the i2c data with M3 using the example provided in the controlSUITE. But F28m36x in the controlSUITE do not have an example for I2C with C28. So I used the example i2c_eeprom code from similar family of controllers as a reference.
But I'm not able to send any data with i2c, I can see the slave address byte on the oscilloscope and after that the clock signal stays low permanently and I cannot see data after that byte.(this happens irrespective of external hardware(DAC) connected or disconnected)
Is there any TI source where I can find the I2C example code for C28 core of the F28m36x? even the F28M36x_I2C.c library code looks incomplete.
NOTE: external pullup is used for the GPIO32,33 I2C pins as there is no pullup config available through software in C28.
I'm using the following configurations for sending the data. I used (http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/268548?I2C-Nothing) as a reference for the clock settings.
void InitI2CGpio()
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
//GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0; // Enable pull-up for GPIO32 (SDAA)
//GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0; // Enable pull-up for GPIO33
// (SCLA)
/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.
GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; // Asynch input GPIO32 (SDAA)
GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3; // Asynch input GPIO33 (SCLA)
/* Configure I2C pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be I2C functional pins.
// Comment out other unwanted lines.
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // Configure GPIO32 for SDAA
// operation
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1; // Configure GPIO33 for SCLA
// operation
EDIS;
}
void I2CA_Init(void)
{
I2caRegs.I2CSAR = 0x60; // Slave address of DAC
I2caRegs.I2CPSC.all = 14; //for CPU_FRQ_150MHZ, SYSCLK/(I2CPSC+1)
I2caRegs.I2CCLKL = 76; // NOTE: must be non zero
I2caRegs.I2CCLKH = 38; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x0; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
return;
}
void I2C_write_new()
{
Uint16 i = 0;
// Setup slave address
I2caRegs.I2CSAR = 0x60;
while (I2caRegs.I2CSTR.bit.BB == 1)
{
i = 1;
}
I2caRegs.I2CCNT = 3;
I2caRegs.I2CDXR = 0x60;
I2caRegs.I2CDXR = 0x66;
I2caRegs.I2CDXR = 0x60;
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
I2caRegs.I2CMDR.bit.STP = 1; //Master must release bus once Tx is complete , i.e. I2CCNT =0
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
I2caRegs.I2CMDR.bit.FREE = 1; //Debugger will not halt the bus on a breakpoint
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
// Send start as master transmitter
// I2caRegs.I2CMDR.all = 0x6E20;
}
I have attached the I2CMDR register settings before and after sending i2c data.
We don't have any examples specifically for the C28 side of the F28M36x, but you were correct in your use of one of the other C28 device's i2c_eeprom examples--aside from some possible changes in FIFO size, the I2C is the same.
Just to clarify, the clock does toggle while the slave address is being sent--it just stays low afterward, correct? It sounds like maybe it's what is described under "Hardware Response to a NACK" on this page. Can you check the status bits in I2CSTR and try what that page recommends for NACK handling?
Whitney
Yes based on that wiki link I'm checking the ARDY status bit in I2CSTR, set and cleared STP and NACK registers. Now my clock signal goes back to high. But still I can only see the Address byte and after that both the SDA and SCL stays high.
I'm trying to send the data based on FIFO transmit and I enabled it with the following setting.
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
My I2C init and I2C write are as follows:
void I2CA_Init(void)
{
I2caRegs.I2CSAR = 0x60; // Slave address of DAC
I2caRegs.I2CPSC.all = 14; //for CPU_FRQ_150MHZ, SYSCLK/(I2CPSC+1)
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x0; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
return;
}
void I2C_write_new()
{
Uint16 i = 0;
// Setup slave address
// I2caRegs.I2CSAR = 0x60;
while (I2caRegs.I2CSTR.bit.BB == 1)
{
i = 1;
}
I2caRegs.I2CCNT = 3;
I2caRegs.I2CDXR = 0x60;
I2caRegs.I2CDXR = 0x66;
I2caRegs.I2CDXR = 0x60;
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
I2caRegs.I2CMDR.bit.STP = 1; //Master must release bus once Tx is complete , i.e. I2CCNT =0
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
I2caRegs.I2CMDR.bit.FREE = 1; //Debugger will not halt the bus on a breakpoint
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
// Send start as master transmitter
// I2caRegs.I2CMDR.all = 0x6E20;
while(!(I2caRegs.I2CSTR.bit.ARDY));
if(I2caRegs.I2CSTR.bit.NACK)
{
I2caRegs.I2CMDR.bit.STP = 1;
I2caRegs.I2CSTR.bit.NACK = 1;
}
}
I'm trying to send 3 bytes of data and the data is given to I2CDXR, Are there any other register setting required for a FIFO data send?
Thanks
Your FIFO setup seems okay. As you step through your writes to I2CDXR, do you see the FIFO level status in I2CFFTX increasing? After you run the rest of the code, do you see it go back to 0? What about I2CCNT? Does it return to 0 after you run the code?
Whitney
Hello Whitney,
I removed the FIFO send code and trying to send 3 bytes of data by polling the XRDY register. After "I2caRegs.I2CMDR.bit.STT = 1;" is executed I'm polling for the XRDY register and sending data. Initially the XRDY is 1 and after I send the 1st byte of data, it is set to 0 and never resets to 1 and I don't see any data after the address byte on the scope.
According to the TRM when XRDY is 1 "I2CDXR ready: Data has been copied from I2CDXR to I2CXSR" so after I give my data to I2CDXR, internally it is not sent to I2CXSR to make the XRDY 1. (page 1229)
Only when XRDY is 1 I can send my 2nd byte of data and can assume that my 1st byte is sent successfully. The code snippet to I2C write is as follows:
void I2C_write_new_nofifo() { Uint16 i = 0; // Setup slave address I2caRegs.I2CSAR = 0x60; I2caRegs.I2CCNT = 3; I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode I2caRegs.I2CMDR.bit.STP = 1; //Master must release bus once Tx is complete , i.e. I2CCNT =0 I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode I2caRegs.I2CMDR.bit.FREE = 1; //Debugger will not halt the bus on a breakpoint I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow for(i=0; i<3 ;i++) { while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till bus is free I2caRegs.I2CDXR = (unsigned int)ulDataTx[i]; //Next data byte } }
My I2C init is as follows:
void I2CA_Init(void) { I2caRegs.I2CPSC.all = 14; //for CPU_FRQ_150MHZ, SYSCLK/(I2CPSC+1) I2caRegs.I2CCLKL = 45; // NOTE: must be non zero//SCL 100khz I2caRegs.I2CCLKH = 45; // NOTE: must be non zero I2caRegs.I2CIER.all = 0x0; // Enable SCD & ARDY interrupts I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset return; }
Is there any register setting which is missing to shift the data from I2CDXR -> I2CXSR?
The I2CCNT remains as 3 and is not decremented.
status register is as follows:
Karthik
Have you seen your DAC ACK that it has recognized its address? If you look at the SDA signal, can you actually see an ACK? It looks like the NACK bit is just continuously being set so the C28 I2C won't even try to send the data.
Are you confident your slave device is working and that you're meeting its requirements (correct address, correct clock speed, etc...)?
Whitney
Yes I resolved the issue the DAC ACK is not received due to a digital isolator in between. This hardware setup worked without any issues with M3, and the c28 do not send the next byte without ACK. Is there any way for my C28 to ignore the ACK bit and continue sending the data bytes?
Thanks