diff options
-rw-r--r-- | boards/base/STM32F746-Discovery/board.mk | 5 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/board_STM32F746Discovery.h | 85 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.c | 499 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.h | 165 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.c | 333 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.h | 96 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.c | 1123 | ||||
-rw-r--r-- | boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.h | 1337 | ||||
-rw-r--r-- | drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h | 61 | ||||
-rw-r--r-- | drivers/gdisp/STM32F746Discovery/driver.mk | 2 | ||||
-rw-r--r-- | drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c | 365 | ||||
-rw-r--r-- | drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h | 24 | ||||
-rw-r--r-- | drivers/gdisp/STM32F746Discovery/readme.txt | 11 | ||||
-rw-r--r-- | drivers/gdisp/STM32F746Discovery/stm32_ltdc.h | 138 |
14 files changed, 4244 insertions, 0 deletions
diff --git a/boards/base/STM32F746-Discovery/board.mk b/boards/base/STM32F746-Discovery/board.mk new file mode 100644 index 00000000..92854414 --- /dev/null +++ b/boards/base/STM32F746-Discovery/board.mk @@ -0,0 +1,5 @@ +GFXINC += $(GFXLIB)/boards/base/STM32F746-Discovery +GFXSRC += $(GFXLIB)/boards/base/STM32F746-Discovery/STM32F746_discovery_sdram.c \ + $(GFXLIB)/boards/base/STM32F746-Discovery/stm32f4xx_fmc.c + +include $(GFXLIB)/drivers/gdisp/STM32F746Discovery/driver.mk
\ No newline at end of file diff --git a/boards/base/STM32F746-Discovery/board_STM32F746Discovery.h b/boards/base/STM32F746-Discovery/board_STM32F746Discovery.h new file mode 100644 index 00000000..c06d06c6 --- /dev/null +++ b/boards/base/STM32F746-Discovery/board_STM32F746Discovery.h @@ -0,0 +1,85 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +#include "stm32f4xx_fmc.h" +#include "stm32f429i_discovery_sdram.h" +#include <string.h> + +static const ltdcConfig driverCfg = { + 480, 270, // Width, Height (pixels) + 10, 2, // Horizontal, Vertical sync (pixels) + 20, 2, // Horizontal, Vertical back porch (pixels) + 10, 4, // Horizontal, Vertical front porch (pixels) + 0, // Sync flags + 0x000000, // Clear color (RGB888) + + { // Background layer config + (LLDCOLOR_TYPE *)SDRAM_BANK_ADDR, // Frame buffer address + 480, 270, // Width, Height (pixels) + 480 * LTDC_PIXELBYTES, // Line pitch (bytes) + LTDC_PIXELFORMAT, // Pixel format + 0, 0, // Start pixel position (x, y) + 480, 270, // Size of virtual layer (cx, cy) + LTDC_COLOR_FUCHSIA, // Default color (ARGB8888) + 0x980088, // Color key (RGB888) + LTDC_BLEND_FIX1_FIX2, // Blending factors + 0, // Palette (RGB888, can be NULL) + 0, // Palette length + 0xFF, // Constant alpha factor + LTDC_LEF_ENABLE // Layer configuration flags + }, + + LTDC_UNUSED_LAYER_CONFIG // Foreground layer config +}; + +static inline void init_board(GDisplay *g) { + + // As we are not using multiple displays we set g->board to NULL as we don't use it. + g->board = 0; + + switch(g->controllerdisplay) { + case 0: + #define STM32_SAISRC_NOCLOCK (0 << 23) /**< No clock. */ + #define STM32_SAISRC_PLL (1 << 23) /**< SAI_CKIN is PLL. */ + #define STM32_SAIR_DIV2 (0 << 16) /**< R divided by 2. */ + #define STM32_SAIR_DIV4 (1 << 16) /**< R divided by 4. */ + #define STM32_SAIR_DIV8 (2 << 16) /**< R divided by 8. */ + #define STM32_SAIR_DIV16 (3 << 16) /**< R divided by 16. */ + + #define STM32_PLLSAIN_VALUE 192 + #define STM32_PLLSAIQ_VALUE 7 + #define STM32_PLLSAIR_VALUE 4 + #define STM32_PLLSAIR_POST STM32_SAIR_DIV4 + + /* PLLSAI activation.*/ + RCC->PLLSAICFGR = (STM32_PLLSAIN_VALUE << 6) | (STM32_PLLSAIR_VALUE << 28) | (STM32_PLLSAIQ_VALUE << 24); + RCC->DCKCFGR = (RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR) | STM32_PLLSAIR_POST; + RCC->CR |= RCC_CR_PLLSAION; + + // Initialise the SDRAM + SDRAM_Init(); + + // Clear the SDRAM + memset((void *)SDRAM_BANK_ADDR, 0, 0x400000); + + break; + } +} + +static inline void post_init_board(GDisplay *g) { + (void) g; +} + +static inline void set_backlight(GDisplay *g, uint8_t percent) { + (void) g; + (void) percent; +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.c b/boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.c new file mode 100644 index 00000000..d214b3f1 --- /dev/null +++ b/boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.c @@ -0,0 +1,499 @@ +/** + ****************************************************************************** + * @file stm32746g_discovery_sdram.c + * @author MCD Application Team + * @version V1.0.0 + * @date 25-June-2015 + * @brief This file includes the SDRAM driver for the MT48LC4M32B2B5-7 memory + * device mounted on STM32746G-Discovery board. + @verbatim + 1. How To use this driver: + -------------------------- + - This driver is used to drive the MT48LC4M32B2B5-7 SDRAM external memory mounted + on STM32746G-Discovery board. + - This driver does not need a specific component driver for the SDRAM device + to be included with. + + 2. Driver description: + --------------------- + + Initialization steps: + o Initialize the SDRAM external memory using the BSP_SDRAM_Init() function. This + function includes the MSP layer hardware resources initialization and the + FMC controller configuration to interface with the external SDRAM memory. + o It contains the SDRAM initialization sequence to program the SDRAM external + device using the function BSP_SDRAM_Initialization_sequence(). Note that this + sequence is standard for all SDRAM devices, but can include some differences + from a device to another. If it is the case, the right sequence should be + implemented separately. + + + SDRAM read/write operations + o SDRAM external memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_SDRAM_ReadData()/BSP_SDRAM_WriteData(), or by DMA transfer using the functions + BSP_SDRAM_ReadData_DMA()/BSP_SDRAM_WriteData_DMA(). + o The AHB access is performed with 32-bit width transaction, the DMA transfer + configuration is fixed at single (no burst) word transfer (see the + SDRAM_MspInit() static function). + o User can implement his own functions for read/write access with his desired + configurations. + o If interrupt mode is used for DMA transfer, the function BSP_SDRAM_DMA_IRQHandler() + is called in IRQ handler file, to serve the generated interrupt once the DMA + transfer is complete. + o You can send a command to the SDRAM device in runtime using the function + BSP_SDRAM_Sendcmd(), and giving the desired command as parameter chosen between + the predefined commands of the "FMC_SDRAM_CommandTypeDef" structure. + + @endverbatim + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32746g_discovery_sdram.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32746G_DISCOVERY + * @{ + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM STM32746G_DISCOVERY_SDRAM + * @{ + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Types_Definitions STM32746G_DISCOVERY_SDRAM Private Types Definitions + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Defines STM32746G_DISCOVERY_SDRAM Private Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Macros STM32746G_DISCOVERY_SDRAM Private Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Variables STM32746G_DISCOVERY_SDRAM Private Variables + * @{ + */ +static SDRAM_HandleTypeDef sdramHandle; +static FMC_SDRAM_TimingTypeDef Timing; +static FMC_SDRAM_CommandTypeDef Command; +/** + * @} + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Private_Function_Prototypes STM32746G_DISCOVERY_SDRAM Private Function Prototypes + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Functions STM32746G_DISCOVERY_SDRAM Exported Functions + * @{ + */ + +/** + * @brief Initializes the SDRAM device. + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_Init(void) +{ + static uint8_t sdramstatus = SDRAM_ERROR; + /* SDRAM device configuration */ + sdramHandle.Instance = FMC_SDRAM_DEVICE; + + /* Timing configuration for 100Mhz as SD clock frequency (System clock is up to 200Mhz) */ + Timing.LoadToActiveDelay = 2; + Timing.ExitSelfRefreshDelay = 7; + Timing.SelfRefreshTime = 4; + Timing.RowCycleDelay = 7; + Timing.WriteRecoveryTime = 2; + Timing.RPDelay = 2; + Timing.RCDDelay = 2; + + sdramHandle.Init.SDBank = FMC_SDRAM_BANK1; + sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; + sdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; + sdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH; + sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; + sdramHandle.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2; + sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; + sdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD; + sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE; + sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0; + + /* SDRAM controller initialization */ + + BSP_SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */ + + if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK) + { + sdramstatus = SDRAM_ERROR; + } + else + { + sdramstatus = SDRAM_OK; + } + + /* SDRAM initialization sequence */ + BSP_SDRAM_Initialization_sequence(REFRESH_COUNT); + + return sdramstatus; +} + +/** + * @brief DeInitializes the SDRAM device. + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_DeInit(void) +{ + static uint8_t sdramstatus = SDRAM_ERROR; + /* SDRAM device de-initialization */ + sdramHandle.Instance = FMC_SDRAM_DEVICE; + + if(HAL_SDRAM_DeInit(&sdramHandle) != HAL_OK) + { + sdramstatus = SDRAM_ERROR; + } + else + { + sdramstatus = SDRAM_OK; + } + + /* SDRAM controller de-initialization */ + BSP_SDRAM_MspDeInit(&sdramHandle, NULL); + + return sdramstatus; +} + +/** + * @brief Programs the SDRAM device. + * @param RefreshCount: SDRAM refresh counter value + * @retval None + */ +void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount) +{ + __IO uint32_t tmpmrd = 0; + + /* Step 1: Configure a clock configuration enable command */ + Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 2: Insert 100 us minimum delay */ + /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ + HAL_Delay(1); + + /* Step 3: Configure a PALL (precharge all) command */ + Command.CommandMode = FMC_SDRAM_CMD_PALL; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 4: Configure an Auto Refresh command */ + Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + Command.AutoRefreshNumber = 8; + Command.ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 5: Program the external memory mode register */ + tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |\ + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |\ + SDRAM_MODEREG_CAS_LATENCY_2 |\ + SDRAM_MODEREG_OPERATING_MODE_STANDARD |\ + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = tmpmrd; + + /* Send the command */ + HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 6: Set the refresh rate counter */ + /* Set the device refresh rate */ + HAL_SDRAM_ProgramRefreshRate(&sdramHandle, RefreshCount); +} + +/** + * @brief Reads an amount of data from the SDRAM memory in polling mode. + * @param uwStartAddress: Read start address + * @param pData: Pointer to data to be read + * @param uwDataSize: Size of read data from the memory + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) +{ + if(HAL_SDRAM_Read_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK) + { + return SDRAM_ERROR; + } + else + { + return SDRAM_OK; + } +} + +/** + * @brief Reads an amount of data from the SDRAM memory in DMA mode. + * @param uwStartAddress: Read start address + * @param pData: Pointer to data to be read + * @param uwDataSize: Size of read data from the memory + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) +{ + if(HAL_SDRAM_Read_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK) + { + return SDRAM_ERROR; + } + else + { + return SDRAM_OK; + } +} + +/** + * @brief Writes an amount of data to the SDRAM memory in polling mode. + * @param uwStartAddress: Write start address + * @param pData: Pointer to data to be written + * @param uwDataSize: Size of written data from the memory + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) +{ + if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK) + { + return SDRAM_ERROR; + } + else + { + return SDRAM_OK; + } +} + +/** + * @brief Writes an amount of data to the SDRAM memory in DMA mode. + * @param uwStartAddress: Write start address + * @param pData: Pointer to data to be written + * @param uwDataSize: Size of written data from the memory + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize) +{ + if(HAL_SDRAM_Write_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK) + { + return SDRAM_ERROR; + } + else + { + return SDRAM_OK; + } +} + +/** + * @brief Sends command to the SDRAM bank. + * @param SdramCmd: Pointer to SDRAM command structure + * @retval SDRAM status + */ +uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd) +{ + if(HAL_SDRAM_SendCommand(&sdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK) + { + return SDRAM_ERROR; + } + else + { + return SDRAM_OK; + } +} + +/** + * @brief Handles SDRAM DMA transfer interrupt request. + * @retval None + */ +void BSP_SDRAM_DMA_IRQHandler(void) +{ + HAL_DMA_IRQHandler(sdramHandle.hdma); +} + +/** + * @brief Initializes SDRAM MSP. + * @param hsdram: SDRAM handle + * @param Params + * @retval None + */ +__weak void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params) +{ + static DMA_HandleTypeDef dma_handle; + GPIO_InitTypeDef gpio_init_structure; + + /* Enable FMC clock */ + __HAL_RCC_FMC_CLK_ENABLE(); + + /* Enable chosen DMAx clock */ + __DMAx_CLK_ENABLE(); + + /* Enable GPIOs clock */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + /* Common GPIO configuration */ + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Speed = GPIO_SPEED_FAST; + gpio_init_structure.Alternate = GPIO_AF12_FMC; + + /* GPIOC configuration */ + gpio_init_structure.Pin = GPIO_PIN_3; + HAL_GPIO_Init(GPIOC, &gpio_init_structure); + + /* GPIOD configuration */ + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15; + HAL_GPIO_Init(GPIOD, &gpio_init_structure); + + /* GPIOE configuration */ + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7| GPIO_PIN_8 | GPIO_PIN_9 |\ + GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\ + GPIO_PIN_15; + HAL_GPIO_Init(GPIOE, &gpio_init_structure); + + /* GPIOF configuration */ + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3 | GPIO_PIN_4 |\ + GPIO_PIN_5 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 |\ + GPIO_PIN_15; + HAL_GPIO_Init(GPIOF, &gpio_init_structure); + + /* GPIOG configuration */ + gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_8 |\ + GPIO_PIN_15; + HAL_GPIO_Init(GPIOG, &gpio_init_structure); + + /* GPIOH configuration */ + gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_5; + HAL_GPIO_Init(GPIOH, &gpio_init_structure); + + /* Configure common DMA parameters */ + dma_handle.Init.Channel = SDRAM_DMAx_CHANNEL; + dma_handle.Init.Direction = DMA_MEMORY_TO_MEMORY; + dma_handle.Init.PeriphInc = DMA_PINC_ENABLE; + dma_handle.Init.MemInc = DMA_MINC_ENABLE; + dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + dma_handle.Init.Mode = DMA_NORMAL; + dma_handle.Init.Priority = DMA_PRIORITY_HIGH; + dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + dma_handle.Init.MemBurst = DMA_MBURST_SINGLE; + dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE; + + dma_handle.Instance = SDRAM_DMAx_STREAM; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsdram, hdma, dma_handle); + + /* Deinitialize the stream for new transfer */ + HAL_DMA_DeInit(&dma_handle); + + /* Configure the DMA stream */ + HAL_DMA_Init(&dma_handle); + + /* NVIC configuration for DMA transfer complete interrupt */ + HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn); +} + +/** + * @brief DeInitializes SDRAM MSP. + * @param hsdram: SDRAM handle + * @param Params + * @retval None + */ +__weak void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params) +{ + static DMA_HandleTypeDef dma_handle; + + /* Disable NVIC configuration for DMA interrupt */ + HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn); + + /* Deinitialize the stream for new transfer */ + dma_handle.Instance = SDRAM_DMAx_STREAM; + HAL_DMA_DeInit(&dma_handle); + + /* GPIO pins clock, FMC clock and DMA clock can be shut down in the applications + by surcharging this __weak function */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.h b/boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.h new file mode 100644 index 00000000..cafdce5c --- /dev/null +++ b/boards/base/STM32F746-Discovery/stm32746g_discovery_sdram.h @@ -0,0 +1,165 @@ +/** + ****************************************************************************** + * @file stm32746g_discovery_sdram.h + * @author MCD Application Team + * @version V1.0.0 + * @date 25-June-2015 + * @brief This file contains the common defines and functions prototypes for + * the stm32746g_discovery_sdram.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32746G_DISCOVERY_SDRAM_H +#define __STM32746G_DISCOVERY_SDRAM_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32746G_DISCOVERY + * @{ + */ + +/** @addtogroup STM32746G_DISCOVERY_SDRAM + * @{ + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Types STM32746G_DISCOVERY_SDRAM Exported Types + * @{ + */ + +/** + * @brief SDRAM status structure definition + */ +#define SDRAM_OK ((uint8_t)0x00) +#define SDRAM_ERROR ((uint8_t)0x01) + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Constants STM32746G_DISCOVERY_SDRAM Exported Constants + * @{ + */ +#define SDRAM_DEVICE_ADDR ((uint32_t)0xC0000000) +#define SDRAM_DEVICE_SIZE ((uint32_t)0x800000) /* SDRAM device size in MBytes */ + +/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */ +#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 + +#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2 +/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */ + +#define REFRESH_COUNT ((uint32_t)0x0603) /* SDRAM refresh counter (100Mhz SD clock) */ + +#define SDRAM_TIMEOUT ((uint32_t)0xFFFF) + +/* DMA definitions for SDRAM DMA transfer */ +#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define __DMAx_CLK_DISABLE __HAL_RCC_DMA2_CLK_DISABLE +#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0 +#define SDRAM_DMAx_STREAM DMA2_Stream0 +#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn +#define SDRAM_DMAx_IRQHandler DMA2_Stream0_IRQHandler +/** + * @} + */ + +/** + * @brief FMC SDRAM Mode definition register defines + */ +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) +/** + * @} + */ + +/** @defgroup STM32746G_DISCOVERY_SDRAM_Exported_Macro STM32746G_DISCOVERY_SDRAM Exported Macro + * @{ + */ +/** + * @} + */ + +/** @addtogroup STM32746G_DISCOVERY_SDRAM_Exported_Functions + * @{ + */ +uint8_t BSP_SDRAM_Init(void); +uint8_t BSP_SDRAM_DeInit(void); +void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount); +uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); +uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); +uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); +uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize); +uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd); +void BSP_SDRAM_DMA_IRQHandler(void); + +/* These functions can be modified in case the current settings (e.g. DMA stream) + need to be changed for specific application needs */ +void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params); +void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params); + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32746G_DISCOVERY_SDRAM_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.c b/boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.c new file mode 100644 index 00000000..3b467b4b --- /dev/null +++ b/boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.c @@ -0,0 +1,333 @@ +#include "ch.h" +#include "hal.h" + +#include "stm32f429i_discovery_sdram.h" +#include "stm32f4xx_fmc.h" + +/** + * @brief Configures the FMC and GPIOs to interface with the SDRAM memory. + * This function must be called before any read/write operation + * on the SDRAM. + * @param None + * @retval None + */ +void SDRAM_Init(void) +{ + FMC_SDRAMInitTypeDef FMC_SDRAMInitStructure; + FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure; + + /* Enable FMC clock */ + rccEnableAHB3(RCC_AHB3ENR_FMCEN, FALSE); + +/* FMC Configuration ---------------------------------------------------------*/ +/* FMC SDRAM Bank configuration */ + /* Timing configuration for 84 Mhz of SD clock frequency (168Mhz/2) */ + /* TMRD: 2 Clock cycles */ + FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2; + /* TXSR: min=70ns (6x11.90ns) */ + FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7; + /* TRAS: min=42ns (4x11.90ns) max=120k (ns) */ + FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4; + /* TRC: min=63 (6x11.90ns) */ + FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7; + /* TWR: 2 Clock cycles */ + FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2; + /* TRP: 15ns => 2x11.90ns */ + FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2; + /* TRCD: 15ns => 2x11.90ns */ + FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2; + +/* FMC SDRAM control configuration */ + FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM; + /* Row addressing: [7:0] */ + FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b; + /* Column addressing: [11:0] */ + FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b; + FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = SDRAM_MEMORY_WIDTH; + FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4; + FMC_SDRAMInitStructure.FMC_CASLatency = SDRAM_CAS_LATENCY; + FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable; + FMC_SDRAMInitStructure.FMC_SDClockPeriod = SDCLOCK_PERIOD; + FMC_SDRAMInitStructure.FMC_ReadBurst = SDRAM_READBURST; + FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1; + FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure; + + /* FMC SDRAM bank initialization */ + FMC_SDRAMInit(&FMC_SDRAMInitStructure); + + /* FMC SDRAM device initialization sequence */ + SDRAM_InitSequence(); + +} + +/*-- GPIOs Configuration -----------------------------------------------------*/ +/* + +-------------------+--------------------+--------------------+--------------------+ + + SDRAM pins assignment + + +-------------------+--------------------+--------------------+--------------------+ + | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 | + | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 | + | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> FMC_A2 | PG8 <-> FMC_SDCLK | + | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF3 <-> FMC_A3 | PG15 <-> FMC_NCAS | + | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF4 <-> FMC_A4 |--------------------+ + | PD14 <-> FMC_D0 | PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | + | PD15 <-> FMC_D1 | PE11 <-> FMC_D8 | PF11 <-> FMC_NRAS | + +-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 | + | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 | + | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 | + | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 | + +-------------------+--------------------+--------------------+ + | PB5 <-> FMC_SDCKE1| + | PB6 <-> FMC_SDNE1 | + | PC0 <-> FMC_SDNWE | + +-------------------+ + +*/ + +// /* Common GPIO configuration */ +// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; +// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; +// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; +// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; +// +// /* GPIOB configuration */ +// GPIO_PinAFConfig(GPIOB, GPIO_PinSource5 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOB, GPIO_PinSource6 , GPIO_AF_FMC); +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6; +// +// GPIO_Init(GPIOB, &GPIO_InitStructure); +// +// /* GPIOC configuration */ +// GPIO_PinAFConfig(GPIOC, GPIO_PinSource0 , GPIO_AF_FMC); +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; +// +// GPIO_Init(GPIOC, &GPIO_InitStructure); +// +// /* GPIOD configuration */ +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FMC); +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | +// GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | +// GPIO_Pin_15; +// +// GPIO_Init(GPIOD, &GPIO_InitStructure); +// +// /* GPIOE configuration */ +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource0 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource1 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FMC); +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_7 | +// GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | +// GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | +// GPIO_Pin_14 | GPIO_Pin_15; +// +// GPIO_Init(GPIOE, &GPIO_InitStructure); +// +// /* GPIOF configuration */ +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource0 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource1 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource2 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource3 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource4 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource5 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource11 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource12 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource13 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource14 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOF, GPIO_PinSource15 , GPIO_AF_FMC); +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | +// GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | +// GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | +// GPIO_Pin_14 | GPIO_Pin_15; +// +// GPIO_Init(GPIOF, &GPIO_InitStructure); +// +// /* GPIOG configuration */ +// GPIO_PinAFConfig(GPIOG, GPIO_PinSource0 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOG, GPIO_PinSource1 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOG, GPIO_PinSource4 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOG, GPIO_PinSource5 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOG, GPIO_PinSource8 , GPIO_AF_FMC); +// GPIO_PinAFConfig(GPIOG, GPIO_PinSource15 , GPIO_AF_FMC); +// +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | +// GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_15; +// +// GPIO_Init(GPIOG, &GPIO_InitStructure); + +/** + * @brief Executes the SDRAM memory initialization sequence. + * @param None. + * @retval None. + */ +void SDRAM_InitSequence(void) +{ + FMC_SDRAMCommandTypeDef FMC_SDRAMCommandStructure; + uint32_t tmpr = 0; + +/* Step 3 --------------------------------------------------------------------*/ + /* Configure a clock configuration enable command */ + FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled; + FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2; + FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; + FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + /* Send the command */ + FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); + + //In the ST example, this is 100ms, but the 429 RM says 100us is typical, and + //the ISSI datasheet confirms this. 1ms seems plenty, and is much shorter than + //refresh interval, meaning we won't risk losing contents if the SDRAM is in self-refresh + //mode +/* Step 4 --------------------------------------------------------------------*/ + /* Insert 1 ms delay */ + chThdSleepMilliseconds(1); + +/* Step 5 --------------------------------------------------------------------*/ + /* Configure a PALL (precharge all) command */ + FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL; + FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2; + FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; + FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + /* Send the command */ + FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); + +/* Step 6 --------------------------------------------------------------------*/ + /* Configure a Auto-Refresh command */ + FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh; + FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2; + FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 4; + FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0; + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + /* Send the first command */ + FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); + + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + /* Send the second command */ + FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); + +/* Step 7 --------------------------------------------------------------------*/ + /* Program the external memory mode register */ + tmpr = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | + SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_OPERATING_MODE_STANDARD | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + /* Configure a load Mode register command*/ + FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode; + FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2; + FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1; + FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = tmpr; + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + /* Send the command */ + FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure); + +/* Step 8 --------------------------------------------------------------------*/ + + /* Set the refresh rate counter */ + /* (7.81 us x Freq) - 20 */ + /* Set the device refresh counter */ + FMC_SetRefreshCount(683); + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } +} + + +/** + * @brief Writes a Entire-word buffer to the SDRAM memory. + * @param pBuffer: pointer to buffer. + * @param uwWriteAddress: SDRAM memory internal address from which the data will be + * written. + * @param uwBufferSize: number of words to write. + * @retval None. + */ +void SDRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize) +{ + __IO uint32_t write_pointer = (uint32_t)uwWriteAddress; + + /* Disable write protection */ + FMC_SDRAMWriteProtectionConfig(FMC_Bank2_SDRAM, DISABLE); + + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + + /* While there is data to write */ + for (; uwBufferSize != 0; uwBufferSize--) + { + /* Transfer data to the memory */ + *(uint32_t *) (SDRAM_BANK_ADDR + write_pointer) = *pBuffer++; + + /* Increment the address*/ + write_pointer += 4; + } + +} + +/** + * @brief Reads data buffer from the SDRAM memory. + * @param pBuffer: pointer to buffer. + * @param ReadAddress: SDRAM memory internal address from which the data will be + * read. + * @param uwBufferSize: number of words to write. + * @retval None. + */ +void SDRAM_ReadBuffer(uint32_t* pBuffer, uint32_t uwReadAddress, uint32_t uwBufferSize) +{ + __IO uint32_t write_pointer = (uint32_t)uwReadAddress; + + + /* Wait until the SDRAM controller is ready */ + while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) != RESET) + { + } + + /* Read data */ + for(; uwBufferSize != 0x00; uwBufferSize--) + { + *pBuffer++ = *(__IO uint32_t *)(SDRAM_BANK_ADDR + write_pointer ); + + /* Increment the address*/ + write_pointer += 4; + } +} + diff --git a/boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.h b/boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.h new file mode 100644 index 00000000..fba5115d --- /dev/null +++ b/boards/base/STM32F746-Discovery/stm32f429i_discovery_sdram.h @@ -0,0 +1,96 @@ +/** + ****************************************************************************** + * @file stm32f429i_discovery_sdram.h + * @author MCD Application Team + * @version V1.0.0 + * @date 20-September-2013 + * @brief This file contains all the functions prototypes for the + * stm324x9i_disco_sdram.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32429I_DISCO_SDRAM_H +#define __STM32429I_DISCO_SDRAM_H + +#ifdef __cplusplus + extern "C" { +#endif + +//FIXME this should not be needed +#define STM32F429_439xx + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx.h" + +/** + * @brief FMC SDRAM Bank address + */ +#define SDRAM_BANK_ADDR ((uint32_t)0xD0000000) + +/** + * @brief FMC SDRAM Memory Width + */ +/* #define SDRAM_MEMORY_WIDTH FMC_SDMemory_Width_8b */ +#define SDRAM_MEMORY_WIDTH FMC_SDMemory_Width_16b + +/** + * @brief FMC SDRAM CAS Latency + */ +/* #define SDRAM_CAS_LATENCY FMC_CAS_Latency_2 */ +#define SDRAM_CAS_LATENCY FMC_CAS_Latency_3 + +/** + * @brief FMC SDRAM Memory clock period + */ +#define SDCLOCK_PERIOD FMC_SDClock_Period_2 /* Default configuration used with LCD */ +/* #define SDCLOCK_PERIOD FMC_SDClock_Period_3 */ + +/** + * @brief FMC SDRAM Memory Read Burst feature + */ +#define SDRAM_READBURST FMC_Read_Burst_Disable /* Default configuration used with LCD */ +/* #define SDRAM_READBURST FMC_Read_Burst_Enable */ + +/** + * @brief FMC SDRAM Mode definition register defines + */ +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +void SDRAM_Init(void); +void SDRAM_InitSequence(void); +void SDRAM_WriteBuffer(uint32_t* pBuffer, uint32_t uwWriteAddress, uint32_t uwBufferSize); +void SDRAM_ReadBuffer(uint32_t* pBuffer, uint32_t uwReadAddress, uint32_t uwBufferSize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.c b/boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.c new file mode 100644 index 00000000..38adbcae --- /dev/null +++ b/boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.c @@ -0,0 +1,1123 @@ +/** + ****************************************************************************** + * @file stm32f7xx_ll_fmc.c + * @author MCD Application Team + * @version V1.0.1 + * @date 25-June-2015 + * @brief FMC Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the Flexible Memory Controller (FMC) peripheral memories: + * + Initialization/de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * + @verbatim + ============================================================================== + ##### FMC peripheral features ##### + ============================================================================== + [..] The Flexible memory controller (FMC) includes three memory controllers: + (+) The NOR/PSRAM memory controller + (+) The NAND memory controller + (+) The Synchronous DRAM (SDRAM) controller + + [..] The FMC functional block makes the interface with synchronous and asynchronous static + memories, SDRAM memories, and 16-bit PC memory cards. Its main purposes are: + (+) to translate AHB transactions into the appropriate external device protocol + (+) to meet the access time requirements of the external memory devices + + [..] All external memories share the addresses, data and control signals with the controller. + Each external device is accessed by means of a unique Chip Select. The FMC performs + only one access at a time to an external device. + The main features of the FMC controller are the following: + (+) Interface with static-memory mapped devices including: + (++) Static random access memory (SRAM) + (++) Read-only memory (ROM) + (++) NOR Flash memory/OneNAND Flash memory + (++) PSRAM (4 memory banks) + (++) 16-bit PC Card compatible devices + (++) Two banks of NAND Flash memory with ECC hardware to check up to 8 Kbytes of + data + (+) Interface with synchronous DRAM (SDRAM) memories + (+) Independent Chip Select control for each memory bank + (+) Independent configuration for each memory bank + + @endverbatim + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @defgroup FMC_LL FMC Low Layer + * @brief FMC driver modules + * @{ + */ + +#if defined (HAL_SRAM_MODULE_ENABLED) || defined(HAL_NOR_MODULE_ENABLED) || defined(HAL_NAND_MODULE_ENABLED) || defined(HAL_SDRAM_MODULE_ENABLED) + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup FMC_LL_Exported_Functions FMC Low Layer Exported Functions + * @{ + */ + +/** @defgroup FMC_LL_Exported_Functions_NORSRAM FMC Low Layer NOR SRAM Exported Functions + * @brief NORSRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use NORSRAM device driver ##### + ============================================================================== + + [..] + This driver contains a set of APIs to interface with the FMC NORSRAM banks in order + to run the NORSRAM external devices. + + (+) FMC NORSRAM bank reset using the function FMC_NORSRAM_DeInit() + (+) FMC NORSRAM bank control configuration using the function FMC_NORSRAM_Init() + (+) FMC NORSRAM bank timing configuration using the function FMC_NORSRAM_Timing_Init() + (+) FMC NORSRAM bank extended timing configuration using the function + FMC_NORSRAM_Extended_Timing_Init() + (+) FMC NORSRAM bank enable/disable write operation using the functions + FMC_NORSRAM_WriteOperation_Enable()/FMC_NORSRAM_WriteOperation_Disable() + + +@endverbatim + * @{ + */ + +/** @defgroup FMC_LL_NORSRAM_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * + @verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NORSRAM interface + (+) De-initialize the FMC NORSRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initialize the FMC_NORSRAM device according to the specified + * control parameters in the FMC_NORSRAM_InitTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Init: Pointer to NORSRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef* Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Init->NSBank)); + assert_param(IS_FMC_MUX(Init->DataAddressMux)); + assert_param(IS_FMC_MEMORY(Init->MemoryType)); + assert_param(IS_FMC_NORSRAM_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_BURSTMODE(Init->BurstAccessMode)); + assert_param(IS_FMC_WAIT_POLARITY(Init->WaitSignalPolarity)); + assert_param(IS_FMC_WAIT_SIGNAL_ACTIVE(Init->WaitSignalActive)); + assert_param(IS_FMC_WRITE_OPERATION(Init->WriteOperation)); + assert_param(IS_FMC_WAITE_SIGNAL(Init->WaitSignal)); + assert_param(IS_FMC_EXTENDED_MODE(Init->ExtendedMode)); + assert_param(IS_FMC_ASYNWAIT(Init->AsynchronousWait)); + assert_param(IS_FMC_WRITE_BURST(Init->WriteBurst)); + assert_param(IS_FMC_CONTINOUS_CLOCK(Init->ContinuousClock)); + assert_param(IS_FMC_WRITE_FIFO(Init->WriteFifo)); + assert_param(IS_FMC_PAGESIZE(Init->PageSize)); + + /* Get the BTCR register value */ + tmpr = Device->BTCR[Init->NSBank]; + + /* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WAITCFG, WREN, + WAITEN, EXTMOD, ASYNCWAIT, CBURSTRW and CCLKEN bits */ + tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN | FMC_BCR1_MUXEN | FMC_BCR1_MTYP | \ + FMC_BCR1_MWID | FMC_BCR1_FACCEN | FMC_BCR1_BURSTEN | \ + FMC_BCR1_WAITPOL | FMC_BCR1_CPSIZE | FMC_BCR1_WAITCFG | \ + FMC_BCR1_WREN | FMC_BCR1_WAITEN | FMC_BCR1_EXTMOD | \ + FMC_BCR1_ASYNCWAIT | FMC_BCR1_CBURSTRW | FMC_BCR1_CCLKEN | FMC_BCR1_WFDIS)); + + /* Set NORSRAM device control parameters */ + tmpr |= (uint32_t)(Init->DataAddressMux |\ + Init->MemoryType |\ + Init->MemoryDataWidth |\ + Init->BurstAccessMode |\ + Init->WaitSignalPolarity |\ + Init->WaitSignalActive |\ + Init->WriteOperation |\ + Init->WaitSignal |\ + Init->ExtendedMode |\ + Init->AsynchronousWait |\ + Init->WriteBurst |\ + Init->ContinuousClock |\ + Init->PageSize |\ + Init->WriteFifo); + + if(Init->MemoryType == FMC_MEMORY_TYPE_NOR) + { + tmpr |= (uint32_t)FMC_NORSRAM_FLASH_ACCESS_ENABLE; + } + + Device->BTCR[Init->NSBank] = tmpr; + + /* Configure synchronous mode when Continuous clock is enabled for bank2..4 */ + if((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1)) + { + Init->BurstAccessMode = FMC_BURST_ACCESS_MODE_ENABLE; + Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t)(Init->BurstAccessMode |\ + Init->ContinuousClock); + } + if(Init->NSBank != FMC_NORSRAM_BANK1) + { + Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t)(Init->WriteFifo); + } + + return HAL_OK; +} + + +/** + * @brief DeInitialize the FMC_NORSRAM peripheral + * @param Device: Pointer to NORSRAM device instance + * @param ExDevice: Pointer to NORSRAM extended mode device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(ExDevice)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable the FMC_NORSRAM device */ + __FMC_NORSRAM_DISABLE(Device, Bank); + + /* De-initialize the FMC_NORSRAM device */ + /* FMC_NORSRAM_BANK1 */ + if(Bank == FMC_NORSRAM_BANK1) + { + Device->BTCR[Bank] = 0x000030DB; + } + /* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */ + else + { + Device->BTCR[Bank] = 0x000030D2; + } + + Device->BTCR[Bank + 1] = 0x0FFFFFFF; + ExDevice->BWTR[Bank] = 0x0FFFFFFF; + + return HAL_OK; +} + + +/** + * @brief Initialize the FMC_NORSRAM Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Timing: Pointer to NORSRAM Timing structure + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Get the BTCR register value */ + tmpr = Device->BTCR[Bank + 1]; + + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */ + tmpr &= ((uint32_t)~(FMC_BTR1_ADDSET | FMC_BTR1_ADDHLD | FMC_BTR1_DATAST | \ + FMC_BTR1_BUSTURN | FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT | \ + FMC_BTR1_ACCMOD)); + + /* Set FMC_NORSRAM device timing parameters */ + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (((Timing->CLKDivision)-1) << 20) |\ + (((Timing->DataLatency)-2) << 24) |\ + (Timing->AccessMode) + ); + + Device->BTCR[Bank + 1] = tmpr; + + /* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */ + if(HAL_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN)) + { + tmpr = (uint32_t)(Device->BTCR[FMC_NORSRAM_BANK1 + 1] & ~(((uint32_t)0x0F) << 20)); + tmpr |= (uint32_t)(((Timing->CLKDivision)-1) << 20); + Device->BTCR[FMC_NORSRAM_BANK1 + 1] = tmpr; + } + + return HAL_OK; +} + +/** + * @brief Initialize the FMC_NORSRAM Extended mode Timing according to the specified + * parameters in the FMC_NORSRAM_TimingTypeDef + * @param Device: Pointer to NORSRAM device instance + * @param Timing: Pointer to NORSRAM Timing structure + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_EXTENDED_MODE(ExtendedMode)); + + /* Set NORSRAM device timing register for write configuration, if extended mode is used */ + if(ExtendedMode == FMC_EXTENDED_MODE_ENABLE) + { + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_EXTENDED_DEVICE(Device)); + assert_param(IS_FMC_ADDRESS_SETUP_TIME(Timing->AddressSetupTime)); + assert_param(IS_FMC_ADDRESS_HOLD_TIME(Timing->AddressHoldTime)); + assert_param(IS_FMC_DATASETUP_TIME(Timing->DataSetupTime)); + assert_param(IS_FMC_TURNAROUND_TIME(Timing->BusTurnAroundDuration)); + assert_param(IS_FMC_CLK_DIV(Timing->CLKDivision)); + assert_param(IS_FMC_DATA_LATENCY(Timing->DataLatency)); + assert_param(IS_FMC_ACCESS_MODE(Timing->AccessMode)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Get the BWTR register value */ + tmpr = Device->BWTR[Bank]; + + /* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */ + tmpr &= ((uint32_t)~(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD | FMC_BWTR1_DATAST | \ + FMC_BWTR1_BUSTURN | FMC_BWTR1_ACCMOD)); + + tmpr |= (uint32_t)(Timing->AddressSetupTime |\ + ((Timing->AddressHoldTime) << 4) |\ + ((Timing->DataSetupTime) << 8) |\ + ((Timing->BusTurnAroundDuration) << 16) |\ + (Timing->AccessMode)); + + Device->BWTR[Bank] = tmpr; + } + else + { + Device->BWTR[Bank] = 0x0FFFFFFF; + } + + return HAL_OK; +} +/** + * @} + */ + +/** @addtogroup FMC_LL_NORSRAM_Private_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NORSRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NORSRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FMC_NORSRAM write operation. + * @param Device: Pointer to NORSRAM device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Enable write operation */ + Device->BTCR[Bank] |= FMC_WRITE_OPERATION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NORSRAM write operation. + * @param Device: Pointer to NORSRAM device instance + * @param Bank: NORSRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NORSRAM_DEVICE(Device)); + assert_param(IS_FMC_NORSRAM_BANK(Bank)); + + /* Disable write operation */ + Device->BTCR[Bank] &= ~FMC_WRITE_OPERATION_ENABLE; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_Exported_Functions_NAND FMC Low Layer NAND Exported Functions + * @brief NAND Controller functions + * + @verbatim + ============================================================================== + ##### How to use NAND device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC NAND banks in order + to run the NAND external devices. + + (+) FMC NAND bank reset using the function FMC_NAND_DeInit() + (+) FMC NAND bank control configuration using the function FMC_NAND_Init() + (+) FMC NAND bank common space timing configuration using the function + FMC_NAND_CommonSpace_Timing_Init() + (+) FMC NAND bank attribute space timing configuration using the function + FMC_NAND_AttributeSpace_Timing_Init() + (+) FMC NAND bank enable/disable ECC correction feature using the functions + FMC_NAND_ECC_Enable()/FMC_NAND_ECC_Disable() + (+) FMC NAND bank get ECC correction code using the function FMC_NAND_GetECC() + +@endverbatim + * @{ + */ + +/** @defgroup FMC_LL_NAND_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC NAND interface + (+) De-initialize the FMC NAND interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_NAND device according to the specified + * control parameters in the FMC_NAND_HandleTypeDef + * @param Device: Pointer to NAND device instance + * @param Init: Pointer to NAND Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Init->NandBank)); + assert_param(IS_FMC_WAIT_FEATURE(Init->Waitfeature)); + assert_param(IS_FMC_NAND_MEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_ECC_STATE(Init->EccComputation)); + assert_param(IS_FMC_ECCPAGE_SIZE(Init->ECCPageSize)); + assert_param(IS_FMC_TCLR_TIME(Init->TCLRSetupTime)); + assert_param(IS_FMC_TAR_TIME(Init->TARSetupTime)); + + /* Get the NAND bank 3 register value */ + tmpr = Device->PCR; + + /* Clear PWAITEN, PBKEN, PTYP, PWID, ECCEN, TCLR, TAR and ECCPS bits */ + tmpr &= ((uint32_t)~(FMC_PCR_PWAITEN | FMC_PCR_PBKEN | FMC_PCR_PTYP | \ + FMC_PCR_PWID | FMC_PCR_ECCEN | FMC_PCR_TCLR | \ + FMC_PCR_TAR | FMC_PCR_ECCPS)); + /* Set NAND device control parameters */ + tmpr |= (uint32_t)(Init->Waitfeature |\ + FMC_PCR_MEMORY_TYPE_NAND |\ + Init->MemoryDataWidth |\ + Init->EccComputation |\ + Init->ECCPageSize |\ + ((Init->TCLRSetupTime) << 9) |\ + ((Init->TARSetupTime) << 13)); + + /* NAND bank 3 registers configuration */ + Device->PCR = tmpr; + + return HAL_OK; + +} + +/** + * @brief Initializes the FMC_NAND Common space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get the NAND bank 3 register value */ + tmpr = Device->PMEM; + + /* Clear MEMSETx, MEMWAITx, MEMHOLDx and MEMHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PMEM_MEMSET3 | FMC_PMEM_MEMWAIT3 | FMC_PMEM_MEMHOLD3 | \ + FMC_PMEM_MEMHIZ3)); + /* Set FMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24) + ); + + /* NAND bank 3 registers configuration */ + Device->PMEM = tmpr; + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_NAND Attribute space Timing according to the specified + * parameters in the FMC_NAND_PCC_TimingTypeDef + * @param Device: Pointer to NAND device instance + * @param Timing: Pointer to NAND timing structure + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_SETUP_TIME(Timing->SetupTime)); + assert_param(IS_FMC_WAIT_TIME(Timing->WaitSetupTime)); + assert_param(IS_FMC_HOLD_TIME(Timing->HoldSetupTime)); + assert_param(IS_FMC_HIZ_TIME(Timing->HiZSetupTime)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get the NAND bank 3 register value */ + tmpr = Device->PATT; + + /* Clear ATTSETx, ATTWAITx, ATTHOLDx and ATTHIZx bits */ + tmpr &= ((uint32_t)~(FMC_PATT_ATTSET3 | FMC_PATT_ATTWAIT3 | FMC_PATT_ATTHOLD3 | \ + FMC_PATT_ATTHIZ3)); + /* Set FMC_NAND device timing parameters */ + tmpr |= (uint32_t)(Timing->SetupTime |\ + ((Timing->WaitSetupTime) << 8) |\ + ((Timing->HoldSetupTime) << 16) |\ + ((Timing->HiZSetupTime) << 24)); + + /* NAND bank 3 registers configuration */ + Device->PATT = tmpr; + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_NAND device + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable the NAND Bank */ + __FMC_NAND_DISABLE(Device); + + /* Set the FMC_NAND_BANK3 registers to their reset values */ + Device->PCR = 0x00000018; + Device->SR = 0x00000040; + Device->PMEM = 0xFCFCFCFC; + Device->PATT = 0xFCFCFCFC; + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup HAL_FMC_NAND_Group3 Control functions + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_NAND Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC NAND interface. + +@endverbatim + * @{ + */ + + +/** + * @brief Enables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Enable ECC feature */ + Device->PCR |= FMC_PCR_ECCEN; + + return HAL_OK; +} + + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param Bank: NAND bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Disable ECC feature */ + Device->PCR &= ~FMC_PCR_ECCEN; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_NAND ECC feature. + * @param Device: Pointer to NAND device instance + * @param ECCval: Pointer to ECC value + * @param Bank: NAND bank number + * @param Timeout: Timeout wait value + * @retval HAL status + */ +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout) +{ + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_FMC_NAND_DEVICE(Device)); + assert_param(IS_FMC_NAND_BANK(Bank)); + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* Wait until FIFO is empty */ + while(__FMC_NAND_GET_FLAG(Device, Bank, FMC_FLAG_FEMPT) == RESET) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + } + + /* Get the ECCR register value */ + *ECCval = (uint32_t)Device->ECCR; + + return HAL_OK; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM + * @brief SDRAM Controller functions + * + @verbatim + ============================================================================== + ##### How to use SDRAM device driver ##### + ============================================================================== + [..] + This driver contains a set of APIs to interface with the FMC SDRAM banks in order + to run the SDRAM external devices. + + (+) FMC SDRAM bank reset using the function FMC_SDRAM_DeInit() + (+) FMC SDRAM bank control configuration using the function FMC_SDRAM_Init() + (+) FMC SDRAM bank timing configuration using the function FMC_SDRAM_Timing_Init() + (+) FMC SDRAM bank enable/disable write operation using the functions + FMC_SDRAM_WriteOperation_Enable()/FMC_SDRAM_WriteOperation_Disable() + (+) FMC SDRAM bank send command using the function FMC_SDRAM_SendCommand() + +@endverbatim + * @{ + */ + +/** @addtogroup FMC_LL_SDRAM_Private_Functions_Group1 + * @brief Initialization and Configuration functions + * +@verbatim + ============================================================================== + ##### Initialization and de_initialization functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the FMC SDRAM interface + (+) De-initialize the FMC SDRAM interface + (+) Configure the FMC clock and associated GPIOs + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the FMC_SDRAM device according to the specified + * control parameters in the FMC_SDRAM_InitTypeDef + * @param Device: Pointer to SDRAM device instance + * @param Init: Pointer to SDRAM Initialization structure + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init) +{ + uint32_t tmpr1 = 0; + uint32_t tmpr2 = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Init->SDBank)); + assert_param(IS_FMC_COLUMNBITS_NUMBER(Init->ColumnBitsNumber)); + assert_param(IS_FMC_ROWBITS_NUMBER(Init->RowBitsNumber)); + assert_param(IS_FMC_SDMEMORY_WIDTH(Init->MemoryDataWidth)); + assert_param(IS_FMC_INTERNALBANK_NUMBER(Init->InternalBankNumber)); + assert_param(IS_FMC_CAS_LATENCY(Init->CASLatency)); + assert_param(IS_FMC_WRITE_PROTECTION(Init->WriteProtection)); + assert_param(IS_FMC_SDCLOCK_PERIOD(Init->SDClockPeriod)); + assert_param(IS_FMC_READ_BURST(Init->ReadBurst)); + assert_param(IS_FMC_READPIPE_DELAY(Init->ReadPipeDelay)); + + /* Set SDRAM bank configuration parameters */ + if (Init->SDBank != FMC_SDRAM_BANK2) + { + tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; + + /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ + tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ + FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); + + tmpr1 |= (uint32_t)(Init->ColumnBitsNumber |\ + Init->RowBitsNumber |\ + Init->MemoryDataWidth |\ + Init->InternalBankNumber |\ + Init->CASLatency |\ + Init->WriteProtection |\ + Init->SDClockPeriod |\ + Init->ReadBurst |\ + Init->ReadPipeDelay + ); + Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; + } + else /* FMC_Bank2_SDRAM */ + { + tmpr1 = Device->SDCR[FMC_SDRAM_BANK1]; + + /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ + tmpr1 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ + FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); + + tmpr1 |= (uint32_t)(Init->SDClockPeriod |\ + Init->ReadBurst |\ + Init->ReadPipeDelay); + + tmpr2 = Device->SDCR[FMC_SDRAM_BANK2]; + + /* Clear NC, NR, MWID, NB, CAS, WP, SDCLK, RBURST, and RPIPE bits */ + tmpr2 &= ((uint32_t)~(FMC_SDCR1_NC | FMC_SDCR1_NR | FMC_SDCR1_MWID | \ + FMC_SDCR1_NB | FMC_SDCR1_CAS | FMC_SDCR1_WP | \ + FMC_SDCR1_SDCLK | FMC_SDCR1_RBURST | FMC_SDCR1_RPIPE)); + + tmpr2 |= (uint32_t)(Init->ColumnBitsNumber |\ + Init->RowBitsNumber |\ + Init->MemoryDataWidth |\ + Init->InternalBankNumber |\ + Init->CASLatency |\ + Init->WriteProtection); + + Device->SDCR[FMC_SDRAM_BANK1] = tmpr1; + Device->SDCR[FMC_SDRAM_BANK2] = tmpr2; + } + + return HAL_OK; +} + +/** + * @brief Initializes the FMC_SDRAM device timing according to the specified + * parameters in the FMC_SDRAM_TimingTypeDef + * @param Device: Pointer to SDRAM device instance + * @param Timing: Pointer to SDRAM Timing structure + * @param Bank: SDRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank) +{ + uint32_t tmpr1 = 0; + uint32_t tmpr2 = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_LOADTOACTIVE_DELAY(Timing->LoadToActiveDelay)); + assert_param(IS_FMC_EXITSELFREFRESH_DELAY(Timing->ExitSelfRefreshDelay)); + assert_param(IS_FMC_SELFREFRESH_TIME(Timing->SelfRefreshTime)); + assert_param(IS_FMC_ROWCYCLE_DELAY(Timing->RowCycleDelay)); + assert_param(IS_FMC_WRITE_RECOVERY_TIME(Timing->WriteRecoveryTime)); + assert_param(IS_FMC_RP_DELAY(Timing->RPDelay)); + assert_param(IS_FMC_RCD_DELAY(Timing->RCDDelay)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Set SDRAM device timing parameters */ + if (Bank != FMC_SDRAM_BANK2) + { + tmpr1 = Device->SDTR[FMC_SDRAM_BANK1]; + + /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ + tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ + FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)); + + tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1) |\ + (((Timing->ExitSelfRefreshDelay)-1) << 4) |\ + (((Timing->SelfRefreshTime)-1) << 8) |\ + (((Timing->RowCycleDelay)-1) << 12) |\ + (((Timing->WriteRecoveryTime)-1) <<16) |\ + (((Timing->RPDelay)-1) << 20) |\ + (((Timing->RCDDelay)-1) << 24)); + Device->SDTR[FMC_SDRAM_BANK1] = tmpr1; + } + else /* FMC_Bank2_SDRAM */ + { + tmpr1 = Device->SDTR[FMC_SDRAM_BANK2]; + + /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ + tmpr1 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ + FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)); + + tmpr1 |= (uint32_t)(((Timing->LoadToActiveDelay)-1) |\ + (((Timing->ExitSelfRefreshDelay)-1) << 4) |\ + (((Timing->SelfRefreshTime)-1) << 8) |\ + (((Timing->WriteRecoveryTime)-1) <<16) |\ + (((Timing->RCDDelay)-1) << 24)); + + tmpr2 = Device->SDTR[FMC_SDRAM_BANK1]; + + /* Clear TMRD, TXSR, TRAS, TRC, TWR, TRP and TRCD bits */ + tmpr2 &= ((uint32_t)~(FMC_SDTR1_TMRD | FMC_SDTR1_TXSR | FMC_SDTR1_TRAS | \ + FMC_SDTR1_TRC | FMC_SDTR1_TWR | FMC_SDTR1_TRP | \ + FMC_SDTR1_TRCD)); + tmpr2 |= (uint32_t)((((Timing->RowCycleDelay)-1) << 12) |\ + (((Timing->RPDelay)-1) << 20)); + + Device->SDTR[FMC_SDRAM_BANK2] = tmpr1; + Device->SDTR[FMC_SDRAM_BANK1] = tmpr2; + } + + return HAL_OK; +} + +/** + * @brief DeInitializes the FMC_SDRAM peripheral + * @param Device: Pointer to SDRAM device instance + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* De-initialize the SDRAM device */ + Device->SDCR[Bank] = 0x000002D0; + Device->SDTR[Bank] = 0x0FFFFFFF; + Device->SDCMR = 0x00000000; + Device->SDRTR = 0x00000000; + Device->SDSR = 0x00000000; + + return HAL_OK; +} + +/** + * @} + */ + +/** @addtogroup FMC_LL_SDRAMPrivate_Functions_Group2 + * @brief management functions + * +@verbatim + ============================================================================== + ##### FMC_SDRAM Control functions ##### + ============================================================================== + [..] + This subsection provides a set of functions allowing to control dynamically + the FMC SDRAM interface. + +@endverbatim + * @{ + */ + +/** + * @brief Enables dynamically FMC_SDRAM write protection. + * @param Device: Pointer to SDRAM device instance + * @param Bank: SDRAM bank number + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Enable write protection */ + Device->SDCR[Bank] |= FMC_SDRAM_WRITE_PROTECTION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Disables dynamically FMC_SDRAM write protection. + * @param hsdram: FMC_SDRAM handle + * @retval HAL status + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Disable write protection */ + Device->SDCR[Bank] &= ~FMC_SDRAM_WRITE_PROTECTION_ENABLE; + + return HAL_OK; +} + +/** + * @brief Send Command to the FMC SDRAM bank + * @param Device: Pointer to SDRAM device instance + * @param Command: Pointer to SDRAM command structure + * @param Timing: Pointer to SDRAM Timing structure + * @param Timeout: Timeout wait value + * @retval HAL state + */ +HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout) +{ + __IO uint32_t tmpr = 0; + uint32_t tickstart = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_COMMAND_MODE(Command->CommandMode)); + assert_param(IS_FMC_COMMAND_TARGET(Command->CommandTarget)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(Command->AutoRefreshNumber)); + assert_param(IS_FMC_MODE_REGISTER(Command->ModeRegisterDefinition)); + + /* Set command register */ + tmpr = (uint32_t)((Command->CommandMode) |\ + (Command->CommandTarget) |\ + (((Command->AutoRefreshNumber)-1) << 5) |\ + ((Command->ModeRegisterDefinition) << 9) + ); + + Device->SDCMR = tmpr; + + /* Get tick */ + tickstart = HAL_GetTick(); + + /* wait until command is send */ + while(HAL_IS_BIT_SET(Device->SDSR, FMC_SDSR_BUSY)) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + return HAL_TIMEOUT; + } + } + + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief Program the SDRAM Memory Refresh rate. + * @param Device: Pointer to SDRAM device instance + * @param RefreshRate: The SDRAM refresh rate value. + * @retval HAL state + */ +HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_REFRESH_RATE(RefreshRate)); + + /* Set the refresh rate in command register */ + Device->SDRTR |= (RefreshRate<<1); + + return HAL_OK; +} + +/** + * @brief Set the Number of consecutive SDRAM Memory auto Refresh commands. + * @param Device: Pointer to SDRAM device instance + * @param AutoRefreshNumber: Specifies the auto Refresh number. + * @retval None + */ +HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, uint32_t AutoRefreshNumber) +{ + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_AUTOREFRESH_NUMBER(AutoRefreshNumber)); + + /* Set the Auto-refresh number in command register */ + Device->SDCMR |= (AutoRefreshNumber << 5); + + return HAL_OK; +} + +/** + * @brief Returns the indicated FMC SDRAM bank mode status. + * @param Device: Pointer to SDRAM device instance + * @param Bank: Defines the FMC SDRAM bank. This parameter can be + * FMC_Bank1_SDRAM or FMC_Bank2_SDRAM. + * @retval The FMC SDRAM bank mode status, could be on of the following values: + * FMC_SDRAM_NORMAL_MODE, FMC_SDRAM_SELF_REFRESH_MODE or + * FMC_SDRAM_POWER_DOWN_MODE. + */ +uint32_t FMC_SDRAM_GetModeStatus(FMC_SDRAM_TypeDef *Device, uint32_t Bank) +{ + uint32_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_FMC_SDRAM_DEVICE(Device)); + assert_param(IS_FMC_SDRAM_BANK(Bank)); + + /* Get the corresponding bank mode */ + if(Bank == FMC_SDRAM_BANK1) + { + tmpreg = (uint32_t)(Device->SDSR & FMC_SDSR_MODES1); + } + else + { + tmpreg = ((uint32_t)(Device->SDSR & FMC_SDSR_MODES2) >> 2); + } + + /* Return the mode status */ + return tmpreg; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* HAL_SRAM_MODULE_ENABLED || HAL_NOR_MODULE_ENABLED || HAL_NAND_MODULE_ENABLED || HAL_SDRAM_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.h b/boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.h new file mode 100644 index 00000000..019ec064 --- /dev/null +++ b/boards/base/STM32F746-Discovery/stm32f7xx_ll_fmc.h @@ -0,0 +1,1337 @@ +/** + ****************************************************************************** + * @file stm32f7xx_ll_fmc.h + * @author MCD Application Team + * @version V1.0.1 + * @date 25-June-2015 + * @brief Header file of FMC HAL module. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F7xx_LL_FMC_H +#define __STM32F7xx_LL_FMC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f7xx_hal_def.h" + +/** @addtogroup STM32F7xx_HAL_Driver + * @{ + */ + +/** @addtogroup FMC_LL + * @{ + */ + +/** @addtogroup FMC_LL_Private_Macros + * @{ + */ +#define IS_FMC_NORSRAM_BANK(BANK) (((BANK) == FMC_NORSRAM_BANK1) || \ + ((BANK) == FMC_NORSRAM_BANK2) || \ + ((BANK) == FMC_NORSRAM_BANK3) || \ + ((BANK) == FMC_NORSRAM_BANK4)) + +#define IS_FMC_MUX(__MUX__) (((__MUX__) == FMC_DATA_ADDRESS_MUX_DISABLE) || \ + ((__MUX__) == FMC_DATA_ADDRESS_MUX_ENABLE)) + +#define IS_FMC_MEMORY(__MEMORY__) (((__MEMORY__) == FMC_MEMORY_TYPE_SRAM) || \ + ((__MEMORY__) == FMC_MEMORY_TYPE_PSRAM)|| \ + ((__MEMORY__) == FMC_MEMORY_TYPE_NOR)) + +#define IS_FMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_8) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_16) || \ + ((__WIDTH__) == FMC_NORSRAM_MEM_BUS_WIDTH_32)) + +#define IS_FMC_ACCESS_MODE(__MODE__) (((__MODE__) == FMC_ACCESS_MODE_A) || \ + ((__MODE__) == FMC_ACCESS_MODE_B) || \ + ((__MODE__) == FMC_ACCESS_MODE_C) || \ + ((__MODE__) == FMC_ACCESS_MODE_D)) + +#define IS_FMC_NAND_BANK(BANK) ((BANK) == FMC_NAND_BANK3) + +#define IS_FMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FMC_NAND_WAIT_FEATURE_DISABLE) || \ + ((FEATURE) == FMC_NAND_WAIT_FEATURE_ENABLE)) + +#define IS_FMC_NAND_MEMORY_WIDTH(WIDTH) (((WIDTH) == FMC_NAND_MEM_BUS_WIDTH_8) || \ + ((WIDTH) == FMC_NAND_MEM_BUS_WIDTH_16)) + +#define IS_FMC_ECC_STATE(STATE) (((STATE) == FMC_NAND_ECC_DISABLE) || \ + ((STATE) == FMC_NAND_ECC_ENABLE)) + +#define IS_FMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FMC_NAND_ECC_PAGE_SIZE_256BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_512BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \ + ((SIZE) == FMC_NAND_ECC_PAGE_SIZE_8192BYTE)) + +#define IS_FMC_SDMEMORY_WIDTH(WIDTH) (((WIDTH) == FMC_SDRAM_MEM_BUS_WIDTH_8) || \ + ((WIDTH) == FMC_SDRAM_MEM_BUS_WIDTH_16) || \ + ((WIDTH) == FMC_SDRAM_MEM_BUS_WIDTH_32)) + +#define IS_FMC_WRITE_PROTECTION(__WRITE__) (((__WRITE__) == FMC_SDRAM_WRITE_PROTECTION_DISABLE) || \ + ((__WRITE__) == FMC_SDRAM_WRITE_PROTECTION_ENABLE)) + +#define IS_FMC_SDCLOCK_PERIOD(__PERIOD__) (((__PERIOD__) == FMC_SDRAM_CLOCK_DISABLE) || \ + ((__PERIOD__) == FMC_SDRAM_CLOCK_PERIOD_2) || \ + ((__PERIOD__) == FMC_SDRAM_CLOCK_PERIOD_3)) + +#define IS_FMC_READ_BURST(__RBURST__) (((__RBURST__) == FMC_SDRAM_RBURST_DISABLE) || \ + ((__RBURST__) == FMC_SDRAM_RBURST_ENABLE)) + +#define IS_FMC_READPIPE_DELAY(__DELAY__) (((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_0) || \ + ((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_1) || \ + ((__DELAY__) == FMC_SDRAM_RPIPE_DELAY_2)) + +#define IS_FMC_COMMAND_MODE(__COMMAND__) (((__COMMAND__) == FMC_SDRAM_CMD_NORMAL_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_CLK_ENABLE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_PALL) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_AUTOREFRESH_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_LOAD_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_SELFREFRESH_MODE) || \ + ((__COMMAND__) == FMC_SDRAM_CMD_POWERDOWN_MODE)) + +#define IS_FMC_COMMAND_TARGET(__TARGET__) (((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK1) || \ + ((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK2) || \ + ((__TARGET__) == FMC_SDRAM_CMD_TARGET_BANK1_2)) + +/** @defgroup FMC_TCLR_Setup_Time FMC TCLR Setup Time + * @{ + */ +#define IS_FMC_TCLR_TIME(__TIME__) ((__TIME__) <= 255) +/** + * @} + */ + +/** @defgroup FMC_TAR_Setup_Time FMC TAR Setup Time + * @{ + */ +#define IS_FMC_TAR_TIME(TIME) ((TIME) <= 255) +/** + * @} + */ + +/** @defgroup FMC_Setup_Time FMC Setup Time + * @{ + */ +#define IS_FMC_SETUP_TIME(TIME) ((TIME) <= 254) +/** + * @} + */ + +/** @defgroup FMC_Wait_Setup_Time FMC Wait Setup Time + * @{ + */ +#define IS_FMC_WAIT_TIME(TIME) ((TIME) <= 254) +/** + * @} + */ + +/** @defgroup FMC_Hold_Setup_Time FMC Hold Setup Time + * @{ + */ +#define IS_FMC_HOLD_TIME(TIME) ((TIME) <= 254) +/** + * @} + */ + +/** @defgroup FMC_HiZ_Setup_Time FMC HiZ Setup Time + * @{ + */ +#define IS_FMC_HIZ_TIME(TIME) ((TIME) <= 254) +/** + * @} + */ + +#define IS_FMC_BURSTMODE(__STATE__) (((__STATE__) == FMC_BURST_ACCESS_MODE_DISABLE) || \ + ((__STATE__) == FMC_BURST_ACCESS_MODE_ENABLE)) + +#define IS_FMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_LOW) || \ + ((__POLARITY__) == FMC_WAIT_SIGNAL_POLARITY_HIGH)) + +#define IS_FMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FMC_WAIT_TIMING_BEFORE_WS) || \ + ((__ACTIVE__) == FMC_WAIT_TIMING_DURING_WS)) + +#define IS_FMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FMC_WRITE_OPERATION_DISABLE) || \ + ((__OPERATION__) == FMC_WRITE_OPERATION_ENABLE)) + +#define IS_FMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FMC_WAIT_SIGNAL_DISABLE) || \ + ((__SIGNAL__) == FMC_WAIT_SIGNAL_ENABLE)) + +#define IS_FMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FMC_EXTENDED_MODE_DISABLE) || \ + ((__MODE__) == FMC_EXTENDED_MODE_ENABLE)) + +#define IS_FMC_ASYNWAIT(__STATE__) (((__STATE__) == FMC_ASYNCHRONOUS_WAIT_DISABLE) || \ + ((__STATE__) == FMC_ASYNCHRONOUS_WAIT_ENABLE)) + +/** @defgroup FMC_Data_Latency FMC Data Latency + * @{ + */ +#define IS_FMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1) && ((__LATENCY__) <= 17)) +/** + * @} + */ + +#define IS_FMC_WRITE_BURST(__BURST__) (((__BURST__) == FMC_WRITE_BURST_DISABLE) || \ + ((__BURST__) == FMC_WRITE_BURST_ENABLE)) + +#define IS_FMC_CONTINOUS_CLOCK(CCLOCK) (((CCLOCK) == FMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \ + ((CCLOCK) == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC)) + + +/** @defgroup FMC_Address_Setup_Time FMC Address Setup Time + * @{ + */ +#define IS_FMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15) +/** + * @} + */ + +/** @defgroup FMC_Address_Hold_Time FMC Address Hold Time + * @{ + */ +#define IS_FMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 15)) +/** + * @} + */ + +/** @defgroup FMC_Data_Setup_Time FMC Data Setup Time + * @{ + */ +#define IS_FMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 255)) +/** + * @} + */ + +/** @defgroup FMC_Bus_Turn_around_Duration FMC Bus Turn around Duration + * @{ + */ +#define IS_FMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15) +/** + * @} + */ + +/** @defgroup FMC_CLK_Division FMC CLK Division + * @{ + */ +#define IS_FMC_CLK_DIV(DIV) (((DIV) > 1) && ((DIV) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_LoadToActive_Delay FMC SDRAM LoadToActive Delay + * @{ + */ +#define IS_FMC_LOADTOACTIVE_DELAY(__DELAY__) (((__DELAY__) > 0) && ((__DELAY__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_ExitSelfRefresh_Delay FMC SDRAM ExitSelfRefresh Delay + * @{ + */ +#define IS_FMC_EXITSELFREFRESH_DELAY(__DELAY__) (((__DELAY__) > 0) && ((__DELAY__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_SelfRefresh_Time FMC SDRAM SelfRefresh Time + * @{ + */ +#define IS_FMC_SELFREFRESH_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_RowCycle_Delay FMC SDRAM RowCycle Delay + * @{ + */ +#define IS_FMC_ROWCYCLE_DELAY(__DELAY__) (((__DELAY__) > 0) && ((__DELAY__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Write_Recovery_Time FMC SDRAM Write Recovery Time + * @{ + */ +#define IS_FMC_WRITE_RECOVERY_TIME(__TIME__) (((__TIME__) > 0) && ((__TIME__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_RP_Delay FMC SDRAM RP Delay + * @{ + */ +#define IS_FMC_RP_DELAY(__DELAY__) (((__DELAY__) > 0) && ((__DELAY__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_RCD_Delay FMC SDRAM RCD Delay + * @{ + */ +#define IS_FMC_RCD_DELAY(__DELAY__) (((__DELAY__) > 0) && ((__DELAY__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_AutoRefresh_Number FMC SDRAM AutoRefresh Number + * @{ + */ +#define IS_FMC_AUTOREFRESH_NUMBER(__NUMBER__) (((__NUMBER__) > 0) && ((__NUMBER__) <= 16)) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_ModeRegister_Definition FMC SDRAM ModeRegister Definition + * @{ + */ +#define IS_FMC_MODE_REGISTER(__CONTENT__) ((__CONTENT__) <= 8191) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Refresh_rate FMC SDRAM Refresh rate + * @{ + */ +#define IS_FMC_REFRESH_RATE(__RATE__) ((__RATE__) <= 8191) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Device_Instance FMC NORSRAM Device Instance + * @{ + */ +#define IS_FMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_DEVICE) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_EXTENDED_Device_Instance FMC NORSRAM EXTENDED Device Instance + * @{ + */ +#define IS_FMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NORSRAM_EXTENDED_DEVICE) +/** + * @} + */ + +/** @defgroup FMC_NAND_Device_Instance FMC NAND Device Instance + * @{ + */ +#define IS_FMC_NAND_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_NAND_DEVICE) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Device_Instance FMC SDRAM Device Instance + * @{ + */ +#define IS_FMC_SDRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FMC_SDRAM_DEVICE) +/** + * @} + */ + +#define IS_FMC_SDRAM_BANK(BANK) (((BANK) == FMC_SDRAM_BANK1) || \ + ((BANK) == FMC_SDRAM_BANK2)) + +#define IS_FMC_COLUMNBITS_NUMBER(COLUMN) (((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_8) || \ + ((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_9) || \ + ((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_10) || \ + ((COLUMN) == FMC_SDRAM_COLUMN_BITS_NUM_11)) + +#define IS_FMC_ROWBITS_NUMBER(ROW) (((ROW) == FMC_SDRAM_ROW_BITS_NUM_11) || \ + ((ROW) == FMC_SDRAM_ROW_BITS_NUM_12) || \ + ((ROW) == FMC_SDRAM_ROW_BITS_NUM_13)) + +#define IS_FMC_INTERNALBANK_NUMBER(NUMBER) (((NUMBER) == FMC_SDRAM_INTERN_BANKS_NUM_2) || \ + ((NUMBER) == FMC_SDRAM_INTERN_BANKS_NUM_4)) + + +#define IS_FMC_CAS_LATENCY(LATENCY) (((LATENCY) == FMC_SDRAM_CAS_LATENCY_1) || \ + ((LATENCY) == FMC_SDRAM_CAS_LATENCY_2) || \ + ((LATENCY) == FMC_SDRAM_CAS_LATENCY_3)) + +#define IS_FMC_PAGESIZE(__SIZE__) (((__SIZE__) == FMC_PAGE_SIZE_NONE) || \ + ((__SIZE__) == FMC_PAGE_SIZE_128) || \ + ((__SIZE__) == FMC_PAGE_SIZE_256) || \ + ((__SIZE__) == FMC_PAGE_SIZE_1024)) + +#define IS_FMC_WRITE_FIFO(__FIFO__) (((__FIFO__) == FMC_WRITE_FIFO_DISABLE) || \ + ((__FIFO__) == FMC_WRITE_FIFO_ENABLE)) +/** + * @} + */ + +/* Exported typedef ----------------------------------------------------------*/ +/** @defgroup FMC_Exported_typedef FMC Low Layer Exported Types + * @{ + */ +#define FMC_NORSRAM_TypeDef FMC_Bank1_TypeDef +#define FMC_NORSRAM_EXTENDED_TypeDef FMC_Bank1E_TypeDef +#define FMC_NAND_TypeDef FMC_Bank3_TypeDef +#define FMC_SDRAM_TypeDef FMC_Bank5_6_TypeDef + +#define FMC_NORSRAM_DEVICE FMC_Bank1 +#define FMC_NORSRAM_EXTENDED_DEVICE FMC_Bank1E +#define FMC_NAND_DEVICE FMC_Bank3 +#define FMC_SDRAM_DEVICE FMC_Bank5_6 + +/** + * @brief FMC NORSRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t NSBank; /*!< Specifies the NORSRAM memory device that will be used. + This parameter can be a value of @ref FMC_NORSRAM_Bank */ + + uint32_t DataAddressMux; /*!< Specifies whether the address and data values are + multiplexed on the data bus or not. + This parameter can be a value of @ref FMC_Data_Address_Bus_Multiplexing */ + + uint32_t MemoryType; /*!< Specifies the type of external memory attached to + the corresponding memory device. + This parameter can be a value of @ref FMC_Memory_Type */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be a value of @ref FMC_NORSRAM_Data_Width */ + + uint32_t BurstAccessMode; /*!< Enables or disables the burst access mode for Flash memory, + valid only with synchronous burst Flash memories. + This parameter can be a value of @ref FMC_Burst_Access_Mode */ + + uint32_t WaitSignalPolarity; /*!< Specifies the wait signal polarity, valid only when accessing + the Flash memory in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal_Polarity */ + + uint32_t WaitSignalActive; /*!< Specifies if the wait signal is asserted by the memory one + clock cycle before the wait state or during the wait state, + valid only when accessing memories in burst mode. + This parameter can be a value of @ref FMC_Wait_Timing */ + + uint32_t WriteOperation; /*!< Enables or disables the write operation in the selected device by the FMC. + This parameter can be a value of @ref FMC_Write_Operation */ + + uint32_t WaitSignal; /*!< Enables or disables the wait state insertion via wait + signal, valid for Flash memory access in burst mode. + This parameter can be a value of @ref FMC_Wait_Signal */ + + uint32_t ExtendedMode; /*!< Enables or disables the extended mode. + This parameter can be a value of @ref FMC_Extended_Mode */ + + uint32_t AsynchronousWait; /*!< Enables or disables wait signal during asynchronous transfers, + valid only with asynchronous Flash memories. + This parameter can be a value of @ref FMC_AsynchronousWait */ + + uint32_t WriteBurst; /*!< Enables or disables the write burst operation. + This parameter can be a value of @ref FMC_Write_Burst */ + + uint32_t ContinuousClock; /*!< Enables or disables the FMC clock output to external memory devices. + This parameter is only enabled through the FMC_BCR1 register, and don't care + through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Continous_Clock */ + + uint32_t WriteFifo; /*!< Enables or disables the write FIFO used by the FMC controller. + This parameter is only enabled through the FMC_BCR1 register, and don't care + through FMC_BCR2..4 registers. + This parameter can be a value of @ref FMC_Write_FIFO */ + + uint32_t PageSize; /*!< Specifies the memory page size. + This parameter can be a value of @ref FMC_Page_Size */ + +}FMC_NORSRAM_InitTypeDef; + +/** + * @brief FMC NORSRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t AddressSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address setup time. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t AddressHoldTime; /*!< Defines the number of HCLK cycles to configure + the duration of the address hold time. + This parameter can be a value between Min_Data = 1 and Max_Data = 15. + @note This parameter is not used with synchronous NOR Flash memories. */ + + uint32_t DataSetupTime; /*!< Defines the number of HCLK cycles to configure + the duration of the data setup time. + This parameter can be a value between Min_Data = 1 and Max_Data = 255. + @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed + NOR Flash memories. */ + + uint32_t BusTurnAroundDuration; /*!< Defines the number of HCLK cycles to configure + the duration of the bus turnaround. + This parameter can be a value between Min_Data = 0 and Max_Data = 15. + @note This parameter is only used for multiplexed NOR Flash memories. */ + + uint32_t CLKDivision; /*!< Defines the period of CLK clock output signal, expressed in number of + HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16. + @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM + accesses. */ + + uint32_t DataLatency; /*!< Defines the number of memory clock cycles to issue + to the memory before getting the first data. + The parameter value depends on the memory type as shown below: + - It must be set to 0 in case of a CRAM + - It is don't care in asynchronous NOR, SRAM or ROM accesses + - It may assume a value between Min_Data = 2 and Max_Data = 17 in NOR Flash memories + with synchronous burst mode enable */ + + uint32_t AccessMode; /*!< Specifies the asynchronous access mode. + This parameter can be a value of @ref FMC_Access_Mode */ +}FMC_NORSRAM_TimingTypeDef; + +/** + * @brief FMC NAND Configuration Structure definition + */ +typedef struct +{ + uint32_t NandBank; /*!< Specifies the NAND memory device that will be used. + This parameter can be a value of @ref FMC_NAND_Bank */ + + uint32_t Waitfeature; /*!< Enables or disables the Wait feature for the NAND Memory device. + This parameter can be any value of @ref FMC_Wait_feature */ + + uint32_t MemoryDataWidth; /*!< Specifies the external memory device width. + This parameter can be any value of @ref FMC_NAND_Data_Width */ + + uint32_t EccComputation; /*!< Enables or disables the ECC computation. + This parameter can be any value of @ref FMC_ECC */ + + uint32_t ECCPageSize; /*!< Defines the page size for the extended ECC. + This parameter can be any value of @ref FMC_ECC_Page_Size */ + + uint32_t TCLRSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between CLE low and RE low. + This parameter can be a value between Min_Data = 0 and Max_Data = 255 */ + + uint32_t TARSetupTime; /*!< Defines the number of HCLK cycles to configure the + delay between ALE low and RE low. + This parameter can be a number between Min_Data = 0 and Max_Data = 255 */ +}FMC_NAND_InitTypeDef; + +/** + * @brief FMC NAND Timing parameters structure definition + */ +typedef struct +{ + uint32_t SetupTime; /*!< Defines the number of HCLK cycles to setup address before + the command assertion for NAND-Flash read or write access + to common/Attribute or I/O memory space (depending on + the memory space timing to be configured). + This parameter can be a value between Min_Data = 0 and Max_Data = 254 */ + + uint32_t WaitSetupTime; /*!< Defines the minimum number of HCLK cycles to assert the + command for NAND-Flash read or write access to + common/Attribute or I/O memory space (depending on the + memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ + + uint32_t HoldSetupTime; /*!< Defines the number of HCLK clock cycles to hold address + (and data for write access) after the command de-assertion + for NAND-Flash read or write access to common/Attribute + or I/O memory space (depending on the memory space timing + to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ + + uint32_t HiZSetupTime; /*!< Defines the number of HCLK clock cycles during which the + data bus is kept in HiZ after the start of a NAND-Flash + write access to common/Attribute or I/O memory space (depending + on the memory space timing to be configured). + This parameter can be a number between Min_Data = 0 and Max_Data = 254 */ +}FMC_NAND_PCC_TimingTypeDef; + +/** + * @brief FMC SDRAM Configuration Structure definition + */ +typedef struct +{ + uint32_t SDBank; /*!< Specifies the SDRAM memory device that will be used. + This parameter can be a value of @ref FMC_SDRAM_Bank */ + + uint32_t ColumnBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Column_Bits_number. */ + + uint32_t RowBitsNumber; /*!< Defines the number of bits of column address. + This parameter can be a value of @ref FMC_SDRAM_Row_Bits_number. */ + + uint32_t MemoryDataWidth; /*!< Defines the memory device width. + This parameter can be a value of @ref FMC_SDRAM_Memory_Bus_Width. */ + + uint32_t InternalBankNumber; /*!< Defines the number of the device's internal banks. + This parameter can be of @ref FMC_SDRAM_Internal_Banks_Number. */ + + uint32_t CASLatency; /*!< Defines the SDRAM CAS latency in number of memory clock cycles. + This parameter can be a value of @ref FMC_SDRAM_CAS_Latency. */ + + uint32_t WriteProtection; /*!< Enables the SDRAM device to be accessed in write mode. + This parameter can be a value of @ref FMC_SDRAM_Write_Protection. */ + + uint32_t SDClockPeriod; /*!< Define the SDRAM Clock Period for both SDRAM devices and they allow + to disable the clock before changing frequency. + This parameter can be a value of @ref FMC_SDRAM_Clock_Period. */ + + uint32_t ReadBurst; /*!< This bit enable the SDRAM controller to anticipate the next read + commands during the CAS latency and stores data in the Read FIFO. + This parameter can be a value of @ref FMC_SDRAM_Read_Burst. */ + + uint32_t ReadPipeDelay; /*!< Define the delay in system clock cycles on read data path. + This parameter can be a value of @ref FMC_SDRAM_Read_Pipe_Delay. */ +}FMC_SDRAM_InitTypeDef; + +/** + * @brief FMC SDRAM Timing parameters structure definition + */ +typedef struct +{ + uint32_t LoadToActiveDelay; /*!< Defines the delay between a Load Mode Register command and + an active or Refresh command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t ExitSelfRefreshDelay; /*!< Defines the delay from releasing the self refresh command to + issuing the Activate command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t SelfRefreshTime; /*!< Defines the minimum Self Refresh period in number of memory clock + cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RowCycleDelay; /*!< Defines the delay between the Refresh command and the Activate command + and the delay between two consecutive Refresh commands in number of + memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t WriteRecoveryTime; /*!< Defines the Write recovery Time in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RPDelay; /*!< Defines the delay between a Precharge Command and an other command + in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + + uint32_t RCDDelay; /*!< Defines the delay between the Activate Command and a Read/Write + command in number of memory clock cycles. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ +}FMC_SDRAM_TimingTypeDef; + +/** + * @brief SDRAM command parameters structure definition + */ +typedef struct +{ + uint32_t CommandMode; /*!< Defines the command issued to the SDRAM device. + This parameter can be a value of @ref FMC_SDRAM_Command_Mode. */ + + uint32_t CommandTarget; /*!< Defines which device (1 or 2) the command will be issued to. + This parameter can be a value of @ref FMC_SDRAM_Command_Target. */ + + uint32_t AutoRefreshNumber; /*!< Defines the number of consecutive auto refresh command issued + in auto refresh mode. + This parameter can be a value between Min_Data = 1 and Max_Data = 16 */ + uint32_t ModeRegisterDefinition; /*!< Defines the SDRAM Mode register content */ +}FMC_SDRAM_CommandTypeDef; +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @addtogroup FMC_LL_Exported_Constants FMC Low Layer Exported Constants + * @{ + */ + +/** @defgroup FMC_LL_NOR_SRAM_Controller FMC NOR/SRAM Controller + * @{ + */ + +/** @defgroup FMC_NORSRAM_Bank FMC NOR/SRAM Bank + * @{ + */ +#define FMC_NORSRAM_BANK1 ((uint32_t)0x00000000) +#define FMC_NORSRAM_BANK2 ((uint32_t)0x00000002) +#define FMC_NORSRAM_BANK3 ((uint32_t)0x00000004) +#define FMC_NORSRAM_BANK4 ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FMC_Data_Address_Bus_Multiplexing FMC Data Address Bus Multiplexing + * @{ + */ +#define FMC_DATA_ADDRESS_MUX_DISABLE ((uint32_t)0x00000000) +#define FMC_DATA_ADDRESS_MUX_ENABLE ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup FMC_Memory_Type FMC Memory Type + * @{ + */ +#define FMC_MEMORY_TYPE_SRAM ((uint32_t)0x00000000) +#define FMC_MEMORY_TYPE_PSRAM ((uint32_t)0x00000004) +#define FMC_MEMORY_TYPE_NOR ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Data_Width FMC NORSRAM Data Width + * @{ + */ +#define FMC_NORSRAM_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FMC_NORSRAM_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +#define FMC_NORSRAM_MEM_BUS_WIDTH_32 ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup FMC_NORSRAM_Flash_Access FMC NOR/SRAM Flash Access + * @{ + */ +#define FMC_NORSRAM_FLASH_ACCESS_ENABLE ((uint32_t)0x00000040) +#define FMC_NORSRAM_FLASH_ACCESS_DISABLE ((uint32_t)0x00000000) +/** + * @} + */ + +/** @defgroup FMC_Burst_Access_Mode FMC Burst Access Mode + * @{ + */ +#define FMC_BURST_ACCESS_MODE_DISABLE ((uint32_t)0x00000000) +#define FMC_BURST_ACCESS_MODE_ENABLE ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal_Polarity FMC Wait Signal Polarity + * @{ + */ +#define FMC_WAIT_SIGNAL_POLARITY_LOW ((uint32_t)0x00000000) +#define FMC_WAIT_SIGNAL_POLARITY_HIGH ((uint32_t)0x00000200) +/** + * @} + */ + +/** @defgroup FMC_Wait_Timing FMC Wait Timing + * @{ + */ +#define FMC_WAIT_TIMING_BEFORE_WS ((uint32_t)0x00000000) +#define FMC_WAIT_TIMING_DURING_WS ((uint32_t)0x00000800) +/** + * @} + */ + +/** @defgroup FMC_Write_Operation FMC Write Operation + * @{ + */ +#define FMC_WRITE_OPERATION_DISABLE ((uint32_t)0x00000000) +#define FMC_WRITE_OPERATION_ENABLE ((uint32_t)0x00001000) +/** + * @} + */ + +/** @defgroup FMC_Wait_Signal FMC Wait Signal + * @{ + */ +#define FMC_WAIT_SIGNAL_DISABLE ((uint32_t)0x00000000) +#define FMC_WAIT_SIGNAL_ENABLE ((uint32_t)0x00002000) +/** + * @} + */ + +/** @defgroup FMC_Extended_Mode FMC Extended Mode + * @{ + */ +#define FMC_EXTENDED_MODE_DISABLE ((uint32_t)0x00000000) +#define FMC_EXTENDED_MODE_ENABLE ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FMC_AsynchronousWait FMC Asynchronous Wait + * @{ + */ +#define FMC_ASYNCHRONOUS_WAIT_DISABLE ((uint32_t)0x00000000) +#define FMC_ASYNCHRONOUS_WAIT_ENABLE ((uint32_t)0x00008000) +/** + * @} + */ + +/** @defgroup FMC_Page_Size FMC Page Size + * @{ + */ +#define FMC_PAGE_SIZE_NONE ((uint32_t)0x00000000) +#define FMC_PAGE_SIZE_128 ((uint32_t)FMC_BCR1_CPSIZE_0) +#define FMC_PAGE_SIZE_256 ((uint32_t)FMC_BCR1_CPSIZE_1) +#define FMC_PAGE_SIZE_1024 ((uint32_t)FMC_BCR1_CPSIZE_2) +/** + * @} + */ + +/** @defgroup FMC_Write_Burst FMC Write Burst + * @{ + */ +#define FMC_WRITE_BURST_DISABLE ((uint32_t)0x00000000) +#define FMC_WRITE_BURST_ENABLE ((uint32_t)0x00080000) +/** + * @} + */ + +/** @defgroup FMC_Continous_Clock FMC Continuous Clock + * @{ + */ +#define FMC_CONTINUOUS_CLOCK_SYNC_ONLY ((uint32_t)0x00000000) +#define FMC_CONTINUOUS_CLOCK_SYNC_ASYNC ((uint32_t)0x00100000) +/** + * @} + */ + +/** @defgroup FMC_Write_FIFO FMC Write FIFO + * @{ + */ +#define FMC_WRITE_FIFO_DISABLE ((uint32_t)0x00000000) +#define FMC_WRITE_FIFO_ENABLE ((uint32_t)FMC_BCR1_WFDIS) +/** + * @} + */ + +/** @defgroup FMC_Access_Mode FMC Access Mode + * @{ + */ +#define FMC_ACCESS_MODE_A ((uint32_t)0x00000000) +#define FMC_ACCESS_MODE_B ((uint32_t)0x10000000) +#define FMC_ACCESS_MODE_C ((uint32_t)0x20000000) +#define FMC_ACCESS_MODE_D ((uint32_t)0x30000000) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Controller FMC NAND Controller + * @{ + */ +/** @defgroup FMC_NAND_Bank FMC NAND Bank + * @{ + */ +#define FMC_NAND_BANK3 ((uint32_t)0x00000100) +/** + * @} + */ + +/** @defgroup FMC_Wait_feature FMC Wait feature + * @{ + */ +#define FMC_NAND_WAIT_FEATURE_DISABLE ((uint32_t)0x00000000) +#define FMC_NAND_WAIT_FEATURE_ENABLE ((uint32_t)0x00000002) +/** + * @} + */ + +/** @defgroup FMC_PCR_Memory_Type FMC PCR Memory Type + * @{ + */ +#define FMC_PCR_MEMORY_TYPE_NAND ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FMC_NAND_Data_Width FMC NAND Data Width + * @{ + */ +#define FMC_NAND_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FMC_NAND_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +/** + * @} + */ + +/** @defgroup FMC_ECC FMC ECC + * @{ + */ +#define FMC_NAND_ECC_DISABLE ((uint32_t)0x00000000) +#define FMC_NAND_ECC_ENABLE ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup FMC_ECC_Page_Size FMC ECC Page Size + * @{ + */ +#define FMC_NAND_ECC_PAGE_SIZE_256BYTE ((uint32_t)0x00000000) +#define FMC_NAND_ECC_PAGE_SIZE_512BYTE ((uint32_t)0x00020000) +#define FMC_NAND_ECC_PAGE_SIZE_1024BYTE ((uint32_t)0x00040000) +#define FMC_NAND_ECC_PAGE_SIZE_2048BYTE ((uint32_t)0x00060000) +#define FMC_NAND_ECC_PAGE_SIZE_4096BYTE ((uint32_t)0x00080000) +#define FMC_NAND_ECC_PAGE_SIZE_8192BYTE ((uint32_t)0x000A0000) +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM_Controller FMC SDRAM Controller + * @{ + */ +/** @defgroup FMC_SDRAM_Bank FMC SDRAM Bank + * @{ + */ +#define FMC_SDRAM_BANK1 ((uint32_t)0x00000000) +#define FMC_SDRAM_BANK2 ((uint32_t)0x00000001) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Column_Bits_number FMC SDRAM Column Bits number + * @{ + */ +#define FMC_SDRAM_COLUMN_BITS_NUM_8 ((uint32_t)0x00000000) +#define FMC_SDRAM_COLUMN_BITS_NUM_9 ((uint32_t)0x00000001) +#define FMC_SDRAM_COLUMN_BITS_NUM_10 ((uint32_t)0x00000002) +#define FMC_SDRAM_COLUMN_BITS_NUM_11 ((uint32_t)0x00000003) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Row_Bits_number FMC SDRAM Row Bits number + * @{ + */ +#define FMC_SDRAM_ROW_BITS_NUM_11 ((uint32_t)0x00000000) +#define FMC_SDRAM_ROW_BITS_NUM_12 ((uint32_t)0x00000004) +#define FMC_SDRAM_ROW_BITS_NUM_13 ((uint32_t)0x00000008) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Memory_Bus_Width FMC SDRAM Memory Bus Width + * @{ + */ +#define FMC_SDRAM_MEM_BUS_WIDTH_8 ((uint32_t)0x00000000) +#define FMC_SDRAM_MEM_BUS_WIDTH_16 ((uint32_t)0x00000010) +#define FMC_SDRAM_MEM_BUS_WIDTH_32 ((uint32_t)0x00000020) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Internal_Banks_Number FMC SDRAM Internal Banks Number + * @{ + */ +#define FMC_SDRAM_INTERN_BANKS_NUM_2 ((uint32_t)0x00000000) +#define FMC_SDRAM_INTERN_BANKS_NUM_4 ((uint32_t)0x00000040) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_CAS_Latency FMC SDRAM CAS Latency + * @{ + */ +#define FMC_SDRAM_CAS_LATENCY_1 ((uint32_t)0x00000080) +#define FMC_SDRAM_CAS_LATENCY_2 ((uint32_t)0x00000100) +#define FMC_SDRAM_CAS_LATENCY_3 ((uint32_t)0x00000180) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Write_Protection FMC SDRAM Write Protection + * @{ + */ +#define FMC_SDRAM_WRITE_PROTECTION_DISABLE ((uint32_t)0x00000000) +#define FMC_SDRAM_WRITE_PROTECTION_ENABLE ((uint32_t)0x00000200) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Clock_Period FMC SDRAM Clock Period + * @{ + */ +#define FMC_SDRAM_CLOCK_DISABLE ((uint32_t)0x00000000) +#define FMC_SDRAM_CLOCK_PERIOD_2 ((uint32_t)0x00000800) +#define FMC_SDRAM_CLOCK_PERIOD_3 ((uint32_t)0x00000C00) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Burst FMC SDRAM Read Burst + * @{ + */ +#define FMC_SDRAM_RBURST_DISABLE ((uint32_t)0x00000000) +#define FMC_SDRAM_RBURST_ENABLE ((uint32_t)0x00001000) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Read_Pipe_Delay FMC SDRAM Read Pipe Delay + * @{ + */ +#define FMC_SDRAM_RPIPE_DELAY_0 ((uint32_t)0x00000000) +#define FMC_SDRAM_RPIPE_DELAY_1 ((uint32_t)0x00002000) +#define FMC_SDRAM_RPIPE_DELAY_2 ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Mode FMC SDRAM Command Mode + * @{ + */ +#define FMC_SDRAM_CMD_NORMAL_MODE ((uint32_t)0x00000000) +#define FMC_SDRAM_CMD_CLK_ENABLE ((uint32_t)0x00000001) +#define FMC_SDRAM_CMD_PALL ((uint32_t)0x00000002) +#define FMC_SDRAM_CMD_AUTOREFRESH_MODE ((uint32_t)0x00000003) +#define FMC_SDRAM_CMD_LOAD_MODE ((uint32_t)0x00000004) +#define FMC_SDRAM_CMD_SELFREFRESH_MODE ((uint32_t)0x00000005) +#define FMC_SDRAM_CMD_POWERDOWN_MODE ((uint32_t)0x00000006) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Command_Target FMC SDRAM Command Target + * @{ + */ +#define FMC_SDRAM_CMD_TARGET_BANK2 FMC_SDCMR_CTB2 +#define FMC_SDRAM_CMD_TARGET_BANK1 FMC_SDCMR_CTB1 +#define FMC_SDRAM_CMD_TARGET_BANK1_2 ((uint32_t)0x00000018) +/** + * @} + */ + +/** @defgroup FMC_SDRAM_Mode_Status FMC SDRAM Mode Status + * @{ + */ +#define FMC_SDRAM_NORMAL_MODE ((uint32_t)0x00000000) +#define FMC_SDRAM_SELF_REFRESH_MODE FMC_SDSR_MODES1_0 +#define FMC_SDRAM_POWER_DOWN_MODE FMC_SDSR_MODES1_1 +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup FMC_LL_Interrupt_definition FMC Low Layer Interrupt definition + * @{ + */ +#define FMC_IT_RISING_EDGE ((uint32_t)0x00000008) +#define FMC_IT_LEVEL ((uint32_t)0x00000010) +#define FMC_IT_FALLING_EDGE ((uint32_t)0x00000020) +#define FMC_IT_REFRESH_ERROR ((uint32_t)0x00004000) +/** + * @} + */ + +/** @defgroup FMC_LL_Flag_definition FMC Low Layer Flag definition + * @{ + */ +#define FMC_FLAG_RISING_EDGE ((uint32_t)0x00000001) +#define FMC_FLAG_LEVEL ((uint32_t)0x00000002) +#define FMC_FLAG_FALLING_EDGE ((uint32_t)0x00000004) +#define FMC_FLAG_FEMPT ((uint32_t)0x00000040) +#define FMC_SDRAM_FLAG_REFRESH_IT FMC_SDSR_RE +#define FMC_SDRAM_FLAG_BUSY FMC_SDSR_BUSY +#define FMC_SDRAM_FLAG_REFRESH_ERROR FMC_SDRTR_CRE +/** + * @} + */ +/** + * @} + */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Macros FMC_LL Private Macros + * @{ + */ + +/** @defgroup FMC_LL_NOR_Macros FMC NOR/SRAM Macros + * @brief macros to handle NOR device enable/disable and read/write operations + * @{ + */ + +/** + * @brief Enable the NORSRAM device access. + * @param __INSTANCE__: FMC_NORSRAM Instance + * @param __BANK__: FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] |= FMC_BCR1_MBKEN) + +/** + * @brief Disable the NORSRAM device access. + * @param __INSTANCE__: FMC_NORSRAM Instance + * @param __BANK__: FMC_NORSRAM Bank + * @retval None + */ +#define __FMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] &= ~FMC_BCR1_MBKEN) + +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Macros FMC NAND Macros + * @brief macros to handle NAND device enable/disable + * @{ + */ + +/** + * @brief Enable the NAND device access. + * @param __INSTANCE__: FMC_NAND Instance + * @retval None + */ +#define __FMC_NAND_ENABLE(__INSTANCE__) ((__INSTANCE__)->PCR |= FMC_PCR_PBKEN) + +/** + * @brief Disable the NAND device access. + * @param __INSTANCE__: FMC_NAND Instance + * @retval None + */ +#define __FMC_NAND_DISABLE(__INSTANCE__) ((__INSTANCE__)->PCR &= ~FMC_PCR_PBKEN) + +/** + * @} + */ + +/** @defgroup FMC_Interrupt FMC Interrupt + * @brief macros to handle FMC interrupts + * @{ + */ + +/** + * @brief Enable the NAND device interrupt. + * @param __INSTANCE__: FMC_NAND instance + * @param __INTERRUPT__: FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR |= (__INTERRUPT__)) + +/** + * @brief Disable the NAND device interrupt. + * @param __INSTANCE__: FMC_NAND Instance + * @param __INTERRUPT__: FMC_NAND interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_RISING_EDGE: Interrupt rising edge. + * @arg FMC_IT_LEVEL: Interrupt level. + * @arg FMC_IT_FALLING_EDGE: Interrupt falling edge. + * @retval None + */ +#define __FMC_NAND_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the NAND device. + * @param __INSTANCE__: FMC_NAND Instance + * @param __BANK__: FMC_NAND Bank + * @param __FLAG__: FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__) (((__INSTANCE__)->SR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the NAND device. + * @param __INSTANCE__: FMC_NAND Instance + * @param __FLAG__: FMC_NAND flag + * This parameter can be any combination of the following values: + * @arg FMC_FLAG_RISING_EDGE: Interrupt rising edge flag. + * @arg FMC_FLAG_LEVEL: Interrupt level edge flag. + * @arg FMC_FLAG_FALLING_EDGE: Interrupt falling edge flag. + * @arg FMC_FLAG_FEMPT: FIFO empty flag. + * @retval None + */ +#define __FMC_NAND_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SR &= ~(__FLAG__)) + +/** + * @brief Enable the SDRAM device interrupt. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __INTERRUPT__: FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_ENABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR |= (__INTERRUPT__)) + +/** + * @brief Disable the SDRAM device interrupt. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __INTERRUPT__: FMC_SDRAM interrupt + * This parameter can be any combination of the following values: + * @arg FMC_IT_REFRESH_ERROR: Interrupt refresh error + * @retval None + */ +#define __FMC_SDRAM_DISABLE_IT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->SDRTR &= ~(__INTERRUPT__)) + +/** + * @brief Get flag status of the SDRAM device. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __FLAG__: FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_IT: Interrupt refresh error. + * @arg FMC_SDRAM_FLAG_BUSY: SDRAM busy flag. + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR: Refresh error flag. + * @retval The state of FLAG (SET or RESET). + */ +#define __FMC_SDRAM_GET_FLAG(__INSTANCE__, __FLAG__) (((__INSTANCE__)->SDSR &(__FLAG__)) == (__FLAG__)) + +/** + * @brief Clear flag status of the SDRAM device. + * @param __INSTANCE__: FMC_SDRAM instance + * @param __FLAG__: FMC_SDRAM flag + * This parameter can be any combination of the following values: + * @arg FMC_SDRAM_FLAG_REFRESH_ERROR + * @retval None + */ +#define __FMC_SDRAM_CLEAR_FLAG(__INSTANCE__, __FLAG__) ((__INSTANCE__)->SDRTR |= (__FLAG__)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup FMC_LL_Private_Functions FMC LL Private Functions + * @{ + */ + +/** @defgroup FMC_LL_NORSRAM NOR SRAM + * @{ + */ +/** @defgroup FMC_LL_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef *Init); +HAL_StatusTypeDef FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode); +HAL_StatusTypeDef FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions + * @{ + */ +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Enable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NORSRAM_WriteOperation_Disable(FMC_NORSRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ +/** + * @} + */ + +/** @defgroup FMC_LL_NAND NAND + * @{ + */ +/** @defgroup FMC_LL_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_NAND_Init(FMC_NAND_TypeDef *Device, FMC_NAND_InitTypeDef *Init); +HAL_StatusTypeDef FMC_NAND_CommonSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_AttributeSpace_Timing_Init(FMC_NAND_TypeDef *Device, FMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_DeInit(FMC_NAND_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** @defgroup FMC_LL_NAND_Private_Functions_Group2 NAND Control functions + * @{ + */ +HAL_StatusTypeDef FMC_NAND_ECC_Enable(FMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_ECC_Disable(FMC_NAND_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_NAND_GetECC(FMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout); +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM SDRAM + * @{ + */ +/** @defgroup FMC_LL_SDRAM_Private_Functions_Group1 SDRAM Initialization/de-initialization functions + * @{ + */ +HAL_StatusTypeDef FMC_SDRAM_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_InitTypeDef *Init); +HAL_StatusTypeDef FMC_SDRAM_Timing_Init(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_TimingTypeDef *Timing, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_DeInit(FMC_SDRAM_TypeDef *Device, uint32_t Bank); + +/** + * @} + */ + +/** @defgroup FMC_LL_SDRAM_Private_Functions_Group2 SDRAM Control functions + * @{ + */ +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Enable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_WriteProtection_Disable(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +HAL_StatusTypeDef FMC_SDRAM_SendCommand(FMC_SDRAM_TypeDef *Device, FMC_SDRAM_CommandTypeDef *Command, uint32_t Timeout); +HAL_StatusTypeDef FMC_SDRAM_ProgramRefreshRate(FMC_SDRAM_TypeDef *Device, uint32_t RefreshRate); +HAL_StatusTypeDef FMC_SDRAM_SetAutoRefreshNumber(FMC_SDRAM_TypeDef *Device, uint32_t AutoRefreshNumber); +uint32_t FMC_SDRAM_GetModeStatus(FMC_SDRAM_TypeDef *Device, uint32_t Bank); +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F7xx_LL_FMC_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h b/drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h new file mode 100644 index 00000000..df605838 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/board_STM32F746Discovery_template.h @@ -0,0 +1,61 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_BOARD_H +#define _GDISP_LLD_BOARD_H + +static const ltdcConfig driverCfg = { + 480, 270, // Width, Height (pixels) + 10, 2, // Horizontal, Vertical sync (pixels) + 20, 2, // Horizontal, Vertical back porch (pixels) + 10, 4, // Horizontal, Vertical front porch (pixels) + 0, // Sync flags + 0x000000, // Clear color (RGB888) + + { // Background layer config + (LLDCOLOR_TYPE *)SDRAM_BANK_ADDR, // Frame buffer address + 480, 270, // Width, Height (pixels) + 480 * LTDC_PIXELBYTES, // Line pitch (bytes) + LTDC_PIXELFORMAT, // Pixel format + 0, 0, // Start pixel position (x, y) + 480, 270, // Size of virtual layer (cx, cy) + LTDC_COLOR_FUCHSIA, // Default color (ARGB8888) + 0x980088, // Color key (RGB888) + LTDC_BLEND_FIX1_FIX2, // Blending factors + 0, // Palette (RGB888, can be NULL) + 0, // Palette length + 0xFF, // Constant alpha factor + LTDC_LEF_ENABLE // Layer configuration flags + }, + + LTDC_UNUSED_LAYER_CONFIG // Foreground layer config +}; + +static inline void init_board(GDisplay* g) { + + // As we are not using multiple displays we set g->board to NULL as we don't use it. + g->board = 0; + + switch(g->controllerdisplay) { + case 0: // Set up for Display 0 + // Your init here + break; + } +} + +static inline void post_init_board(GDisplay* g) +{ + (void)g; +} + +static inline void set_backlight(GDisplay* g, uint8_t percent) +{ + (void)g; + (void)percent; +} + +#endif /* _GDISP_LLD_BOARD_H */ diff --git a/drivers/gdisp/STM32F746Discovery/driver.mk b/drivers/gdisp/STM32F746Discovery/driver.mk new file mode 100644 index 00000000..720d5d1c --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/driver.mk @@ -0,0 +1,2 @@ +GFXINC += $(GFXLIB)/drivers/gdisp/STM32F746Discovery +GFXSRC += $(GFXLIB)/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c diff --git a/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c b/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c new file mode 100644 index 00000000..ed4e8e20 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/gdisp_lld_STM32F746Discovery.c @@ -0,0 +1,365 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "gfx.h" + +#if GFX_USE_GDISP + +#if defined(GDISP_SCREEN_HEIGHT) + #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored." + #undef GISP_SCREEN_HEIGHT +#endif +#if defined(GDISP_SCREEN_WIDTH) + #warning "GDISP: This low level driver does not support setting a screen size. It is being ignored." + #undef GDISP_SCREEN_WIDTH +#endif + +#define GDISP_DRIVER_VMT GDISPVMT_STM32F746Discovery +#include "drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h" +#include "src/gdisp/gdisp_driver.h" + +#include "stm32_ltdc.h" + +typedef struct ltdcLayerConfig { + // frame + LLDCOLOR_TYPE *frame; // Frame buffer address + coord_t width, height; // Frame size in pixels + coord_t pitch; // Line pitch, in bytes + uint16_t fmt; // Pixel format in LTDC format + + // window + coord_t x, y; // Start pixel position of the virtual layer + coord_t cx, cy; // Size of the virtual layer + + uint32_t defcolor; // Default color, ARGB8888 + uint32_t keycolor; // Color key, RGB888 + uint32_t blending; // Blending factors + const uint32_t *palette; // The palette, RGB888 (can be NULL) + uint16_t palettelen; // Palette length + uint8_t alpha; // Constant alpha factor + uint8_t layerflags; // Layer configuration +} ltdcLayerConfig; + +#define LTDC_UNUSED_LAYER_CONFIG { 0, 1, 1, 1, LTDC_FMT_L8, 0, 0, 1, 1, 0x000000, 0x000000, LTDC_BLEND_FIX1_FIX2, 0, 0, 0, 0 } + +typedef struct ltdcConfig { + coord_t width, height; // Screen size + coord_t hsync, vsync; // Horizontal and Vertical sync pixels + coord_t hbackporch, vbackporch; // Horizontal and Vertical back porch pixels + coord_t hfrontporch, vfrontporch; // Horizontal and Vertical front porch pixels + uint8_t syncflags; // Sync flags + uint32_t bgcolor; // Clear screen color RGB888 + + ltdcLayerConfig bglayer; // Background layer config + ltdcLayerConfig fglayer; // Foreground layer config +} ltdcConfig; + +#if GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB565 + #define LTDC_PIXELFORMAT LTDC_FMT_RGB565 + #define LTDC_PIXELBYTES 2 + #define LTDC_PIXELBITS 16 +#elif GDISP_LLD_PIXELFORMAT == GDISP_PIXELFORMAT_RGB888 + #define LTDC_PIXELFORMAT LTDC_FMT_RGB888 + #define LTDC_PIXELBYTES 3 + #define LTDC_PIXELBITS 24 +#else + #error "GDISP: STM32F746Discovery - unsupported pixel format" +#endif + +#include "board_STM32F746Discovery.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#ifndef GDISP_INITIAL_CONTRAST + #define GDISP_INITIAL_CONTRAST 50 +#endif +#ifndef GDISP_INITIAL_BACKLIGHT + #define GDISP_INITIAL_BACKLIGHT 100 +#endif + +/*===========================================================================*/ +/* Driver local routines . */ +/*===========================================================================*/ + +#define PIXIL_POS(g, x, y) ((y) * driverCfg.bglayer.pitch + (x) * LTDC_PIXELBYTES) +#define PIXEL_ADDR(g, pos) ((LLDCOLOR_TYPE *)((uint8_t *)driverCfg.bglayer.frame+pos)) + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +static void LTDC_Reload(void) +{ + LTDC->SRCR |= LTDC_SRCR_IMR; + + while (LTDC->SRCR & (LTDC_SRCR_IMR | LTDC_SRCR_VBR)) { + gfxYield(); + } +} + +static void LTDC_LayerInit(LTDC_Layer_TypeDef* pLayReg, const ltdcLayerConfig* pCfg) +{ + static const uint8_t fmt2Bpp[] = { + 4, /* LTDC_FMT_ARGB8888 */ + 3, /* LTDC_FMT_RGB888 */ + 2, /* LTDC_FMT_RGB565 */ + 2, /* LTDC_FMT_ARGB1555 */ + 2, /* LTDC_FMT_ARGB4444 */ + 1, /* LTDC_FMT_L8 */ + 1, /* LTDC_FMT_AL44 */ + 2 /* LTDC_FMT_AL88 */ + }; + uint32_t start, stop; + + // Set the framebuffer dimensions and format + pLayReg->PFCR = (pLayReg->PFCR & ~LTDC_LxPFCR_PF) | ((uint32_t)pCfg->fmt & LTDC_LxPFCR_PF); + pLayReg->CFBAR = (uint32_t)pCfg->frame & LTDC_LxCFBAR_CFBADD; + pLayReg->CFBLR = ((((uint32_t)pCfg->pitch << 16) & LTDC_LxCFBLR_CFBP) | (((uint32_t)fmt2Bpp[pCfg->fmt] * pCfg->width + 3) & LTDC_LxCFBLR_CFBLL)); + pLayReg->CFBLNR = (uint32_t)pCfg->height & LTDC_LxCFBLNR_CFBLNBR; + + // Set the display window boundaries + start = (uint32_t)pCfg->x + driverCfg.hsync + driverCfg.hbackporch; + stop = start + pCfg->cx - 1; + pLayReg->WHPCR = ((start << 0) & LTDC_LxWHPCR_WHSTPOS) | ((stop << 16) & LTDC_LxWHPCR_WHSPPOS); + start = (uint32_t)pCfg->y + driverCfg.vsync + driverCfg.vbackporch; + stop = start + pCfg->cy - 1; + pLayReg->WVPCR = ((start << 0) & LTDC_LxWVPCR_WVSTPOS) | ((stop << 16) & LTDC_LxWVPCR_WVSPPOS); + + // Set colors + pLayReg->DCCR = pCfg->defcolor; + pLayReg->CKCR = (pLayReg->CKCR & ~0x00FFFFFF) | (pCfg->keycolor & 0x00FFFFFF); + pLayReg->CACR = (pLayReg->CACR & ~LTDC_LxCACR_CONSTA) | ((uint32_t)pCfg->alpha & LTDC_LxCACR_CONSTA); + pLayReg->BFCR = (pLayReg->BFCR & ~(LTDC_LxBFCR_BF1 | LTDC_LxBFCR_BF2)) | ((uint32_t)pCfg->blending & (LTDC_LxBFCR_BF1 | LTDC_LxBFCR_BF2)); + for (start = 0; start < pCfg->palettelen; start++) + pLayReg->CLUTWR = ((uint32_t)start << 24) | (pCfg->palette[start] & 0x00FFFFFF); + + // Final flags + pLayReg->CR = (pLayReg->CR & ~LTDC_LEF_MASK) | ((uint32_t)pCfg->layerflags & LTDC_LEF_MASK); +} + +static void LTDC_Init(void) +{ + // Set up the display scanning + uint32_t hacc, vacc; + + /* Reset the LTDC hardware module.*/ + RCC->APB2RSTR |= RCC_APB2RSTR_LTDCRST; + RCC->APB2RSTR = 0; + + /* Enable the LTDC clock.*/ + RCC->DCKCFGR = (RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR) | (1 << 16); /* /4 */ + + // Enable the module + RCC->APB2ENR |= RCC_APB2ENR_LTDCEN; + + // Turn off the controller and its interrupts. + LTDC->GCR = 0; + LTDC->IER = 0; + LTDC_Reload(); + + // Set synchronization params + hacc = driverCfg.hsync - 1; + vacc = driverCfg.vsync - 1; + LTDC->SSCR = ((hacc << 16) & LTDC_SSCR_HSW) | ((vacc << 0) & LTDC_SSCR_VSH); + + // Set accumulated back porch params + hacc += driverCfg.hbackporch; + vacc += driverCfg.vbackporch; + LTDC->BPCR = ((hacc << 16) & LTDC_BPCR_AHBP) | ((vacc << 0) & LTDC_BPCR_AVBP); + + // Set accumulated active params + hacc += driverCfg.width; + vacc += driverCfg.height; + LTDC->AWCR = ((hacc << 16) & LTDC_AWCR_AAW) | ((vacc << 0) & LTDC_AWCR_AAH); + + // Set accumulated total params + hacc += driverCfg.hfrontporch; + vacc += driverCfg.vfrontporch; + LTDC->TWCR = ((hacc << 16) & LTDC_TWCR_TOTALW) | ((vacc << 0) & LTDC_TWCR_TOTALH); + + // Set signal polarities and other flags + LTDC->GCR = driverCfg.syncflags & (LTDC_EF_MASK & ~LTDC_EF_ENABLE); + + // Set background color + LTDC->BCCR = (LTDC->BCCR & ~0x00FFFFFF) | (driverCfg.bgcolor & 0x00FFFFFF); + + // Load the background layer + LTDC_LayerInit(LTDC_Layer1, &driverCfg.bglayer); + + // Load the foreground layer + LTDC_LayerInit(LTDC_Layer2, &driverCfg.fglayer); + + // Interrupt handling + //nvicEnableVector(STM32_LTDC_EV_NUMBER, CORTEX_PRIORITY_MASK(STM32_LTDC_EV_IRQ_PRIORITY)); + //nvicEnableVector(STM32_LTDC_ER_NUMBER, CORTEX_PRIORITY_MASK(STM32_LTDC_ER_IRQ_PRIORITY)); + // Possible flags - LTDC_IER_RRIE, LTDC_IER_LIE, LTDC_IER_FUIE, LTDC_IER_TERRIE etc + LTDC->IER = 0; + + // Set everything going + LTDC_Reload(); + LTDC->GCR |= LTDC_GCR_LTDCEN; + LTDC_Reload(); +} + +LLDSPEC bool_t gdisp_lld_init(GDisplay* g) +{ + // Initialize the private structure + g->priv = 0; + g->board = 0; + //if (!(g->priv = gfxAlloc(sizeof(fbPriv)))) + // gfxHalt("GDISP Framebuffer: Failed to allocate private memory"); + + // Init the board + init_board(g); + //((fbPriv *)g->priv)->fbi.cfg = init_board(g); + + // Initialise the LTDC controller + LTDC_Init(); + + // Initialise DMA2D + //dma2dStart(&DMA2DD1, &dma2d_cfg); + //dma2d_test(); + + // Finish Init the board + post_init_board(g); + + // Turn on the back-light + set_backlight(g, GDISP_INITIAL_BACKLIGHT); + + // Initialise the GDISP structure + g->g.Width = driverCfg.bglayer.width; + g->g.Height = driverCfg.bglayer.height; + g->g.Orientation = GDISP_ROTATE_0; + g->g.Powermode = powerOn; + g->g.Backlight = GDISP_INITIAL_BACKLIGHT; + g->g.Contrast = GDISP_INITIAL_CONTRAST; + + return TRUE; +} + +LLDSPEC void gdisp_lld_draw_pixel(GDisplay* g) +{ + unsigned pos; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + default: + pos = PIXIL_POS(g, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); + break; + case GDISP_ROTATE_180: + pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); + break; + case GDISP_ROTATE_270: + pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); + break; + } + #else + pos = PIXIL_POS(g, g->p.x, g->p.y); + #endif + + PIXEL_ADDR(g, pos)[0] = gdispColor2Native(g->p.color); +} + +LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay* g) +{ + unsigned pos; + LLDCOLOR_TYPE color; + + #if GDISP_NEED_CONTROL + switch(g->g.Orientation) { + case GDISP_ROTATE_0: + default: + pos = PIXIL_POS(g, g->p.x, g->p.y); + break; + case GDISP_ROTATE_90: + pos = PIXIL_POS(g, g->p.y, g->g.Width-g->p.x-1); + break; + case GDISP_ROTATE_180: + pos = PIXIL_POS(g, g->g.Width-g->p.x-1, g->g.Height-g->p.y-1); + break; + case GDISP_ROTATE_270: + pos = PIXIL_POS(g, g->g.Height-g->p.y-1, g->p.x); + break; + } + #else + pos = PIXIL_POS(g, g->p.x, g->p.y); + #endif + + color = PIXEL_ADDR(g, pos)[0]; + + return gdispNative2Color(color); +} + +#if GDISP_NEED_CONTROL + LLDSPEC void gdisp_lld_control(GDisplay* g) + { + switch(g->p.x) { + case GDISP_CONTROL_POWER: + if (g->g.Powermode == (powermode_t)g->p.ptr) + return; + switch((powermode_t)g->p.ptr) { + case powerOff: case powerOn: case powerSleep: case powerDeepSleep: + // TODO + break; + default: + return; + } + g->g.Powermode = (powermode_t)g->p.ptr; + return; + + case GDISP_CONTROL_ORIENTATION: + if (g->g.Orientation == (orientation_t)g->p.ptr) + return; + switch((orientation_t)g->p.ptr) { + case GDISP_ROTATE_0: + case GDISP_ROTATE_180: + if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) { + coord_t tmp; + + tmp = g->g.Width; + g->g.Width = g->g.Height; + g->g.Height = tmp; + } + break; + case GDISP_ROTATE_90: + case GDISP_ROTATE_270: + if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) { + coord_t tmp; + + tmp = g->g.Width; + g->g.Width = g->g.Height; + g->g.Height = tmp; + } + break; + default: + return; + } + g->g.Orientation = (orientation_t)g->p.ptr; + return; + + case GDISP_CONTROL_BACKLIGHT: + if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; + set_backlight(g, (unsigned)g->p.ptr); + g->g.Backlight = (unsigned)g->p.ptr; + return; + + case GDISP_CONTROL_CONTRAST: + if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; + // TODO + g->g.Contrast = (unsigned)g->p.ptr; + return; + } + } +#endif + +#endif /* GFX_USE_GDISP */ diff --git a/drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h b/drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h new file mode 100644 index 00000000..29e016ce --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/gdisp_lld_config.h @@ -0,0 +1,24 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef _GDISP_LLD_CONFIG_H +#define _GDISP_LLD_CONFIG_H + +#if GFX_USE_GDISP + +/*===========================================================================*/ +/* Driver hardware support. */ +/*===========================================================================*/ + +#define GDISP_HARDWARE_DRAWPIXEL TRUE +#define GDISP_HARDWARE_PIXELREAD TRUE +#define GDISP_HARDWARE_CONTROL TRUE +#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565 + +#endif /* GFX_USE_GDISP */ + +#endif /* _GDISP_LLD_CONFIG_H */ diff --git a/drivers/gdisp/STM32F746Discovery/readme.txt b/drivers/gdisp/STM32F746Discovery/readme.txt new file mode 100644 index 00000000..e21429df --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/readme.txt @@ -0,0 +1,11 @@ +To use this driver: + +1. Add in your gfxconf.h: + a) #define GFX_USE_GDISP TRUE + +2. To your makefile add the following lines: + include $(GFXLIB)/gfx.mk + include $(GFXLIB)/drivers/gdisp/STM32F746Discovery/driver.mk + +3. Add a board_STM32F746Discovery.h to you project directory (or board directory) + based on one of the templates. diff --git a/drivers/gdisp/STM32F746Discovery/stm32_ltdc.h b/drivers/gdisp/STM32F746Discovery/stm32_ltdc.h new file mode 100644 index 00000000..429d8627 --- /dev/null +++ b/drivers/gdisp/STM32F746Discovery/stm32_ltdc.h @@ -0,0 +1,138 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#ifndef STM32_LTDC_H +#define STM32_LTDC_H + +// LTDC enable flags +#define LTDC_EF_ENABLE (1 << 0) /**< LTDC enabled.*/ +#define LTDC_EF_DITHER (1 << 16) /**< Dithering enabled.*/ +#define LTDC_EF_PIXCLK_INVERT (1 << 28) /**< Inverted pixel clock.*/ +#define LTDC_EF_DATAEN_HIGH (1 << 29) /**< Active-high data enable.*/ +#define LTDC_EF_VSYNC_HIGH (1 << 30) /**< Active-high vsync.*/ +#define LTDC_EF_HSYNC_HIGH (1 << 31) /**< Active-high hsync.*/ + +#define LTDC_EF_MASK (LTDC_EF_ENABLE | LTDC_EF_DITHER | LTDC_EF_PIXCLK_INVERT | LTDC_EF_DATAEN_HIGH | LTDC_EF_VSYNC_HIGH | LTDC_EF_HSYNC_HIGH) + +// LTDC layer enable flags +#define LTDC_LEF_ENABLE (1 << 0) /**< Layer enabled*/ +#define LTDC_LEF_KEYING (1 << 1) /**< Color keying enabled.*/ +#define LTDC_LEF_PALETTE (1 << 4) /**< Palette enabled.*/ + +#define LTDC_LEF_MASK (LTDC_LEF_ENABLE | LTDC_LEF_KEYING | LTDC_LEF_PALETTE) + +// LTDC pixel formats +#define LTDC_FMT_ARGB8888 0 /**< ARGB-8888 format.*/ +#define LTDC_FMT_RGB888 1 /**< RGB-888 format.*/ +#define LTDC_FMT_RGB565 2 /**< RGB-565 format.*/ +#define LTDC_FMT_ARGB1555 3 /**< ARGB-1555 format.*/ +#define LTDC_FMT_ARGB4444 4 /**< ARGB-4444 format.*/ +#define LTDC_FMT_L8 5 /**< L-8 format.*/ +#define LTDC_FMT_AL44 6 /**< AL-44 format.*/ +#define LTDC_FMT_AL88 7 /**< AL-88 format.*/ + +// LTDC pixel format aliased raw masks +#define LTDC_XMASK_ARGB8888 0xFFFFFFFF /**< ARGB-8888 aliased mask.*/ +#define LTDC_XMASK_RGB888 0x00FFFFFF /**< RGB-888 aliased mask.*/ +#define LTDC_XMASK_RGB565 0x00F8FCF8 /**< RGB-565 aliased mask.*/ +#define LTDC_XMASK_ARGB1555 0x80F8F8F8 /**< ARGB-1555 aliased mask.*/ +#define LTDC_XMASK_ARGB4444 0xF0F0F0F0 /**< ARGB-4444 aliased mask.*/ +#define LTDC_XMASK_L8 0x000000FF /**< L-8 aliased mask.*/ +#define LTDC_XMASK_AL44 0xF00000F0 /**< AL-44 aliased mask.*/ +#define LTDC_XMASK_AL88 0xFF0000FF /**< AL-88 aliased mask.*/ + +// LTDC blending factors +#define LTDC_BLEND_FIX1_FIX2 0x0405 /**< cnst1; 1 - cnst2 */ +#define LTDC_BLEND_FIX1_MOD2 0x0407 /**< cnst1; 1 - a2 * cnst2 */ +#define LTDC_BLEND_MOD1_FIX2 0x0605 /**< a1 * cnst1; 1 - cnst2 */ +#define LTDC_BLEND_MOD1_MOD2 0x0607 /**< a1 * cnst1; 1 - a2 * cnst2 */ + +// LTDC parameter bounds +#define LTDC_MIN_SCREEN_WIDTH 1 +#define LTDC_MIN_SCREEN_HEIGHT 1 +#define LTDC_MAX_SCREEN_WIDTH 800 +#define LTDC_MAX_SCREEN_HEIGHT 600 + +#define LTDC_MIN_HSYNC_WIDTH 1 +#define LTDC_MIN_VSYNC_HEIGHT 1 +#define LTDC_MAX_HSYNC_WIDTH (1 << 12) +#define LTDC_MAX_VSYNC_HEIGHT (1 << 11) + +#define LTDC_MIN_HBP_WIDTH 0 +#define LTDC_MIN_VBP_HEIGHT 0 +#define LTDC_MAX_HBP_WIDTH (1 << 12) +#define LTDC_MAX_VBP_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_HBP_WIDTH 1 +#define LTDC_MIN_ACC_VBP_HEIGHT 1 +#define LTDC_MAX_ACC_HBP_WIDTH (1 << 12) +#define LTDC_MAX_ACC_VBP_HEIGHT (1 << 11) + +#define LTDC_MIN_HFP_WIDTH 0 +#define LTDC_MIN_VFP_HEIGHT 0 +#define LTDC_MAX_HFP_WIDTH (1 << 12) +#define LTDC_MAX_VFP_HEIGHT (1 << 11) + +#define LTDC_MIN_ACTIVE_WIDTH 0 +#define LTDC_MIN_ACTIVE_HEIGHT 0 +#define LTDC_MAX_ACTIVE_WIDTH (1 << 12) +#define LTDC_MAX_ACTIVE_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_ACTIVE_WIDTH 1 +#define LTDC_MIN_ACC_ACTIVE_HEIGHT 1 +#define LTDC_MAX_ACC_ACTIVE_WIDTH (1 << 12) +#define LTDC_MAX_ACC_ACTIVE_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_TOTAL_WIDTH 1 +#define LTDC_MIN_ACC_TOTAL_HEIGHT 1 +#define LTDC_MAX_ACC_TOTAL_WIDTH (1 << 12) +#define LTDC_MAX_ACC_TOTAL_HEIGHT (1 << 11) + +#define LTDC_MIN_LINE_INTERRUPT_POS 0 +#define LTDC_MAX_LINE_INTERRUPT_POS ((1 << 11) - 1) + +#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) +#define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) + +#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) +#define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) + +#define LTDC_MIN_FRAME_WIDTH_BYTES 0 +#define LTDC_MIN_FRAME_HEIGHT_LINES 0 +#define LTDC_MIN_FRAME_PITCH_BYTES 0 +#define LTDC_MAX_FRAME_WIDTH_BYTES ((1 << 13) - 1 - 3) +#define LTDC_MAX_FRAME_HEIGHT_LINES ((1 << 11) - 1) +#define LTDC_MAX_FRAME_PITCH_BYTES ((1 << 13) - 1) + +#define LTDC_MIN_PIXFMT_ID 0 +#define LTDC_MAX_PIXFMT_ID 7 + +#define LTDC_MAX_PALETTE_LENGTH 256 + +// LTDC basic ARGB-8888 colors. +#define LTDC_COLOR_BLACK 0xFF000000 +#define LTDC_COLOR_MAROON 0xFF800000 +#define LTDC_COLOR_GREEN 0xFF008000 +#define LTDC_COLOR_OLIVE 0xFF808000 +#define LTDC_COLOR_NAVY 0xFF000080 +#define LTDC_COLOR_PURPLE 0xFF800080 +#define LTDC_COLOR_TEAL 0xFF008080 +#define LTDC_COLOR_SILVER 0xFFC0C0C0 +#define LTDC_COLOR_GRAY 0xFF808080 +#define LTDC_COLOR_RED 0xFFFF0000 +#define LTDC_COLOR_LIME 0xFF00FF00 +#define LTDC_COLOR_YELLOW 0xFFFFFF00 +#define LTDC_COLOR_BLUE 0xFF0000FF +#define LTDC_COLOR_FUCHSIA 0xFFFF00FF +#define LTDC_COLOR_AQUA 0xFF00FFFF +#define LTDC_COLOR_WHITE 0xFFFFFFFF + +#endif /* STM32_LTDC_H */ |