Commit ff91156d authored by Damien George's avatar Damien George
Browse files

stmhal: Improved configurability for I2C and SPI busses.

The HAL handles for the I2C/SPI objects are rather large, so we don't
want to unnecessarily include them.
parent 2b925d76
......@@ -12,6 +12,8 @@
#include "i2c.h"
#include "accel.h"
#if MICROPY_HW_HAS_MMA7660
#define MMA_ADDR (0x98)
#define MMA_REG_X (0)
#define MMA_REG_Y (1)
......@@ -174,3 +176,5 @@ const mp_obj_type_t pyb_accel_type = {
.make_new = pyb_accel_make_new,
.locals_dict = (mp_obj_t)&pyb_accel_locals_dict,
};
#endif // MICROPY_HW_HAS_MMA7660
......@@ -17,8 +17,9 @@
#define MICROPY_HW_ENABLE_TIMER (1)
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_DAC (0)
#define MICROPU_HW_ENABLE_I2C1 (0)
#define MICROPU_HW_ENABLE_SPI1 (0)
#define MICROPY_HW_ENABLE_I2C1 (0)
#define MICROPY_HW_ENABLE_SPI1 (0)
#define MICROPY_HW_ENABLE_SPI3 (0)
// USRSW is pulled low. Pressing the button makes the input go high.
#define MICROPY_HW_USRSW_PIN (pin_B11)
......
......@@ -13,6 +13,9 @@
#define MICROPY_HW_ENABLE_TIMER (1)
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_DAC (1)
#define MICROPY_HW_ENABLE_I2C1 (1)
#define MICROPY_HW_ENABLE_SPI1 (1)
#define MICROPY_HW_ENABLE_SPI3 (0)
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
#define MICROPY_HW_USRSW_PIN (pin_B3)
......
......@@ -13,6 +13,9 @@
#define MICROPY_HW_ENABLE_TIMER (1)
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_DAC (0)
#define MICROPY_HW_ENABLE_I2C1 (1)
#define MICROPY_HW_ENABLE_SPI1 (1)
#define MICROPY_HW_ENABLE_SPI3 (0)
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
#define MICROPY_HW_USRSW_PIN (pin_A13)
......
......@@ -13,6 +13,9 @@
#define MICROPY_HW_ENABLE_TIMER (1)
#define MICROPY_HW_ENABLE_SERVO (1)
#define MICROPY_HW_ENABLE_DAC (1)
#define MICROPY_HW_ENABLE_I2C1 (1)
#define MICROPY_HW_ENABLE_SPI1 (1)
#define MICROPY_HW_ENABLE_SPI3 (0)
// USRSW has no pullup or pulldown, and pressing the switch makes the input go low
#define MICROPY_HW_USRSW_PIN (pin_B3)
......@@ -20,7 +23,7 @@
#define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_FALLING)
#define MICROPY_HW_USRSW_PRESSED (0)
// LEDs
// The pyboard has 4 LEDs
#define MICROPY_HW_LED1 (pin_A13) // red
#define MICROPY_HW_LED2 (pin_A14) // green
#define MICROPY_HW_LED3 (pin_A15) // yellow
......
......@@ -13,6 +13,9 @@
#define MICROPY_HW_ENABLE_TIMER (1)
#define MICROPY_HW_ENABLE_SERVO (0)
#define MICROPY_HW_ENABLE_DAC (0)
#define MICROPY_HW_ENABLE_I2C1 (1)
#define MICROPY_HW_ENABLE_SPI1 (1)
#define MICROPY_HW_ENABLE_SPI3 (0)
// USRSW is pulled low. Pressing the button makes the input go high.
#define MICROPY_HW_USRSW_PIN (pin_A0)
......
......@@ -13,17 +13,17 @@
#include "genhdr/pins.h"
#include "i2c.h"
#if !defined(MICROPU_HW_ENABLE_I2C1)
#define MICROPY_HW_ENABLE_I2C1 (1)
#endif
#if MICROPY_HW_ENABLE_I2C1
I2C_HandleTypeDef I2CHandle1 = {.Instance = NULL};
#endif
I2C_HandleTypeDef I2CHandle2 = {.Instance = NULL};
void i2c_init0(void) {
// reset the I2C1 handles
#if MICROPY_HW_ENABLE_I2C1
memset(&I2CHandle1, 0, sizeof(I2C_HandleTypeDef));
I2CHandle1.Instance = I2C1;
#endif
memset(&I2CHandle2, 0, sizeof(I2C_HandleTypeDef));
I2CHandle2.Instance = I2C2;
}
......@@ -36,23 +36,26 @@ void i2c_init(I2C_HandleTypeDef *i2c) {
GPIO_InitStructure.Pull = GPIO_NOPULL; // have external pull-up resistors on both lines
const pin_obj_t *pins[2];
if (0) {
#if MICROPY_HW_ENABLE_I2C1
if (i2c == &I2CHandle1) {
} else if (i2c == &I2CHandle1) {
// X-skin: X9=PB6=SCL, X10=PB7=SDA
pins[0] = &pin_B6;
pins[1] = &pin_B7;
GPIO_InitStructure.Alternate = GPIO_AF4_I2C1;
// enable the I2C clock
__I2C1_CLK_ENABLE();
} else
#endif
if (i2c == &I2CHandle2) {
} else if (i2c == &I2CHandle2) {
// Y-skin: Y9=PB10=SCL, Y10=PB11=SDA
pins[0] = &pin_B10;
pins[1] = &pin_B11;
GPIO_InitStructure.Alternate = GPIO_AF4_I2C2;
// enable the I2C clock
__I2C2_CLK_ENABLE();
} else {
// I2C does not exist for this board (shouldn't get here, should be checked by caller)
return;
}
// init the GPIO lines
......@@ -73,6 +76,8 @@ void i2c_init(I2C_HandleTypeDef *i2c) {
if (HAL_I2C_Init(i2c) != HAL_OK) {
// init error
// TODO should raise an exception, but this function is not necessarily going to be
// called via Python, so may not be properly wrapped in an NLR handler
printf("HardwareError: HAL_I2C_Init failed\n");
return;
}
......@@ -81,17 +86,20 @@ void i2c_init(I2C_HandleTypeDef *i2c) {
/******************************************************************************/
/* Micro Python bindings */
#define PYB_NUM_I2C (2)
typedef struct _pyb_i2c_obj_t {
mp_obj_base_t base;
I2C_HandleTypeDef *i2c;
} pyb_i2c_obj_t;
STATIC const pyb_i2c_obj_t pyb_i2c_obj[PYB_NUM_I2C] = {
STATIC const pyb_i2c_obj_t pyb_i2c_obj[] = {
#if MICROPY_HW_ENABLE_I2C1
{{&pyb_i2c_type}, &I2CHandle1},
#else
{{&pyb_i2c_type}, NULL},
#endif
{{&pyb_i2c_type}, &I2CHandle2}
};
#define PYB_NUM_I2C (sizeof(pyb_i2c_obj) / sizeof(pyb_i2c_obj[0]))
STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
// check arguments
......@@ -101,7 +109,7 @@ STATIC mp_obj_t pyb_i2c_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
machine_int_t i2c_id = mp_obj_get_int(args[0]) - 1;
// check i2c number
if (!(0 <= i2c_id && i2c_id < PYB_NUM_I2C)) {
if (!(0 <= i2c_id && i2c_id < PYB_NUM_I2C && pyb_i2c_obj[i2c_id].i2c != NULL)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "I2C bus %d does not exist", i2c_id + 1));
}
......
......@@ -13,22 +13,26 @@
#include "genhdr/pins.h"
#include "spi.h"
#if !defined(MICROPU_HW_ENABLE_SPI1)
#define MICROPY_HW_ENABLE_SPI1 (1)
#endif
#if MICROPY_HW_ENABLE_SPI1
SPI_HandleTypeDef SPIHandle1 = {.Instance = NULL};
#endif
SPI_HandleTypeDef SPIHandle2 = {.Instance = NULL};
#if MICROPY_HW_ENABLE_SPI3
SPI_HandleTypeDef SPIHandle3 = {.Instance = NULL};
#endif
void spi_init0(void) {
// reset the SPI handles
#if MICROPY_HW_ENABLE_SPI1
memset(&SPIHandle1, 0, sizeof(SPI_HandleTypeDef));
SPIHandle1.Instance = SPI1;
#endif
memset(&SPIHandle2, 0, sizeof(SPI_HandleTypeDef));
SPIHandle2.Instance = SPI2;
#if MICROPY_HW_ENABLE_SPI3
memset(&SPIHandle3, 0, sizeof(SPI_HandleTypeDef));
SPIHandle3.Instance = SPI3;
#endif
}
// TODO allow to take a list of pins to use
......@@ -40,36 +44,40 @@ void spi_init(SPI_HandleTypeDef *spi) {
GPIO_InitStructure.Pull = GPIO_PULLUP; // ST examples use PULLUP
const pin_obj_t *pins[4];
if (0) {
#if MICROPY_HW_ENABLE_SPI1
if (spi->Instance == SPI1) {
} else if (spi->Instance == SPI1) {
// X-skin: X5=PA4=SPI1_NSS, X6=PA5=SPI1_SCK, X7=PA6=SPI1_MISO, X8=PA7=SPI1_MOSI
pins[0] = &pin_A4;
pins[1] = &pin_A5;
pins[2] = &pin_A6;
pins[3] = &pin_A7;
GPIO_InitStructure.Alternate = GPIO_AF5_SPI1;
} else
// enable the SPI clock
__SPI1_CLK_ENABLE();
#endif
if (spi->Instance == SPI2) {
} else if (spi->Instance == SPI2) {
// Y-skin: Y5=PB12=SPI2_NSS, Y6=PB13=SPI2_SCK, Y7=PB14=SPI2_MISO, Y8=PB15=SPI2_MOSI
pins[0] = &pin_B12;
pins[1] = &pin_B13;
pins[2] = &pin_B14;
pins[3] = &pin_B15;
GPIO_InitStructure.Alternate = GPIO_AF5_SPI2;
} else
// enable the SPI clock
__SPI2_CLK_ENABLE();
#if MICROPY_HW_ENABLE_SPI3
if (spi->Instance == SPI3) {
} else if (spi->Instance == SPI3) {
pins[0] = &pin_A4;
pins[1] = &pin_B3;
pins[2] = &pin_B4;
pins[3] = &pin_B5;
GPIO_InitStructure.Alternate = GPIO_AF6_SPI3;
} else
// enable the SPI clock
__SPI3_CLK_ENABLE();
#endif
{
// SPI does not exist for this board
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "SPI bus does not exist"));
} else {
// SPI does not exist for this board (shouldn't get here, should be checked by caller)
return;
}
for (uint i = 0; i < 4; i++) {
......@@ -77,16 +85,7 @@ void spi_init(SPI_HandleTypeDef *spi) {
HAL_GPIO_Init(pins[i]->gpio, &GPIO_InitStructure);
}
// enable the SPI clock
if (spi->Instance == SPI1) {
__SPI1_CLK_ENABLE();
} else if (spi->Instance == SPI2) {
__SPI2_CLK_ENABLE();
} else if (spi->Instance == SPI3) {
__SPI3_CLK_ENABLE();
}
// init the I2C device
// init the SPI device
if (HAL_SPI_Init(spi) != HAL_OK) {
// init error
// TODO should raise an exception, but this function is not necessarily going to be
......@@ -98,29 +97,42 @@ void spi_init(SPI_HandleTypeDef *spi) {
void spi_deinit(SPI_HandleTypeDef *spi) {
HAL_SPI_DeInit(spi);
if (spi->Instance == SPI1) {
if (0) {
#if MICROPY_HW_ENABLE_SPI1
} else if (spi->Instance == SPI1) {
__SPI1_CLK_DISABLE();
#endif
} else if (spi->Instance == SPI2) {
__SPI2_CLK_DISABLE();
#if MICROPY_HW_ENABLE_SPI3
} else if (spi->Instance == SPI3) {
__SPI3_CLK_DISABLE();
#endif
}
}
/******************************************************************************/
/* Micro Python bindings */
#define PYB_NUM_SPI (2)
typedef struct _pyb_spi_obj_t {
mp_obj_base_t base;
SPI_HandleTypeDef *spi;
} pyb_spi_obj_t;
STATIC const pyb_spi_obj_t pyb_spi_obj[PYB_NUM_SPI] = {
STATIC const pyb_spi_obj_t pyb_spi_obj[] = {
#if MICROPY_HW_ENABLE_SPI1
{{&pyb_spi_type}, &SPIHandle1},
{{&pyb_spi_type}, &SPIHandle2}
#else
{{&pyb_spi_type}, NULL},
#endif
{{&pyb_spi_type}, &SPIHandle2},
#if MICROPY_HW_ENABLE_SPI3
{{&pyb_spi_type}, &SPIHandle3},
#else
{{&pyb_spi_type}, NULL},
#endif
};
#define PYB_NUM_SPI (sizeof(pyb_spi_obj) / sizeof(pyb_spi_obj[0]))
STATIC void pyb_spi_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_spi_obj_t *self = self_in;
......@@ -223,7 +235,7 @@ STATIC mp_obj_t pyb_spi_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
machine_int_t spi_id = mp_obj_get_int(args[0]) - 1;
// check SPI number
if (!(0 <= spi_id && spi_id < PYB_NUM_SPI)) {
if (!(0 <= spi_id && spi_id < PYB_NUM_SPI && pyb_spi_obj[spi_id].spi != NULL)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "SPI bus %d does not exist", spi_id + 1));
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment