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.
This commit is contained in:
Dave Hylands 2016-02-10 21:20:14 -08:00
parent e372e83b30
commit 7bb501ef9f
4 changed files with 37 additions and 19 deletions

View File

@ -217,32 +217,30 @@ void i2c_init(I2C_HandleTypeDef *i2c) {
GPIO_InitStructure.Speed = GPIO_SPEED_FAST; GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines
const pyb_i2c_obj_t *self; int i2c_unit;
const pin_obj_t *pins[2]; const pin_obj_t *scl_pin;
const pin_obj_t *sda_pin;
if (0) { if (0) {
#if defined(MICROPY_HW_I2C1_SCL) #if defined(MICROPY_HW_I2C1_SCL)
} else if (i2c == &I2CHandle1) { } else if (i2c == &I2CHandle1) {
self = &pyb_i2c_obj[0]; i2c_unit = 1;
pins[0] = &MICROPY_HW_I2C1_SCL; scl_pin = &MICROPY_HW_I2C1_SCL;
pins[1] = &MICROPY_HW_I2C1_SDA; sda_pin = &MICROPY_HW_I2C1_SDA;
GPIO_InitStructure.Alternate = GPIO_AF4_I2C1;
__I2C1_CLK_ENABLE(); __I2C1_CLK_ENABLE();
#endif #endif
#if defined(MICROPY_HW_I2C2_SCL) #if defined(MICROPY_HW_I2C2_SCL)
} else if (i2c == &I2CHandle2) { } else if (i2c == &I2CHandle2) {
self = &pyb_i2c_obj[1]; i2c_unit = 2;
pins[0] = &MICROPY_HW_I2C2_SCL; scl_pin = &MICROPY_HW_I2C2_SCL;
pins[1] = &MICROPY_HW_I2C2_SDA; sda_pin = &MICROPY_HW_I2C2_SDA;
GPIO_InitStructure.Alternate = GPIO_AF4_I2C2;
__I2C2_CLK_ENABLE(); __I2C2_CLK_ENABLE();
#endif #endif
#if defined(MICROPY_HW_I2C3_SCL) #if defined(MICROPY_HW_I2C3_SCL)
} else if (i2c == &I2CHandle3) { } else if (i2c == &I2CHandle3) {
self = &pyb_i2c_obj[2]; i2c_unit = 3;
pins[0] = &MICROPY_HW_I2C3_SCL; scl_pin = &MICROPY_HW_I2C3_SCL;
pins[1] = &MICROPY_HW_I2C3_SDA; sda_pin = &MICROPY_HW_I2C3_SDA;
GPIO_InitStructure.Alternate = GPIO_AF4_I2C3;
__I2C3_CLK_ENABLE(); __I2C3_CLK_ENABLE();
#endif #endif
} else { } else {
@ -251,11 +249,8 @@ void i2c_init(I2C_HandleTypeDef *i2c) {
} }
// init the GPIO lines // init the GPIO lines
for (uint i = 0; i < 2; i++) { mp_hal_gpio_set_af(scl_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit);
mp_hal_gpio_clock_enable(pins[i]->gpio); mp_hal_gpio_set_af(sda_pin, &GPIO_InitStructure, AF_FN_I2C, i2c_unit);
GPIO_InitStructure.Pin = pins[i]->pin_mask;
HAL_GPIO_Init(pins[i]->gpio, &GPIO_InitStructure);
}
// init the I2C device // init the I2C device
if (HAL_I2C_Init(i2c) != HAL_OK) { 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 // 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->tx_dma_stream, self->tx_dma_channel);
dma_invalidate_channel(self->rx_dma_stream, self->rx_dma_channel); dma_invalidate_channel(self->rx_dma_stream, self->rx_dma_channel);
} }

View File

@ -118,3 +118,17 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
#endif #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;
}

View File

@ -1,5 +1,6 @@
// We use the ST Cube HAL library for most hardware peripherals // We use the ST Cube HAL library for most hardware peripherals
#include STM32_HAL_H #include STM32_HAL_H
#include "pin.h"
// The unique id address differs per MCU. Ideally this define should // The unique id address differs per MCU. Ideally this define should
// go in some MCU-specific header, but for now it lives here. // 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) #define GPIO_read_output_pin(gpio, pin) (((gpio)->ODR >> (pin)) & 1)
void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio); 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]; extern const unsigned char mp_hal_status_to_errno_table[4];

View File

@ -24,10 +24,14 @@
* THE SOFTWARE. * 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 // 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 // defines, so we include it here. It should never be included directly
#include MICROPY_PIN_DEFS_PORT_H #include MICROPY_PIN_DEFS_PORT_H
#include "py/obj.h"
typedef struct { typedef struct {
mp_obj_base_t base; 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(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_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); const pin_af_obj_t *pin_find_af_by_name(const pin_obj_t *pin, const char *name);
#endif // __MICROPY_INCLUDED_STMHAL_PIN_H__