boart test board

Dependencies:   USBDevice mbed-dev lwip

Fork of USBSerial_HelloWorld by Compass Yap

STM32_FMC.cpp

Committer:
ua1arn
Date:
2018-07-30
Revision:
20:4b2a3c310b61
Parent:
19:8b7595ced647

File content as of revision 20:4b2a3c310b61:

#include "mbed.h"
#include "platform/mbed_critical.h"
#include "platform/mbed_power_mgmt.h"

#include "platform/platform.h"
#include "hal/pinmap.h"

#define BLD446 1


#define SDRAM_TIMEOUT     ((uint32_t)0xFFFF)

#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)

#define REFRESH_COUNT       ((uint32_t)0x056A)   /* SDRAM refresh counter (90MHz SDRAM clock) */

/**
  * @brief  Perform the SDRAM exernal memory inialization sequence
  * @param  hsdram: SDRAM handle
  * @param  Command: Pointer to SDRAM command structure
  * @retval None
  */
static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram)
{
    FMC_SDRAM_CommandTypeDef Command = { 0 };
#if BLD446
    unsigned CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2;
#else
    unsigned CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;  // 429
#endif
    uint32_t tmpmrd = 0;
    /* Step 3:  Configure a clock configuration enable command */
    Command.CommandMode           = FMC_SDRAM_CMD_CLK_ENABLE;
    Command.CommandTarget         = CommandTarget;
    Command.AutoRefreshNumber     = 1;
    Command.ModeRegisterDefinition = 0;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000);

    /* Step 4: Insert 100 ms delay */
    wait((float)0.1);

    /* Step 5: Configure a PALL (precharge all) command */
    Command.CommandMode           = FMC_SDRAM_CMD_PALL;
    Command.CommandTarget         = CommandTarget;
    Command.AutoRefreshNumber     = 1;
    Command.ModeRegisterDefinition = 0;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000);
    wait((float)0.1);

    /* Step 6 : Configure a Auto-Refresh command */
    Command.CommandMode           = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
    Command.CommandTarget         = CommandTarget;
    Command.AutoRefreshNumber     = 4;
    Command.ModeRegisterDefinition = 0;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000);
    wait((float)0.1);

    /* Step 7: 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         = CommandTarget;
    Command.AutoRefreshNumber     = 1;
    Command.ModeRegisterDefinition = tmpmrd;

    /* Send the command */
    HAL_SDRAM_SendCommand(hsdram, &Command, 0x1000);
    wait((float)0.1);

    /* Step 8: Set the refresh rate counter */
    /* (15.62 us x Freq) - 20 */
    /* Set the device refresh counter */
    HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
    wait((float)0.1);
}

