6
votes

I am currently trying to get a pair of stm32l152 (discovery kit) to communicate via I2C. (i am not using the standard peripheral library provided by STM as i want to try to implement the i2c myself..)

My configuration is as followed:

  • 7-bit addressing mode (no dual address, only OAR1)

  • 100khz speed

  • ACK enabled (on slave)

  • ACK disabled (on master, since only 1 byte is transferred between master/slave at any time)

  • on both master/slave, using GPIOB (PB10) as SCL and GPIOB (PB11) as SDA

Here's the weird part: when i configure the 2 GPIOB pins as push-pull (no pullup/down), i am able to see my master send out the start bit, address byte.. on the oscilloscope.

But my slave is not sending back an acknowledgement. i know this for sure because the master did not assert ADDR bit in SR1, i see no ack on the scope and also the slave did not go into interrupt ( i enabled I2C event interrupt on the slave).

on closer look at the waveform on the scope, i realised the signal (both SCL, SDA) did not fully go to 0Volts for logic low, they are at 1 volts instead. i am guessing this maybe why the slave cannot read the address byte from the master and therefore did not send back ack.

So i configure the 2 GPIO pins to be open-drain (no pullup/down)..but now my master cannot send out the start bit.. i step through the code and saw that the master's SB bit in SR1 is set when i set the START bit.. but i do not see the any response on the SDA and SCL signals on the scope (both are high at 3V).

(i pulled both SCL and SDA to 3v using 10kohms on each line).

1

1 Answers

7
votes

ok, i think i found the answer.. I looked up the standard peripheral library provided by STM and followed their configuration sequence. Before that, i was using the wrong sequence of configuring the GPIO ports...

The sequence tested to be working is:

  1. Enable i2c and GPIOs clocks.

  2. Configure the desired AF of the ports. (AF4 for i2c in stm32).

  3. Configure GPIOs:

    3a. set GPIOs as AF.

    3b. set port speed.

    3c. set port type (open-drain).

    3d. set to no pull-up/pull-down.

  4. Configure i2c. (registers CR2, CCR, CR1, OAR1, ...).

Previously, i was doing step 3 BEFORE step 2, and there is no output from the ports when i generated the START bit.

Hope this helps those who have the same problem.