zynq-rs/libboard_zynq/src/sdio/regs.rs

380 lines
8.9 KiB
Rust
Raw Normal View History

2020-04-28 23:00:47 +08:00
use volatile_register::{RO, RW, WO};
use libregister::{register, register_at, register_bit, register_bits, register_bits_typed};
#[allow(unused)]
#[repr(u8)]
pub enum CommandType {
Normal = 0b00,
Suspend = 0b01,
Resume = 0b10,
Abort = 0b11,
}
#[allow(unused)]
#[repr(u8)]
pub enum ResponseTypeSelect {
NoResponse = 0b00,
Length136 = 0b01,
Length48 = 0b10,
Legnth48Check = 0b11,
}
2020-04-29 09:34:17 +08:00
#[allow(unused)]
#[repr(u8)]
pub enum BusVoltage {
/// 3.3V
2020-04-29 21:19:24 +08:00
V33 = 0b111,
2020-04-29 09:34:17 +08:00
/// 3.0V, typ.
2020-04-29 21:19:24 +08:00
V30 = 0b110,
2020-04-29 09:34:17 +08:00
/// 1.8V, typ.
2020-04-29 21:19:24 +08:00
V18 = 0b101,
2020-04-29 09:34:17 +08:00
}
#[allow(unused)]
#[repr(u8)]
pub enum DmaSelect {
2020-04-29 21:19:24 +08:00
SDMA = 0b00,
ADMA1 = 0b01,
ADMA2 = 0b10,
ADMA3 = 0b11,
2020-04-29 09:34:17 +08:00
}
#[allow(unused)]
#[repr(u8)]
/// SDCLK Frequency divisor, d(number) means baseclock divides by (number).
pub enum SdclkFreqDivisor {
2020-04-29 21:19:24 +08:00
D256 = 0x80,
D128 = 0x40,
D64 = 0x20,
D32 = 0x10,
D16 = 0x08,
D8 = 0x04,
D4 = 0x02,
D2 = 0x01,
D1 = 0x00,
2020-04-29 09:34:17 +08:00
}
2020-04-28 23:00:47 +08:00
#[repr(C)]
pub struct RegisterBlock {
2020-04-29 21:19:24 +08:00
pub sdma_system_address: RO<u32>,
pub block_size_block_count: BlockSizeBlockCount,
2020-04-28 23:00:47 +08:00
pub argument: RW<u32>,
pub transfer_mode_command: TransferModeCommand,
pub responses: [RO<u32>; 4],
pub buffer: RW<u32>,
pub present_state: PresentState,
2020-04-29 09:34:17 +08:00
/// Host. power, block gap, wakeup control
pub control: Control,
/// Clock and timeout control, and software reset register.
pub timing_control: TimingControl,
2020-04-29 21:19:24 +08:00
pub interrupt_status: InterruptStatus,
2020-04-28 23:00:47 +08:00
}
register_at!(RegisterBlock, 0xE0100000, sd0);
register_at!(RegisterBlock, 0xE0101000, sd1);
register!(block_size_block_count, BlockSizeBlockCount, RW, u32);
register_bits!(
block_size_block_count,
/// Current transfer block count.
blocks_count,
u16,
16,
31
);
register_bits!(
block_size_block_count,
/// Host SDMA Buffer Size, size = 2^(val + 2) KB.
dma_buffer_size,
u8,
12,
14
);
register_bits!(
block_size_block_count,
/// Block size for data transfer. Unit: byte.
transfer_block_size,
u16,
0,
11
);
register!(transfer_mode_command, TransferModeCommand, RW, u32);
register_bits!(
transfer_mode_command,
/// Command Number.
command_index,
u8,
24,
29
);
register_bits_typed!(
transfer_mode_command,
/// Command type register.
command_type,
u8,
CommandType,
24,
29
);
register_bit!(
transfer_mode_command,
/// 1 if data is present and shall be transferred using the DAT line.
data_present_select,
21
);
register_bit!(
transfer_mode_command,
/// If the index field shall be checked.
index_check_en,
20
);
register_bit!(
transfer_mode_command,
/// If CRC shall be checked.
crc_check_en,
19
);
register_bits_typed!(
transfer_mode_command,
/// Different type of response.
response_type_select,
u8,
ResponseTypeSelect,
16,
17
);
register_bit!(
transfer_mode_command,
/// Enables the multi block DAT line data transfer.
multi_block_en,
5
);
register_bit!(
transfer_mode_command,
/// 1 if read (card to host), 0 if write (host to card).
direction_select,
4
);
register_bit!(
transfer_mode_command,
/// If CMD12 shall be issued automatically when last block transfer is completed.
auto_cmd12_en,
2
);
register_bit!(
transfer_mode_command,
/// Enable the block count register.
block_count_en,
1
);
register_bit!(
transfer_mode_command,
/// Enable DMA,
dma_en,
0
);
register!(present_state, PresentState, RO, u32);
register_bit!(
present_state,
/// CMD Line Signal Level.
cmd_line_level,
24
);
register_bit!(
present_state,
/// Signal level in DAT[3]
dat3_level,
23
);
register_bit!(
present_state,
/// Signal level in DAT[2]
dat2_level,
22
);
register_bit!(
present_state,
/// Signal level in DAT[1]
dat1_level,
21
);
register_bit!(
present_state,
/// Signal level in DAT[0]
dat0_level,
20
);
register_bit!(
present_state,
/// Write enabled and inverse of SDx_WP pin level.
write_enabled,
19
);
register_bit!(
present_state,
/// Card detected and inverse of SDx_CDn pin level.
card_detected,
18
);
2020-04-29 21:19:24 +08:00
register_bit!(present_state, card_state_stable, 17);
2020-04-29 09:34:17 +08:00
register_bit!(present_state, card_inserted, 16);
2020-04-29 21:19:24 +08:00
register_bit!(present_state, buffer_read_en, 11);
2020-04-29 09:34:17 +08:00
register_bit!(present_state, buffer_write_en, 10);
register_bit!(present_state, read_transfer_active, 9);
register_bit!(present_state, write_transfer_active, 8);
register_bit!(present_state, dat_line_active, 2);
register_bit!(present_state, command_inhibit_dat, 1);
register_bit!(present_state, command_inhibit_cmd, 0);
register!(control, Control, RW, u32);
register_bit!(
2020-04-29 21:19:24 +08:00
control,
2020-04-29 09:34:17 +08:00
/// Enable wakeup event via SD card removal assertion.
wakeup_on_removal,
26
2020-04-28 23:00:47 +08:00
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// Enable wakeup event via SD card insertion assertion.
wakeup_on_insertion,
25
2020-04-28 23:00:47 +08:00
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// Enable wakeup event via card interrupt assertion.
wakeup_on_interrupt,
24
2020-04-28 23:00:47 +08:00
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
///Enable interrupt detection at the block gap for a multiple block transfer.
interrupt_at_block_gap,
19
2020-04-28 23:00:47 +08:00
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// Enable the use of the read wait protocol.
read_wait_control,
18
2020-04-28 23:00:47 +08:00
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// Restart a trasaction which was stopped using the stop at block gap request.
continue_req,
17
2020-04-28 23:00:47 +08:00
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// Stop executing a transaction at the next block gap.
stop_at_block_gap_req,
16
2020-04-28 23:00:47 +08:00
);
2020-04-29 09:34:17 +08:00
register_bits_typed!(control, bus_voltage, u8, BusVoltage, 9, 11);
register_bit!(control, bus_power, 8);
2020-04-28 23:00:47 +08:00
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// Selects source for card detection. 0 for SDCD#, 1 for card detect test level.
card_detect_signal,
7
);
register_bit!(
control,
/// Indicates card inserted or not. Enabled when card detect signal is 1.
card_detect_test_level,
6
);
register_bits_typed!(control, dma_select, u8, DmaSelect, 3, 4);
register_bit!(control, high_speed_en, 2);
register_bit!(
control,
/// Select the data width of the HC. 1 for 4-bit, 0 for 1-bit.
data_width_select,
2020-04-28 23:00:47 +08:00
1
);
register_bit!(
2020-04-29 09:34:17 +08:00
control,
/// 1 for LED on, 0 for LED off.
led_control,
2020-04-28 23:00:47 +08:00
0
2020-04-29 09:34:17 +08:00
);
register!(timing_control, TimingControl, RW, u32);
register_bit!(
timing_control,
/// Software reset for DAT line.
software_reset_dat,
26
);
register_bit!(
timing_control,
/// Software reset for CMD line.
software_reset_cmd,
25
);
register_bit!(
timing_control,
/// Software reset for ALL.
software_reset_all,
24
);
register_bits!(
timing_control,
/// Determines the interval by which DAT line time-outs are detected.
/// Interval = TMCLK * 2^(13 + val)
/// Note: 0b1111 is reserved.
timeout_counter_value,
u8,
16,
19
);
register_bits_typed!(
timing_control,
/// Selects the frequency divisor, thus the clock frequency for SDCLK.
/// Choose the smallest possible divisor which results in a clock frequency
/// that is less than or equal to the target frequency.
sdclk_freq_divisor,
u8,
SdclkFreqDivisor,
8,
15
);
2020-04-29 21:19:24 +08:00
register_bit!(timing_control, sd_clk_en, 2);
register_bit!(
timing_control,
2020-04-29 09:34:17 +08:00
/// 1 when SD clock is stable.
/// Note that this field is read-only.
2020-04-29 21:19:24 +08:00
internal_clk_stable,
1,
RO
);
register_bit!(timing_control, internal_clk_en, 0);
register!(interrupt_status, InterruptStatus, RW, u32, 1 << 15 | 1 << 8);
register_bit!(interrupt_status, ceata_error, 29, WTC);
register_bit!(interrupt_status, target_response_error, 28, WTC);
register_bit!(interrupt_status, adma_error, 25, WTC);
register_bit!(interrupt_status, auto_cmd12_error, 24, WTC);
register_bit!(interrupt_status, current_limit_error, 23, WTC);
register_bit!(interrupt_status, data_end_bit_error, 22, WTC);
register_bit!(interrupt_status, data_crc_error, 21, WTC);
register_bit!(interrupt_status, data_timeout_error, 20, WTC);
register_bit!(interrupt_status, command_index_error, 19, WTC);
register_bit!(interrupt_status, command_end_bit_error, 18, WTC);
register_bit!(interrupt_status, command_crc_error, 17, WTC);
register_bit!(interrupt_status, command_timeout_error, 16, WTC);
register_bit!(interrupt_status, error_interrupt, 15, RO);
register_bit!(interrupt_status, boot_terminate_interrupt, 10, WTC);
register_bit!(interrupt_status, boot_ack_rcv, 9, WTC);
register_bit!(interrupt_status, card_interrupt, 8, RO);
register_bit!(interrupt_status, card_removal, 7, WTC);
register_bit!(interrupt_status, card_insertion, 6, WTC);
register_bit!(interrupt_status, buffer_read_ready, 5, WTC);
register_bit!(interrupt_status, buffer_write_ready, 4, WTC);
register_bit!(interrupt_status, dma_interrupt, 3, WTC);
register_bit!(interrupt_status, block_gap_event, 2, WTC);
register_bit!(interrupt_status, transfer_complete, 1, WTC);
register_bit!(interrupt_status, command_complete, 0, WTC);