From 3238dae99fcb6fc0ebe54a2d62fb4a89528b6e7b Mon Sep 17 00:00:00 2001 From: pca Date: Tue, 28 Apr 2020 23:00:47 +0800 Subject: [PATCH 1/5] started writing register definitions --- libboard_zynq/src/sdio/regs.rs | 228 +++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 libboard_zynq/src/sdio/regs.rs diff --git a/libboard_zynq/src/sdio/regs.rs b/libboard_zynq/src/sdio/regs.rs new file mode 100644 index 0000000..0817ebd --- /dev/null +++ b/libboard_zynq/src/sdio/regs.rs @@ -0,0 +1,228 @@ +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, +} + +#[repr(C)] +pub struct RegisterBlock { + pub sdma_system_address: RM, + pub block_size_block_count: BockSizeBlockCount, + pub argument: RW, + pub transfer_mode_command: TransferModeCommand, + pub responses: [RO; 4], + pub buffer: RW, + pub present_state: PresentState, +} + +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 +); +regsiter_bit!( + present_state, + card_state_stable, + 17 +); +register_bit!( + present_state, + card_inserted, + 16 +); +register_bit!( + present_state, + buffer_read_en, + 11, +); +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 +); \ No newline at end of file From b22cc4e2b625d97c343834ae444e4b1a8973b323 Mon Sep 17 00:00:00 2001 From: pca Date: Wed, 29 Apr 2020 09:34:17 +0800 Subject: [PATCH 2/5] various control registers --- libboard_zynq/src/sdio/regs.rs | 186 +++++++++++++++++++++++++++------ 1 file changed, 153 insertions(+), 33 deletions(-) diff --git a/libboard_zynq/src/sdio/regs.rs b/libboard_zynq/src/sdio/regs.rs index 0817ebd..2e32fe7 100644 --- a/libboard_zynq/src/sdio/regs.rs +++ b/libboard_zynq/src/sdio/regs.rs @@ -20,6 +20,41 @@ pub enum ResponseTypeSelect { Legnth48Check = 0b11, } +#[allow(unused)] +#[repr(u8)] +pub enum BusVoltage { + /// 3.3V + v33 = 0b111, + /// 3.0V, typ. + v30 = 0b110, + /// 1.8V, typ. + v18 = 0b101, +} + +#[allow(unused)] +#[repr(u8)] +pub enum DmaSelect { + sdma = 0b00, + adma1 = 0b01, + adma2 = 0b10, + adma3 = 0b11, +} + +#[allow(unused)] +#[repr(u8)] +/// SDCLK Frequency divisor, d(number) means baseclock divides by (number). +pub enum SdclkFreqDivisor { + d256 = 0x80, + d128 = 0x40, + d64 = 0x20, + d32 = 0x10, + d16 = 0x08, + d8 = 0x04, + d4 = 0x02, + d2 = 0x01, + d1 = 0x00, +} + #[repr(C)] pub struct RegisterBlock { pub sdma_system_address: RM, @@ -29,6 +64,10 @@ pub struct RegisterBlock { pub responses: [RO; 4], pub buffer: RW, pub present_state: PresentState, + /// Host. power, block gap, wakeup control + pub control: Control, + /// Clock and timeout control, and software reset register. + pub timing_control: TimingControl, } register_at!(RegisterBlock, 0xE0100000, sd0); @@ -60,7 +99,6 @@ register_bits!( 11 ); - register!(transfer_mode_command, TransferModeCommand, RW, u32); register_bits!( transfer_mode_command, @@ -137,7 +175,6 @@ register_bit!( 0 ); - register!(present_state, PresentState, RO, u32); register_bit!( present_state, @@ -181,48 +218,131 @@ register_bit!( card_detected, 18 ); -regsiter_bit!( - present_state, - card_state_stable, +regsiter_bit!(present_state, card_state_stable, 17); +register_bit!(present_state, card_inserted, 16); +register_bit!(present_state, buffer_read_en, 11,); +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!( + contorl, + /// Enable wakeup event via SD card removal assertion. + wakeup_on_removal, + 26 +); +register_bit!( + control, + /// Enable wakeup event via SD card insertion assertion. + wakeup_on_insertion, + 25 +); +register_bit!( + control, + /// Enable wakeup event via card interrupt assertion. + wakeup_on_interrupt, + 24 +); +register_bit!( + control, + ///Enable interrupt detection at the block gap for a multiple block transfer. + interrupt_at_block_gap, + 19 +); +register_bit!( + control, + /// Enable the use of the read wait protocol. + read_wait_control, + 18 +); +register_bit!( + control, + /// Restart a trasaction which was stopped using the stop at block gap request. + continue_req, 17 ); register_bit!( - present_state, - card_inserted, + control, + /// Stop executing a transaction at the next block gap. + stop_at_block_gap_req, 16 ); +register_bits_typed!(control, bus_voltage, u8, BusVoltage, 9, 11); +register_bit!(control, bus_power, 8); register_bit!( - present_state, - buffer_read_en, - 11, + control, + /// Selects source for card detection. 0 for SDCD#, 1 for card detect test level. + card_detect_signal, + 7 ); register_bit!( - present_state, - buffer_write_en, - 10 + 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!( - 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, + control, + /// Select the data width of the HC. 1 for 4-bit, 0 for 1-bit. + data_width_select, 1 ); register_bit!( - present_state, - command_inhibit_cmd, + control, + /// 1 for LED on, 0 for LED off. + led_control, 0 -); \ No newline at end of file +); + +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 +); +register_bits!(timing_control, sd_clk_en, 2); +register_bits!(timing_control, + /// 1 when SD clock is stable. + /// Note that this field is read-only. + internal_clk_stable, 1); +register_bits!(timing_control, internal_clk_en, 0); From d9e8a667bd3ed57b7e1acccdd4138bdc38fd96d7 Mon Sep 17 00:00:00 2001 From: pca Date: Wed, 29 Apr 2020 21:19:24 +0800 Subject: [PATCH 3/5] some macro changes and more registers --- libboard_zynq/src/lib.rs | 1 + libboard_zynq/src/sdio/mod.rs | 1 + libboard_zynq/src/sdio/regs.rs | 81 +++++++++++++++++++++++----------- libregister/src/lib.rs | 61 +++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 libboard_zynq/src/sdio/mod.rs diff --git a/libboard_zynq/src/lib.rs b/libboard_zynq/src/lib.rs index 9276c93..429c279 100644 --- a/libboard_zynq/src/lib.rs +++ b/libboard_zynq/src/lib.rs @@ -17,3 +17,4 @@ pub mod flash; pub mod dmac; pub mod time; pub mod timer; +pub mod sdio; \ No newline at end of file diff --git a/libboard_zynq/src/sdio/mod.rs b/libboard_zynq/src/sdio/mod.rs new file mode 100644 index 0000000..77e8519 --- /dev/null +++ b/libboard_zynq/src/sdio/mod.rs @@ -0,0 +1 @@ +mod regs; \ No newline at end of file diff --git a/libboard_zynq/src/sdio/regs.rs b/libboard_zynq/src/sdio/regs.rs index 2e32fe7..55ce4d8 100644 --- a/libboard_zynq/src/sdio/regs.rs +++ b/libboard_zynq/src/sdio/regs.rs @@ -24,41 +24,41 @@ pub enum ResponseTypeSelect { #[repr(u8)] pub enum BusVoltage { /// 3.3V - v33 = 0b111, + V33 = 0b111, /// 3.0V, typ. - v30 = 0b110, + V30 = 0b110, /// 1.8V, typ. - v18 = 0b101, + V18 = 0b101, } #[allow(unused)] #[repr(u8)] pub enum DmaSelect { - sdma = 0b00, - adma1 = 0b01, - adma2 = 0b10, - adma3 = 0b11, + SDMA = 0b00, + ADMA1 = 0b01, + ADMA2 = 0b10, + ADMA3 = 0b11, } #[allow(unused)] #[repr(u8)] /// SDCLK Frequency divisor, d(number) means baseclock divides by (number). pub enum SdclkFreqDivisor { - d256 = 0x80, - d128 = 0x40, - d64 = 0x20, - d32 = 0x10, - d16 = 0x08, - d8 = 0x04, - d4 = 0x02, - d2 = 0x01, - d1 = 0x00, + D256 = 0x80, + D128 = 0x40, + D64 = 0x20, + D32 = 0x10, + D16 = 0x08, + D8 = 0x04, + D4 = 0x02, + D2 = 0x01, + D1 = 0x00, } #[repr(C)] pub struct RegisterBlock { - pub sdma_system_address: RM, - pub block_size_block_count: BockSizeBlockCount, + pub sdma_system_address: RO, + pub block_size_block_count: BlockSizeBlockCount, pub argument: RW, pub transfer_mode_command: TransferModeCommand, pub responses: [RO; 4], @@ -68,6 +68,7 @@ pub struct RegisterBlock { pub control: Control, /// Clock and timeout control, and software reset register. pub timing_control: TimingControl, + pub interrupt_status: InterruptStatus, } register_at!(RegisterBlock, 0xE0100000, sd0); @@ -218,9 +219,9 @@ register_bit!( card_detected, 18 ); -regsiter_bit!(present_state, card_state_stable, 17); +register_bit!(present_state, card_state_stable, 17); register_bit!(present_state, card_inserted, 16); -register_bit!(present_state, buffer_read_en, 11,); +register_bit!(present_state, buffer_read_en, 11); register_bit!(present_state, buffer_write_en, 10); register_bit!(present_state, read_transfer_active, 9); register_bit!(present_state, write_transfer_active, 8); @@ -230,7 +231,7 @@ register_bit!(present_state, command_inhibit_cmd, 0); register!(control, Control, RW, u32); register_bit!( - contorl, + control, /// Enable wakeup event via SD card removal assertion. wakeup_on_removal, 26 @@ -340,9 +341,39 @@ register_bits_typed!( 8, 15 ); -register_bits!(timing_control, sd_clk_en, 2); -register_bits!(timing_control, +register_bit!(timing_control, sd_clk_en, 2); +register_bit!( + timing_control, /// 1 when SD clock is stable. /// Note that this field is read-only. - internal_clk_stable, 1); -register_bits!(timing_control, internal_clk_en, 0); + 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); diff --git a/libregister/src/lib.rs b/libregister/src/lib.rs index 603507b..65aae5c 100644 --- a/libregister/src/lib.rs +++ b/libregister/src/lib.rs @@ -100,6 +100,19 @@ macro_rules! register_rw { } } ); + ($mod_name: ident, $struct_name: ident, $mask: expr) => ( + impl libregister::RegisterRW for $struct_name { + #[inline] + fn modify Self::W>(&mut self, f: F) { + unsafe { + self.inner.modify(|inner| { + f($mod_name::Read { inner }, $mod_name::Write { inner: inner & ($mask) }) + .inner + }); + } + } + } + ); } #[doc(hidden)] @@ -168,6 +181,14 @@ macro_rules! register { libregister::register_common!($mod_name, $struct_name, VolatileCell<$inner>, $inner); libregister::register_vcell!($mod_name, $struct_name); ); + + // Define read-write register with mask on write (for WTC mixed access.) + ($mod_name: ident, $struct_name: ident, RW, $inner: ty, $mask: expr) => ( + libregister::register_common!($mod_name, $struct_name, volatile_register::RW<$inner>, $inner); + libregister::register_r!($mod_name, $struct_name); + libregister::register_w!($mod_name, $struct_name); + libregister::register_rw!($mod_name, $struct_name, $mask); + ); } /// Define a 1-bit field of a register @@ -197,6 +218,46 @@ macro_rules! register_bit { } } ); + + // Single bit read-only + ($mod_name: ident, $(#[$outer:meta])* $name: ident, $bit: expr, RO) => ( + $(#[$outer])* + impl $mod_name::Read { + #[allow(unused)] + #[inline] + pub fn $name(&self) -> bool { + use bit_field::BitField; + + self.inner.get_bit($bit) + } + } + ); + + // Single bit write to clear. Note that this must be used with WTC register. + ($mod_name: ident, $(#[$outer:meta])* $name: ident, $bit: expr, WTC) => ( + $(#[$outer])* + impl $mod_name::Read { + #[allow(unused)] + #[inline] + pub fn $name(&self) -> bool { + use bit_field::BitField; + + self.inner.get_bit($bit) + } + } + + $(#[$outer])* + impl $mod_name::Write { + #[allow(unused)] + #[inline] + pub fn $name(mut self) -> Self { + use bit_field::BitField; + + self.inner.set_bit($bit, true); + self + } + } + ); } /// Define a multi-bit field of a register From 244ccdeac276efcef858f6914fa16c1a157ee0b8 Mon Sep 17 00:00:00 2001 From: pca Date: Fri, 1 May 2020 15:38:07 +0800 Subject: [PATCH 4/5] finished register definitions --- libboard_zynq/src/sdio/regs.rs | 200 ++++++++++++++++++++++++++++++--- libregister/src/lib.rs | 1 + 2 files changed, 185 insertions(+), 16 deletions(-) diff --git a/libboard_zynq/src/sdio/regs.rs b/libboard_zynq/src/sdio/regs.rs index 55ce4d8..4538ca3 100644 --- a/libboard_zynq/src/sdio/regs.rs +++ b/libboard_zynq/src/sdio/regs.rs @@ -2,6 +2,34 @@ use volatile_register::{RO, RW, WO}; use libregister::{register, register_at, register_bit, register_bits, register_bits_typed}; +#[repr(C)] +pub struct RegisterBlock { + pub sdma_system_address: RW, + pub block_size_block_count: BlockSizeBlockCount, + pub argument: RW, + pub transfer_mode_command: TransferModeCommand, + pub responses: [RO; 4], + pub buffer: RW, + pub present_state: PresentState, + /// Host. power, block gap, wakeup control + pub control: Control, + /// Clock and timeout control, and software reset register. + pub timing_control: TimingControl, + pub interrupt_status: InterruptStatus, + pub interrupt_status_en: InterruptStatusEn, + pub interrupt_signal_en: InterruptSignalEn, + pub auto_cmd12_error_status: AutoCmd12ErrorStatus, + pub capabilities: Capabilities, + pub max_current_capabilities: MaxCurrentCapabilities, + pub force_event: ForceEvent, + pub adma_error_status: AdmaErrorStatus, + pub adma_system_address: RW, + pub boot_data_timeout_counter: RW, + pub debug_selection: DebugSelection, + pub spi_interrupt_support: SpiInterruptSupport, + pub misc_reg: MiscReg, +} + #[allow(unused)] #[repr(u8)] pub enum CommandType { @@ -34,7 +62,7 @@ pub enum BusVoltage { #[allow(unused)] #[repr(u8)] pub enum DmaSelect { - SDMA = 0b00, + SDMA = 0b00, ADMA1 = 0b01, ADMA2 = 0b10, ADMA3 = 0b11, @@ -42,7 +70,7 @@ pub enum DmaSelect { #[allow(unused)] #[repr(u8)] -/// SDCLK Frequency divisor, d(number) means baseclock divides by (number). +/// SDCLK Frequency divisor, d(number) means baseclock divided by (number). pub enum SdclkFreqDivisor { D256 = 0x80, D128 = 0x40, @@ -55,20 +83,19 @@ pub enum SdclkFreqDivisor { D1 = 0x00, } -#[repr(C)] -pub struct RegisterBlock { - pub sdma_system_address: RO, - pub block_size_block_count: BlockSizeBlockCount, - pub argument: RW, - pub transfer_mode_command: TransferModeCommand, - pub responses: [RO; 4], - pub buffer: RW, - pub present_state: PresentState, - /// Host. power, block gap, wakeup control - pub control: Control, - /// Clock and timeout control, and software reset register. - pub timing_control: TimingControl, - pub interrupt_status: InterruptStatus, +#[allow(unused)] +#[repr(u8)] +pub enum AdmaErrorState { + StStop = 0b00, + StFds = 0b01, + StTfr = 0b11, +} + +#[allow(unused)] +#[repr(u8)] +pub enum SpecificationVersion { + V1 = 0, + V2 = 1, } register_at!(RegisterBlock, 0xE0100000, sd0); @@ -377,3 +404,144 @@ 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); + +register!(interrupt_status_en, InterruptStatusEn, RW, u32); +register_bit!(interrupt_status_en, ceata_error_status_en, 29); +register_bit!(interrupt_status_en, target_response_error_status_en, 28); +register_bit!(interrupt_status_en, adma_error_status_en, 25); +register_bit!(interrupt_status_en, auto_cmd12_error_status_en, 24); +register_bit!(interrupt_status_en, current_limit_error_status_en, 23); +register_bit!(interrupt_status_en, data_end_bit_error_status_en, 22); +register_bit!(interrupt_status_en, data_crc_error_status_en, 21); +register_bit!(interrupt_status_en, data_timeout_error_status_en, 20); +register_bit!(interrupt_status_en, cmd_index_error_status_en, 19); +register_bit!(interrupt_status_en, cmd_end_bit_error_status_en, 18); +register_bit!(interrupt_status_en, cmd_crc_error_status_en, 17); +register_bit!(interrupt_status_en, cmd_timeout_error_status_en, 16); +register_bit!(interrupt_status_en, fixed_to_0, 15, RO); +register_bit!(interrupt_status_en, boot_terminate_interrupt_en, 10); +register_bit!(interrupt_status_en, boot_ack_rcv_en, 9); +register_bit!(interrupt_status_en, card_interrupt_status_en, 8); +register_bit!(interrupt_status_en, card_removal_status_en, 7); +register_bit!(interrupt_status_en, card_insertion_status_en, 6); +register_bit!(interrupt_status_en, buffer_read_ready_status_en, 5); +register_bit!(interrupt_status_en, buffer_write_ready_status_en, 4); +register_bit!(interrupt_status_en, dma_interrupt_status_en, 3); +register_bit!(interrupt_status_en, block_gap_evt_status_en, 2); +register_bit!(interrupt_status_en, transfer_complete_status_en, 1); +register_bit!(interrupt_status_en, cmd_complete_status_en, 0); + +register!(interrupt_signal_en, InterruptSignalEn, RW, u32); +register_bit!(interrupt_signal_en, ceata_error_signal_en, 29); +register_bit!(interrupt_signal_en, target_response_error_signal_en, 28); +register_bit!(interrupt_signal_en, adma_error_signal_en, 25); +register_bit!(interrupt_signal_en, auto_cmd12_error_signal_en, 24); +register_bit!(interrupt_signal_en, current_limit_error_signal_en, 23); +register_bit!(interrupt_signal_en, data_end_bit_error_signal_en, 22); +register_bit!(interrupt_signal_en, data_crc_error_signal_en, 21); +register_bit!(interrupt_signal_en, data_timeout_error_signal_en, 20); +register_bit!(interrupt_signal_en, cmd_index_error_signal_en, 19); +register_bit!(interrupt_signal_en, cmd_end_bit_error_signal_en, 18); +register_bit!(interrupt_signal_en, cmd_crc_error_signal_en, 17); +register_bit!(interrupt_signal_en, cmd_timeout_error_signal_en, 16); +register_bit!(interrupt_signal_en, fixed_to_0, 15, RO); +register_bit!(interrupt_signal_en, boot_terminate_interrupt_signal_en, 10); +register_bit!(interrupt_signal_en, boot_ack_rcv_signal_en, 9); +register_bit!(interrupt_signal_en, card_interrupt_signal_en, 8); +register_bit!(interrupt_signal_en, card_removal_signal_en, 7); +register_bit!(interrupt_signal_en, card_insertion_signal_en, 6); +register_bit!(interrupt_signal_en, buffer_read_ready_signal_en, 5); +register_bit!(interrupt_signal_en, buffer_write_ready_signal_en, 4); +register_bit!(interrupt_signal_en, dma_interrupt_signal_en, 3); +register_bit!(interrupt_signal_en, block_gap_evt_signal_en, 2); +register_bit!(interrupt_signal_en, transfer_complete_signal_en, 1); +register_bit!(interrupt_signal_en, cmd_complete_signal_en, 0); + +register!(auto_cmd12_error_status, AutoCmd12ErrorStatus, RO, u32); +register_bit!( + auto_cmd12_error_status, + cmd_not_issued_by_auto_cmd12_error, + 7 +); +register_bit!(auto_cmd12_error_status, index_error, 4); +register_bit!(auto_cmd12_error_status, end_bit_error, 3); +register_bit!(auto_cmd12_error_status, crc_error, 2); +register_bit!(auto_cmd12_error_status, timeout_error, 1); +register_bit!(auto_cmd12_error_status, not_executed, 0); + +register!(capabilities, Capabilities, RO, u32); +register_bit!(capabilities, spi_block_mode, 30); +register_bit!(capabilities, spi_mode, 29); +register_bit!(capabilities, support_64bit, 28); +register_bit!(capabilities, interrupt_mode, 27); +register_bit!(capabilities, voltage_1_8, 26); +register_bit!(capabilities, voltage_3_0, 25); +register_bit!(capabilities, voltage_3_3, 24); +register_bit!(capabilities, suspend_resume, 23); +register_bit!(capabilities, sdma, 22); +register_bit!(capabilities, hgih_speed, 21); +register_bit!(capabilities, adma2, 19); +register_bit!(capabilities, extended_media_bus, 18); +register_bits!( + capabilities, + /// Length = 2^(9 + v) bytes. + max_block_len, + u8, + 16, + 17 +); +register_bit!(capabilities, timeout_clock_unit, 7); + +register!(max_current_capabilities, MaxCurrentCapabilities, RO, u32); +register_bits!(max_current_capabilities, max_current_1_8v, u8, 16, 23); +register_bits!(max_current_capabilities, max_current_3_0v, u8, 8, 15); +register_bits!(max_current_capabilities, max_current_3_3v, u8, 0, 7); + +register!(force_event, ForceEvent, WO, u32); +register_bit!(force_event, ceata_error, 29); +register_bit!(force_event, target_response_error, 28); +register_bit!(force_event, adma_error, 25); +register_bit!(force_event, auto_cmd12_error, 24); +register_bit!(force_event, current_limit_error, 23); +register_bit!(force_event, data_end_bit_error, 22); +register_bit!(force_event, data_crc_error, 21); +register_bit!(force_event, data_timeout_error, 20); +register_bit!(force_event, cmd_index_error, 19); +register_bit!(force_event, cmd_end_bit_error, 18); +register_bit!(force_event, cmd_crc_error, 17); +register_bit!(force_event, cmd_timeout_error, 16); +register_bit!(force_event, cmd_not_issued_by_auto_cmd12_error, 7); +register_bit!(force_event, auto_cmd12_index_error, 4); +register_bit!(force_event, auto_cmd12_end_bit_error, 3); +register_bit!(force_event, auto_cmd12_crc_error, 2); +register_bit!(force_event, auto_cmd12_timeout_error, 1); +register_bit!(force_event, auto_cmd12_not_executed, 0); + +register!(adma_error_status, AdmaErrorStatus, RW, u32, 0b11); +register_bit!(adma_error_status, length_mismatch_error, 2, WTC); +register_bits_typed!(adma_error_status, error_state, u8, AdmaErrorState, 0, 1); + +register!(debug_selection, DebugSelection, WO, u32); +register_bit!(debug_selection, debug_select, 0); + +register!(spi_interrupt_support, SpiInterruptSupport, RW, u32); +register_bits!( + spi_interrupt_support, + /// There should be a problem with the documentation of this field. + spi_int_support, + u8, + 0, + 7 +); + +register!(misc_reg, MiscReg, RO, u32); +register_bits!(misc_reg, vendor_version_num, u8, 24, 31); +register_bits_typed!(misc_reg, spec_ver, u8, SpecificationVersion, 16, 23); +register_bits!( + misc_reg, + /// Logical OR of interrupt signal and wakeup signal for each slot. + slot_interrupt_signal, + u8, + 0, + 7 +); diff --git a/libregister/src/lib.rs b/libregister/src/lib.rs index 65aae5c..56696db 100644 --- a/libregister/src/lib.rs +++ b/libregister/src/lib.rs @@ -248,6 +248,7 @@ macro_rules! register_bit { $(#[$outer])* impl $mod_name::Write { + /// Clear bit field. (WTC) #[allow(unused)] #[inline] pub fn $name(mut self) -> Self { From 73b0ec9837c1065aa073aae36f659e57a517ec58 Mon Sep 17 00:00:00 2001 From: pca Date: Wed, 6 May 2020 13:58:46 +0800 Subject: [PATCH 5/5] fixed typo --- libboard_zynq/src/sdio/regs.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libboard_zynq/src/sdio/regs.rs b/libboard_zynq/src/sdio/regs.rs index 4538ca3..0cd47cb 100644 --- a/libboard_zynq/src/sdio/regs.rs +++ b/libboard_zynq/src/sdio/regs.rs @@ -142,8 +142,8 @@ register_bits_typed!( command_type, u8, CommandType, - 24, - 29 + 22, + 23 ); register_bit!( transfer_mode_command,