typedef class fmc
{
public:

    ~fmc() {
        core_util_critical_section_enter();
        unlock_deep_sleep();
        core_util_critical_section_exit();
    }

    fmc() :
        _deep_sleep_locked(false) {
        core_util_critical_section_enter();

        __HAL_RCC_GPIOB_CLK_ENABLE();   // 429
        __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();


        /** FMC GPIO Configuration
        PF0   ------> FMC_A0
        PF1   ------> FMC_A1
        PF2   ------> FMC_A2
        PF3   ------> FMC_A3
        PF4   ------> FMC_A4
        PF5   ------> FMC_A5
        PC0   ------> FMC_SDNWE
        PC2   ------> FMC_SDNE0
        PC3   ------> FMC_SDCKE0
        PF11   ------> FMC_SDNRAS
        PF12   ------> FMC_A6
        PF13   ------> FMC_A7
        PF14   ------> FMC_A8
        PF15   ------> FMC_A9
        PG0   ------> FMC_A10
        PG1   ------> FMC_A11
        PE7   ------> FMC_D4
        PE8   ------> FMC_D5
        PE9   ------> FMC_D6
        PE10   ------> FMC_D7
        PE11   ------> FMC_D8
        PE12   ------> FMC_D9
        PE13   ------> FMC_D10
        PE14   ------> FMC_D11
        PE15   ------> FMC_D12
        PD8   ------> FMC_D13
        PD9   ------> FMC_D14
        PD10   ------> FMC_D15
        PD14   ------> FMC_D0
        PD15   ------> FMC_D1
        PG4   ------> FMC_BA0
        PG5   ------> FMC_BA1
        PG8   ------> FMC_SDCLK
        PD0   ------> FMC_D2
        PD1   ------> FMC_D3
        PG15   ------> FMC_SDNCAS
        PE0   ------> FMC_NBL0
        PE1   ------> FMC_NBL1
        */
        pin_function(PF_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));   // FMC_A0
        pin_function(PF_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A1
        pin_function(PF_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A2
        pin_function(PF_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A3
        pin_function(PF_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A4
        pin_function(PF_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A5
        pin_function(PF_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A6
        pin_function(PF_13, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A7
        pin_function(PF_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A8
        pin_function(PF_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A9
        pin_function(PG_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A10
        pin_function(PG_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_A11

        pin_function(PD_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D0
        pin_function(PD_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D1
        pin_function(PD_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D2
        pin_function(PD_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D3
        pin_function(PE_7, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D4
        pin_function(PE_8, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D5
        pin_function(PE_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D6
        pin_function(PE_10, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D7
        pin_function(PE_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D8
        pin_function(PE_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D9
        pin_function(PE_13, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D10
        pin_function(PE_14, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D11
        pin_function(PE_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D12
        pin_function(PD_8, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D13
        pin_function(PD_9, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D14
        pin_function(PD_10, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_D15

#if BLD446
        // STM32F446
        pin_function(PC_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDCKE0
        pin_function(PC_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDNE0
#else
        // STM32F429
        pin_function(PB_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDCKE1
        pin_function(PB_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDNE1
#endif
        pin_function(PC_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDNWE
        pin_function(PE_0, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_NBL0
        pin_function(PE_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_NBL1
        pin_function(PF_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDNRAS
        pin_function(PG_4, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_BA0
        pin_function(PG_5, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_BA1
        pin_function(PG_8, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDCLK
        pin_function(PG_15, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF12_FMC));  // FMC_SDNCAS

        __HAL_RCC_FMC_CLK_ENABLE();

        FMC_SDRAM_TimingTypeDef SdramTiming = { 0 };
        /** Perform the SDRAM1 memory initialization sequence
        */
        SDRAM_HandleTypeDef hsdram1 = { 0 };

        hsdram1.Instance = FMC_Bank5_6;

        /* hsdram1.Init */
#if BLD446
        hsdram1.Init.SDBank = FMC_SDRAM_BANK1;      // 446
#else
        hsdram1.Init.SDBank = FMC_SDRAM_BANK2;      // 429
#endif
        hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
        hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
        hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
        hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
        hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
        hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
        hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_3;
        hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
        hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
        /* SdramTiming */
        SdramTiming.LoadToActiveDelay = 2;
        SdramTiming.ExitSelfRefreshDelay = 7;
        SdramTiming.SelfRefreshTime = 4;
        SdramTiming.RowCycleDelay = 2;
        SdramTiming.WriteRecoveryTime = 2;
        SdramTiming.RPDelay = 2;
        SdramTiming.RCDDelay = 2;

        if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK) {
            //_Error_Handler(__FILE__, __LINE__);
        }
        /* Program the SDRAM external device */
        SDRAM_Initialization_Sequence(&hsdram1);

        core_util_critical_section_exit();
    }

protected:
    /** Lock deep sleep only if it is not yet locked */
    void lock_deep_sleep() {
        if (_deep_sleep_locked == false) {
            sleep_manager_lock_deep_sleep();
            _deep_sleep_locked = true;
        }
    }

    /** Unlock deep sleep in case it is locked */
    void unlock_deep_sleep() {
        if (_deep_sleep_locked == true) {
            sleep_manager_unlock_deep_sleep();
            _deep_sleep_locked = false;
        }
    }

    bool _deep_sleep_locked;

} FMC;

//static FMC fmc;