I'm running into an issue with I2C where I never break out of this while loop: while(I2CMasterBusy(m_I2CBus)); I have 16kOhm pullup resistors on both th SDATA and SCLOCK. They are not connected to a device, but I think it should still work.
I use the following commmands to setup the I2c
//I2C1 SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); //(m_Periferal); //SYSCTL_PERIPH_I2C0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); //(m_Port); //SYSCTL_PERIPH_GPIOB GPIOPinConfigure(GPIO_PA6_I2C1SCL); GPIOPinConfigure(GPIO_PA7_I2C1SDA); GPIOPinTypeI2C(SYSCTL_PERIPH_GPIOA, GPIO_PIN_6 | GPIO_PIN_7 ); //m_Port, m_ClockPin | m_DataPin); //SYSCTL_PERIPH_GPIOB, GPIO_PIN_2 | GPIO_PIN_3 I2CMasterInitExpClk(I2C1_MASTER_BASE, SysCtlClockGet(), false); //false = 100 Khz, true = 400KHz m_I2CBus I2CMasterEnable(I2C1_MASTER_BASE); //I2C0_MASTER_BASE
Then I have a send command function that gets called in the Main that should send I2C bytes.
int SendCommand(NanoMotionASICCommands commandCode, short int commandValue){ unsigned char buf[2];
unsigned long m_I2CBus = I2C1_MASTER_BASE;
if(commandCode < 1) return -1;
//printf("Writing Command: %d %d\n", commandCode, commandValue);
//Set Address Write I2CMasterSlaveAddrSet(m_I2CBus, ID_I2C_ADDR, false);
//Send Command Code Byte I2CMasterDataPut(m_I2CBus, commandCode); I2CMasterControl(m_I2CBus, I2C_MASTER_CMD_BURST_SEND_START); // I2C_MASTER_CMD_SINGLE_SENDwhile(I2CMasterBusy(m_I2CBus)); << Always get stuck here !!!!
//Divide Command Value into 2 bytes. Send in Little Endian (LSB first) memcpy(buf, &commandValue, 2);
I2CMasterDataPut(m_I2CBus, buf[0]); I2CMasterControl(m_I2CBus, I2C_MASTER_CMD_BURST_SEND_CONT); //I2C_MASTER_CMD_SINGLE_SEND while(I2CMasterBusy(m_I2CBus));
//Send Command Value I2CMasterDataPut(m_I2CBus, buf[1]); I2CMasterControl(m_I2CBus, I2C_MASTER_CMD_BURST_SEND_FINISH); // I2C_MASTER_CMD_SINGLE_SEND while(I2CMasterBusy(m_I2CBus));
return 0;}
Why is this the case? What would make it return busy always? Any suggestions?
Here is an extract from a TI I2C Slave ADC datasheet - expect it is helpful:
"Every byte transmitted on the I2C bus, whether it is address or data, is acknowledged with an acknowledge bit. When the master has finished sending a byte (eight data bits) to a slave, it stops driving SDA and waits for the slave to acknowledge the byte. The slave acknowledges the byte by pulling SDA low."
Thus your "test" of I2C - minus any connected, proper I2C device - appears doomed. Suggest that you acquire a small capacity EEprom - there is a past application note showing Stellaris "talking" to a small Atmel EEprom via I2C. (EEprom is about the simplest device to build confidence)
Also don't especially like your order of I2C transacting - a very recent forum post - blessed both by Stellaris Sue & independent forum user - provides I2C set-up/guidance from both TI responder and this reporter.
http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/p/169023/639164.aspx#639164
Suggest that you follow this basic guide - later refine/improve as/if you're able... Simplicity is your friend @ this stage...
Hi Stephen,
Can you please indicate which processor you are using?
Yes. Of course. I'm using the lm3s9d96. THanks for your help.
Hmm... I see. I didn't realize this. I'll try that out. Thanks. That was very helpful.
I'm using the lm3s9d96.
As CB1 points out, you won't get an ACK since there is no slave device. However, I would expect the busy status bit to toggle normally as long as the clock is not held low. The suggestion to simplify is always a good idea to isolate the problem. It would also be useful to see the full setup for the processor in your application code.
As a side note, there's a loopback bit in the MCR register if you want to test basic I2C code (examples of that are in the top level StellarisWare /examples directory).