#include <stm32h7xx.h>
#include <stdbool.h>
#include <stdint.h>
#ifndef FMC_H
#define FMC_H
typedef enum {
SDRAM_BANK1 = 0,
SDRAM_BANK2 = 1,
} sdram_bank_t;
typedef struct {
uint32_t* base;
uint32_t allocated;
} fmc_sdram_t;
typedef struct {
FMC_Bank1_TypeDef *bank1;
FMC_Bank2_TypeDef *bank2;
FMC_Bank3_TypeDef *bank3;
FMC_Bank5_6_TypeDef *bank5_6;
fmc_sdram_t sdram[2];
} fmc_t;
typedef struct {
uint8_t startup_delay_us;
uint32_t max_sd_clock_hz;
uint32_t refresh_period_ns;
uint8_t mode_register_to_active;
uint8_t exit_self_refresh;
uint8_t active_to_precharge;
uint8_t row_cycle;
uint8_t row_precharge;
uint8_t row_to_column;
} fmc_sdram_timing_t;
typedef struct {
uint32_t clock_frequency;
uint8_t column_bits;
uint8_t row_bits;
uint8_t memory_data_width;
uint8_t internal_banks;
uint8_t cas_latency;
bool write_protection;
bool read_burst;
uint8_t read_pipe_delay_cycles;
} fmc_sdram_configuration_t;
typedef enum {
SDRAM_NORMAL_MODE,
SDRAM_CLK_ENABLE,
SDRAM_PRECHARGE_ALL,
SDRAM_AUTOREFRESH,
SDRAM_LOAD_MODE,
SDRAM_SELFREFRESH,
SDRAM_POWERDOWN,
} fmc_sdram_cmd_type_t;
void fmc_init(fmc_t* fmc);
void fmc_sdram_configure(fmc_t *fmc, sdram_bank_t target_bank,
fmc_sdram_configuration_t config,
fmc_sdram_timing_t timing,
uint16_t mode_register);
void fmc_sdram_send_command(fmc_t* fmc, uint16_t bank, fmc_sdram_cmd_type_t cmd, uint16_t argument);
void* fmc_sdram_allocate(fmc_t* fmc, sdram_bank_t bank, uint32_t size);
#endif // FMC_H