401 lines
18 KiB
C
Executable File
401 lines
18 KiB
C
Executable File
//
|
||
// Created by Guangzong Chen on 4/5/23.
|
||
//
|
||
|
||
#ifndef STM32U5XX_HAL_REG_SDMMC_H
|
||
#define STM32U5XX_HAL_REG_SDMMC_H
|
||
|
||
#include "global_variable.h"
|
||
#include "stm32u5xx.h"
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
///////////////// sdmmc power control register (SDMCC_POWER) ///////////////////
|
||
|
||
typedef enum {
|
||
sdmmc_power_vswitchen_reset =
|
||
0x00U, ///< Reset: the voltage switch sequence is not started and not active.
|
||
sdmmc_power_vswitchen_start =
|
||
0x01U, ///< Start: the voltage switch sequence is started or active.
|
||
} reg_sdmmc_power_vswitchen;
|
||
|
||
typedef enum {
|
||
sdmmc_power_pwrctrl_reset = 0x00U,
|
||
sdmmc_power_pwrctrl_reserved = 0x01U,
|
||
sdmmc_power_pwrctrl_power_cycle = 0x02U,
|
||
sdmmc_power_pwrctrl_power_on = 0x03U,
|
||
} reg_sdmmc_power_pwrctrl; ///< SDMMC_POWER_PWRCTRL
|
||
|
||
typedef struct {
|
||
reg_sdmmc_power_pwrctrl pwrctrl : 2; ///< 1:0 Power supply control bits
|
||
reg_sdmmc_power_vswitchen vswitch : 1; ///< 2 Voltage switch sequence start
|
||
uint32_t vswitchen : 1; ///< 3 Voltage switch procedure enable
|
||
uint32_t dirpol : 1; ///< 4 Data and Command direction signals polarity selection
|
||
uint32_t reserved : 27; ///< 31:5 Reserved1
|
||
} reg_sdmmc_power_t;
|
||
|
||
//static inline reg_sdmmc_power_t sdmmc_reg_get_power(SDMMC_TypeDef *sdmmc) {
|
||
// reg_sdmmc_power_t ret;
|
||
// uint32_t tmp = sdmmc->POWER;
|
||
// ret.RESERVED = tmp >> 5;
|
||
// ret.DIRPOL = (tmp >> 4) & 0x1;
|
||
// ret.VSWITCH = static_cast<reg_sdmmc_power_vswitchen>((tmp >> 3) & 0x1);
|
||
// ret.PWRCTRL = static_cast<reg_sdmmc_power_pwrctrl>(tmp & 0x3);
|
||
// return ret;
|
||
//}
|
||
|
||
//static inline void sdmmc_reg_set_power(SDMMC_TypeDef *sdmmc, reg_sdmmc_power_t val) {
|
||
// uint32_t tmp = 0;
|
||
// tmp |= val.RESERVED << 5;
|
||
// tmp |= val.DIRPOL << 4;
|
||
// tmp |= val.VSWITCH << 3;
|
||
// tmp |= val.PWRCTRL;
|
||
// sdmmc->POWER = tmp;
|
||
//}
|
||
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
///////// sdmmc clock control register (SDMMC_CLKCR) //////////////////////////
|
||
|
||
typedef enum {
|
||
REG_SDMMC_WIDBUS_1BIT = 0, ///< 1-bit wide bus mode: SDMMC_D0 used (Does not support DDR)
|
||
REG_SDMMC_WIDBUS_4BIT = 1, ///< 4-bit wide bus mode: SDMMC_D[3:0] used
|
||
REG_SDMMC_WIDBUS_8BIT = 2, ///< 8-bit wide bus mode: SDMMC_D[7:0] used
|
||
} reg_sdmmc_clkcr_widbus;
|
||
|
||
// reverse the bit order of the enum reg_sdmmc_clkcr_t
|
||
typedef struct {
|
||
uint32_t
|
||
clkdiv : 10; ///< 9:0 Clock divide factor (SDMMC_CK frequency = SDMMCCLK / [2 × CLKDIV])
|
||
uint32_t reserved2 : 2; ///< 11:10 Reserved
|
||
uint32_t pwr_sav : 1; ///< 12 Power saving configuration bit
|
||
uint32_t reserved1 : 1; ///< 13 Reserved
|
||
reg_sdmmc_clkcr_widbus widbus : 2; ///< 15:14 Wide bus mode enable bit
|
||
uint32_t negedge : 1; ///< 16 SDMMC_CK dephasing selection bit for data and command
|
||
uint32_t hwfc_en : 1; ///< 17 Hardware Flow Control enable
|
||
uint32_t ddr : 1; ///< 18 Data rate signaling selection
|
||
uint32_t busspeed : 1; ///< 19 Bus speed mode selection of SDMMC operating modes
|
||
uint32_t selclkrx : 2; ///< 21:20 Receive clock selection
|
||
uint32_t reserved : 10; ///< 31:22 Reserved
|
||
} reg_sdmmc_clkcr_t;
|
||
|
||
static inline reg_sdmmc_clkcr_t sdmmc_reg_get_clkcr(SDMMC_TypeDef *sdmmc) {
|
||
reg_sdmmc_clkcr_t ret;
|
||
uint32_t tmp = sdmmc->CLKCR;
|
||
ret.reserved = (tmp >> 22) & 0x3FF;
|
||
ret.selclkrx = (tmp >> 21) & 0x1;
|
||
ret.busspeed = (tmp >> 19) & 0x1;
|
||
ret.ddr = (tmp >> 18) & 0x1;
|
||
ret.hwfc_en = (tmp >> 17) & 0x1;
|
||
ret.negedge = (tmp >> 16) & 0x1;
|
||
ret.widbus = static_cast<reg_sdmmc_clkcr_widbus>((tmp >> 14) & 0x3);
|
||
ret.reserved1 = (tmp >> 13) & 0x1;
|
||
ret.pwr_sav = (tmp >> 12) & 0x1;
|
||
ret.reserved2 = (tmp >> 10) & 0x3;
|
||
ret.clkdiv = tmp & 0x3FF;
|
||
return ret;
|
||
}
|
||
|
||
static inline void sdmmc_reg_set_clkcr(SDMMC_TypeDef *sdmmc, reg_sdmmc_clkcr_t val) {
|
||
uint32_t tmp = 0;
|
||
tmp |= val.reserved << 22;
|
||
tmp |= val.selclkrx << 21;
|
||
tmp |= val.busspeed << 19;
|
||
tmp |= val.ddr << 18;
|
||
tmp |= val.hwfc_en << 17;
|
||
tmp |= val.negedge << 16;
|
||
tmp |= val.widbus << 14;
|
||
tmp |= val.reserved1 << 13;
|
||
tmp |= val.pwr_sav << 12;
|
||
tmp |= val.reserved2 << 10;
|
||
tmp |= val.clkdiv;
|
||
sdmmc->CLKCR = tmp;
|
||
}
|
||
|
||
//////////////////////////////////////////////////// CMD register ///////////////
|
||
|
||
typedef enum {
|
||
REG_SDMMC_CMD_WAITRESP_NO = 0, ///< No response
|
||
REG_SDMMC_CMD_WAITRESP_SHORT_CRC = 1, ///< Short response
|
||
REG_SDMMC_CMD_WAITRESP_SHORT_NOCRC = 2, ///< Short response, no CRC check
|
||
REG_SDMMC_CMD_WAITRESP_LONG = 3, ///< Long response
|
||
} REG_SDMMC_CMD_WAITRESP;
|
||
|
||
typedef struct {
|
||
uint32_t cmdindex : 6; ///< 5:0 Command index.
|
||
uint32_t cmdtrans : 1; ///< 6 CPSM treats the command as a data transfer command, stops the
|
||
///< interrupt period, and signals DataEnable to the DPSM.
|
||
uint32_t cmdstop : 1; ///< 7 CPSM treats the command as a Stop Transmission command and signals
|
||
///< Abort to the DPSM.
|
||
REG_SDMMC_CMD_WAITRESP waitresp : 2; ///< 9:8 Wait for response bits. 0 no response, 1 short
|
||
///< response, 2 short response(NON CRC), 3 long response
|
||
uint32_t waitint : 1; ///< 10 CPSM waits for interrupt request.
|
||
uint32_t waitpend : 1; ///< 11 CPSM Waits for ends of data transfer (CmdPend internal signal).
|
||
uint32_t cpsmen : 1; ///< 12 Command path state machine (CPSM) Enable bit.
|
||
uint32_t dthold : 1; ///< 13 Hold the data block transmission/reception in the DPSM.
|
||
uint32_t bootmode : 1; ///< 14 Select the boot mode procedure to be used.
|
||
uint32_t booten : 1; ///< 15 enable boot mode procedure
|
||
uint32_t cmdsuspend : 1; ///< 16 The CPSM treats the command as a Suspend Command or Resume
|
||
///< Command and signals interrupt period start/end.
|
||
uint32_t reserved : 15; ///< 31-17 Reserved, must be kept at reset value.
|
||
} reg_sdmmc_cmd_t;
|
||
|
||
//static inline void sdmmc_reg_set_cmd(SDMMC_TypeDef *sdmmc, sdmmc_cmd_t value) {
|
||
// uint32_t ret =
|
||
// (value.cmdindex << SDMMC_CMD_CMDINDEX_Pos) | (value.cmdtrans << SDMMC_CMD_CMDTRANS_Pos) |
|
||
// (value.cmdstop << SDMMC_CMD_CMDSTOP_Pos) | (value.waitresp << SDMMC_CMD_WAITRESP_Pos) |
|
||
// (value.waitint << SDMMC_CMD_WAITINT_Pos) | (value.waitpend << SDMMC_CMD_WAITPEND_Pos) |
|
||
// (value.cpsmen << SDMMC_CMD_CPSMEN_Pos) | (value.dthold << SDMMC_CMD_DTHOLD_Pos) |
|
||
// (value.bootmode << SDMMC_CMD_BOOTMODE_Pos) | (value.booten << SDMMC_CMD_BOOTEN_Pos) |
|
||
// (value.cmdsuspend << SDMMC_CMD_CMDSUSPEND_Pos);
|
||
// sdmmc->CMD = ret;
|
||
//}
|
||
//
|
||
//static inline sdmmc_cmd_t sdmmc_reg_get_cmd(SDMMC_TypeDef *sdmmc) {
|
||
// uint32_t value = sdmmc->CMD;
|
||
// sdmmc_cmd_t ret = {0};
|
||
// ret.cmdindex = (value & SDMMC_CMD_CMDINDEX_Msk) >> SDMMC_CMD_CMDINDEX_Pos;
|
||
// ret.cmdtrans = (value & SDMMC_CMD_CMDTRANS_Msk) >> SDMMC_CMD_CMDTRANS_Pos;
|
||
// ret.cmdstop = (value & SDMMC_CMD_CMDSTOP_Msk) >> SDMMC_CMD_CMDSTOP_Pos;
|
||
// ret.waitresp = static_cast<REG_SDMMC_CMD_WAITRESP>((value & SDMMC_CMD_WAITRESP_Msk) >>
|
||
// SDMMC_CMD_WAITRESP_Pos);
|
||
// ret.waitint = (value & SDMMC_CMD_WAITINT_Msk) >> SDMMC_CMD_WAITINT_Pos;
|
||
// ret.waitpend = (value & SDMMC_CMD_WAITPEND_Msk) >> SDMMC_CMD_WAITPEND_Pos;
|
||
// ret.cpsmen = (value & SDMMC_CMD_CPSMEN_Msk) >> SDMMC_CMD_CPSMEN_Pos;
|
||
// ret.dthold = (value & SDMMC_CMD_DTHOLD_Msk) >> SDMMC_CMD_DTHOLD_Pos;
|
||
// ret.bootmode = (value & SDMMC_CMD_BOOTMODE_Msk) >> SDMMC_CMD_BOOTMODE_Pos;
|
||
// ret.booten = (value & SDMMC_CMD_BOOTEN_Msk) >> SDMMC_CMD_BOOTEN_Pos;
|
||
// ret.cmdsuspend = (value & SDMMC_CMD_CMDSUSPEND_Msk) >> SDMMC_CMD_CMDSUSPEND_Pos;
|
||
// return ret;
|
||
//}
|
||
|
||
//////////////////////////////////////////////////// END CMD register ///////////
|
||
|
||
//////////////////////////////////////////////////// Status register(STAR) ////////////
|
||
|
||
// reverse and lower case of reg_sdmmc_sta_t
|
||
typedef struct {
|
||
uint32_t ccrcfail : 1; ///< 0 Command response received (CRC check failed)
|
||
uint32_t dcrcfail : 1; ///< 1 Data block sent/received (CRC check failed)
|
||
uint32_t ctimeout : 1; ///< 2 Command response timeout
|
||
uint32_t dtimeout : 1; ///< 3 Data timeout
|
||
uint32_t
|
||
txunderr : 1; ///< 4 Transmit FIFO underrun error (masked by hardware when IDMA is enabled)
|
||
uint32_t
|
||
rxoverr : 1; ///< 5 Received FIFO overrun error (masked by hardware when IDMA is enabled)
|
||
uint32_t cmdrend : 1; ///< 6 Command response received (CRC check passed, or no CRC)
|
||
uint32_t cmdsent : 1; ///< 7 Command sent (no response required)
|
||
uint32_t dataend : 1; ///< 8 Data transfer ended correctly
|
||
uint32_t dhold : 1; ///< 9 Data transfer Hold
|
||
uint32_t dbckend : 1; ///< 10 Data block sent/received
|
||
uint32_t dabort : 1; ///< 11 Data transfer aborted by CMD12
|
||
uint32_t dpsmact : 1; ///< 12 Data path state machine active, i.e. not in Idle state /// Not
|
||
///< an interrupt
|
||
uint32_t cpsmact : 1; ///< 13 Command path state machine active, i.e. not in Idle state /// Not
|
||
///< an interrupt
|
||
uint32_t txfifohe : 1; ///< 14 Transmit FIFO half empty
|
||
uint32_t rxfifohf : 1; ///< 15 Receive FIFO half full
|
||
uint32_t txfifof : 1; ///< 16 Transmit FIFO full
|
||
uint32_t rxfifof : 1; ///< 17 Receive FIFO full
|
||
uint32_t txfifoe : 1; ///< 18 Transmit FIFO empty
|
||
uint32_t rxfifoe : 1; ///< 19 Receive FIFO empty
|
||
uint32_t busyd0 : 1; ///< 20 Inverted value of SDMMC_DO line (Busy) // Not an interrupt
|
||
uint32_t busydoend : 1; ///< 21 end of SDMMC_D0 Busy following a CMD response detected
|
||
uint32_t sdioit : 1; ///< 22 SDIO interrupt received
|
||
uint32_t ackfail : 1; ///< 23 Boot acknowledgment received (boot acknowledgment check fail)
|
||
uint32_t acktimeout : 1; ///< 24 Boot acknowledgment timeout
|
||
uint32_t vswend : 1; ///< 25 Voltage switch critical timing section completion
|
||
uint32_t ckstop : 1; ///< 26 SDMMC_CK stopped in Voltage switch procedure
|
||
uint32_t idmate : 1; ///< 27 IDMA transfer error
|
||
uint32_t idmabtc : 1; ///< 28 IDMA buffer transfer complete
|
||
uint32_t reserved : 3; ///< 29-31 Reserved
|
||
} reg_sdmmc_sta_t; ///< SDMMC status register read only bits
|
||
|
||
static inline reg_sdmmc_sta_t sdmmc_reg_get_sta(SDMMC_TypeDef *sdmmc) {
|
||
uint32_t value = sdmmc->STA;
|
||
reg_sdmmc_sta_t ret;
|
||
ret.reserved = (value >> 29) & 0x7;
|
||
ret.idmabtc = (value >> 28) & 0x1;
|
||
ret.idmate = (value >> 27) & 0x1;
|
||
ret.ckstop = (value >> 26) & 0x1;
|
||
ret.vswend = (value >> 25) & 0x1;
|
||
ret.acktimeout = (value >> 24) & 0x1;
|
||
ret.ackfail = (value >> 23) & 0x1;
|
||
ret.sdioit = (value >> 22) & 0x1;
|
||
ret.busydoend = (value >> 21) & 0x1;
|
||
ret.busyd0 = (value >> 20) & 0x1;
|
||
ret.rxfifoe = (value >> 19) & 0x1;
|
||
ret.txfifoe = (value >> 18) & 0x1;
|
||
ret.rxfifof = (value >> 17) & 0x1;
|
||
ret.txfifof = (value >> 16) & 0x1;
|
||
ret.rxfifohf = (value >> 15) & 0x1;
|
||
ret.txfifohe = (value >> 14) & 0x1;
|
||
ret.cpsmact = (value >> 13) & 0x1;
|
||
ret.dpsmact = (value >> 12) & 0x1;
|
||
ret.dabort = (value >> 11) & 0x1;
|
||
ret.dbckend = (value >> 10) & 0x1;
|
||
ret.dhold = (value >> 9) & 0x1;
|
||
ret.dataend = (value >> 8) & 0x1;
|
||
ret.cmdsent = (value >> 7) & 0x1;
|
||
ret.cmdrend = (value >> 6) & 0x1;
|
||
ret.rxoverr = (value >> 5) & 0x1;
|
||
ret.txunderr = (value >> 4) & 0x1;
|
||
ret.dtimeout = (value >> 3) & 0x1;
|
||
ret.ctimeout = (value >> 2) & 0x1;
|
||
ret.dcrcfail = (value >> 1) & 0x1;
|
||
ret.ccrcfail = (value >> 0) & 0x1;
|
||
return ret;
|
||
}
|
||
|
||
//////////////////////// Data control register ////////////////////////
|
||
|
||
// reverse and low case of reg_sdmmc_dctrl_t
|
||
typedef struct {
|
||
uint32_t data_en : 1; ///< 0 DTEN: Data transfer enabled bit
|
||
uint32_t data_dir : 1; ///< 1 DTDIR: Data transfer direction selection 0: From controller to
|
||
///< card 1: From card to controller
|
||
uint32_t data_mode : 2; ///< 3:2 DTMODE: Data transfer mode selection 0: Block data transfer 1:
|
||
///< Stream or SDIO multibyte data transfer
|
||
uint32_t data_blocksize : 4; ///< 7:4 DBLOCKSIZE[3:0]: Data block size
|
||
uint32_t rwstart : 1; ///< 8 RWSTART: Read Wait start
|
||
uint32_t rwstop : 1; ///< 9 RWSTOP: Read Wait stop
|
||
uint32_t rwmod : 1; ///< 10 RWMOD: Read Wait mode
|
||
uint32_t sdioen : 1; ///< 11 SDIOEN: SD I/O interrupt enable functions
|
||
uint32_t bootacken : 1; ///< 12 BOOTACKEN: Enable the reception of the boot acknowledgment
|
||
uint32_t fifo_reset : 1; ///< 13 FIFORST: FIFO reset, flushes any remaining data
|
||
uint32_t reserved : 18; ///< 31:14 Reserved, must be kept at reset value.
|
||
} reg_sdmmc_dctrl_t; ///< SDMMC data control register
|
||
|
||
// static inline uint32_t sdmmc_dctrl_to_uint32(sdmmc_dctrl_t value) {
|
||
static inline void sdmmc_reg_set_dctrl(SDMMC_TypeDef *sdmmc, reg_sdmmc_dctrl_t value) {
|
||
uint32_t ret =
|
||
(value.fifo_reset << SDMMC_DCTRL_FIFORST_Pos) |
|
||
(value.bootacken << SDMMC_DCTRL_BOOTACKEN_Pos) | (value.sdioen << SDMMC_DCTRL_SDIOEN_Pos) |
|
||
(value.rwmod << SDMMC_DCTRL_RWMOD_Pos) | (value.rwstop << SDMMC_DCTRL_RWSTOP_Pos) |
|
||
(value.rwstart << SDMMC_DCTRL_RWSTART_Pos) |
|
||
(value.data_blocksize << SDMMC_DCTRL_DBLOCKSIZE_Pos) |
|
||
(value.data_mode << SDMMC_DCTRL_DTMODE_Pos) | (value.data_dir << SDMMC_DCTRL_DTDIR_Pos) |
|
||
(value.data_en << SDMMC_DCTRL_DTEN_Pos);
|
||
sdmmc->DCTRL = ret;
|
||
}
|
||
|
||
static inline reg_sdmmc_dctrl_t sdmmc_reg_get_dctrl(SDMMC_TypeDef *sdmmc) {
|
||
uint32_t value = sdmmc->DCTRL;
|
||
reg_sdmmc_dctrl_t ret;
|
||
ret.fifo_reset = (value >> SDMMC_DCTRL_FIFORST_Pos) & SDMMC_DCTRL_FIFORST_Msk;
|
||
ret.bootacken = (value >> SDMMC_DCTRL_BOOTACKEN_Pos) & SDMMC_DCTRL_BOOTACKEN_Msk;
|
||
ret.sdioen = (value >> SDMMC_DCTRL_SDIOEN_Pos) & SDMMC_DCTRL_SDIOEN_Msk;
|
||
ret.rwmod = (value >> SDMMC_DCTRL_RWMOD_Pos) & SDMMC_DCTRL_RWMOD_Msk;
|
||
ret.rwstop = (value >> SDMMC_DCTRL_RWSTOP_Pos) & SDMMC_DCTRL_RWSTOP_Msk;
|
||
ret.rwstart = (value >> SDMMC_DCTRL_RWSTART_Pos) & SDMMC_DCTRL_RWSTART_Msk;
|
||
ret.data_blocksize = (value >> SDMMC_DCTRL_DBLOCKSIZE_Pos) & SDMMC_DCTRL_DBLOCKSIZE_Msk;
|
||
ret.data_mode = (value >> SDMMC_DCTRL_DTMODE_Pos) & SDMMC_DCTRL_DTMODE_Msk;
|
||
ret.data_dir = (value >> SDMMC_DCTRL_DTDIR_Pos) & SDMMC_DCTRL_DTDIR_Msk;
|
||
ret.data_en = (value >> SDMMC_DCTRL_DTEN_Pos) & SDMMC_DCTRL_DTEN_Msk;
|
||
return ret;
|
||
}
|
||
|
||
////////////////////// idma control register /////////////////////////
|
||
|
||
// reverse and low case of reg_sdmmc_idmactrl_t
|
||
typedef struct {
|
||
uint32_t idma_en : 1; ///< 0 IDMAEN: IDMA enable bit
|
||
uint32_t idma_buffer_mode : 1; ///< 1 IDMABMODE: IDMA buffer mode selection. 0: Single buffer
|
||
///< mode 1: Linked buffer mode
|
||
uint32_t reserved : 30; ///< 31:2 Reserved, must be kept at reset value.
|
||
} reg_sdmmc_idmactrl_t; ///< SDMMC IDMA control register
|
||
|
||
static inline void sdmmc_reg_set_idma(SDMMC_TypeDef *sdmmc, reg_sdmmc_idmactrl_t value) {
|
||
uint32_t ret = (value.idma_buffer_mode << SDMMC_IDMA_IDMABMODE_Pos) |
|
||
(value.idma_en << SDMMC_IDMA_IDMAEN_Pos);
|
||
sdmmc->IDMACTRL = ret;
|
||
}
|
||
|
||
static inline reg_sdmmc_idmactrl_t sdmmc_reg_get_idma(SDMMC_TypeDef *sdmmc) {
|
||
uint32_t value = sdmmc->IDMACTRL;
|
||
reg_sdmmc_idmactrl_t ret;
|
||
ret.idma_buffer_mode = (value >> SDMMC_IDMA_IDMABMODE_Pos) & SDMMC_IDMA_IDMABMODE_Msk;
|
||
ret.idma_en = (value >> SDMMC_IDMA_IDMAEN_Pos) & SDMMC_IDMA_IDMAEN_Msk;
|
||
return ret;
|
||
}
|
||
|
||
////////////////////// idma buffer size register /////////////////////////
|
||
|
||
// reverse and low case of reg_sdmmc_idmabsize_t
|
||
typedef struct {
|
||
uint32_t reserved : 5; ///< 4:0 Reserved, must be kept at reset value.
|
||
uint32_t size : 12; ///< 16:5 number of bytes per buffer // multiple by 8 get 32-bit words and
|
||
///< by 32 to get the size of bytes. 1 --> 32 bytes, 0x800 -->64Kbyte
|
||
uint32_t reserved2 : 20; ///< 31:17 Reserved, must be kept at reset value.
|
||
} reg_sdmmc_idmabsize_t; ///< SDMMC IDMA buffer size register
|
||
|
||
/// \brief Set the IDMA size
|
||
/// \param size number of bytes per buffer int byte
|
||
/// \todo the maximum value of parameter
|
||
/// \note this is used for dma when link list is used
|
||
static inline hal_status_e sdmmc_set_idma_buffer_size(SDMMC_TypeDef *sdmmc, uint32_t size) {
|
||
uint16_t tmp = size / 32;
|
||
sdmmc->IDMABSIZE = tmp << 5;
|
||
if (size % 32 != 0) { return SDMMC_ERROR; }
|
||
return HAL_OK;
|
||
}
|
||
|
||
////////////////////// idma butter base address register /////////////////////////
|
||
/// \brief Set the IDMA base address
|
||
/// \param address base address of the IDMA buffer (for the buffer)
|
||
/// \todo the maximum value of parameter
|
||
static inline hal_status_e sdmmc_reg_set_idma_base_address(SDMMC_TypeDef *sdmmc, uint32_t address) {
|
||
sdmmc->IDMABASER = address;
|
||
return HAL_OK;
|
||
}
|
||
|
||
////////////////////// idma linked list address register /////////////////////////
|
||
|
||
typedef struct {
|
||
uint32_t reserved : 2; ///< 1:0 Reserved, must be kept at reset value.
|
||
uint32_t la : 14; ///< 15:2 IDMALA. Word aligned linked list address offset
|
||
uint32_t reserved1 : 13; ///< 28:16 Reserved, must be kept at reset value.
|
||
uint32_t abr : 1; ///< 29 ABR: Acknowledge buffer ready
|
||
uint32_t uls : 1; ///< 30 ULS: Update linked list size (SMDDC_IDMABSIZE)
|
||
uint32_t ula : 1; ///< 31 ULA: Update linked list address (SMDDC_IDMALAR)
|
||
} reg_sdmmc_idmalar_t; ///< SDMMC IDMA linked list address register
|
||
|
||
////////////////////// idma linked list address register /////////////////////////
|
||
/// for the linked list
|
||
static inline hal_status_e sdmmc_set_idma_linked_list_address(uint32_t address) {
|
||
SDMMC1->IDMABAR = address;
|
||
return HAL_OK;
|
||
}
|
||
|
||
/////////////////////// data length register ///////////////////////
|
||
static inline void sdmmc_reg_set_dlen(SDMMC_TypeDef *sdmmc, uint32_t value) { sdmmc->DLEN = value; }
|
||
|
||
typedef struct {
|
||
reg_sdmmc_power_t power;
|
||
reg_sdmmc_clkcr_t clkcr;
|
||
uint32_t arg;
|
||
reg_sdmmc_cmd_t cmd;
|
||
uint32_t respcmd;
|
||
uint32_t resp1;
|
||
uint32_t resp2;
|
||
uint32_t resp3;
|
||
uint32_t resp4;
|
||
uint32_t dtimer;
|
||
uint32_t dlen;
|
||
reg_sdmmc_dctrl_t dctrl;
|
||
uint32_t dcount;
|
||
reg_sdmmc_sta_t sta;
|
||
uint32_t icr;
|
||
uint32_t mask;
|
||
uint32_t acktime;
|
||
uint32_t reserved0[3];
|
||
reg_sdmmc_idmactrl_t idmactrl;
|
||
reg_sdmmc_idmabsize_t idmabsize;
|
||
uint32_t idmabaser;
|
||
uint32_t reserved1[2];
|
||
reg_sdmmc_idmalar_t idmalar;
|
||
uint32_t idmabar;
|
||
uint32_t reserved2[5];
|
||
uint32_t fifo;
|
||
} reg_sdmmc_s;
|
||
|
||
#endif // STM32U5XX_HAL_REG_SDMMC_H
|