#ifndef STM32U5XX_HAL_SDMMC_HPP #define STM32U5XX_HAL_SDMMC_HPP #include "reg_sdmmc.h" #include "sdmmc_typedef.h" #include "reg_sdmmc_gen.h" typedef union { r1_response_t r1; r2_response_t r2; r3_response_t r3; r6_response_t r6; r7_response_t r7; } response_t; typedef struct { bool transfer_single_block_complete; // transfer complete bool transfer_multi_block_complete; // transfer complete } sd_state_t; typedef struct { bool command_crc_fail; // command crc fail bool data_crc_fail; // data crc fail bool command_timeout; // command timeout bool data_timeout; // data timeout bool tx_underrun; // tx underrun bool rx_overrun; // rx overrun bool ack_fail; // ack fail bool ack_timeout; // ack timeout bool idma_error; // dma error } sd_error_t; //#include "gpio.h" //const static gpio_settings sdmmc_gpio_settings = { // . mode = AF, // . ot = PULL_PUSH, // . spd = VERY_HIGH_SPEED, // . af = 12, // may need to change based on datasheet // . pull = LL_PULLUP, //}; ///////////////////////// following can be hide from user ///////////////////////// hal_status_e checkR1(r1_response_t r1); //hal_status_e sdmmc_send_cmd(uint8_t cmd, uint32_t arg, REG_SDMMC_CMD_WAITRESP wait_response, response_t *response); typedef enum { SDMMC_BUS_WIDTH_1BIT = 0, SDMMC_BUS_WIDTH_4BIT = 2, } sdmmc_bus_width_e; class Sdmmc { private: SDMMC_TypeDef *sdmmc; ///< sdmmc register // reg_sdmmc_s *reg; ///< sdmmc register reg_sdmmc_t *reg2; sd_state_t state; ///< sdmmc state sd_error_t error; ///< sdmmc error uint32_t rca; ///< relative card address. This will be get after initialization csd_v2_t csd; ///< card specific data cid_t cid; ///< card identification public: void setup(SDMMC_TypeDef *sdmmc){ this->sdmmc = sdmmc; // reg = (reg_sdmmc_s *) sdmmc; reg2 = (reg_sdmmc_t *)sdmmc; } ///////////////////////// sdmmc api ///////////////////////// hal_status_e sdmmc_init(); hal_status_e sdmmc_read_single_block( uint32_t buffer_addr, uint32_t block_addr); hal_status_e sdmmc_read_multiple_block(uint32_t buffer_addr, uint32_t block_addr, uint32_t block_num); hal_status_e sdmmc_write_single_block(uint32_t buffer_addr, uint32_t block_addr); hal_status_e sdmmc_write_multiple_block( uint32_t buffer_addr, uint32_t block_addr, uint32_t block_count); private: hal_status_e sdmmc_send_cmd(uint8_t cmd, uint32_t arg, response_t *response); void sdmmc_cmd_go_idle_state(); // cmd0 - go idle state - no response // hal_status_e sdmmc_cmd_all_send_cid(sdmmc_s *sd, cid_t *cid); // cmd2 - send cid - r2 response // hal_status_e sdmmc_cmd_send_rca(sdmmc_s *sd); // cmd3 - send relative address - r6 response // hal_status_e sdmmc_cmd_sel_desel_card(sdmmc_s *sd); // cmd7 - select/deselect card - r1b response // hal_status_e sdmmc_cmd_send_interface_condition(sdmmc_s *sd); // cmd8 - send interface condition - r7 response // hal_status_e sdmmc_cmd_send_csd(sdmmc_s *sd); // cmd9 - send card specific data - r2 response // hal_status_e sdmmc_cmd_send_cid(sdmmc_s *sd); // cmd10 - send card identification - r2 response // hal_status_e sdmmc_cmd_voltage_switch(sdmmc_s *sd); // cmd11 - voltage switch - r1 response // hal_status_e sdmmc_cmd_stop_transmission(sdmmc_s *sd); // cmd12 - stop transmission - r1b response // hal_status_e sdmmc_cmd_send_status(sdmmc_s *sd); // cmd13 - send status - r1 response // hal_status_e sdmmc_cmd_go_inactive_state(sdmmc_s *sd); // cmd15 - go inactive state - no response // hal_status_e sdmmc_cmd_set_block_length(sdmmc_s *sd, uint32_t block_len); // cmd16 - set block length - r1 response // hal_status_e sdmmc_cmd_read_single_block(sdmmc_s *sd, uint32_t block_addr); // cmd17 - read single block - r1 response // hal_status_e sdmmc_cmd_read_multi_block(sdmmc_s *sd, uint32_t block_addr); // cmd18 - read multiple block - r1 response // hal_status_e sdmmc_cmd_set_block_count(sdmmc_s *sd, uint32_t block_num); // cmd23 - set block count - r1 response // hal_status_e sdmmc_cmd_write_single_block(sdmmc_s *sd, uint32_t block_addr); // cmd24 - write single block - r1 response // hal_status_e sdmmc_cmd_write_multi_block(sdmmc_s *sd, uint32_t block_addr); // cmd25 - write multiple block - r1 response // hal_status_e sdmmc_cmd_program_csd(csd_v2_t *csd); // cmd27 - program csd - r1 response // hal_status_e sdmmc_cmd_set_write_protect(uint32_t addr); // cmd28 - set write protect - r1b response // hal_status_e sdmmc_cmd_clr_write_protect(uint32_t addr); // cmd29 - clear write protect - r1b response // hal_status_e sdmmc_cmd_send_write_protect(uint32_t addr); // cmd30 - send write protect - r1 response // hal_status_e sdmmc_cmd_erase_wr_blk_start(uint32_t addr); // cmd32 - erase write block start - r1 response // hal_status_e sdmmc_cmd_erase_wr_blk_end(uint32_t addr); // cmd33 - erase write block end - r1 response // hal_status_e sdmmc_cmd_erase(); // cmd38 - erase all previously selected write blocks - r1b response // hal_status_e sdmmc_cmd_lock_unlock(uint32_t RCA, uint32_t data); // cmd42 - lock/unlock card - r1 response // hal_status_e sdmmc_cmd_app_cmd(sdmmc_s *sd, uint32_t RCA); // cmd55 - app cmd - r1 response hal_status_e sdmmc_acmd_set_bus_width(sdmmc_bus_width_e width); // acmd6 - set bus width - r1 response hal_status_e sdmmc_acmd_send_app_op_cond(); // acmd41 - send operation condition - r3 response }; #endif