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 using the I2C1 peripheral with an AT24CM01 EEProm. I'm attempting to write some dummy values into the EEProm to see if I can write and read the data out properly. The code below writes the Address of the device followed by a 2 byte memory address followed by 50 Data Bytes. The value of the Data bytes increments from 0 to 49.
The issue I'm having is missing data bytes. For instance, when I watch the transmission on an oscilloscope, the Data byte should increment from 0 to 49 but when it runs, data bytes are being skipped. (i.e. 1 --> 3 -->6-->9 etc instead of 0-->1-->2-->3)
If I insert Breakpoints in the code(as highlighted below) each byte is written correctly and the code works correctly. When the Breakpoints are removed, data bytes are skipped. The BUSY bit in the I2CMCS register doesn't seem to ever get set to "1" as the data is being clocked out. I've included the relevant code snippets I'm using to setup the I2C1 peripheral along with the simple test code.
Have I missed a setup step?
Thanks,
Joe
#define EXTERNAL_MEM_PERIPH I2C1_BASE
void main(void)
{
//-- Setup the I2C Port --
TD_Init_I2CPorts(dwSystemClock); //dwSystemClock = 120MHz
ExternalMem_Init(EXTERNAL_MEM_PERIPH);
}
// Initialization routine
static void TD_Init_I2CPorts(uint32_t dwSystemClock)
{
//-- Enable I2C1
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
while(!ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1))
{
}
//-- Enable Port G pins for I2C1
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
//-- Configure G0 and G1 for I2C
ROM_GPIOPinConfigure(GPIO_PG0_I2C1SCL);
ROM_GPIOPinConfigure(GPIO_PG1_I2C1SDA);
ROM_GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);
ROM_GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);
//Setup the transfer speed for 400kbps and run off of the System Clock
I2CMasterInitExpClk(I2C1_BASE, dwSystemClock, true);
}
//Dummy Variable Write operation
uint32_t ExternalMem_Init(uint32_t dwCommPort)
{
uint32_t dwNumberofBytes = 50;
uint32_t i;
volatile uint32_t dwSlaveAdd;
uint32_t byLowerAddress = 0x0A;
volatile uint32_t byData = 0;
volatile uint32_t counter = 0;
volatile uint32_t dwReturnedData[50];
volatile uint32_t dwError = 0x000;
dwSlaveAdd = EXT_MEM_SLAVE_ADDRESS | EXT_MEM_WRITE | EXT_MEM_LOWER_PAGES;
I2CSlaveAddressSet(EXTERNAL_MEM_PERIPH,0,dwSlaveAdd);
//-- Send the Slave Address and Upper Address
HWREG(EXTERNAL_MEM_PERIPH + I2C_O_MSA) = dwSlaveAdd;
I2CMasterDataPut(EXTERNAL_MEM_PERIPH,0x00);
while(I2CMasterBusBusy(EXTERNAL_MEM_PERIPH))
{
}
I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_START);
while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
{
}
//-- Send the lower byte of the Memory Address
I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byLowerAddress); // BREAK POINT HERE
I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_CONT);
while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
{
}
//Write Data
for(i=0; i < dwNumberofBytes; i++)
{
I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byData); //BREAK POINT HERE
if((i+1) == dwNumberofBytes)
{
I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_FINISH);
}
else
{
I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_CONT);
}
//-- Wait for Master to finish
while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
{
}
byData++;
}
Hi Joe,
Can you try
Replacing:
I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_START);
while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
{
}
//-- Send the lower byte of the Memory Address
I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byLowerAddress); // BREAK POINT HERE
With:
I2CMasterControl(EXTERNAL_MEM_PERIPH,I2C_MASTER_CMD_BURST_SEND_START);
while(!I2CMasterBusy(EXTERNAL_MEM_PERIPH)) // Add this code
{
}
while(I2CMasterBusy(EXTERNAL_MEM_PERIPH))
{
}
//-- Send the lower byte of the Memory Address
I2CMasterDataPut(EXTERNAL_MEM_PERIPH,byLowerAddress); // BREAK POINT HERE
You might want to try the same for the second place highlighted in yellow in your code.
Hi Charles,
That did it. I tried adding a small delay but evidently it wasn't long enough. Thanks for the advice.
Joe