cancel
Showing results for 
Search instead for 
Did you mean: 

ST9+ I2C

sandra
Associate II
Posted on April 01, 2003 at 22:55

ST9+ I2C

13 REPLIES 13
scott239955
Associate II
Posted on May 17, 2011 at 11:32

I have been trying to get the I2C peripheral to work in master mode on the ST92F150 emulator for some time now and am still having problems. I took the sample code provided (thanks) and modified it to work with my EEPROM 24LC

I get all of the interrupts (EV5 to event eight), but I have to stop the program with breakpoints at a couple places and I still do not get the correct data. I'm writing one byte to address zero, then reading it back by writting the memory address with out a STOP bit, and then generate a START again and do the read. I do not send an ACK back after receiving the one byte becasue this is the last (and only) byte to read and a STOP is generated instead. I had a few specific questions maybe some one can answer:

1. BTF flag on Tx: on transmission, the BTF flag is set after receiving an ACK, and cleared after reading I2CSR1 and writing to I2CDR. If done transmitting and the STOP flag is set, do you still have to write to the I2CDR to clear the event flag?

2. BTF flag on Rx: after reception, the BTF flag is set after transmitting an ACK if ACK=1. If ACK does not equal one, does the bit still get set on reception? The last byte read does not get an ACK (for the EEPROM.)

3. It seems like I probably have a timing problem - I'm not sure how much of the I2C hardware interface takes care of timing when using interrupts. Do I need to put delays in various places? If I do not put the breakpoints in that I mentioned, I do not get most interrupts.

4. Busy and generating a START: I started to think about the EEPROM requirements for a random read and realized that according to the documentation, I should not be able to generate a START unless a STOP was previously generated for sending the address. The documentation states that a START is generated when the bus is not busy, and the time the bus is busy is defined as the time between when a START is generated and a STOP is generated. Again, the EERPOM requires the address to be sent to it and then one more START to transfer the data to be read (see attached.)

[ This message was edited by: Smiles on 19-03-2003 19:15 ]

johanpauvert2
Associate II
Posted on May 17, 2011 at 11:32

1. This one is easy to test

Requesting a stop will clear the event flags

2. In your case, it is up to the ST9 to acknowlede for the reception. So, if the byte is correctly received, there is BTF and acknowledge events.

Otherwise, no BTF and the ST9 will not acknowledge

3. No delay

4. No question !

Skywalker
Posted on May 17, 2011 at 11:32

Nick, find a I2C with DMA example.

Jojo

scott239955
Associate II
Posted on May 17, 2011 at 11:32

Thank you for responding. I have since been able to write and read back bytes from the EEPROM, but still am having issues. I attached my code. It basically is the same as the previous sample code, except I broke the flag checking in i2_isr() function up into their specific interruptus. In other words, I am only testing for conditions that may have caused the specific interrupts:

1. Ok.

2. In my attached code at first I kept track of the bytes received and when there was only 1 byte left, I disable the ACK so that the next byte received (the last byte) does not get an ACK, and a STOP is then generated instead. Otherwise, since the interrupt is generated because the ACK was sent (according to data sheet), I would expect the EEPROM to send another byte because it was acknowledged. However, I remove this section and replaced it with a STOP and it works ok. I'm not sure why it works like this though. Does anyone understand why?

3. In the attached code, if I remove the delay in main() between the write and the read, I do not get the correct data read. I thought removing the delay would work because the START bit would be set and then an AF would be generated. In the error interrupt, I set the START bit...this would repeat until the write cycle was finished. At that time the EEPROM would send an ACK and then the process would proceed. Does not work though. I get a lot of AFs, but no data read?

4. I am questioning the ability of the peripheral to send a repeated start. It seems like this is not possible. In other words, you can not generate a START before generating a STOP when a previous START has been sent. An example of this is the random read in the previous attached file. Does anyone agree? In my code I too ended up generating a STOP after writing the memory address that I want to read from. This seems to work. I'm wondering if it cause the EEPROM to perform a longer read cycle by sending it a STOP like that?

I also noticed that putting break points into the code cause different results than if the read and write cycles are allowed to complete. this is why I have the variables in the code that count the bytes, control words, and address sent.

Note: On my same application board I am using a real time clock with an I2C interface (ST M41T00). In order to get it to work, I had to un-remark the two lines of code (described in (2) above ) that disabled the interface from generating an ACK before the last byte read. In other words, the M41T00 did not work unless the ACK was disabled before receiving the last byte.

[ This message was edited by: Smiles on 06-04-2003 00:17 ]