From 32c094570ba7b01f48d65572f671a2a54bb9dddf Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Sat, 9 May 2015 18:25:38 +0200 Subject: [PATCH] Start enabling the LTDC --- Makefile | 3 +- platform/stm32f429/init_lcd.c | 231 +++++++++++++++++----------- platform/stm32f429/registers.h | 22 +++ platform/stm32f429/registers/gpio.c | 74 --------- platform/stm32f429/registers/gpio.h | 91 +++++++++++ platform/stm32f429/registers/ltdc.h | 132 ++++++++++++++++ platform/stm32f429/registers/rcc.c | 8 - platform/stm32f429/registers/rcc.h | 163 +++++++++++++------- platform/stm32f429/registers/spi.c | 32 ---- platform/stm32f429/registers/spi.h | 108 ++++++------- 10 files changed, 546 insertions(+), 318 deletions(-) create mode 100644 platform/stm32f429/registers.h delete mode 100644 platform/stm32f429/registers/gpio.c create mode 100644 platform/stm32f429/registers/ltdc.h delete mode 100644 platform/stm32f429/registers/rcc.c delete mode 100644 platform/stm32f429/registers/spi.c diff --git a/Makefile b/Makefile index 542010e96..324268320 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,8 @@ objs := platform/stm32f429/boot/crt0.o objs += external/freertos/tasks.o external/freertos/list.o external/freertos/queue.o external/freertos/portable/GCC/ARM_CM4F/port.o external/freertos/portable/MemMang/heap_1.o objs += external/newlib/libc/string/memset.o external/newlib/libc/string/memcpy.o -objs += platform/stm32f429/boot/isr.o platform/stm32f429/registers/gpio.o platform/stm32f429/registers/rcc.o platform/stm32f429/registers/spi.o +objs += platform/stm32f429/boot/isr.o +#platform/stm32f429/registers/gpio.o platform/stm32f429/registers/rcc.o platform/stm32f429/registers/spi.o platform/stm32f429/registers/ltdc.o objs += platform/stm32f429/init.o platform/stm32f429/init_lcd.o objs += platform/ili9341/ili9341.o diff --git a/platform/stm32f429/init_lcd.c b/platform/stm32f429/init_lcd.c index e2048efad..f00074f6e 100644 --- a/platform/stm32f429/init_lcd.c +++ b/platform/stm32f429/init_lcd.c @@ -23,24 +23,16 @@ * That's wat ST says in stm32f429i_discovery_lcd.c. */ -#include "registers/rcc.h" +/*#include "registers/rcc.h" #include "registers/gpio.h" #include "registers/spi.h" +#include "registers/ltdc.h"*/ +#include "registers.h" #include -static void spi_5_write(char * data, size_t size); -static void gpio_c2_write(bool pin_state); -static void gpio_d13_write(bool pin_state); - -ili9341_t sPanel = { - .chip_select_pin_write = gpio_c2_write, - .data_command_pin_write = gpio_d13_write, - .spi_write = spi_5_write -}; - -static void init_lcd_gpio(); -static void init_lcd_spi(); -static void init_lcd_panel(); +static void init_spi_interface(); +static void init_rgb_interface(); +static void init_panel(); void init_lcd() { /* This routine is responsible for initializing the LCD panel. @@ -48,107 +40,170 @@ void init_lcd() { * this routine, everyone can expect to write to the LCD by writing to the * framebuffer. */ - /* The LCD panel is connected on GPIO pins. Let's configure them. */ - init_lcd_gpio(); + init_spi_interface(); - /* According to our GPIO config, we send commands to the LCD panel over SPI on - * port SPI5. Let's configure it. */ - init_lcd_spi(); + init_rgb_interface(); - /* configure display */ - init_lcd_panel(); - - /* Last but not least */ - //TODO: init_lcd_dma(); + init_panel(); } -#pragma mark - GPIO initialization +// SPI interface + +static void init_spi_gpios(); +static void init_spi_port(); + +static void init_spi_interface() { + init_spi_gpios(); + init_spi_port(); +} + +static void init_spi_gpios() { + // The LCD panel is connected on GPIO pins. Let's configure them -static void init_lcd_gpio_clocks() { // We are using groups C, D, and F. Let's enable their clocks - RCC_AHB1ENR->GPIOCEN = 1; - RCC_AHB1ENR->GPIODEN = 1; - RCC_AHB1ENR->GPIOFEN = 1; -} + RCC_AHB1ENR |= (GPIOCEN | GPIODEN | GPIOFEN); -static void init_lcd_gpio_modes() { // PC2 and PD13 are controlled directly - GPIO_MODER(GPIOC)->MODER2 = GPIO_MODE_OUTPUT; - GPIO_MODER(GPIOD)->MODER13 = GPIO_MODE_OUTPUT; + REGISTER_SET_VALUE(GPIO_MODER(GPIOC), MODER(2), GPIO_MODE_OUTPUT); + REGISTER_SET_VALUE(GPIO_MODER(GPIOD), MODER(13), GPIO_MODE_OUTPUT); // PF7 and PF9 are used for an alternate function (in that case, SPI) - GPIO_MODER(GPIOF)->MODER7 = GPIO_MODE_ALTERNATE_FUNCTION; - GPIO_MODER(GPIOF)->MODER9 = GPIO_MODE_ALTERNATE_FUNCTION; + REGISTER_SET_VALUE(GPIO_MODER(GPIOF), MODER(7), GPIO_MODE_ALTERNATE_FUNCTION); + REGISTER_SET_VALUE(GPIO_MODER(GPIOF), MODER(9), GPIO_MODE_ALTERNATE_FUNCTION); // More precisely, PF7 and PF9 are doing SPI-SCL and SPI-SDO/SDO. // This corresponds to Alternate Function 5 using SPI port 5 // (See STM32F429 p78) - GPIO_AFRL(GPIOF)->AFRL7 = GPIO_AF_AF5; // Pin 7 is in the "low" register - GPIO_AFRH(GPIOF)->AFRH9 = GPIO_AF_AF5; // and pin 9 in the "high" one - - // For debug - /* - GPIO_MODER(GPIOF)->MODER6 = GPIO_MODE_ALTERNATE_FUNCTION; - GPIO_MODER(GPIOF)->MODER8 = GPIO_MODE_ALTERNATE_FUNCTION; - GPIO_AFRL(GPIOF)->AFRL6 = GPIO_AF_AF5; // and pin 9 in the "high" one - GPIO_AFRH(GPIOF)->AFRH8 = GPIO_AF_AF5; // and pin 9 in the "high" one - */ + REGISTER_SET_VALUE(GPIO_AFRL(GPIOF), AFR(7), 5); // Pin 7 is in the "low" register + REGISTER_SET_VALUE(GPIO_AFRH(GPIOF), AFR(9), 5); // and pin 9 in the "high" one } -static void init_lcd_gpio() { - /* The LCD panel is connected on GPIO pins. Let's configure them. */ - init_lcd_gpio_clocks(); - init_lcd_gpio_modes(); -} - -void gpio_c2_write(bool pin_state) { - GPIO_ODR(GPIOC)->ODR2 = pin_state; -} - -void gpio_d13_write(bool pin_state) { - GPIO_ODR(GPIOD)->ODR13 = pin_state; -} - -#pragma mark - SPI initialization - -static void init_lcd_spi() { +static void init_spi_port() { // Enable the SPI5 clock (SPI5 lives on the APB2 bus) - RCC_APB2ENR->SPI5EN = 1; + RCC_APB2ENR |= SPI5EN; // Configure the SPI port - // Using a C99 compound litteral. C99 guarantees all non-set values are zero - *SPI_CR1(SPI5) = (SPI_CR1_t){ - .BIDIMODE = 1, - .BIDIOE = 1, - .MSTR = 1, - .DFF = SPI_DFF_8_BITS, - .CPOL = 0, - .CPHA = 0, - .BR = SPI_BR_DIV_2, - .SSM = 1, - .SSI = 1, - .LSBFIRST = 0, // Send the most significant bit first - .SPE = 1 - }; + SPI_CR1(SPI5) = (SPI_BIDIMODE | SPI_BIDIOE | SPI_MSTR | SPI_DFF_8_BITS | SPI_BR(SPI_BR_DIV_2) | SPI_SSM | SPI_SSI | SPI_SPE); +} + +// RGB interface + +static void init_rgb_gpios(); +static void init_rgb_clocks(); + +static void init_rgb_interface() { + init_rgb_gpios(); + init_rgb_clocks(); +} + +struct gpio_pin { + char group; + char number; +}; + +#define RGB_PIN_COUNT 77 + +struct gpio_pin rgb_pins[RGB_PIN_COUNT] = { + {GPIOA, 3}, {GPIOA, 4}, {GPIOA, 6}, {GPIOA, 8}, {GPIOA, 11}, {GPIOA, 12}, + {GPIOB, 8}, {GPIOB, 9}, {GPIOB, 10}, {GPIOB, 11}, + {GPIOC, 6}, {GPIOC, 7}, {GPIOC, 10}, + {GPIOD, 3}, {GPIOD, 6}, {GPIOD, 10}, + {GPIOE, 4}, {GPIOE, 5}, {GPIOE, 6}, {GPIOE, 11}, {GPIOE, 12}, {GPIOE, 13}, + {GPIOE, 14}, {GPIOE, 15}, {GPIOF, 10}, + {GPIOG, 6}, {GPIOG, 7}, {GPIOG, 10}, {GPIOG, 11}, {GPIOG, 12}, + {GPIOH, 2}, {GPIOH, 3}, {GPIOH, 8}, {GPIOH, 9}, {GPIOH, 10}, {GPIOH, 11}, + {GPIOH, 12}, {GPIOH, 13}, {GPIOH, 14}, {GPIOH, 15}, + {GPIOI, 0}, {GPIOI, 1}, {GPIOI, 2}, {GPIOI, 4}, {GPIOI, 5}, {GPIOI, 6}, + {GPIOI, 7}, {GPIOI, 9}, {GPIOI, 10}, {GPIOI, 12}, {GPIOI, 13}, {GPIOI, 14}, + {GPIOI, 15}, + {GPIOJ, 0}, {GPIOJ, 1}, {GPIOJ, 2}, {GPIOJ, 3}, {GPIOJ, 4}, {GPIOJ, 5}, + {GPIOJ, 6}, {GPIOJ, 7}, {GPIOJ, 8}, {GPIOJ, 9}, {GPIOJ, 10}, {GPIOJ, 11}, + {GPIOJ, 12}, {GPIOJ, 13}, {GPIOJ, 14}, {GPIOJ, 15}, {GPIOK, 0}, {GPIOK, 1}, + {GPIOK, 2}, {GPIOK, 3}, {GPIOK, 4}, {GPIOK, 5}, {GPIOK, 6}, {GPIOK, 7} +}; + +static void init_rgb_gpios() { + // The RGB interface uses GPIO pins in all groups! + RCC_AHB1ENR |= ( + GPIOAEN | GPIOBEN | GPIOCEN | GPIODEN | + GPIOEEN | GPIOFEN | GPIOGEN | GPIOHEN | + GPIOIEN | GPIOJEN | GPIOJEN + ); + + // The LTDC is always mapped to AF14 + for (int i=0; inumber > 7) { + REGISTER_SET_VALUE(GPIO_AFRL(pin->group), AFR(pin->number), 14); + } else { + REGISTER_SET_VALUE(GPIO_AFRH(pin->group), AFR(pin->number), 14); + } + } + + //FIXME: Apprently DMA should be enabled? + RCC_AHB1ENR |= (DMA1EN | DMA2EN | DMA2DEN); +} + +static void init_rgb_clocks() { + // STEP 1 : Enable the LTDC clock in the RCC register + // + // TFT-LCD lives on the APB2 bus, so we'll want to play with RCC_APB2ENR + // (RCC stands for "Reset and Clock Control) + RCC_APB2ENR |= LTDCEN; + + // STEP 2 : Configure the required Pixel clock following the panel datasheet + // + // We're setting PLLSAIN = 192, PLLSAIR = 4, and PLLSAIDIVR = 0x2 meaning divide-by-8 + // So with a f(PLLSAI clock input) = 1MHz + // we get f(VCO clock) = PLLSAIN * fPPLSAI = 192 MHz + // and f(PLL LCD clock) = fVCO / PLLSAIR = 48 MHz + // and eventually f(LCD_CLK) = fPLLLCD/8 = 6 MHz + + int pllsain = 192; + int pllsair = 4; + int pllsaidivr = 0x2; // This value means "divide by 8" + //FIXME: A macro here + + REGISTER_SET_VALUE(RCC_PLLSAICFGR, PLLSAIR, pllsair); + REGISTER_SET_VALUE(RCC_PLLSAICFGR, PLLSAIN, pllsain); + REGISTER_SET_VALUE(RCC_DCKCFGR, PLLSAIDIVR, pllsaidivr); + + // Now let's enable the PLL/PLLSAI clocks + RCC_CR |= (PLLSAION | PLLON); +} + +// Panel + +static void spi_5_write(char * data, size_t size); +static void gpio_c2_write(bool pin_state); +static void gpio_d13_write(bool pin_state); + +static ili9341_t panel = { + .chip_select_pin_write = gpio_c2_write, + .data_command_pin_write = gpio_d13_write, + .spi_write = spi_5_write +}; + +static void init_panel() { + ili9341_initialize(&panel); } static void spi_5_write(char * data, size_t size) { - volatile SPI_SR_t * spi_status = SPI_SR(SPI5); - volatile SPI_DR_t * spi_data_register = SPI_DR(SPI5); - - while (spi_status->BSY != 0) { + while (SPI_SR(SPI5) & SPI_BSY) { } for (size_t i=0; iTXE == 0) { + SPI_DR(SPI5) = data[i]; + while (!(SPI_SR(SPI5) & SPI_TXE)) { } } - while (spi_status->BSY != 0) { + while (SPI_SR(SPI5) & SPI_BSY) { } } -#pragma mark - Panel initialization - -void init_lcd_panel() { - ili9341_initialize(&sPanel); +void gpio_c2_write(bool pin_state) { + REGISTER_SET_VALUE(GPIO_ODR(GPIOC), ODR(2), pin_state); +} + +void gpio_d13_write(bool pin_state) { + REGISTER_SET_VALUE(GPIO_ODR(GPIOD), ODR(13), pin_state); } diff --git a/platform/stm32f429/registers.h b/platform/stm32f429/registers.h new file mode 100644 index 000000000..6b981fa64 --- /dev/null +++ b/platform/stm32f429/registers.h @@ -0,0 +1,22 @@ +#include + +/* Example usage: + * + * REGISTER_SET_VALUE(RCC_CR, HSITRIM, 37); + * RCC_CR = (HSION|HSITRIM_VALUE(15)); + * if (RCC_CR & HSIRDY) { } + */ + +#define BIT_MASK(high, low) ((((uint32_t)1<<((high)-(low)+1))-1)<<(low)) +#define BIT_VALUE(value, high, low) (((value)<<(low))&BIT_MASK(high, low)) + +#include "registers/rcc.h" +#include "registers/gpio.h" +#include "registers/spi.h" + +#define REGISTER_FIELD_MASK(field) (BIT_MASK(HIGH_BIT_##field,LOW_BIT_##field)) +#define REGISTER_FIELD_VALUE(field, value) (BIT_VALUE(value,HIGH_BIT_##field,LOW_BIT_##field)) + +#define REGISTER_SET_VALUE(reg, field, value) (reg = ((reg&(~REGISTER_FIELD_MASK(field)))|REGISTER_FIELD_VALUE(field,value))) +//#define SET(reg, field) (reg |= field) +//#define CLEAR(reg, field) (reg &= ~field) diff --git a/platform/stm32f429/registers/gpio.c b/platform/stm32f429/registers/gpio.c deleted file mode 100644 index 26ed72822..000000000 --- a/platform/stm32f429/registers/gpio.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "gpio.h" - -#define GPIOA_BASE 0x40020000 -#define GPIOB_BASE 0x40020400 -#define GPIOC_BASE 0x40020800 -#define GPIOD_BASE 0x40020C00 -#define GPIOE_BASE 0x40021000 -#define GPIOF_BASE 0x40021400 -#define GPIOG_BASE 0x40021800 -#define GPIOH_BASE 0x40021C00 -#define GPIOI_BASE 0x40022000 -#define GPIOJ_BASE 0x40022400 -#define GPIOK_BASE 0x40022800 - -#define GPIO_MODER_OFFSET 0x00 -#define GPIO_OTYPER_OFFSET 0x04 -#define GPIO_OSPEEDR_OFFSET 0x08 -#define GPIO_PUPDR_OFFSET 0x0C -#define GPIO_IDR_OFFSET 0x10 -#define GPIO_ODR_OFFSET 0x14 -#define GPIO_BSRR_OFFSET 0x18 -#define GPIO_LCKR_OFFSET 0x1C -#define GPIO_AFRL_OFFSET 0x20 -#define GPIO_AFRH_OFFSET 0x24 - -char * GPIO_REGISTER_ADDRESS(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_group] + registerOffset; -} - -GPIO_MODER_t * GPIO_MODER(GPIO_GROUP_t gpio_group) { - return (GPIO_MODER_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_MODER_OFFSET); -} - -GPIO_OTYPER_t * GPIO_OTYPER(GPIO_GROUP_t gpio_group) { - return (GPIO_OTYPER_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_OTYPER_OFFSET); -} - -GPIO_OSPEEDR_t * GPIO_OSPEEDR(GPIO_GROUP_t gpio_group) { - return (GPIO_OSPEEDR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_OSPEEDR_OFFSET); -} - -GPIO_PUPDR_t * GPIO_PUPDR(GPIO_GROUP_t gpio_group) { - return (GPIO_PUPDR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_PUPDR_OFFSET); -} - -GPIO_IDR_t * GPIO_IDR(GPIO_GROUP_t gpio_group) { - return (GPIO_IDR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_IDR_OFFSET); -} - -GPIO_ODR_t * GPIO_ODR(GPIO_GROUP_t gpio_group) { - return (GPIO_ODR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_ODR_OFFSET); -} - -GPIO_BSRR_t * GPIO_BSRR(GPIO_GROUP_t gpio_group) { - return (GPIO_BSRR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_BSRR_OFFSET); -} - -GPIO_LCKR_t * GPIO_LCKR(GPIO_GROUP_t gpio_group) { - return (GPIO_LCKR_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_LCKR_OFFSET); -} - -GPIO_AFRL_t * GPIO_AFRL(GPIO_GROUP_t gpio_group) { - return (GPIO_AFRL_t *)GPIO_REGISTER_ADDRESS(gpio_group, GPIO_AFRL_OFFSET); -} - -GPIO_AFRH_t * GPIO_AFRH(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 593743437..bc239160e 100644 --- a/platform/stm32f429/registers/gpio.h +++ b/platform/stm32f429/registers/gpio.h @@ -1,6 +1,93 @@ #ifndef STM32_REGISTERS_GPIO_H #define STM32_REGISTERS_GPIO_H 1 +#define GPIO_BASE 0x40020000 + +#define GPIOA 0 +#define GPIOB 1 +#define GPIOC 2 +#define GPIOD 3 +#define GPIOE 4 +#define GPIOF 5 +#define GPIOG 6 +#define GPIOH 7 +#define GPIOI 8 +#define GPIOJ 9 +#define GPIOK 10 + +#define GPIO_REGISTER_AT(gpio_group,offset) (*(volatile uint32_t *)(GPIO_BASE+(gpio_group*0x400)+offset)) + +/* + //DELEte me when implementing + #define GPIO_OTYPER_OFFSET 0x04 +#define GPIO_OSPEEDR_OFFSET 0x08 +#define GPIO_PUPDR_OFFSET 0x0C +#define GPIO_IDR_OFFSET 0x10 +#define GPIO_ODR_OFFSET 0x14 +#define GPIO_BSRR_OFFSET 0x18 +#define GPIO_LCKR_OFFSET 0x1C +#define GPIO_AFRL_OFFSET 0x20 +#define GPIO_AFRH_OFFSET 0x24 +*/ + +// GPIO port mode registers + +#define GPIO_MODER(gpio_group) GPIO_REGISTER_AT(gpio_group, 0x00) + +#define GPIO_MODE_INPUT 0 +#define GPIO_MODE_OUTPUT 1 +#define GPIO_MODE_ALTERNATE_FUNCTION 2 +#define GPIO_MODE_ANALOG 3 + +#define LOW_BIT_MODER(v) (2*v) +#define HIGH_BIT_MODER(v) (2*v+1) + +// GPIO port output data registers + +#define GPIO_ODR(gpio_group) GPIO_REGISTER_AT(gpio_group, 0x14) + +#define LOW_BIT_ODR(v) (v) +#define HIGH_BIT_ODR(v) (v) + +// GPIO port alternate function registers + +#define GPIO_AFRL(gpio_group) GPIO_REGISTER_AT(gpio_group, 0x20) +#define GPIO_AFRH(gpio_group) GPIO_REGISTER_AT(gpio_group, 0x24) + +#define LOW_BIT_AFR(v) (4*(v%8)) +#define HIGH_BIT_AFR(v) (4*(v%8)+3) + + +#if 0 + + +typedef struct { + GPIO_AF_t AFRL0:4; + GPIO_AF_t AFRL1:4; + GPIO_AF_t AFRL2:4; + GPIO_AF_t AFRL3:4; + GPIO_AF_t AFRL4:4; + GPIO_AF_t AFRL5:4; + GPIO_AF_t AFRL6:4; + GPIO_AF_t AFRL7:4; +} GPIO_AFRL_t; + +typedef struct { + GPIO_AF_t AFRH8:4; + GPIO_AF_t AFRH9:4; + GPIO_AF_t AFRH10:4; + GPIO_AF_t AFRH11:4; + GPIO_AF_t AFRH12:4; + GPIO_AF_t AFRH13:4; + GPIO_AF_t AFRH14:4; + GPIO_AF_t AFRH15:4; +} GPIO_AFRH_t; + +GPIO_AFRL_t * GPIO_AFRL(GPIO_GROUP_t gpio_group); +GPIO_AFRH_t * GPIO_AFRH(GPIO_GROUP_t gpio_group); +// + + typedef enum { GPIOA = 0, GPIOB = 1, @@ -15,6 +102,8 @@ typedef enum { GPIOK = 10 } GPIO_GROUP_t; + +#define #pragma mark - GPIO port mode registers typedef enum { @@ -301,3 +390,5 @@ GPIO_AFRL_t * GPIO_AFRL(GPIO_GROUP_t gpio_group); GPIO_AFRH_t * GPIO_AFRH(GPIO_GROUP_t gpio_group); #endif + +#endif diff --git a/platform/stm32f429/registers/ltdc.h b/platform/stm32f429/registers/ltdc.h new file mode 100644 index 000000000..da2e57ead --- /dev/null +++ b/platform/stm32f429/registers/ltdc.h @@ -0,0 +1,132 @@ +#ifndef STM32_REGISTERS_LTDC_H +#define STM32_REGISTERS_LTDC_H 1 + +// LCD-TFT Controller + +#define LTDC_BASE 0x40016800 + +#define LTDC_REGISTER_AT(offset) (*(volatile uint32_t *)(LTDC_BASE+offset)) + +// LTDC Synchronization size configuration register + +#define LTDC_SSCR LTDC_REGISTER_AT(0x08) + +#define LOW_BIT_VSH 0 +#define HIGH_BIT_VSH 10 +#define LOW_BIT_HSW 15 +#define HIGH_BIT_HSW 27 + +// LTDC Back porch configuration register + +#define LTDC_BPCR LTDC_REGISTER_AT(0x0C) + +#define LOW_BIT_AVBP 0 +#define HIGH_BIT_AVBP 10 +#define LOW_BIT_AHBP 15 +#define HIGH_BIT_AHBP 27 + +#if 0 +extern LTDC_BPCR_t * LTDC_BPCR; + +typedef struct { + unsigned int AAH:11; + unsigned int :5; + unsigned int AAW:12; + unsigned int :4; +} LTDC_AWCR_t; + +extern LTDC_AWCR_t * LTDC_AWCR; + +typedef struct { + unsigned int TOTALH:11; + unsigned int :5; + unsigned int TOTALW:12; + unsigned int :4; +} LTDC_TWCR_t; + +extern LTDC_TWCR_t * LTDC_TWCR; + +typedef struct { + unsigned int LTDCEN:1; + unsigned int :3; + unsigned int DBW:3; + unsigned int :1; + unsigned int DGW:3; + unsigned int :1; + unsigned int DRW:3; + unsigned int :1; + unsigned int DEN:1; + unsigned int :11; + unsigned int PCPOL:1; + unsigned int DEPOL:1; + unsigned int VSPOL:1; + unsigned int HPOL:1; +} LTDC_GCR_t; + +extern LTDC_GCR_t * LTDC_GCR; + +typedef struct { + unsigned int IMR:1; + unsigned int VBR:1; + unsigned int :30; +} LTDC_SRCR_t; + +extern LTDC_SRCR_t * LTDC_SRCR; + +typedef struct { + unsigned int BCBLUE:8; + unsigned int BCGREEN:8; + unsigned int BCRED:8; + unsigned int :8; +} LTDC_BCCR_t; + +extern LTDC_BCCR_t * LTDC_BCCR; + +typedef struct { + unsigned int LIE:1; + unsigned int FUIE:1; + unsigned int TERRIE:1; + unsigned int RRIE:1; + unsigned int :28; +} LTDC_IER_t; + +extern LTDC_IER_t * LTDC_IER; + +typedef struct { + unsigned int LIF:1; + unsigned int FUIF:1; + unsigned int TERRIF:1; + unsigned int RRIF:1; + unsigned int :28; +} LTDC_ISR_t; + +extern LTDC_ISR_t * LTDC_ISR; + +typedef struct { + unsigned int CLIF:1; + unsigned int CFUIF:1; + unsigned int CTERRIF:1; + unsigned int CRIF:1; + unsigned int :28; +} LTDC_ICR_t; + +extern LTDC_ICR_t * LTDC_ICR; + +typedef enum { + LAYER1 = 0, + LAYER2 = 1, +} LTDC_LAYER_t; + +typedef struct { + unsigned int LEN:1; + unsigned int COLKEN:1; + unsigned int :2; + unsigned int CLUTEN:1; + unsigned int :27; +} LTDC_LCR_t; + +LTDC_LCR_t * LTDC_LCR(LTDC_LAYER_t ltdc_layer); + +#endif + +#endif diff --git a/platform/stm32f429/registers/rcc.c b/platform/stm32f429/registers/rcc.c deleted file mode 100644 index 057aec044..000000000 --- a/platform/stm32f429/registers/rcc.c +++ /dev/null @@ -1,8 +0,0 @@ -// The non-inclusion of rcc.h here is voluntary. -// Since we didn't define a type for RCC_AHB1ENR, we cannot implement it here -// If we don't include rcc.h, we declare a "new" symbol which will happen to match... -//#include - -#define RCC_BASE 0x40023800 -void * RCC_AHB1ENR = (void *)(RCC_BASE + 0x30); -void * RCC_APB2ENR = (void *)(RCC_BASE + 0x44); diff --git a/platform/stm32f429/registers/rcc.h b/platform/stm32f429/registers/rcc.h index 153f9116f..231656645 100644 --- a/platform/stm32f429/registers/rcc.h +++ b/platform/stm32f429/registers/rcc.h @@ -1,63 +1,112 @@ #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; - unsigned int GPIOBEN:1; - unsigned int GPIOCEN:1; - unsigned int GPIODEN:1; - unsigned int GPIOEEN:1; - unsigned int GPIOFEN:1; - unsigned int GPIOGEN:1; - unsigned int GPIOHEN:1; - unsigned int GPIOIEN:1; - unsigned int GPIOJEN:1; - unsigned int GPIOKEN:1; - unsigned int :1; - unsigned int CRCEN:1; - unsigned int :5; - unsigned int BKPSRAMEN:1; - unsigned int :1; - unsigned int CCMDATARAMEN:1; - unsigned int DMA1EN:1; - unsigned int DMA2EN:1; - unsigned int DMA2DEN:1; - unsigned int :1; - unsigned int ETHMACEN:1; - unsigned int ETHMACTXEN:1; - unsigned int ETHMACRXEN:1; - unsigned int ETHMACPTPEN:1; - unsigned int OTGHSEN:1; - unsigned int OTGHSULPIEN:1; - unsigned int :1; -} * RCC_AHB1ENR; +// Reset and clock control -extern struct { - unsigned int TIM1EN:1; - unsigned int TIM8EN:1; - unsigned int :2; - unsigned int USART1EN:1; - unsigned int USART6EN:1; - unsigned int :2; - unsigned int ADC1EN:1; - unsigned int ADC2EN:1; - unsigned int ADC3EN:1; - unsigned int SDIOEN:1; - unsigned int SPI1EN:1; - unsigned int SPI4EN:1; - unsigned int SYSCFGEN:1; - unsigned int :1; - unsigned int TIM9EN:1; - unsigned int TIM10EN:1; - unsigned int TIM11EN:1; - unsigned int :1; - unsigned int SPI5EN:1; - unsigned int SPI6EN:1; - unsigned int SAI1EN:1; - unsigned int :3; - unsigned int LTDCEN:1; - unsigned int :5; -} * RCC_APB2ENR; +#define RCC_BASE 0x40023800 + +#define RCC_REGISTER_AT(offset) (*(volatile uint32_t *)(RCC_BASE+offset)) + +// RCC clock control register + +#define RCC_CR RCC_REGISTER_AT(0x00) + +#define HSION (1<<0) +#define HSIRDY (1<<1) +#define LOW_BIT_HSITRIM 3 +#define HIGH_BIT_HSITRIM 7 +#define LOW_BIT_HSICAL 8 +#define HIGH_BIT_HSICAL 15 +#define HSEON (1<<16) +#define HSERDY (1<<17) +#define HSEBYP (1<<18) +#define CSSON (1<<19) +#define PLLON (1<<24) +#define PLLRDY (1<<25) +#define PLLI2SON (1<<26) +#define PLLI2SRDY (1<<27) +#define PLLSAION (1<<28) +#define PLLSAIRDY (1<<29) + +// RCC AHB1 peripheral clock enable register + +#define RCC_AHB1ENR RCC_REGISTER_AT(0x30) + +#define GPIOAEN (1<<0) +#define GPIOBEN (1<<1) +#define GPIOCEN (1<<2) +#define GPIODEN (1<<3) +#define GPIOEEN (1<<4) +#define GPIOFEN (1<<5) +#define GPIOGEN (1<<6) +#define GPIOHEN (1<<7) +#define GPIOIEN (1<<8) +#define GPIOJEN (1<<9) +#define GPIOKEN (1<<10) +#define CRCEN (1<<12) +#define BKPSRAMEN (1<<18) +#define CCMDATARAMEN (1<<20) +#define DMA1EN (1<<21) +#define DMA2EN (1<<22) +#define DMA2DEN (1<<23) +#define ETHMACEN (1<<25) +#define ETHMACTXEN (1<<26) +#define ETHMACRXEN (1<<27) +#define ETHMACPTPEN (1<<28) +#define OTGHSEN (1<<29) +#define OTGHSULPIEN (1<<30) + +// RCC APB2 peripheral clock enable register + +#define RCC_APB2ENR RCC_REGISTER_AT(0x44) + +#define TIM1EN (1<<0) +#define TIM8EN (1<<1) +#define USART1EN (1<<4) +#define USART6EN (1<<5) +#define ADC1 (1<<8) +#define ADC2 (1<<9) +#define ADC3 (1<<10) +#define SDIOEN (1<<11) +#define SPI1EN (1<<12) +#define SPI4EN (1<<13) +#define SYSCFGEN (1<<14) +#define TIM9EN (1<<16) +#define TIM10EN (1<<17) +#define TIM11EN (1<<18) +#define SPI5EN (1<<20) +#define SPI6EN (1<<21) +#define SAI1EN (1<<22) +#define LTDCEN (1<<26) + +// RCC PLL configuration register + +#define RCC_PLLSAICFGR RCC_REGISTER_AT(0x88) + +#define LOW_BIT_PLLSAIN 6 +#define HIGH_BIT_PLLSAIN 14 +#define RCC_PLLSAIN(v) REGISTER_FIELD_VALUE(PLLSAIN, v) +#define LOW_BIT_PLLSAIQ 24 +#define HIGH_BIT_PLLSAIQ 27 +#define RCC_PLLSAIQ(v) REGISTER_FIELD_VALUE(PLLSAIQ, v) +#define LOW_BIT_PLLSAIR 28 +#define HIGH_BIT_PLLSAIR 30 +#define RCC_PLLSAIR(v) REGISTER_FIELD_VALUE(PLLSAIR, v) + +// RCC dedicated clock configuration register + +#define RCC_DCKCFGR RCC_REGISTER_AT(0x8C) + +#define LOW_BIT_PLLIS2DIVQ 0 +#define HIGH_BIT_PLLIS2DIVQ 4 +#define LOW_BIT_PLLSAIDIVQ 8 +#define HIGH_BIT_PLLSAIDIVQ 12 +#define LOW_BIT_PLLSAIDIVR 16 +#define HIGH_BIT_PLLSAIDIVR 17 +#define LOW_BIT_SAI1ASRC 20 +#define HIGH_BIT_SAI1ASRC 21 +#define LOW_BIT_SAI1BSRC 22 +#define HIGH_BIT_SAI1BSRC 23 +#define TIMPRE (1<<24) #endif diff --git a/platform/stm32f429/registers/spi.c b/platform/stm32f429/registers/spi.c deleted file mode 100644 index d8b46f56b..000000000 --- a/platform/stm32f429/registers/spi.c +++ /dev/null @@ -1,32 +0,0 @@ -#include "spi.h" - -#define SPI1_BASE 0x40013000 -#define SPI2_BASE 0x40003800 -#define SPI3_BASE 0x40003C00 -#define SPI4_BASE 0x40013400 -#define SPI5_BASE 0x40015000 -#define SPI6_BASE 0x40015400 - -#define SPI_CR1_OFFSET 0x00 -#define SPI_SR_OFFSET 0x08 -#define SPI_DR_OFFSET 0x0C - -char * SPI_REGISTER_ADDRESS(SPI_t spi, int registerOffset) { - char * spiBaseAddress[6] = { - (char *)SPI1_BASE, (char *)SPI2_BASE, (char *)SPI3_BASE, - (char *)SPI4_BASE, (char *)SPI5_BASE, (char *)SPI6_BASE - }; - return spiBaseAddress[spi] + registerOffset; -} - -SPI_CR1_t * SPI_CR1(SPI_t spi) { - return (SPI_CR1_t *)SPI_REGISTER_ADDRESS(spi, SPI_CR1_OFFSET); -} - -volatile SPI_SR_t * SPI_SR(SPI_t spi) { - return (SPI_SR_t *)SPI_REGISTER_ADDRESS(spi, SPI_SR_OFFSET); -} - -volatile SPI_DR_t * SPI_DR(SPI_t spi) { - return (SPI_DR_t *)SPI_REGISTER_ADDRESS(spi, SPI_DR_OFFSET); -} diff --git a/platform/stm32f429/registers/spi.h b/platform/stm32f429/registers/spi.h index 64832bace..92c74b6ce 100644 --- a/platform/stm32f429/registers/spi.h +++ b/platform/stm32f429/registers/spi.h @@ -1,74 +1,66 @@ #ifndef STM32F429_REGISTERS_SPI_H #define STM32F429_REGISTERS_SPI_H 1 -#include +// Serial Peripheral Interface registers -typedef enum { - SPI1 = 0, - SPI2 = 1, - SPI3 = 2, - SPI4 = 3, - SPI5 = 4, - SPI6 = 5 -} SPI_t; +#define SPI1_BASE 0x40013000 +#define SPI2_BASE 0x40003800 +#define SPI3_BASE 0x40003C00 +#define SPI4_BASE 0x40013400 +#define SPI5_BASE 0x40015000 +#define SPI6_BASE 0x40015400 -#pragma mark - SPI control registers 1 +#define SPI_REGISTER_AT(spi_port,offset) (*(volatile uint16_t *)(spi_port##_BASE+offset)) -typedef enum { - SPI_BR_DIV_2 = 0, - SPI_BR_DIV_4 = 1, - SPI_BR_DIV_8 = 2, - SPI_BR_DIV_16 = 3, - SPI_BR_DIV_32 = 4, - SPI_BR_DIV_64 = 5, - SPI_BR_DIV_128 = 6, - SPI_BR_DIV_256 = 7 -} SPI_BR_t; +// SPI control registers 1 -typedef enum { - SPI_DFF_8_BITS = 0, - SPI_DFF_16_BITS = 1 -} SPI_DFF_t; +#define SPI_CR1(spi_port) SPI_REGISTER_AT(spi_port, 0x00) -typedef struct { - unsigned int CPHA:1; - unsigned int CPOL:1; - unsigned int MSTR:1; - SPI_BR_t BR:3; - unsigned int SPE:1; - unsigned int LSBFIRST:1; - unsigned int SSI:1; - unsigned int SSM:1; - unsigned int RXONLY:1; - SPI_DFF_t DFF:1; - unsigned int CRCNEXT:1; - unsigned int CRCEN:1; - unsigned int BIDIOE:1; - unsigned int BIDIMODE:1; -} SPI_CR1_t; +#define SPI_BR_DIV_2 0 +#define SPI_BR_DIV_4 1 +#define SPI_BR_DIV_8 2 +#define SPI_BR_DIV_16 3 +#define SPI_BR_DIV_32 4 +#define SPI_BR_DIV_64 5 +#define SPI_BR_DIV_128 6 +#define SPI_BR_DIV_256 7 -SPI_CR1_t * SPI_CR1(SPI_t spi); +#define SPI_DFF_8_BITS 0 +#define SPI_DFF_16_BITS 1 -#pragma mark - SPI status registers +#define SPI_CPHA (1<<0) +#define SPI_CPOL (1<<1) +#define SPI_MSTR (1<<2) +#define LOW_BIT_SPI_BR 3 +#define HIGH_BIT_SPI_BR 5 +#define SPI_BR(v) REGISTER_FIELD_VALUE(SPI_BR, v) +#define SPI_SPE (1<<6) +#define SPI_LSBFIRST (1<<7) +#define SPI_SSI (1<<8) +#define SPI_SSM (1<<9) +#define SPI_RXONLY (1<<10) +#define SPI_DFF (1<<11) +#define SPI_CRCNEXT (1<<12) +#define SPI_CRCEN (1<<13) +#define SPI_BIDIOE (1<<14) +#define SPI_BIDIMODE (1<<15) -typedef struct { - unsigned int RXNE:1; - unsigned int TXE:1; - unsigned int CHSIDE:1; - unsigned int UDR:1; - unsigned int CRCERR:1; - unsigned int MODF:1; - unsigned int OVR:1; - unsigned int BSY:1; - unsigned int FRE:1; - unsigned int :7; -} SPI_SR_t; +// SPI status registers -volatile SPI_SR_t * SPI_SR(SPI_t spi); +#define SPI_SR(spi_port) SPI_REGISTER_AT(spi_port, 0x08) -#pragma mark - SPI data registers +#define SPI_RXNE (1<<0) +#define SPI_TXE (1<<1) +#define SPI_CHSIDE (1<<2) +#define SPI_UDR (1<<3) +#define SPI_CRCERR (1<<4) +#define SPI_MODF (1<<5) +#define SPI_OVR (1<<6) +#define SPI_BSY (1<<7) +#define SPI_FRE (1<<8) -typedef uint16_t SPI_DR_t; -volatile SPI_DR_t * SPI_DR(SPI_t spi); +// SPI data registers + +#define SPI_DR(spi_port) SPI_REGISTER_AT(spi_port, 0x0C) #endif