Hello,
I have been having trouble assigning peripherals to an I2C driver on my STM32F407Discovery board. Specifically I am trying to use I2CD3 on pins PA8->SCL and PC9->SDA. I was under the impression that one could assign peripherals through the use of palSetPadMode like so:
palSetPadMode(GPIOC, 9U, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN); // data
palSetPadMode(GPIOA, 8U, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN); // clock
However, when I configure in this way, no signal is generated. I have enabled PAL and I2C in halconf.h and I have also enabled I2CD3 in mcuconf.h. I have also built the I2CConfig object like so:
static const I2CConfig i2cfg3 = {
OPMODE_I2C,
400000,
FAST_DUTY_CYCLE_2,
};
And finally, I have started the port like so:
i2cStart(&I2CD1, &i2cfg1);
Is there any further configuration, specifically related to peripheral assignment I am missing? I will include a copy of my main.c file to this post.
Any advise would be greatly appreciated. Thanks,
Connor
full main.c below
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "ch.h"
#include "hal.h"
/*
* I2C scanning thread
*/
static THD_WORKING_AREA(wai2cScanThread, 256);
static THD_FUNCTION(i2cScanThread, arg) {
(void)arg;
chRegSetThreadName("i2cScan");
chThdSleepMilliseconds(100);
/*
* Thread variables
*/
sysinterval_t timeout = TIME_MS2I(10);
uint8_t test_buffer[] = {1, 2, 3, 4};
/*
* i2c_scanning loop
*/
while (true) {
for (int i = 0; i < 128; i++) {
msg_t MSG = i2cMasterTransmitTimeout(&I2CD3, i, test_buffer, sizeof(test_buffer), NULL, 0, timeout);
/*
i2cflags_t POSSIBLE_ERROR = i2cGetErrors(&I2CD3);
if (MSG == MSG_OK){
palSetPad(GPIOD, GPIOD_LED4); // green led on
chThdSleepMilliseconds(1000);
palClearPad(GPIOD, GPIOD_LED4); // green led off
} else if (MSG == MSG_RESET) {
palSetPad(GPIOD, GPIOD_LED6); // blue led on
chThdSleepMilliseconds(50);
palClearPad(GPIOD, GPIOD_LED6); // blue led off
} else if (MSG == MSG_TIMEOUT) {
palSetPad(GPIOD, GPIOD_LED5); // red led on
chThdSleepMilliseconds(50);
palClearPad(GPIOD, GPIOD_LED5); // red led off
}
*/
chThdSleepMilliseconds(1);
}
chThdSleepMilliseconds(10);
}
}
/*
* Defines
*/
#define ADS1015_ADDR (0x48)
#define I2C3_SDA 9U //PC9
#define I2C3_SCL 8U //PA8
/*
* I2C configuration
*/
static const I2CConfig i2cfg = {
OPMODE_I2C,
400000,
FAST_DUTY_CYCLE_2,
};
/*
* Application entry point.
*/
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
/*
* Configure and activate the I2C peripheral
*/
palSetPadMode(GPIOC, 9U, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN); // data
palSetPadMode(GPIOA, 8U, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN); // clock
i2cStart(&I2CD3, &i2ccfg);
/*
* Creates the example thread.
*/
chThdCreateStatic(wai2cScanThread, sizeof(wai2cScanThread), NORMALPRIO, i2cScanThread, NULL);
/*
* main() thread
*/
while (true) {
/*
* Do nothing
*/
chThdSleepMilliseconds(10);
}
return 0;
}
HAL I2C pin assignment
-
- Posts: 6
- Joined: Mon Mar 08, 2021 8:48 pm
- Been thanked: 2 times
-
- Posts: 6
- Joined: Mon Mar 08, 2021 8:48 pm
- Been thanked: 2 times
Re: HAL I2C pin assignment
Quick Update.
I have confirmed that It is not a hardware issue as I have been able to establish and reconfigure the I2C1, 2, and 3 peripherals using other HAL libraries. After stepping into the entire configuration process while debugging I have observed that pieces of configuration protected by #ifdef statements pertaining to STM32_I2C_USE_I2Cx are being passed over even though these macros are enabled in mcuconf.h. I believe this main be a part of the problem.
If anyone have expierence with this issue/I2C please share. Thanks,
Connor
@Steve
You make a good point. I have noticed that in some example codes running I2C the developer neglected palSetPadMode commands prior to starting the I2C driver. This would suggest that when starting the I2C driver there are some default peripherals selected. Possibly my pin assignments are conflicting with the potential default assignments being made when calling i2cStart(&I2C3, &i2ccfg). I have no been able to determine where these potential defaults are configured or how to disable them. I will provide further updates as I progress.
I have confirmed that It is not a hardware issue as I have been able to establish and reconfigure the I2C1, 2, and 3 peripherals using other HAL libraries. After stepping into the entire configuration process while debugging I have observed that pieces of configuration protected by #ifdef statements pertaining to STM32_I2C_USE_I2Cx are being passed over even though these macros are enabled in mcuconf.h. I believe this main be a part of the problem.
If anyone have expierence with this issue/I2C please share. Thanks,
Connor
@Steve
You make a good point. I have noticed that in some example codes running I2C the developer neglected palSetPadMode commands prior to starting the I2C driver. This would suggest that when starting the I2C driver there are some default peripherals selected. Possibly my pin assignments are conflicting with the potential default assignments being made when calling i2cStart(&I2C3, &i2ccfg). I have no been able to determine where these potential defaults are configured or how to disable them. I will provide further updates as I progress.
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: HAL I2C pin assignment
ConnorBrisebois wrote:I have observed that pieces of configuration protected by #ifdef statements pertaining to STM32_I2C_USE_I2Cx are being passed over even though these macros are enabled in mcuconf.h. I believe this main be a part of the problem.
Hi,
I have not understood this part, could you be more specific about this?
Giovanni
-
- Posts: 6
- Joined: Mon Mar 08, 2021 8:48 pm
- Been thanked: 2 times
Re: HAL I2C pin assignment
Hi Giovanni,
I have since realized I was mistaken about that. I was looking at the wrong block of code while debugging. Currently I am trying to determine where/how peripheral assignments are preformed for the I2C drivers. For example when one enables and starts STM32_I2C_USE_I2C1, SDA is on pin PB9 while SCL is on PB6. Where is this assignment preformed?
Thanks,
Connor
I have since realized I was mistaken about that. I was looking at the wrong block of code while debugging. Currently I am trying to determine where/how peripheral assignments are preformed for the I2C drivers. For example when one enables and starts STM32_I2C_USE_I2C1, SDA is on pin PB9 while SCL is on PB6. Where is this assignment preformed?
Thanks,
Connor
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: HAL I2C pin assignment
There are who ways to assign pins:
1) In board.h there are all pin assignments performed soon after reset.
2) At runtime using palSetPadMode() like in that example.
Make sure to not do it in both places on different pins, like steved explained it can hang GPIOs. Verify your board.h first, if I remember well there are some I2C pins defined there, also, you need to use pins not used already on the board or you could have conflicts.
Giovanni
1) In board.h there are all pin assignments performed soon after reset.
2) At runtime using palSetPadMode() like in that example.
Make sure to not do it in both places on different pins, like steved explained it can hang GPIOs. Verify your board.h first, if I remember well there are some I2C pins defined there, also, you need to use pins not used already on the board or you could have conflicts.
Giovanni
-
- Posts: 6
- Joined: Mon Mar 08, 2021 8:48 pm
- Been thanked: 2 times
Re: HAL I2C pin assignment
Final Update:
After observing the GPIO registers and watching traces on my scope, I realized that external pull up resistors (2-10kOhms) are required when using all I2C ports (except I2CD1 connected to pins PB6 and PB9). It's important to note that if connection to the pull up resistor is disturbed the I2C driver with generate a MSG_RESET error if a write occurrence is attempted. If this error is encountered you will need to re-initialize the I2C driver in question.
Thanks all,
Connor
After observing the GPIO registers and watching traces on my scope, I realized that external pull up resistors (2-10kOhms) are required when using all I2C ports (except I2CD1 connected to pins PB6 and PB9). It's important to note that if connection to the pull up resistor is disturbed the I2C driver with generate a MSG_RESET error if a write occurrence is attempted. If this error is encountered you will need to re-initialize the I2C driver in question.
Thanks all,
Connor
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: HAL I2C pin assignment
It is because those pins have already pull-ups on the board, anyway, glad you solved.
Giovanni
Giovanni
Who is online
Users browsing this forum: No registered users and 5 guests