From 7bb501ef9f724e9ecd209d1fa46b640214928d2a Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Wed, 10 Feb 2016 21:20:14 -0800 Subject: [PATCH] stmhal: Add a function for setting the pin alternate function mp_hal_gpio_set_af will search for a given function and unit and set the alternate function to the alternate function index found. --- stmhal/i2c.c | 34 +++++++++++++++------------------- stmhal/mphalport.c | 14 ++++++++++++++ stmhal/mphalport.h | 2 ++ stmhal/pin.h | 6 ++++++ 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/stmhal/i2c.c b/stmhal/i2c.c index 263ac9ab2..e52db0170 100644 --- a/stmhal/i2c.c +++ b/stmhal/i2c.c @@ -217,32 +217,30 @@ void i2c_init(I2C_HandleTypeDef *i2c) { GPIO_InitStructure.Speed = GPIO_SPEED_FAST; GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines - const pyb_i2c_obj_t *self; - const pin_obj_t *pins[2]; + int i2c_unit; + const pin_obj_t *scl_pin; + const pin_obj_t *sda_pin; if (0) { #if defined(MICROPY_HW_I2C1_SCL) } else if (i2c == &I2CHandle1) { - self = &pyb_i2c_obj[0]; - pins[0] = &MICROPY_HW_I2C1_SCL; - pins[1] = &MICROPY_HW_I2C1_SDA; - GPIO_InitStructure.Alternate = GPIO_AF4_I2C1; + i2c_unit = 1; + scl_pin = &MICROPY_HW_I2C1_SCL; + sda_pin = &MICROPY_HW_I2C1_SDA; __I2C1_CLK_ENABLE(); #endif #if defined(MICROPY_HW_I2C2_SCL) } else if (i2c == &I2CHandle2) { - self = &pyb_i2c_obj[1]; - pins[0] = &MICROPY_HW_I2C2_SCL; - pins[1] = &MICROPY_HW_I2C2_SDA; - GPIO_InitStructure.Alternate = GPIO_AF4_I2C2; + i2c_unit = 2; + scl_pin = &MICROPY_HW_I2C2_SCL; + sda_pin = &MICROPY_HW_I2C2_SDA; __I2C2_CLK_ENABLE(); #endif #if defined(MICROPY_HW_I2C3_SCL) } else if (i2c == &I2CHandle3) { - self = &pyb_i2c_obj[2]; - pins[0] = &MICROPY_HW_I2C3_SCL; - pins[1] = &MICROPY_HW_I2C3_SDA; - GPIO_InitStructure.Alternate = GPIO_AF4_I2C3; + i2c_unit = 3; + scl_pin = &MICROPY_HW_I2C3_SCL; + sda_pin = &MICROPY_HW_I2C3_SDA; __I2C3_CLK_ENABLE(); #endif } else { @@ -251,11 +249,8 @@ void i2c_init(I2C_HandleTypeDef *i2c) { } // init the GPIO lines - for (uint i = 0; i < 2; i++) { - mp_hal_gpio_clock_enable(pins[i]->gpio); - GPIO_InitStructure.Pin = pins[i]->pin_mask; - HAL_GPIO_Init(pins[i]->gpio, &GPIO_InitStructure); - } + mp_hal_gpio_set_af(scl_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit); + mp_hal_gpio_set_af(sda_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit); // init the I2C device if (HAL_I2C_Init(i2c) != HAL_OK) { @@ -267,6 +262,7 @@ void i2c_init(I2C_HandleTypeDef *i2c) { } // invalidate the DMA channels so they are initialised on first use + const pyb_i2c_obj_t *self = &pyb_i2c_obj[i2c_unit - 1]; dma_invalidate_channel(self->tx_dma_stream, self->tx_dma_channel); dma_invalidate_channel(self->rx_dma_stream, self->rx_dma_channel); } diff --git a/stmhal/mphalport.c b/stmhal/mphalport.c index 147a8682d..3fd4395d6 100644 --- a/stmhal/mphalport.c +++ b/stmhal/mphalport.c @@ -118,3 +118,17 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) { #endif } } + +bool mp_hal_gpio_set_af(const pin_obj_t *pin, GPIO_InitTypeDef *init, uint8_t fn, uint8_t unit) { + mp_hal_gpio_clock_enable(pin->gpio); + + const pin_af_obj_t *af = pin_find_af(pin, fn, unit); + if (af == NULL) { + return false; + } + init->Pin = pin->pin_mask; + init->Alternate = af->idx; + HAL_GPIO_Init(pin->gpio, init); + + return true; +} diff --git a/stmhal/mphalport.h b/stmhal/mphalport.h index 652f1e7be..5373eb45a 100644 --- a/stmhal/mphalport.h +++ b/stmhal/mphalport.h @@ -1,5 +1,6 @@ // We use the ST Cube HAL library for most hardware peripherals #include STM32_HAL_H +#include "pin.h" // The unique id address differs per MCU. Ideally this define should // go in some MCU-specific header, but for now it lives here. @@ -23,6 +24,7 @@ #define GPIO_read_output_pin(gpio, pin) (((gpio)->ODR >> (pin)) & 1) void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio); +bool mp_hal_gpio_set_af(const pin_obj_t *pin, GPIO_InitTypeDef *init, uint8_t fn, uint8_t unit); extern const unsigned char mp_hal_status_to_errno_table[4]; diff --git a/stmhal/pin.h b/stmhal/pin.h index 492803871..df7df0ce2 100644 --- a/stmhal/pin.h +++ b/stmhal/pin.h @@ -24,10 +24,14 @@ * THE SOFTWARE. */ +#ifndef __MICROPY_INCLUDED_STMHAL_PIN_H__ +#define __MICROPY_INCLUDED_STMHAL_PIN_H__ + // This file requires pin_defs_xxx.h (which has port specific enums and // defines, so we include it here. It should never be included directly #include MICROPY_PIN_DEFS_PORT_H +#include "py/obj.h" typedef struct { mp_obj_base_t base; @@ -93,3 +97,5 @@ const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t na const pin_af_obj_t *pin_find_af(const pin_obj_t *pin, uint8_t fn, uint8_t unit); const pin_af_obj_t *pin_find_af_by_index(const pin_obj_t *pin, mp_uint_t af_idx); const pin_af_obj_t *pin_find_af_by_name(const pin_obj_t *pin, const char *name); + +#endif // __MICROPY_INCLUDED_STMHAL_PIN_H__