Only one I2C bus responding
Moderator: RoccoMarco
Only one I2C bus responding
Hi,
I am only able to get one of the I2C bus interfaces working on an STM32F4 discovery board. The I2CD1 driver works fine, but I2CD2 and I2CD3 show no activity on the I/O pins. Has anyone else come across this? Or able to see what I am doing wrong?
Here is the code I am using https://gist.github.com/johnhowe/5588359
Cheers,
John
I am only able to get one of the I2C bus interfaces working on an STM32F4 discovery board. The I2CD1 driver works fine, but I2CD2 and I2CD3 show no activity on the I/O pins. Has anyone else come across this? Or able to see what I am doing wrong?
Here is the code I am using https://gist.github.com/johnhowe/5588359
Cheers,
John
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Only one I2C bus responding
Hi,
You need to reconfigure the related pins to the appropriate alternate mode, this is done in board.h or, alternatively, in your application using the PAL driver "change mode" functions.
Second potential problem, DMA conflicts, make sure that the I2C DMA channels are not used by other peripherals, in mcuconf.h.
Giovanni
You need to reconfigure the related pins to the appropriate alternate mode, this is done in board.h or, alternatively, in your application using the PAL driver "change mode" functions.
Second potential problem, DMA conflicts, make sure that the I2C DMA channels are not used by other peripherals, in mcuconf.h.
Giovanni
Re: Only one I2C bus responding
Thanks Giovanni, I hadn't set the alternate pad modes. I was following the code example in /testhal/STM32F4xx/I2C/ which doesn't include that step.
John
John
I2C woes
Hi again,
Carrying on from this, I now have the I2C bus mostly working except for some reason the final received packet will always NAK. Here is what I am doing https://gist.github.com/johnhowe/05839338f1e20ba747a5, which in short is just:
and here is what I am seeing on the bus

Is anyone please able to point me in the right direction here?
Cheers,
John
Carrying on from this, I now have the I2C bus mostly working except for some reason the final received packet will always NAK. Here is what I am doing https://gist.github.com/johnhowe/05839338f1e20ba747a5, which in short is just:
Code: Select all
i2cAcquireBus(cfg->driver);
i2cMasterTransmitTimeout(cfg->driver, *cfg->addr, txBuf, 1, rxBuf, 6, timeout);
i2cReleaseBus(cfg->driver);
and here is what I am seeing on the bus

Is anyone please able to point me in the right direction here?
Cheers,
John
Re: Only one I2C bus responding
Ah, reading into the data sheet:
So it is working as it should. Sorry for the noise.
John
The master sends a NACK for the last byte received from the slave. After receiving this
NACK, the slave releases the control of the SCL and SDA lines. Then the master can send
a Stop/Restart condition.
So it is working as it should. Sorry for the noise.
John
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Only one I2C bus responding
HI,
No problems, it still goes into the knowledge base that is this forum
Giovanni
No problems, it still goes into the knowledge base that is this forum
Giovanni
Re: Only one I2C bus responding
Hi,
I found this thread while googeling since I'm having the same problem as described by johntramp.
Even though I also know that I have to set the appropriate alternate pin modes to make the I2C interfaces work, I have absolutely no clue which value in the function PAL_MODE_ALTERNATE(X) I have to set. For I2CD1 PAL_MODE_ALTERNATE(4) works fine but for the other I2C Drivers, this seems not to be the correct value.
Can somebody help me out with an explanation what the single values are representing?
Greetings,
Pascal
I found this thread while googeling since I'm having the same problem as described by johntramp.
Even though I also know that I have to set the appropriate alternate pin modes to make the I2C interfaces work, I have absolutely no clue which value in the function PAL_MODE_ALTERNATE(X) I have to set. For I2CD1 PAL_MODE_ALTERNATE(4) works fine but for the other I2C Drivers, this seems not to be the correct value.
Can somebody help me out with an explanation what the single values are representing?
Greetings,
Pascal
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Only one I2C bus responding
Hi,
Each pin can have up to 16 alternate modes, the table is in the Data Sheet.
Giovanni
Each pin can have up to 16 alternate modes, the table is in the Data Sheet.
Giovanni
Re: Only one I2C bus responding
Hi everyone,
I looked up the modes in the STM32F4 datasheet (thanks to Giovanni for that hint) but the problem still keeps bothering me. Maybe someone can come up with a clue if I post my configuration (just the important parts):
main.c:
static const I2CConfig i2cfg3 = {
OPMODE_I2C,
400000,
FAST_DUTY_CYCLE_2,
};
int main(void){
halInit();
chSysInit();
tmObjectInit(&dt);
i2cStart(&I2CD3, &i2cfg3);
palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); //SCL
palSetPadMode(GPIOC, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); //SDA
txbuf[0] = HMC_CTRL_1;
txbuf[1] = 0b01111000;
i2cAcquireBus(&I2CD3);
status = i2cMasterTransmitTimeout(&I2CD1, hmc5883l_write_addr, txbuf, 2, rxbuf, 0, tmo);
i2cReleaseBus(&I2CD3);
}
mcuconf.h:
#define STM32_I2C_USE_I2C1 TRUE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_USE_I2C3 TRUE
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_I2C_I2C1_IRQ_PRIORITY 5
#define STM32_I2C_I2C2_IRQ_PRIORITY 5
#define STM32_I2C_I2C3_IRQ_PRIORITY 5
#define STM32_I2C_I2C1_DMA_PRIORITY 3
#define STM32_I2C_I2C2_DMA_PRIORITY 3
#define STM32_I2C_I2C3_DMA_PRIORITY 3
#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
The status variable has the value -1 after executing i2cMasterTransmitTimeout. When using the function i2cGetErrors(&I2CD3) it returns a 0.
It would be great if someone could give me a hint why this is just not working because I have not a clue anymore (the board is completely intact since I checked the code with another STM32F4 and it still did not work).
Greetings,
Pascal
I looked up the modes in the STM32F4 datasheet (thanks to Giovanni for that hint) but the problem still keeps bothering me. Maybe someone can come up with a clue if I post my configuration (just the important parts):
main.c:
static const I2CConfig i2cfg3 = {
OPMODE_I2C,
400000,
FAST_DUTY_CYCLE_2,
};
int main(void){
halInit();
chSysInit();
tmObjectInit(&dt);
i2cStart(&I2CD3, &i2cfg3);
palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); //SCL
palSetPadMode(GPIOC, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); //SDA
txbuf[0] = HMC_CTRL_1;
txbuf[1] = 0b01111000;
i2cAcquireBus(&I2CD3);
status = i2cMasterTransmitTimeout(&I2CD1, hmc5883l_write_addr, txbuf, 2, rxbuf, 0, tmo);
i2cReleaseBus(&I2CD3);
}
mcuconf.h:
#define STM32_I2C_USE_I2C1 TRUE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_USE_I2C3 TRUE
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7)
#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#define STM32_I2C_I2C1_IRQ_PRIORITY 5
#define STM32_I2C_I2C2_IRQ_PRIORITY 5
#define STM32_I2C_I2C3_IRQ_PRIORITY 5
#define STM32_I2C_I2C1_DMA_PRIORITY 3
#define STM32_I2C_I2C2_DMA_PRIORITY 3
#define STM32_I2C_I2C3_DMA_PRIORITY 3
#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt()
#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt()
The status variable has the value -1 after executing i2cMasterTransmitTimeout. When using the function i2cGetErrors(&I2CD3) it returns a 0.
It would be great if someone could give me a hint why this is just not working because I have not a clue anymore (the board is completely intact since I checked the code with another STM32F4 and it still did not work).
Greetings,
Pascal
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times