HAL I2C pin assignment
Posted: Mon Mar 22, 2021 10:29 pm
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;
}
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;
}