patacongo commented on a change in pull request #458: stm32h7: support SDRAM 
via FMC peripherial
URL: https://github.com/apache/incubator-nuttx/pull/458#discussion_r388939870
 
 

 ##########
 File path: arch/arm/src/stm32h7/stm32_fmc.c
 ##########
 @@ -39,40 +39,387 @@
 
 #include <nuttx/config.h>
 
+#if defined(CONFIG_STM32H7_FMC)
+
 #include "stm32.h"
 
-#if defined(CONFIG_STM32H7_FMC)
+#include <debug.h>
+
+//#include "stm32_fmc.h"
+//#include "hardware/stm32_pinmap.h"
+//#include "stm32_gpio.h"
+//#include "stm32_rcc.h"
+
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/****************************************************************************
+ * To use FMC, you must first enable it in configuration:
+ *
+ * CONFIG_STM32H7_FMC=y
+ *
+ * FMC is statically configured at startup. Its configuration is adjusted
+ * using BOARD_XXX macros described below, which should be declared
+ * in your board.h file.
+ *
+ * The BOARD_FMC_CLK macro can be defined to select the clock source for FMC.
+ * This can be one of RCC_D1CCIPR_FMCSEL_xxx macros, and defaults to
+ * RCC_D1CCIPR_FMCSEL_PLL2 (which means PLL2R).
+ *
+ *
+ * To correctly initialize GPIO pins the macro BOARD_FMC_GPIO_CONFIGS should
+ * define a list of 32-bit GPIO configuration bitmasks. Example:
+ *
+ * #define BOARD_FMC_GPIO_CONFIGS       GPIO_FMC_A0,GPIO_FMC_A1,\
+ *         GPIO_FMC_A2,...,GPIO_FMC_D0,...,GPIO_FMC_NBL0,...
+ *
+ *
+ * For SRAM/NOR-Flash memories FMC defines 4 x 64Mb sub-banks at addresses
+ * 0x60000000, 0x64000000, 0x68000000, 0x6C000000. The following macros
+ * can be defined in board.h to initialize FMC for use with SRAM/NOR-Flash:
+ *
+ * *** CURRENTLY SRAM/NOR-FLASH SUPPORT IS NOT IMPLEMENTED ***
+ *
+ * BOARD_FMC_BCR[1..4] - Initial value for control registers
+ *      for subbanks 1-4.
+ * BOARD_FMC_BTR[1..4] - Initial value for SRAM/NOR-Flash timing registers
+ *      for subbanks 1-4.
+ * BOARD_FMC_BWTR[1..4] - Initial value for SRAM/NOR-Flash write timing 
registers
+ *      for subbanks 1-4.
+ *
+ *
+ * For NAND flash memories FMC reserves 64Mb at 0x80000000. Define the 
following
+ * macros in your board.h file to initialize FMC for this type of memory:
+ *
+ * *** CURRENTLY NAND FLASH SUPPORT IS NOT IMPLEMENTED ***
+ *
+ * BOARD_FMC_PCR - Initial value for NAND flash control register.
+ * BOARD_FMC_PMEM - Initial value for NAND flash common memory space timing 
register.
+ * BOARD_FMC_PATT - Initial value for NAND flash attribute memory space timing 
register.
+ *
+ *
+ * For SDRAM memory FMC reserves 2 x 256Mb address ranges at 0xC0000000 and 
0xD0000000.
+ * Define the following macros to initialize FMC to work with SDRAM:
+ *
+ * BOARD_FMC_SDCR[1..2] - Initial value for SDRAM control registers for SDRAM 
bank 1-2.
+ *      Note that some bits in SDCR1 influence both SDRAM banks and are unused 
in SDCR2!
+ * BOARD_FMC_SDTR[1..2] - Initial value for SDRAM timing registeres for SDRAM 
bank 1-2.
+ *      Note that some bits in SDTR1 influence both SDRAM banks and are unused 
in SDTR2!
+ * BOARD_FMC_SDRAM_REFR_PERIOD - The SDRAM refresh rate period in FMC clocks, 
OR
+ * BOARD_FMC_SDRAM_REFR_CYCLES and BOARD_FMC_SDRAM_REFR_PERIOD can be used to 
automatically
+ *      compute refresh counter using data from SDRAM datasheet (cycles 
usually is 4096, 8192
+ *      and such, and typical period is 64 (ms)) and knowing FMC clock 
frequency.
+ * BOARD_FMC_SDRAM_AUTOREFRESH may be defined to a number between 1 and 16 to 
issue
+ *      given number of SDRAM auto-refresh cycles before using it. This 
defaults to 3.
+ *
+ *
+ * Special notes:
+ *      - FMC bank remapping (FMC_BCR_BMAP*) is not currently supported.
+ *
+ *
+ * Here's a working example of a configured IS42S16320D SDRAM on a particular 
board:
+ *
+ *#define BOARD_SDRAM1_SIZE               (64*1024*1024)
+ *
+ *#define BOARD_FMC_SDCR1                 (FMC_SDCR_COLBITS_10 | 
FMC_SDCR_ROWBITS_13 | FMC_SDCR_WIDTH_16 | FMC_SDCR_BANKS_4 | FMC_SDCR_CASLAT_2 
| FMC_SDCR_SDCLK_2X | FMC_SDCR_BURST_READ | FMC_SDCR_RPIPE_1)
+ *#define BOARD_FMC_SDTR1                 (FMC_SDTR_TMRD(2) | FMC_SDTR_TXSR(7) 
| FMC_SDTR_TRAS(4) | FMC_SDTR_TRC(7) | FMC_SDTR_TWR(4) | FMC_SDTR_TRP(2) | 
FMC_SDTR_TRCD(2))
+ *#define BOARD_FMC_SDRAM_REFR_CYCLES     8192
+ *#define BOARD_FMC_SDRAM_REFR_PERIOD     64
+ *#define BOARD_FMC_SDRAM_MODE            FMC_SDCMR_MRD_BURST_LENGTH_8 | \
+ *                                        FMC_SDCMR_MRD_BURST_TYPE_SEQUENTIAL 
| \
+ *                                        FMC_SDCMR_MRD_CAS_LATENCY_2
+ *
+ *#define BOARD_FMC_GPIO_CONFIGS \
+ *    
GPIO_FMC_A0,GPIO_FMC_A1,GPIO_FMC_A2,GPIO_FMC_A3,GPIO_FMC_A4,GPIO_FMC_A5,GPIO_FMC_A6,GPIO_FMC_A7,\
+ *    GPIO_FMC_A8,GPIO_FMC_A9,GPIO_FMC_A10,GPIO_FMC_A11,GPIO_FMC_A12,\
+ *    
GPIO_FMC_D0,GPIO_FMC_D1,GPIO_FMC_D2,GPIO_FMC_D3,GPIO_FMC_D4,GPIO_FMC_D5,GPIO_FMC_D6,GPIO_FMC_D7,\
+ *    
GPIO_FMC_D8,GPIO_FMC_D9,GPIO_FMC_D10,GPIO_FMC_D11,GPIO_FMC_D12,GPIO_FMC_D13,GPIO_FMC_D14,GPIO_FMC_D15,\
+ *    GPIO_FMC_NBL0,GPIO_FMC_NBL1,GPIO_FMC_BA0,GPIO_FMC_BA1,\
+ *    
GPIO_FMC_SDNWE_2,GPIO_FMC_SDNCAS,GPIO_FMC_SDNRAS,GPIO_FMC_SDNE0_1,GPIO_FMC_SDCKE0_1,GPIO_FMC_SDCLK
+ *
+ ****************************************************************************/
+
+#ifndef BOARD_FMC_CLK
+/* Clock FMC from PLL2R by default */
+#  define BOARD_FMC_CLK         RCC_D1CCIPR_FMCSEL_PLL2
+#endif
+
+/* A couple of macros to know if user uses SDRAM1 and/or SDRAM2 */
+
+#if defined BOARD_FMC_SDCR1 && ((BOARD_FMC_SDCR1 & FMC_SDCR_CASLAT_MASK) != 0)
+#  define HAVE_FMC_SDRAM1        1
+#endif
+#if defined BOARD_FMC_SDCR2 && ((BOARD_FMC_SDCR2 & FMC_SDCR_CASLAT_MASK) != 0)
+#  define HAVE_FMC_SDRAM2        1
+#endif
+
+#if defined HAVE_FMC_SDRAM1 || defined HAVE_FMC_SDRAM2
+#  define HAVE_FMC_SDRAM         1
+#endif
+
+/* Number of auto-refresh cycles to issue at SDRAM initialization */
+
+#ifndef BOARD_FMC_SDRAM_AUTOREFRESH
+#  define BOARD_FMC_SDRAM_AUTOREFRESH   3
+#endif
+
+/* Find out the clock frequency for FMC */
+
+#if BOARD_FMC_CLK == RCC_D1CCIPR_FMCSEL_HCLK
+#  define FMC_CLK_FREQUENCY     STM32_HCLK_FREQUENCY
+#elif BOARD_FMC_CLK == RCC_D1CCIPR_FMCSEL_PLL1
+#  define FMC_CLK_FREQUENCY     STM32_PLL1Q_FREQUENCY
+#elif BOARD_FMC_CLK == RCC_D1CCIPR_FMCSEL_PLL2
+#  define FMC_CLK_FREQUENCY     STM32_PLL2R_FREQUENCY
+#elif BOARD_FMC_CLK == RCC_D1CCIPR_FMCSEL_PER
+#  define FMC_CLK_FREQUENCY     STM32_PER_FREQUENCY
+#else
+#  error "BOARD_FMC_CLK has unknown value!"
+#endif
+
+/* Compute the refresh rate in clocks */
+
+#ifndef BOARD_FMC_SDRAM_REFR_PERIOD
+
+#  if !defined(BOARD_FMC_SDRAM_REFR_CYCLES) || 
!defined(BOARD_FMC_SDRAM_REFR_PERIOD)
+#    error "Both BOARD_FMC_SDRAM_REFR_CYCLES and BOARD_FMC_SDRAM_REFR_PERIOD 
have to be defined to compute BOARD_FMC_SDRAM_REFR_PERIOD!"
+#  else
+     /* Take care not to overflow on 32-bit arithmetic */
+#    define BOARD_FMC_SDRAM_REFR_PERIOD        
((uint32_t)((uint64_t)BOARD_FMC_SDRAM_REFR_PERIOD * FMC_CLK_FREQUENCY / 
BOARD_FMC_SDRAM_REFR_CYCLES - 20))
+#  endif
+
+#endif /* BOARD_FMC_SDRAM_REFR_PERIOD */
+
+/* The bits in FMC_SDCR we will alter at initialization */
+#define FMC_SDCR_MASK           (FMC_SDCR_COLBITS_MASK | FMC_SDCR_ROWBITS_MASK 
| \
+    FMC_SDCR_WIDTH_MASK | FMC_SDCR_BANKS_MASK | FMC_SDCR_CASLAT_MASK | 
FMC_SDCR_WP | \
+    FMC_SDCR_SDCLK_MASK | FMC_SDCR_BURST_READ | FMC_SDCR_RPIPE_MASK)
+
+/* The bits in FMC_SDTR we will alter at initialization */
+#define FMC_SDTR_MASK           (FMC_SDTR_TMRD_MASK | FMC_SDTR_TXSR_MASK | \
+    FMC_SDTR_TRAS_MASK | FMC_SDTR_TRC_MASK | FMC_SDTR_TWR_MASK | 
FMC_SDTR_TRP_MASK | \
+    FMC_SDTR_TRCD_MASK)
+
+/* The timeout while waiting for SDRAM controller to initialize, in us */
+#define SDRAM_INIT_TIMEOUT      (1000)
+
+
+/****************************************************************************
+ * Private data
+ ****************************************************************************/
+
+static uint32_t fmc_gpios[] =
+{
+    BOARD_FMC_GPIO_CONFIGS
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void stm32_fmc_sdram_init(void);
+static int stm32_fmc_sdram_wait(unsigned timeout);
+
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: stm32_fmc_enable
+ * Name: stm32_fmc_init
+ *
+ * Description:
+ *   Initialize the FMC peripherial. Because FMC initialization is highly
+ *   dependent on the used parts, definition of the initial values for FMC
+ *   registers is mostly left to board designer.
+ *
+ *   Typically called from up_addregion().
+ *
+ ****************************************************************************/
+
+void stm32_fmc_init(void)
+{
+  uint32_t regval;
+
+  /* Reset the FMC on the AHB3 bus */
+
+  regval  = getreg32(STM32_RCC_AHB3RSTR);
+  regval |= RCC_AHB3RSTR_FMCRST;
+  putreg32(regval, STM32_RCC_AHB3RSTR);
+
+  /* Leave reset state */
+
+  regval &= ~RCC_AHB3RSTR_FMCRST;
+  putreg32(regval, STM32_RCC_AHB3RSTR);
+
+  /* Set FMC clocking */
+
+  modreg32 (BOARD_FMC_CLK, RCC_D1CCIPR_FMCSEL_MASK, STM32_RCC_D1CCIPR);
+
+  /* Set up FMC GPIOs */
+
+  for (regval = 0; regval < ARRAY_SIZE(fmc_gpios); regval++)
+    stm32_configgpio(fmc_gpios[regval]);
+
+  /* Set up FMC registers */
+
+#ifdef BOARD_FMC_SDCR1
+  modreg32(BOARD_FMC_SDCR1, FMC_SDCR_MASK, STM32_FMC_SDCR1);
+#endif
+#ifdef BOARD_FMC_SDCR2
+  modreg32(BOARD_FMC_SDCR2, FMC_SDCR_MASK, STM32_FMC_SDCR2);
+#endif
+
+#ifdef BOARD_FMC_SDTR1
+  modreg32(BOARD_FMC_SDTR1, FMC_SDTR_MASK, STM32_FMC_SDTR1);
+#endif
+#ifdef BOARD_FMC_SDTR2
+  modreg32(BOARD_FMC_SDTR2, FMC_SDTR_MASK, STM32_FMC_SDTR2);
+#endif
+
+  /* Enable the FMC peripherial */
+
+  modreg32(FMC_BCR_FMCEN, FMC_BCR_FMCEN, STM32_FMC_BCR1);
+
+  /* Initialize the SDRAM chips themselves */
+
+#ifdef HAVE_FMC_SDRAM
+  stm32_fmc_sdram_init();
+#endif
+
+  /* Set up SDRAM refresh timings */
+
+#ifdef BOARD_FMC_SDRAM_REFR_PERIOD
+  /* ... The programmed COUNT value must not be equal to the sum of the 
following timings:
+     TWR+TRP+TRC+TRCD+4 memory clock cycles */
 
 Review comment:
   */ must be on a separate line per coding standard
   All comments must be followed by a blank line per coding standard.

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to