diff --git a/include/libopencm3/stm32/common/spi_common_all.h b/include/libopencm3/stm32/common/spi_common_all.h index fbd1e9c4..f27318d5 100644 --- a/include/libopencm3/stm32/common/spi_common_all.h +++ b/include/libopencm3/stm32/common/spi_common_all.h @@ -48,6 +48,9 @@ specific memorymap.h header before including this header file.*/ #define SPI1 SPI1_BASE #define SPI2 SPI2_I2S_BASE #define SPI3 SPI3_I2S_BASE +#define SPI4 SPI4_BASE +#define SPI5 SPI5_BASE +#define SPI6 SPI6_BASE /**@}*/ /* --- SPI registers ------------------------------------------------------- */ diff --git a/include/libopencm3/stm32/common/usart_common_f24.h b/include/libopencm3/stm32/common/usart_common_f24.h index 64a8b152..e8d9f7f0 100644 --- a/include/libopencm3/stm32/common/usart_common_f24.h +++ b/include/libopencm3/stm32/common/usart_common_f24.h @@ -39,29 +39,45 @@ specific memorymap.h header before including this header file.*/ /* --- Convenience macros -------------------------------------------------- */ #define USART6 USART6_BASE +#define UART7 UART7_BASE +#define UART8 UART8_BASE /* --- USART registers ----------------------------------------------------- */ /* Status register (USARTx_SR) */ #define USART6_SR USART_SR(USART6_BASE) +#define UART7_SR USART_SR(UART7) +#define UART8_SR USART_SR(UART8) /* Data register (USARTx_DR) */ #define USART6_DR USART_DR(USART6_BASE) +#define UART7_DR USART_DR(UART7) +#define UART8_DR USART_DR(UART8) /* Baud rate register (USARTx_BRR) */ #define USART6_BRR USART_BRR(USART6_BASE) +#define UART7_BRR USART_BRR(UART7) +#define UART8_BRR USART_BRR(UART8) /* Control register 1 (USARTx_CR1) */ #define USART6_CR1 USART_CR1(USART6_BASE) +#define UART7_CR1 USART_CR1(UART7) +#define UART8_CR1 USART_CR1(UART8) /* Control register 2 (USARTx_CR2) */ #define USART6_CR2 USART_CR2(USART6_BASE) +#define UART7_CR2 USART_CR2(UART7) +#define UART8_CR2 USART_CR2(UART8) /* Control register 3 (USARTx_CR3) */ #define USART6_CR3 USART_CR3(USART6_BASE) +#define UART7_CR3 USART_CR3(UART7) +#define UART8_CR3 USART_CR3(UART8) /* Guard time and prescaler register (USARTx_GTPR) */ #define USART6_GTPR USART_GTPR(USART6_BASE) +#define UART7_GTPR USART_GTPR(UART7) +#define UART8_GTPR USART_GTPR(UART8) /* --- USART_CR1 values ---------------------------------------------------- */ diff --git a/include/libopencm3/stm32/f4/fmc.h b/include/libopencm3/stm32/f4/fmc.h new file mode 100644 index 00000000..65466916 --- /dev/null +++ b/include/libopencm3/stm32/f4/fmc.h @@ -0,0 +1,247 @@ +/* vim: set noexpandtab ts=8 : + * This file is part of the libopencm3 project. + * + * Copyright (C) 2013 Chuck McManis + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#ifndef LIBOPENCM3_FMC_H +#define LIBOPENCM3_FMC_H + +#ifndef LIBOPENCM3_FSMC_H +error "This file should not be included directly, it is included with fsmc.h" +#endif + +/* --- Convenience macros -------------------------------------------------- */ + +#define FMC_BANK5_BASE 0xa0000000U +#define FMC_BANK6_BASE 0xb0000000U +#define FMC_BANK7_BASE 0xc0000000U +#define FMC_BANK8_BASE 0xd0000000U + +/* --- FMC registers ------------------------------------------------------ */ + +/* SDRAM Control Registers 1 .. 2 */ +#define FMC_SDCR(x) MMIO32(FSMC_BASE + 0x140 + 4 * x) +#define FMC_SDCR1 FMC_SDCR(0) +#define FMC_SDCR2 FMC_SDCR(1) + + +/* SDRAM Timing Registers 1 .. 2 */ +#define FMC_SDTR(x) MMIO32(FSMC_BASE + 0x148 + 4 * x) +#define FMC_SDTR1 FMC_SDTR(0) +#define FMC_SDTR2 FMC_SDTR(1) + +/* SDRAM Command Mode Register */ +#define FMC_SDCMR MMIO32(FSMC_BASE + (uint32_t) 0x150) + +/* SDRAM Refresh Timer Register */ +#define FMC_SDRTR MMIO32(FSMC_BASE + 0x154) + +/* SDRAM Status Register */ +#define FMC_SDSR MMIO32(FSMC_BASE + (uint32_t) 0x158) + +/* --- FMC_SDCRx values ---------------------------------------------------- */ + +/* Bits [31:15]: Reserved. */ + +/* RPIPE: Read Pipe */ +#define FMC_SDCR_RPIPE_SHIFT (1 << 13) +#define FMC_SDCR_RPIPE_MASK (3 << 13) +#define FMC_SDCR_RPIPE_NONE (0x0) /* No Delay */ +#define FMC_SDCR_RPIPE_1CLK (1 << 13) /* one clock */ +#define FMC_SDCR_RPIPE_2CLK (2 << 13) /* two clocks */ + +/* RBURST: Burst Read */ +#define FMC_SDCR_RBURST (1 << 12) + +/* SDCLK: SDRAM Clock Configuration */ +#define FMC_SDCR_SDCLK_SHIFT (1 << 10) +#define FMC_SDCR_SDCLK_MASK (3 << 10) +#define FMC_SDCR_SDCLK_DISABLE (0) +#define FMC_SDCR_SDCLK_2HCLK (2 << 10) +#define FMC_SDCR_SDCLK_3HCLK (3 << 10) + +/* WP: Write Protect */ +#define FMC_SDCR_WP_ENABLE (1 << 9) + +/* CAS: CAS Latency */ +#define FMC_SDCR_CAS_SHIFT (1 << 7) +#define FMC_SDCR_CAS_1CYC (1 << 7) +#define FMC_SDCR_CAS_2CYC (2 << 7) +#define FMC_SDCR_CAS_3CYC (3 << 7) + +/* NB: Number of Internal banks */ +#define FMC_SDCR_NB2 0 +#define FMC_SDCR_NB4 (1 << 6) + +/* MWID: Memory width */ +#define FMC_SDCR_MWID_SHIFT (1 << 4) +#define FMC_SDCR_MWID_8b (0 << 4) +#define FMC_SDCR_MWID_16b (1 << 4) +#define FMC_SDCR_MWID_32b (2 << 4) + +/* NR: Number of rows */ +#define FMC_SDCR_NR_SHIFT (1 << 2) +#define FMC_SDCR_NR_11 (0 << 2) +#define FMC_SDCR_NR_12 (1 << 2) +#define FMC_SDCR_NR_13 (2 << 2) + +/* NC: Number of Columns */ +#define FMC_SDCR_NC_SHIFT (1 << 0) +#define FMC_SDCR_NC_8 (0 << 0) +#define FMC_SDCR_NC_9 (1 << 0) +#define FMC_SDCR_NC_10 (2 << 0) +#define FMC_SDCR_NC_11 (3 << 0) + +/* --- FMC_SDTRx values --------------------------------------------------- */ + +/* Bits [31:28]: Reserved. */ + +/* TRCD: Row to Column Delay */ +#define FMC_SDTR_TRCD_SHIFT (1 << 24) +#define FMC_SDTR_TRCD_MASK (15 << 24) + +/* TRP: Row Precharge Delay */ +#define FMC_SDTR_TRP_SHIFT (1 << 20) +#define FMC_SDTR_TRP_MASK (15 << 20) + +/* TWR: Recovery Delay */ +#define FMC_SDTR_TWR_SHIFT (1 << 16) +#define FMC_SDTR_TWR_MASK (15 << 16) + +/* TRC: Row Cycle Delay */ +#define FMC_SDTR_TRC_SHIFT (1 << 12) +#define FMC_SDTR_TRC_MASK (15 << 12) + +/* TRAS: Self Refresh Time */ +#define FMC_SDTR_TRAS_SHIFT (1 << 8) +#define FMC_SDTR_TRAS_MASK (15 << 8) + +/* TXSR: Exit Self-refresh Delay */ +#define FMC_SDTR_TXSR_SHIFT (1 << 4) +#define FMC_SDTR_TXSR_MASK (15 << 4) + +/* TRMD: Load Mode Register to Active */ +#define FMC_SDTR_TMRD_SHIFT (1 << 0) +#define FMC_SDTR_TMRD_MASK (15 << 0) + +/* + * Some config bits only count in CR1 or TR1, even if you + * are just configuring bank 2, so these masks let you copy + * out those bits after you have computed values for CR2 and + * TR2 and put them into CR1 and TR1 + */ +#define FMC_SDTR_DNC_MASK ( FMC_SDTR_TRP_MASK| FMC_SDTR_TRC_MASK ) +#define FMC_SDCR_DNC_MASK ( FMC_SDCR_SDCLK_MASK |\ + FMC_SDCR_RPIPE_MASK |\ + FMC_SDCR_RBURST ) + +/* --- FMC_SDCMR values --------------------------------------------------- */ + +/* Bits [31:22]: Reserved. */ + +/* MRD: Mode Register Definition */ +#define FMC_SDCMR_MRD_SHIFT (1 << 9) +#define FMC_SDCMR_MRD_MASK (0x1fff << 9) + +/* NRFS: Number of Auto-refresh */ +#define FMC_SDCMR_NRFS_SHIFT (1 << 5) +#define FMC_SDCMR_NRFS_MASK (15 << 5) + +/* CTB1: Command Target Bank 1 */ +#define FMC_SDCMR_CTB1 (1 << 4) + +/* CTB2: Command Target Bank 2 */ +#define FMC_SDCMR_CTB2 (1 << 3) + +/* MODE: Command Mode */ +#define FMC_SDCMR_MODE_SHIFT (1 << 0) +#define FMC_SDCMR_MODE_MASK (7 << 0) +#define FMC_SDCMR_MODE_NORMAL 0 +#define FMC_SDCMR_MODE_CLOCK_CONFIG_ENA 1 +#define FMC_SDCMR_MODE_PALL 2 +#define FMC_SDCMR_MODE_AUTO_REFRESH 3 +#define FMC_SDCMR_MODE_LOAD_MODE_REGISTER 4 +#define FMC_SDCMR_MODE_SELF_REFRESH 5 +#define FMC_SDCMR_MODE_POWER_DOWN 6 + +/* --- FMC_SDRTR values ---------------------------------------------------- */ + +/* Bits [31:15]: Reserved. */ + +/* REIE: Refresh Error Interrupt Enable */ +#define FMC_SDRTR_REIE (1 << 14) + +/* COUNT: Refresh Timer Count */ +#define FMC_SDRTR_COUNT_SHIFT (1 << 1) +#define FMC_SDRTR_COUNT_MASK (0x1fff << 1) + +/* CRE: Clear Refresh Error Flag */ +#define FMC_SDRTR_CRE (1 << 0) + +/* --- FMC_SDSR values ---------------------------------------------------- */ + +/* Bits [31:6]: Reserved. */ + +/* BUSY: Set if the SDRAM is working on the command */ +#define FMC_SDSR_BUSY (1 << 5) + +/* MODES: Status modes */ +#define FMC_SDSR_MODE_NORMAL 0 +#define FMC_SDSR_MODE_SELF_REFRESH 1 +#define FMC_SDSR_MODE_POWER_DOWN 2 + +/* Mode shift */ +#define FMC_SDSR_MODE2_SHIFT ( 1 << 3) +#define FMC_SDSR_MODE1_SHIFT ( 1 << 1) + +/* RE: Refresh Error */ +#define FMC_SDSR_RE (1 << 0) + +/* Helper function for setting the timing parameters */ +struct sdram_timing { + int trcd; /* RCD Delay */ + int trp; /* RP Delay */ + int twr; /* Write Recovery Time */ + int trc; /* Row Cycle Delay */ + int tras; /* Self Refresh TIme */ + int txsr; /* Exit Self Refresh Time */ + int tmrd; /* Load to Active delay */ +}; + +/* Mode register parameters */ +#define SDRAM_MODE_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODE_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODE_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODE_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODE_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODE_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODE_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODE_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODE_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODE_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODE_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +enum fmc_sdram_bank { SDRAM_BANK1, SDRAM_BANK2, SDRAM_BOTH_BANKS }; +enum fmc_sdram_command { SDRAM_CLK_CONF, SDRAM_NORMAL, SDRAM_PALL, + SDRAM_AUTO_REFRESH, SDRAM_LOAD_MODE, + SDRAM_SELF_REFRESH, SDRAM_POWER_DOWN }; + +/* Send an array of timing parameters (indices above) to create SDTR register value */ +uint32_t sdram_timing(struct sdram_timing *t); +void sdram_command(enum fmc_sdram_bank bank, enum fmc_sdram_command cmd, + int autorefresh, int modereg); +#endif diff --git a/include/libopencm3/stm32/f4/irq.json b/include/libopencm3/stm32/f4/irq.json index 33d84bdd..9acf1dd7 100644 --- a/include/libopencm3/stm32/f4/irq.json +++ b/include/libopencm3/stm32/f4/irq.json @@ -80,9 +80,19 @@ "otg_hs", "dcmi", "cryp", - "hash_rng" + "hash_rng", + "fpu", + "uart7", + "uart8", + "spi4", + "spi5", + "spi6", + "sai1", + "lcd_tft", + "lcd_tft_err", + "dma2d" ], "partname_humanreadable": "STM32 F4 series", "partname_doxygen": "STM32F4", "includeguard": "LIBOPENCM3_STM32_F4_NVIC_H" -} \ No newline at end of file +} diff --git a/include/libopencm3/stm32/f4/memorymap.h b/include/libopencm3/stm32/f4/memorymap.h index 37c57f2f..136364f9 100644 --- a/include/libopencm3/stm32/f4/memorymap.h +++ b/include/libopencm3/stm32/f4/memorymap.h @@ -29,8 +29,8 @@ #define PERIPH_BASE_APB1 (PERIPH_BASE + 0x00000) #define PERIPH_BASE_APB2 (PERIPH_BASE + 0x10000) #define PERIPH_BASE_AHB1 (PERIPH_BASE + 0x20000) -#define PERIPH_BASE_AHB2 0x50000000 -#define PERIPH_BASE_AHB3 0x60000000 +#define PERIPH_BASE_AHB2 0x50000000U +#define PERIPH_BASE_AHB3 0x60000000U /* Register boundary addresses */ @@ -48,10 +48,10 @@ #define RTC_BASE (PERIPH_BASE_APB1 + 0x2800) #define WWDG_BASE (PERIPH_BASE_APB1 + 0x2c00) #define IWDG_BASE (PERIPH_BASE_APB1 + 0x3000) -/* PERIPH_BASE_APB1 + 0x3400 (0x4000 3400 - 0x4000 37FF): Reserved */ +#define I2S3_EXT_BASE (PERIPH_BASE_APB1 + 0x3400) #define SPI2_I2S_BASE (PERIPH_BASE_APB1 + 0x3800) #define SPI3_I2S_BASE (PERIPH_BASE_APB1 + 0x3c00) -/* PERIPH_BASE_APB1 + 0x4000 (0x4000 4000 - 0x4000 3FFF): Reserved */ +#define I2S2_EXT_BASE (PERIPH_BASE_APB1 + 0x4000) #define USART2_BASE (PERIPH_BASE_APB1 + 0x4400) #define USART3_BASE (PERIPH_BASE_APB1 + 0x4800) #define UART4_BASE (PERIPH_BASE_APB1 + 0x4c00) @@ -65,7 +65,9 @@ /* PERIPH_BASE_APB1 + 0x6C00 (0x4000 6C00 - 0x4000 6FFF): Reserved */ #define POWER_CONTROL_BASE (PERIPH_BASE_APB1 + 0x7000) #define DAC_BASE (PERIPH_BASE_APB1 + 0x7400) -/* PERIPH_BASE_APB1 + 0x7800 (0x4000 7800 - 0x4000 FFFF): Reserved */ +#define UART7_BASE (PERIPH_BASE_APB1 + 0x7800) +#define UART8_BASE (PERIPH_BASE_APB1 + 0x7c00) +/* PERIPH_BASE_APB1 + 0x7800 (0x4000 8000 - 0x4000 FFFF): Reserved */ /* APB2 */ #define TIM1_BASE (PERIPH_BASE_APB2 + 0x0000) @@ -82,13 +84,19 @@ #define SDIO_BASE (PERIPH_BASE_APB2 + 0x2C00) /* PERIPH_BASE_APB2 + 0x2C00 (0x4001 2C00 - 0x4001 2FFF): Reserved */ #define SPI1_BASE (PERIPH_BASE_APB2 + 0x3000) -/* PERIPH_BASE_APB2 + 0x3400 (0x4001 3400 - 0x4001 37FF): Reserved */ +#define SPI4_BASE (PERIPH_BASE_APB2 + 0x3400) +/* PERIPH_BASE_APB2 + 0x3500 (0x4001 3500 - 0x4001 37FF): Reserved */ #define SYSCFG_BASE (PERIPH_BASE_APB2 + 0x3800) #define EXTI_BASE (PERIPH_BASE_APB2 + 0x3C00) #define TIM9_BASE (PERIPH_BASE_APB2 + 0x4000) #define TIM10_BASE (PERIPH_BASE_APB2 + 0x4400) #define TIM11_BASE (PERIPH_BASE_APB2 + 0x4800) -/* PERIPH_BASE_APB2 + 0x4C00 (0x4001 4C00 - 0x4001 FFFF): Reserved */ +/* PERIPH_BASE_APB2 + 0x4C00 (0x4001 4C00 - 0x4001 4FFF): Reserved */ +#define SPI5_BASE (PERIPH_BASE_APB2 + 0x5000) +#define SPI6_BASE (PERIPH_BASE_APB2 + 0x5400) +#define SAI1_BASE (PERIPH_BASE_APB2 + 0x5800) +#define LCD_TFT_BASE (PERIPH_BASE_APB2 + 0x6800) +/* PERIPH_BASE_APB2 + 0x6C00 (0x4001 6C00 - 0x4001 FFFF): Reserved */ /* AHB1 */ #define GPIO_PORT_A_BASE (PERIPH_BASE_AHB1 + 0x0000) @@ -105,7 +113,7 @@ /* PERIPH_BASE_AHB1 + 0x3400 (0x4002 3400 - 0x4002 37FF): Reserved */ #define RCC_BASE (PERIPH_BASE_AHB1 + 0x3800) #define FLASH_MEM_INTERFACE_BASE (PERIPH_BASE_AHB1 + 0x3C00) -#define BKPSRAM_BASE (PERIPH_BASE_AHB1 + 0x4000) +#define BKPSRAM_BASE (PERIPH_BASE_AHB1 + 0x4000) /* PERIPH_BASE_AHB1 + 0x5000 (0x4002 5000 - 0x4002 5FFF): Reserved */ #define DMA1_BASE (PERIPH_BASE_AHB1 + 0x6000) #define DMA2_BASE (PERIPH_BASE_AHB1 + 0x6400) @@ -118,16 +126,16 @@ /* AHB2 */ #define USB_OTG_FS_BASE (PERIPH_BASE_AHB2 + 0x00000) /* PERIPH_BASE_AHB2 + 0x40000 (0x5004 0000 - 0x5004 FFFF): Reserved */ -#define DCMI_BASE (PERIPH_BASE_AHB2 + 0x50000) +#define DCMI_BASE (PERIPH_BASE_AHB2 + 0x50000) /* PERIPH_BASE_AHB2 + 0x50400 (0x5005 0400 - 0x5005 FFFF): Reserved */ -#define CRYP_BASE (PERIPH_BASE_AHB2 + 0x60000) -#define HASH_BASE (PERIPH_BASE_AHB2 + 0x60400) +#define CRYP_BASE (PERIPH_BASE_AHB2 + 0x60000) +#define HASH_BASE (PERIPH_BASE_AHB2 + 0x60400) /* PERIPH_BASE_AHB2 + 0x60C00 (0x5006 0C00 - 0x5006 07FF): Reserved */ -#define RNG_BASE (PERIPH_BASE_AHB2 + 0x60800) +#define RNG_BASE (PERIPH_BASE_AHB2 + 0x60800) /* PERIPH_BASE_AHB2 + 0x61000 (0x5006 1000 - 0x5FFF FFFF): Reserved */ /* AHB3 */ -#define FSMC_BASE (PERIPH_BASE_AHB3 + 0x40000000) +#define FSMC_BASE (PERIPH_BASE_AHB3 + 0x40000000U) /* PPIB */ #define DBGMCU_BASE (PPBI_BASE + 0x00042000) diff --git a/include/libopencm3/stm32/f4/rcc.h b/include/libopencm3/stm32/f4/rcc.h index 861d9fed..928d8fa8 100644 --- a/include/libopencm3/stm32/f4/rcc.h +++ b/include/libopencm3/stm32/f4/rcc.h @@ -310,9 +310,13 @@ /* --- RCC_AHB3ENR values ------------------------------------------------- */ #define RCC_AHB3ENR_FSMCEN (1 << 0) +/* Alternate now that F429 has DRAM controller as well */ +#define RCC_AHB3ENR_FMCEN (1 << 0) /* --- RCC_APB1ENR values ------------------------------------------------- */ +#define RCC_APB1ENR_UART8EN (1 << 31) +#define RCC_APB1ENR_UART7EN (1 << 30) #define RCC_APB1ENR_DACEN (1 << 29) #define RCC_APB1ENR_PWREN (1 << 28) #define RCC_APB1ENR_CAN2EN (1 << 26) @@ -339,10 +343,13 @@ /* --- RCC_APB2ENR values ------------------------------------------------- */ +#define RCC_APB2ENR_SPI6EN (1 << 21) +#define RCC_APB2ENR_SPI5EN (1 << 20) #define RCC_APB2ENR_TIM11EN (1 << 18) #define RCC_APB2ENR_TIM10EN (1 << 17) #define RCC_APB2ENR_TIM9EN (1 << 16) #define RCC_APB2ENR_SYSCFGEN (1 << 14) +#define RCC_APB2ENR_SPI4EN (1 << 13) #define RCC_APB2ENR_SPI1EN (1 << 12) #define RCC_APB2ENR_SDIOEN (1 << 11) #define RCC_APB2ENR_ADC3EN (1 << 10) diff --git a/include/libopencm3/stm32/fsmc.h b/include/libopencm3/stm32/fsmc.h index 2a8e55c3..05773580 100644 --- a/include/libopencm3/stm32/fsmc.h +++ b/include/libopencm3/stm32/fsmc.h @@ -23,6 +23,10 @@ #include #include +#if defined(STM32F4) +# include +#endif + /* --- Convenience macros -------------------------------------------------- */ #define FSMC_BANK1_BASE 0x60000000 /* NOR / PSRAM */ diff --git a/lib/stm32/f4/Makefile b/lib/stm32/f4/Makefile index 8f96e5fb..c649af53 100644 --- a/lib/stm32/f4/Makefile +++ b/lib/stm32/f4/Makefile @@ -50,7 +50,7 @@ OBJS += crc_common_all.o dac_common_all.o dma_common_f24.o \ OBJS += usb.o usb_standard.o usb_control.o usb_fx07_common.o \ usb_f107.o usb_f207.o -OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz8051mll.o +OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz8051mll.o fmc.o VPATH += ../../usb:../:../../cm3:../common VPATH += ../../ethernet diff --git a/lib/stm32/f4/fmc.c b/lib/stm32/f4/fmc.c new file mode 100644 index 00000000..107e9e5f --- /dev/null +++ b/lib/stm32/f4/fmc.c @@ -0,0 +1,99 @@ +/* vim: set noexpandtab ts=8: + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Utility functions for the SDRAM component of the FMC */ + +#include +#include + +/* + * Install various timing values into the correct place in the + * SDRAM Timing Control Register format. + * + * Note that the register is 'zero' based to save bits so 1 cycle + * is stored as '0'. This command takes actual cycles and adjusts + * by subtracting 1. + */ +uint32_t +sdram_timing(struct sdram_timing *t) { + uint32_t result; + + result = 0; + result |= ((t->trcd - 1) & 0xf) * FMC_SDTR_TRCD_SHIFT; + result |= ((t->trp - 1) & 0xf) * FMC_SDTR_TRP_SHIFT; + result |= ((t->twr - 1) & 0xf) * FMC_SDTR_TWR_SHIFT; + result |= ((t->trc - 1) & 0xf) * FMC_SDTR_TRC_SHIFT; + result |= ((t->tras - 1) & 0xf) * FMC_SDTR_TRAS_SHIFT; + result |= ((t->txsr - 1) & 0xf) * FMC_SDTR_TXSR_SHIFT; + result |= ((t->tmrd - 1) & 0xf) * FMC_SDTR_TMRD_SHIFT; + return result; +} + +/* + * Send a command to the SDRAM controller, wait until it is not + * busy before sending. This allows you to chain sending commands + * and the code will pause as needed between them. + */ +void +sdram_command(enum fmc_sdram_bank bank, + enum fmc_sdram_command cmd, int autorefresh, int modereg) { + uint32_t tmp_reg = 0; + + switch (bank) { + case SDRAM_BANK1: + tmp_reg = FMC_SDCMR_CTB1; + break; + case SDRAM_BANK2: + tmp_reg = FMC_SDCMR_CTB2; + break; + case SDRAM_BOTH_BANKS: + tmp_reg = FMC_SDCMR_CTB1 | FMC_SDCMR_CTB2; + break; + } + tmp_reg |= autorefresh * FMC_SDCMR_NRFS_SHIFT; + tmp_reg |= modereg * FMC_SDCMR_MRD_SHIFT; + switch (cmd) { + case SDRAM_CLK_CONF: + tmp_reg |= FMC_SDCMR_MODE_CLOCK_CONFIG_ENA; + break; + case SDRAM_AUTO_REFRESH: + tmp_reg |= FMC_SDCMR_MODE_AUTO_REFRESH; + break; + case SDRAM_LOAD_MODE: + tmp_reg |= FMC_SDCMR_MODE_LOAD_MODE_REGISTER; + break; + case SDRAM_PALL: + tmp_reg |= FMC_SDCMR_MODE_PALL; + break; + case SDRAM_SELF_REFRESH: + tmp_reg |= FMC_SDCMR_MODE_SELF_REFRESH; + break; + case SDRAM_POWER_DOWN: + tmp_reg |= FMC_SDCMR_MODE_POWER_DOWN; + break; + case SDRAM_NORMAL: + default: + break; + } + + /* Wait for the next chance to talk to the controller */ + while (FMC_SDSR & FMC_SDSR_BUSY) ; + + /* Send the next command */ + FMC_SDCMR = tmp_reg; +}