Page 1 of 1

I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 4:18 am
by Abusous2000
I wonder if you can help me. I have been spinning my wheels for the past few days trying to get the CODEC in STM32L476-Discovery board to respond, and always I get ACK FAIL error (or 4 I2C_ISR_NACKF in interrupt). I have code reviewed the internals of ChibiOS' I2C HAL driver and it looks solid. But I don't know what is the problem. It should be noted that:
- If I program bare metal (via I2C polling), it works.
- If I program via STM32L4 HAL driver using interrupts, it works.
- I've tested ChibiOS with I2C with DMA and without DMA (via interrupts), still I could not get it to work.
- I get the same result irrespective if I use ChibiOS 19.1 or 18.2
- Same result even if I comment out all board initialization in board.c and I initialize the pins manually, still the same result
- I tried several variations for the clocks configurations, turned on all debugging, pull up and open drain for the I2C pins, still it didn't work.
- the same program works for STM342F4 Discovery from the get go
I looked hard for any examples for STM32L4 with I2C, and I found nothing. Can you please point me some where where there is an I2C example for the STM32L4XX? I am at a lose here.
Many thanks
I will appreciate any help. I am at a lose here. Here is my program, it is VERY simple. Nothing fancy
[nfo]#include "ch.h"
#include "hal.h"
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

(void)arg;
chRegSetThreadName("blinker");
while (true) {
palClearLine(LINE_LED_GREEN);
chThdSleepMilliseconds(550);
palSetLine(LINE_LED_GREEN);
chThdSleepMilliseconds(500);
}
}
#define CODEC_ADDRESS 0x4A

static I2CConfig i2cfg_1 = {
STM32_TIMINGR_PRESC(15U) |
STM32_TIMINGR_SCLDEL(4) | STM32_TIMINGR_SDADEL(2U) |
STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),//0xf0420f15
0,//I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_STOPI | I2C_IT_NACKI | I2C_IT_TXI,
0
};
int main(void) {
msg_t result = 0;
uint8_t txbuf[2];
uint8_t rxbuf[2];
i2cflags_t flagsError = 0;

halInit();
chSysInit();
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_FAST | PAL_STM32_PUPDR_PULLUP); //SCL = PB6 -> I2CD1
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_FAST | PAL_STM32_PUPDR_PULLUP);
result = 0;
flagsError = 0;

i2cStart(&I2CD1, &i2cfg_1);
//Get CODEC device ID, 0xE0 is expected
txbuf[0]=0x01; txbuf[1]=0x00;
result=i2cMasterTransmitTimeout(&I2CD1, CODEC_ADDRESS, txbuf, 1 ,rxbuf, 1, 1000);
if ( !result)
result=i2cMasterReceiveTimeout(&I2CD1, CODEC_ADDRESS, rxbuf, 1 ,1000);
if ( result != 0 ){
flagsError=i2cGetErrors(&I2CD1);
palToggleLine(LINE_LED_RED);
}
//sdStart(&SD2, NULL);
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
while (true) {
if (palReadLine(LINE_JOY_CENTER)) {
//chprintf(chp, "***LINE_JOY_CENTER Pressed\r\n");
}
chThdSleepMilliseconds(500);
}
}[/nfo]

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 7:52 am
by Giovanni
Hi,

What address are you using? in ChibiOS the "address" is just the 7 bits address field without the R/W bit. Divide the address byte value by two.

Giovanni

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 2:43 pm
by Abusous2000
Giovanni wrote:What address are you using?
Giovanni

Thanks for the quick reply Giovanni. I passed to ChibiOS the address 0x4A by dividing the CODED address of 0x94 by two. Most importantly the same code works but for STM32F4 Discovery which has the same CS43L22 CODEC, I just changed the SDA to port B9.

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 3:18 pm
by Giovanni
Hi,

Some things to check:

1) F4 and L4 use a different I2C (I2Cv1 vs I2Cv2) so your configuration structure is different, make sure you got a valid configuration for I2Cv2.
2) GPIO settings, check that the correct alternate modes are selected and that I2C pins are only configured on ONE GPIO pin.
3) External pull up resistors.

Giovanni

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 6:52 pm
by Abusous2000
Giovanni wrote:Hi Giovanni,
1) F4 and L4 use a different I2C (I2Cv1 vs I2Cv2) so your configuration structure is different, make sure you got a valid configuration for I2Cv2.
2) GPIO settings, check that the correct alternate modes are selected and that I2C pins are only configured on ONE GPIO pin.
Giovanni

YES I am aware it, otherwise the code wouldn't even compile. As follows, the 1st is for the I2Cv2 Config Structure
[nfo]static I2CConfig i2cfg_1 = {
STM32_TIMINGR_PRESC(15U) |
STM32_TIMINGR_SCLDEL(4) | STM32_TIMINGR_SDADEL(2U) |
STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),//0xf0420f15
0,
0
};[/nfo]
this is for the I2C pins
[nfo]palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_FAST | PAL_STM32_PUPDR_PULLUP);// tried open drain too
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_FAST | PAL_STM32_PUPDR_PULLUP);[/nfo]
and I connected PB6 and PB7 each to an external 4.7k resistor on one end, and the other end of each resister to connected to 3.3V
It SHOULD BE NOTED that if code bare metal I2C (or STM32L4 HAL driver) via Polling or Interrupts, it works with or without external pull up resistors. I am at a loss here. If you have any working example for ChibiOS with STM32L476 Discovery, I would appreciate it.
Many thanks in advance, I am big fan of ChibiOS

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 7:28 pm
by Giovanni
I don't have examples with L4 but it should be the same of other devices using I2Cv2.

Both pins must be open drain. I think you should observe signals with a logic analyzer to understand what's the problem.

Giovanni

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 8:14 pm
by Abusous2000
Thanks again Giovanni. YES, I tested with Open Drain for the pins, and still no luck. Below is my result from the logic analyzer, the 1st with ChibiOS, and the second from bare metal I2C driver (it looks fine)
I will keep working on it, and if I have any luck, I will post what I found.
Many thanks Giovanni for your help

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 8:33 pm
by Giovanni
The address is sent as zero, strange, I wonder what could cause that. Of course there is no ACK and the transaction stops there.

Anyway, you need to set those pins open drain, it is not an option, I2C works that way.

Giovanni

Re: I2C with STM32L476 Discovery responds with ACK Fail

Posted: Mon Jul 08, 2019 9:02 pm
by Abusous2000
I just retested but with open drain, that did the trick. I am bad Giovanni.

Many thx that did the trick man.