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