Documentation ¶
Overview ¶
Package usdhc implements a driver for Freescale Enhanced Secure Digital Host Controller (eSDHC) interface, also known as NXP Ultra Secured Digital Host Controller (uSDHC).
It currently supports interfacing with SD/MMC cards up to High Speed mode and Dual Data Rate.
Higher speed modes for eMMC cards are HS200 (controller supported and driver supported) and HS400 mode (unsupported at controller level) [p35, Table 4, JESD84-B51].
Higher speed modes for SD cards are SDR50/SDR104 (controller and driver supported), DDR50 (controller supported, unimplemented in this driver) and UHS-II modes (unsupported at controller level) [p37-38, Figure 3-14 and 3-15, SD-PL-7.10].
The highest speed supported by the driver, card and controller is automatically selected by Detect().
For eMMC cards, speed mode HS200 requires the target board to have eMMC I/O signaling to 1.8V, this must be advertised by the board package by defining LowVoltage() on the relevant USDHC instance.
For SD cards, speed modes SDR50/SDR104 require the target board to switch SD I/O signaling to 1.8V, the switching procedure must be implemented by the board package by defining LowVoltage() on the relevant USDHC instance.
Note that due to NXP errata ERR010450 the following maximum theoretical limits apply:
- eMMC HS200: 150MB/s - 150MHz (instead of 200MB/s - 200MHz), supported
- eMMC DDR52: 90MB/s - 45MHz (instead of 104MB/s - 52MHz), supported
- SD SDR104: 75MB/s - 150MHz (instead of 104MB/s - 208MHz), supported
- SD DDR50: 45MB/s - 45MHz (instead of 50MB/s - 50MHz), unsupported
This package is only meant to be used with `GOOS=tamago GOARCH=arm` as supported by the TamaGo framework for bare metal Go on ARM SoCs, see https://github.com/f-secure-foundry/tamago.
Index ¶
- Constants
- Variables
- type ADMABufferDescriptor
- type CardInfo
- type USDHC
- func (hw *USDHC) Detect() (err error)
- func (hw *USDHC) Info() CardInfo
- func (hw *USDHC) Init(width int)
- func (hw *USDHC) Read(offset int64, size int64) (buf []byte, err error)
- func (hw *USDHC) ReadBlocks(lba int, buf []byte) (err error)
- func (hw *USDHC) ReadRPMB(buf []byte) (err error)
- func (hw *USDHC) WriteBlocks(lba int, buf []byte) (err error)
- func (hw *USDHC) WriteRPMB(buf []byte, rel bool) (err error)
Constants ¶
const ( ATTR_VALID = 0 ATTR_END = 1 ATTR_INT = 2 ATTR_ACT = 4 ACT_TRANSFER = 0b10 ACT_LINK = 0b11 DMASEL_NONE = 0b00 DMASEL_ADMA1 = 0b01 DMASEL_ADMA2 = 0b10 ADMA_BD_MAX_LENGTH = 65532 )
ADMA constants
const ( GO_IDLE_STATE = 0 // p127, 4.9.5 (Published RCA response), SD-PL-7.10 RCA_ADDR = 16 RCA_STATUS = 0 // p131, Table 4-42 : Card Status, SD-PL-7.10 // p160, Table 68 - Device Status, JESD84-B51 STATUS_CURRENT_STATE = 9 STATUS_SWITCH_ERROR = 7 STATUS_APP_CMD = 5 CURRENT_STATE_IDENT = 2 CURRENT_STATE_TRAN = 4 // data transfer direction WRITE = 0 READ = 1 // response types RSP_NONE = 0b00 RSP_136 = 0b01 RSP_48 = 0b10 RSP_48_CHECK_BUSY = 0b11 // SEND_CSD response contains CSD[127:8], CSD_RSP_OFF = -8 DEFAULT_CMD_TIMEOUT = 10 * time.Millisecond )
CMD constants
const ( // p181, 7.1 OCR register, JESD84-B51 MMC_OCR_BUSY = 31 MMC_OCR_ACCESS_MODE = 29 MMC_OCR_VDD_HV_MAX = 23 MMC_OCR_VDD_HV_MIN = 15 MMC_OCR_VDD_LV = 7 ACCESS_MODE_BYTE = 0b00 ACCESS_MODE_SECTOR = 0b10 // p62, 6.6.1 Command sets and extended settings, JESD84-B51 MMC_SWITCH_ACCESS = 24 MMC_SWITCH_INDEX = 16 MMC_SWITCH_VALUE = 8 MMC_SWITCH_CMD_SET = 0 ACCESS_WRITE_BYTE = 0b11 // p184 7.3 CSD register, JESD84-B51 MMC_CSD_SPEC_VERS = 122 + CSD_RSP_OFF MMC_CSD_TRAN_SPEED = 96 + CSD_RSP_OFF MMC_CSD_READ_BL_LEN = 80 + CSD_RSP_OFF MMC_CSD_C_SIZE = 62 + CSD_RSP_OFF MMC_CSD_C_SIZE_MULT = 47 + CSD_RSP_OFF // p186 TRAN_SPEED [103:96], JESD84-B51 TRAN_SPEED_26MHZ = 0x32 // p193, 7.4 Extended CSD register, JESD84-B51 EXT_CSD_SEC_COUNT = 212 EXT_CSD_DEVICE_TYPE = 196 EXT_CSD_HS_TIMING = 185 EXT_CSD_BUS_WIDTH = 183 EXT_CSD_PARTITION_CONFIG = 179 // p224, PARTITION_CONFIG, JESD84-B51 PARTITION_ACCESS_NONE = 0x0 PARTITION_ACCESS_RPMB = 0x3 // p222, 7.4.65 HS_TIMING [185], JESD84-B51 HS_TIMING_HS = 0x1 HS_TIMING_HS200 = 0x2 // p35, 5.3.2 Bus Speed Modes, JESD84-B51 HSSDR_MBPS = 52 HSDDR_MBPS = 104 HS200_MBPS = 150 // instead of 200 due to NXP ERR010450 // PLL2 PFD2 clock divided by 2 ROOTCLK_HS_DDR = 1 // PLL2 PFD2 clock divided by 3 ROOTCLK_HS200 = 2 // instead of 1 due to NXP ERR010450 // Root clock divided by 1 (Single Data Rate mode) SDCLKFS_HS200 = 0 )
MMC registers
const ( MMC_DETECT_TIMEOUT = 1 * time.Second MMC_DEFAULT_BLOCK_SIZE = 512 )
MMC constants
const ( // p101, 4.3.13 Send Interface Condition Command (CMD8), SD-PL-7.10 CMD8_ARG_VHS = 8 CMD8_ARG_CHECK_PATTERN = 0 VHS_HIGH = 0b0001 VHS_LOW = 0b0010 CHECK_PATTERN = 0b10101010 // p59, 4.2.3.1 Initialization Command (ACMD41), SD-PL-7.10 // p198, 5.1 OCR register, SD-PL-7.10 SD_OCR_BUSY = 31 SD_OCR_HCS = 30 SD_OCR_UHSII = 29 SD_OCR_XPC = 28 SD_OCR_S18R = 24 SD_OCR_VDD_HV_MAX = 23 SD_OCR_VDD_HV_MIN = 15 SD_OCR_VDD_LV = 7 // p120, Table 4-32 : Switch Function Commands (class 10), SD-PL-7.10 SD_SWITCH_MODE = 31 // p92, Table 4-11 : Available Functions of CMD6, SD-PL-7.10 SD_SWITCH_POWER_LIMIT_GROUP = 4 SD_SWITCH_ACCESS_MODE_GROUP = 1 // p95, 4.3.10.4 Switch Function Status, SD-PL-7.10 SD_SWITCH_STATUS_LENGTH = 64 // p89, 4.3.10 Switch Function Command, SD-PL-7.10 MODE_CHECK = 0 MODE_SWITCH = 1 ACCESS_MODE_HS = 0x1 ACCESS_MODE_SDR50 = 0x2 ACCESS_MODE_SDR104 = 0x3 POWER_LIMIT_288W = 0x3 // p201 5.3.1 CSD_STRUCTURE, SD-PL-7.10 SD_CSD_STRUCTURE = 126 + CSD_RSP_OFF // p202 5.3.2 CSD Register (CSD Version 1.0), SD-PL-7.10 SD_CSD_C_SIZE_MULT_1 = 47 + CSD_RSP_OFF SD_CSD_C_SIZE_1 = 62 + CSD_RSP_OFF SD_CSD_READ_BL_LEN_1 = 80 + CSD_RSP_OFF // p209 5.3.3 CSD Register (CSD Version 2.0), SD-PL-7.10 SD_CSD_C_SIZE_2 = 48 + CSD_RSP_OFF SD_CSD_READ_BL_LEN_2 = 80 + CSD_RSP_OFF // p212 5.3.4 CSD Register (CSD Version 3.0), SD-PL-7.10 SD_CSD_C_SIZE_3 = 48 + CSD_RSP_OFF SD_CSD_READ_BL_LEN_3 = 80 + CSD_RSP_OFF // p23, 2. System Features, SD-PL-7.10 HS_MBPS = 25 SDR50_MBPS = 50 SDR104_MBPS = 75 // instead of 104 due to NXP ERR010450 // PLL2 PFD2 clock divided by 2 ROOTCLK_UHS_SDR50 = 1 // PLL2 PFD2 clock divided by 3 ROOTCLK_UHS_SDR104 = 2 // instead of 1 due to NXP ERR010450 // Root clock divided by 2 (Single Data Rate mode) SDCLKFS_UHS_SDR50 = 0x01 // Root clock divided by 1 (Single Data Rate mode) SDCLKFS_UHS_SDR104 = 0 )
SD registers
const ( SD_DETECT_TIMEOUT = 1 * time.Second SD_DEFAULT_BLOCK_SIZE = 512 // Tuning should complete in max 40 cycles // p42, 4.2.4.5 Tuning Command, SD-PL-7.10 TUNING_MAX_LOOP_COUNT = 40 // The following values are set to make the standard tuning logic // complete in less then 40 cycles. TUNING_STEP = 2 TUNING_START_TAP = 20 )
SD constants
const ( USDHC1_BASE = 0x02190000 USDHC2_BASE = 0x02194000 USDHCx_BLK_ATT = 0x04 BLK_ATT_BLKCNT = 16 BLK_ATT_BLKSIZE = 0 USDHCx_CMD_ARG = 0x08 USDHCx_CMD_XFR_TYP = 0x0c CMD_XFR_TYP_CMDINX = 24 CMD_XFR_TYP_CMDTYP = 22 CMD_XFR_TYP_DPSEL = 21 CMD_XFR_TYP_CICEN = 20 CMD_XFR_TYP_CCCEN = 19 CMD_XFR_TYP_RSPTYP = 16 USDHCx_CMD_RSP0 = 0x10 USDHCx_CMD_RSP1 = 0x14 USDHCx_CMD_RSP2 = 0x18 USDHCx_CMD_RSP3 = 0x1c USDHCx_PRES_STATE = 0x24 PRES_STATE_DLSL = 24 PRES_STATE_WPSPL = 19 PRES_STATE_BREN = 11 PRES_STATE_SDSTB = 3 PRES_STATE_CDIHB = 1 PRES_STATE_CIHB = 0 USDHCx_PROT_CTRL = 0x28 PROT_CTRL_DMASEL = 8 PROT_CTRL_EMODE = 4 PROT_CTRL_DTW = 1 USDHCx_SYS_CTRL = 0x2c SYS_CTRL_INITA = 27 SYS_CTRL_RSTD = 26 SYS_CTRL_RSTC = 25 SYS_CTRL_RSTA = 24 SYS_CTRL_DTOCV = 16 SYS_CTRL_SDCLKFS = 8 SYS_CTRL_DVS = 4 USDHCx_INT_STATUS = 0x30 INT_STATUS_DMAE = 28 INT_STATUS_TNE = 26 INT_STATUS_AC12E = 24 INT_STATUS_CIE = 19 INT_STATUS_CEBE = 18 INT_STATUS_CCE = 17 INT_STATUS_CTOE = 16 INT_STATUS_CRM = 7 INT_STATUS_BRR = 5 INT_STATUS_TC = 1 INT_STATUS_CC = 0 USDHCx_INT_STATUS_EN = 0x34 INT_STATUS_EN_DTOESEN = 20 INT_STATUS_EN_BWRSEN = 4 USDHCx_INT_SIGNAL_EN = 0x38 INT_SIGNAL_EN_BWRIEN = 4 USDHCx_AUTOCMD12_ERR_STATUS = 0x3c AUTOCMD12_ERR_STATUS_SMP_CLK_SEL = 23 AUTOCMD12_ERR_STATUS_EXE_TUNE = 22 USDHCx_WTMK_LVL = 0x44 WTMK_LVL_WR_WML = 16 WTMK_LVL_RD_WML = 0 USDHCx_MIX_CTRL = 0x48 MIX_CTRL_FBCLK_SEL = 25 MIX_CTRL_AUTO_TUNE_EN = 24 MIX_CTRL_SMP_CLK_SEL = 23 MIX_CTRL_EXE_TUNE = 22 MIX_CTRL_MSBSEL = 5 MIX_CTRL_DTDSEL = 4 MIX_CTRL_DDR_EN = 3 MIX_CTRL_AC12EN = 2 MIX_CTRL_BCEN = 1 MIX_CTRL_DMAEN = 0 USDHCx_ADMA_ERR_STATUS = 0x54 USDHCx_ADMA_SYS_ADDR = 0x58 USDHCx_VEND_SPEC = 0xc0 VEND_SPEC_FRC_SDCLK_ON = 8 VEND_SPEC_VSELECT = 1 USDHCx_VEND_SPEC2 = 0xc8 VEND_SPEC2_TUNING_1bit_EN = 5 VEND_SPEC2_TUNING_8bit_EN = 4 USDHCx_TUNING_CTRL = 0xcc TUNING_CTRL_STD_TUNING_EN = 24 TUNING_CTRL_TUNING_STEP = 16 TUNING_CTRL_TUNING_START_TAP = 0 )
USDHC registers (p4012, 58.8 uSDHC Memory Map/Register Definition, IMX6ULLRM).
const ( // Data Timeout Counter Value: SDCLK x 2** 29 DTOCV = 0xf // Divide-by-8 DVS_ID = 7 // Root clock divided by 64 SDCLKFS_ID = 0x20 // Divide-by-2 DVS_OP = 1 // Root clock divided by 4 SDCLKFS_OP = 0x02 // PLL2 PFD2 clock divided by 2 ROOTCLK_HS_SDR = 1 // Divide-by-1 DVS_HS = 0 // Root clock divided by 4 (Single Data Rate mode) SDCLKFS_HS_SDR = 0x02 // Root clock divided by 4 (Dual Data Rate mode) SDCLKFS_HS_DDR = 0x01 )
Configuration constants (p348, 35.4.2 Frequency divider configuration, IMX6FG) to support the following frequencies:
- Identification frequency ≤ 400 KHz
- Operating frequency ≤ 25 MHz
- High frequency ≤ 50 MHz
Variables ¶
var USDHC1 = &USDHC{n: 1}
USDHC1 instance
var USDHC2 = &USDHC{n: 2}
USDHC2 instance
Functions ¶
This section is empty.
Types ¶
type ADMABufferDescriptor ¶
type ADMABufferDescriptor struct { Attribute uint8 Length uint16 Address uint32 // contains filtered or unexported fields }
ADMABufferDescriptor implements p3964 58.4.2.4.1 ADMA Concept and Descriptor Format, IMX6ULLRM.
func (*ADMABufferDescriptor) Bytes ¶
func (bd *ADMABufferDescriptor) Bytes() []byte
Bytes converts the descriptor structure to byte array format.
func (*ADMABufferDescriptor) Init ¶
func (bd *ADMABufferDescriptor) Init(addr uint32, size int)
Init initializes an ADMA2 buffer descriptor.
type CardInfo ¶
type CardInfo struct { // eMMC card MMC bool // SD card SD bool // High Capacity HC bool // High Speed HS bool // Dual Data Rate DDR bool // Maximum throughput (on this controller) Rate int // Block Size BlockSize int // Capacity Blocks int // device identification number CID [16]byte }
CardInfo holds detected card information.
type USDHC ¶
type USDHC struct { sync.Mutex // LowVoltage is the board specific function responsible for voltage // switching (SD) or low voltage indication (eMMC). // // The return value reflects whether the voltage switch (SD) or // low voltage indication (MMC) is successful. LowVoltage func(enable bool) bool // contains filtered or unexported fields }
USDHC represents a controller instance.
func (*USDHC) Detect ¶
Detect initializes an SD/MMC card. The highest speed supported by the driver, card and controller is automatically selected. Speed modes that require voltage switching require definition of function VoltageSelect on the USDHC instance, which is up to board packages.
func (*USDHC) ReadBlocks ¶
ReadBlocks transfers full blocks of data from the card.
func (*USDHC) ReadRPMB ¶
ReadRPMB transfers a single Replay Protected Memory Block (RPMB) data frame from the card.
func (*USDHC) WriteBlocks ¶
WriteBlocks transfers full blocks of data to the card.