diff --git a/platform/stm32f429/gpio.h b/platform/stm32f429/gpio.h new file mode 100644 index 000000000..d74def770 --- /dev/null +++ b/platform/stm32f429/gpio.h @@ -0,0 +1,25 @@ +#ifndef STM32F429_GPIO_H +#define STM32F429_GPIO_H 1 + +typedef enum { + STM32_GPIO_GROUP_A = 0, + STM32_GPIO_GROUP_B = 1, + STM32_GPIO_GROUP_C = 2, + STM32_GPIO_GROUP_D = 3, + STM32_GPIO_GROUP_E = 4, + STM32_GPIO_GROUP_F = 5, + STM32_GPIO_GROUP_G = 6, + STM32_GPIO_GROUP_H = 7, + STM32_GPIO_GROUP_I = 8, + STM32_GPIO_GROUP_J = 9, + STM32_GPIO_GROUP_K = 10 +} stm32_gpio_group_t; + +typedef struct { + stm32_gpio_group_t group:4; + unsigned int number:4; +} stm32_pin_t; + +#define STM32_PIN(g,i) (stm32_pin_t){.group = STM32_GPIO_GROUP_##g, .number = i} + +#endif diff --git a/platform/stm32f429/pinmux.c b/platform/stm32f429/pinmux.c new file mode 100644 index 000000000..30b25112b --- /dev/null +++ b/platform/stm32f429/pinmux.c @@ -0,0 +1,12 @@ +#include "pinmux.h" + +void stm32_configure_pin(stm32_pin_t pin, stm32_pin_function_t function) { +// GPIOE = pin.group; +// high_or_low = pin.number > 8 ? high : low; + +// alt_fun_number = AlternateFunctions[pin][function]; + // Step 1 -> Figure the Alternate Function (1,2,3,4) + // Step 2 -> Grab the mode register +// GPIO_AFRH(GPIOE)->AFRH12 = GPIO_AF_AF5; +} + diff --git a/platform/stm32f429/pinmux.h b/platform/stm32f429/pinmux.h new file mode 100644 index 000000000..203bd51f1 --- /dev/null +++ b/platform/stm32f429/pinmux.h @@ -0,0 +1,76 @@ +#ifndef STM32F429_PINMUX_H +#define STM32F429_PINMUX_H 1 + +#include "gpio.h" + +/* How to use ? + * + * configure_pin(PB11, TIM2_CH4); + * That's it! + * Who uses this? + * platform/spi for example: + * spi_init(SPI2) + * -> NO. BAD IDEA. PINMUX has nothing to do with SPI per-se. */ + +/* Note that the table is pretty large + * Not using it in production might be an idea. + * Just don't use "stm32_configure_pin", but address registers manually + * and the linker will do its job. */ + +typedef enum { + STM32_BUS_SYS, + STM32_BUS_TIM1, + STM32_BUS_TIM2, + STM32_BUS_TIM3, + STM32_BUS_TIM4, + STM32_BUS_TIM5, + STM32_BUS_TIM8, + STM32_BUS_TIM9, + STM32_BUS_TIM10, + STM32_BUS_TIM11, + STM32_BUS_TIM12, + STM32_BUS_TIM13, + STM32_BUS_SPI1, + STM32_BUS_SPI2, + STM32_BUS_SPI3 +} stm32_bus_t; + +typedef enum { + SPI_WIRE_NSS = 0, + SPI_WIRE_SCK = 1, + SPI_WIRE_MISO = 2, + SPI_WIRE_MOSI = 3, + + USART_WIRE_CK = 0, + USART_WIRE_RX = 1, + USART_WIRE_TX = 2, + USART_WIRE_CTS = 3, + USART_WIRE_RTS = 4 +} stm32_wire_t; + +typedef struct { + stm32_bus_t bus:4; // SPI2 + stm32_wire_t wire:4; // MISO +} stm32_pin_function_t; + + +#define STM32_PIN_FUNCTION(b,i,r) (stm32_pin_function_t){.bus = STM32_BUS_##b##i, .wire = b##_WIRE_##r} +#define P(b,i,r) STM32_PIN_FUNCTION(b,i,r) + +stm32_pin_function_t AlternateFunctionMapping[11*16][16] = { + // This comes from the STM32F429 datasheet + // Page 73 to 83 + //{X, P(SPI2,MISO), X, X, X}, + //{{}, {}, {.bus = SPI2, .role = MOSI}}, + {{}, P(SPI,2,MISO),{}}, + {}, +}; + +#undef P + +// Sample call: +// stm32_configure_pin(STM32_PIN(A,10), STM32_PIN_FUNCTION(SPI,2,MISO)); + +void stm32_configure_pin(stm32_pin_t pin, stm32_pin_function_t function); + +#endif diff --git a/platform/stm32f429/registers/gpio.c b/platform/stm32f429/registers/gpio.c index 7d62b2130..3dd52d9ed 100644 --- a/platform/stm32f429/registers/gpio.c +++ b/platform/stm32f429/registers/gpio.c @@ -23,52 +23,52 @@ #define GPIO_AFRL_OFFSET 0x20 #define GPIO_AFRH_OFFSET 0x24 -char * GPIO_REGISTER_ADDRESS(GPIO_t gpio, int registerOffset) { +char * GPIO_REGISTER_ADDRESS(stm32_gpio_group_t gpio_group, int registerOffset) { char * gpioBaseAddress[11] = { (char *)GPIOA_BASE, (char *)GPIOB_BASE, (char *)GPIOC_BASE, (char *)GPIOD_BASE, (char *)GPIOE_BASE, (char *)GPIOF_BASE, (char *)GPIOG_BASE, (char *)GPIOH_BASE, (char *)GPIOI_BASE, (char *)GPIOJ_BASE, (char *)GPIOK_BASE }; - return gpioBaseAddress[gpio] + registerOffset; + return gpioBaseAddress[gpio_group] + registerOffset; } -GPIO_MODER_t * GPIO_MODER(GPIO_t gpio) { - return (GPIO_MODER_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_MODER_OFFSET); +GPIO_MODER_t * GPIO_MODER(stm32_gpio_group_t gpio_group) { + return (GPIO_MODER_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_MODER_OFFSET); } -GPIO_OTYPER_t * GPIO_OTYPER(GPIO_t gpio) { - return (GPIO_OTYPER_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_OTYPER_OFFSET); +GPIO_OTYPER_t * GPIO_OTYPER(stm32_gpio_group_t gpio_group) { + return (GPIO_OTYPER_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_OTYPER_OFFSET); } -GPIO_OSPEEDR_t * GPIO_OSPEEDR(GPIO_t gpio) { - return (GPIO_OSPEEDR_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_OSPEEDR_OFFSET); +GPIO_OSPEEDR_t * GPIO_OSPEEDR(stm32_gpio_group_t gpio_group) { + return (GPIO_OSPEEDR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_OSPEEDR_OFFSET); } -GPIO_PUPDR_t * GPIO_PUPDR(GPIO_t gpio) { - return (GPIO_PUPDR_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_PUPDR_OFFSET); +GPIO_PUPDR_t * GPIO_PUPDR(stm32_gpio_group_t gpio_group) { + return (GPIO_PUPDR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_PUPDR_OFFSET); } -GPIO_IDR_t * GPIO_IDR(GPIO_t gpio) { - return (GPIO_IDR_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_IDR_OFFSET); +GPIO_IDR_t * GPIO_IDR(stm32_gpio_group_t gpio_group) { + return (GPIO_IDR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_IDR_OFFSET); } -GPIO_ODR_t * GPIO_ODR(GPIO_t gpio) { - return (GPIO_ODR_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_ODR_OFFSET); +GPIO_ODR_t * GPIO_ODR(stm32_gpio_group_t gpio_group) { + return (GPIO_ODR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_ODR_OFFSET); } -GPIO_BSRR_t * GPIO_BSRR(GPIO_t gpio) { - return (GPIO_BSRR_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_BSRR_OFFSET); +GPIO_BSRR_t * GPIO_BSRR(stm32_gpio_group_t gpio_group) { + return (GPIO_BSRR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_BSRR_OFFSET); } -GPIO_LCKR_t * GPIO_LCKR(GPIO_t gpio) { - return (GPIO_LCKR_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_LCKR_OFFSET); +GPIO_LCKR_t * GPIO_LCKR(stm32_gpio_group_t gpio_group) { + return (GPIO_LCKR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_LCKR_OFFSET); } -GPIO_AFRL_t * GPIO_AFRL(GPIO_t gpio) { - return (GPIO_AFRL_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_AFRL_OFFSET); +GPIO_AFRL_t * GPIO_AFRL(stm32_gpio_group_t gpio_group) { + return (GPIO_AFRL_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_AFRL_OFFSET); } -GPIO_AFRH_t * GPIO_AFRH(GPIO_t gpio) { - return (GPIO_AFRH_t *)GPIO_REGISTER_ADDRESS(gpio, GPIO_AFRH_OFFSET); +GPIO_AFRH_t * GPIO_AFRH(stm32_gpio_group_t gpio_group) { + return (GPIO_AFRH_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_AFRH_OFFSET); } diff --git a/platform/stm32f429/registers/gpio.h b/platform/stm32f429/registers/gpio.h index 232bbf0ec..2a20e094b 100644 --- a/platform/stm32f429/registers/gpio.h +++ b/platform/stm32f429/registers/gpio.h @@ -1,16 +1,7 @@ -typedef enum { - GPIOA = 0, - GPIOB = 1, - GPIOC = 2, - GPIOD = 3, - GPIOE = 4, - GPIOF = 5, - GPIOG = 6, - GPIOH = 7, - GPIOI = 8, - GPIOJ = 9, - GPIOK = 10 -} GPIO_t; +#ifndef STM32_REGISTERS_GPIO_H +#define STM32_REGISTERS_GPIO_H 1 + +#include #pragma mark - GPIO port mode registers @@ -40,7 +31,7 @@ typedef struct { GPIO_MODE_t MODER15:2; } GPIO_MODER_t; -GPIO_MODER_t * GPIO_MODER(GPIO_t gpio); +GPIO_MODER_t * GPIO_MODER(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port output type registers @@ -69,7 +60,7 @@ typedef struct { unsigned int :16; } GPIO_OTYPER_t; -GPIO_OTYPER_t * GPIO_OTYPER(GPIO_t gpio); +GPIO_OTYPER_t * GPIO_OTYPER(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port output speed registers @@ -99,7 +90,7 @@ typedef struct { GPIO_OSPEED_t OSPEEDR15:2; } GPIO_OSPEEDR_t; -GPIO_OSPEEDR_t * GPIO_OSPEEDR(GPIO_t gpio); +GPIO_OSPEEDR_t * GPIO_OSPEEDR(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port pull-up/pull-down registers @@ -128,7 +119,7 @@ typedef struct { GPIO_PUPD_t PUPDR15:2; } GPIO_PUPDR_t; -GPIO_PUPDR_t * GPIO_PUPDR(GPIO_t gpio); +GPIO_PUPDR_t * GPIO_PUPDR(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port input data registers @@ -152,7 +143,7 @@ typedef struct { unsigned int :16; } GPIO_IDR_t; -GPIO_IDR_t * GPIO_IDR(GPIO_t gpio); +GPIO_IDR_t * GPIO_IDR(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port output data registers @@ -176,7 +167,7 @@ typedef struct { unsigned int :16; } GPIO_ODR_t; -GPIO_ODR_t * GPIO_ODR(GPIO_t gpio); +GPIO_ODR_t * GPIO_ODR(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port bit set/reset registers @@ -215,7 +206,7 @@ typedef struct { unsigned int BR15:1; } GPIO_BSRR_t; -GPIO_BSRR_t * GPIO_BSRR(GPIO_t gpio); +GPIO_BSRR_t * GPIO_BSRR(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port configuration lock registers @@ -249,7 +240,7 @@ typedef struct { GPIO_LCK_KEY_t LCKK:1; } GPIO_LCKR_t; -GPIO_LCKR_t * GPIO_LCKR(GPIO_t gpio); +GPIO_LCKR_t * GPIO_LCKR(stm32_gpio_group_t gpio_group); #pragma mark - GPIO port alternate function registers @@ -294,5 +285,7 @@ typedef struct { GPIO_AF_t AFRH15:4; } GPIO_AFRH_t; -GPIO_AFRL_t * GPIO_AFRL(GPIO_t gpio); -GPIO_AFRH_t * GPIO_AFRH(GPIO_t gpio); +GPIO_AFRL_t * GPIO_AFRL(stm32_gpio_group_t gpio_group); +GPIO_AFRH_t * GPIO_AFRH(stm32_gpio_group_t gpio_group); + +#endif diff --git a/platform/stm32f429/registers/rcc.h b/platform/stm32f429/registers/rcc.h index 6250f0697..153f9116f 100644 --- a/platform/stm32f429/registers/rcc.h +++ b/platform/stm32f429/registers/rcc.h @@ -1,3 +1,6 @@ +#ifndef STM32_REGISTERS_RCC_H +#define STM32_REGISTERS_RCC_H 1 + /* Sample usage : "RCC_AHB1ENR->GPIOAEN = 1;" will enable the clock on GPIOA.*/ extern struct { unsigned int GPIOAEN:1; @@ -56,3 +59,5 @@ extern struct { unsigned int LTDCEN:1; unsigned int :5; } * RCC_APB2ENR; + +#endif diff --git a/platform/stm32f429/spi.c b/platform/stm32f429/spi.c index 82b47b7bc..becfd42b1 100644 --- a/platform/stm32f429/spi.c +++ b/platform/stm32f429/spi.c @@ -1,5 +1,13 @@ #include "spi.h" +// pin mapping +// +// Give a port number: e.g. SPI2 +// and a pinmatch. e.g "SPI1_SCK -> PB3" +// and obtain an alternate function +// Actually, this should be done elsewhere... + + void spi_init(spi_port_t * port) { // Do shit! }