# HG changeset patch # User Paul Boddie # Date 1707673626 -3600 # Node ID 091e56e0a11371de197e4ff1c989d0128769fe58 # Parent f96263829f7829e1608a925a2d1b7016c7193dcc Fixed ACMD initiation and bus width selection. diff -r f96263829f78 -r 091e56e0a113 pkg/devices/lib/msc/include/msc-common.h --- a/pkg/devices/lib/msc/include/msc-common.h Sun Feb 11 00:39:56 2024 +0100 +++ b/pkg/devices/lib/msc/include/msc-common.h Sun Feb 11 18:47:06 2024 +0100 @@ -75,6 +75,7 @@ struct CID _cid[8]; struct CSD _csd[8]; uint16_t _rca[8], _current_rca; + uint8_t _bus_width[8], _current_bus_width; uint8_t _cards; // Utility methods. @@ -96,6 +97,10 @@ bool command_with_data(uint8_t index); bool command_uses_busy(uint8_t index); uint8_t get_response_format(uint8_t index); + + bool app_command_will_write(uint8_t index); + bool app_command_with_data(uint8_t index); + bool app_command_uses_busy(uint8_t index); uint8_t get_app_response_format(uint8_t index); // Command initiation. diff -r f96263829f78 -r 091e56e0a113 pkg/devices/lib/msc/src/common.cc --- a/pkg/devices/lib/msc/src/common.cc Sun Feb 11 00:39:56 2024 +0100 +++ b/pkg/devices/lib/msc/src/common.cc Sun Feb 11 18:47:06 2024 +0100 @@ -563,6 +563,21 @@ +// Utilities. + +static enum Command_data_control_bits +encode_bus_width(uint8_t width) +{ + switch (width) + { + case 4: return Cdc_bus_width_field_4bit; + case 1: return Cdc_bus_width_field_1bit; + default: return Cdc_bus_width_field_1bit; + } +} + + + // Channel abstraction. Msc_channel::Msc_channel(l4_addr_t msc_start, l4_addr_t addr, l4_cap_idx_t irq) @@ -608,6 +623,16 @@ } bool +Msc_channel::app_command_will_write(uint8_t index) +{ + // NOTE: Probably incomplete coverage. + + (void) index; + + return false; +} + +bool Msc_channel::command_with_data(uint8_t index) { // NOTE: Probably incomplete coverage. @@ -628,6 +653,20 @@ } bool +Msc_channel::app_command_with_data(uint8_t index) +{ + // NOTE: Probably incomplete coverage. + + switch (index) + { + case App_command_sd_status: return true; + case App_command_send_num_wr_blocks: return true; + case App_command_send_scr: return true; + default: return false; + } +} + +bool Msc_channel::command_uses_busy(uint8_t index) { // NOTE: Probably incomplete coverage. @@ -640,6 +679,16 @@ } } +bool +Msc_channel::app_command_uses_busy(uint8_t index) +{ + // NOTE: Probably incomplete coverage. + + (void) index; + + return false; +} + uint8_t Msc_channel::get_response_format(uint8_t index) { @@ -776,11 +825,13 @@ bool Msc_channel::send_app_command(uint8_t index, uint32_t arg) { - if (!send_command(Command_app_cmd, 0, get_app_response_format(index), - false, false, false)) + if (!send_command(Command_app_cmd, _current_rca << 16)) return false; - return send_command(index, arg); + return send_command(index, arg, get_app_response_format(index), + app_command_with_data(index), + app_command_will_write(index), + app_command_uses_busy(index)); } // Send a common MMC/SD command. @@ -789,7 +840,8 @@ Msc_channel::send_command(uint8_t index, uint32_t arg) { return send_command(index, arg, get_response_format(index), - command_with_data(index), command_will_write(index), + command_with_data(index), + command_will_write(index), command_uses_busy(index)); } @@ -821,7 +873,7 @@ // NOTE: May need to set the SD bus width. set_field(Msc_command_data_control, Cdc_bus_width_field_mask, - Cdc_bus_width_field_shift, Cdc_bus_width_field_1bit); + Cdc_bus_width_field_shift, encode_bus_width(_current_bus_width)); set_field(Msc_command_data_control, Cdc_recv_fifo_level_field_mask, Cdc_recv_fifo_level_field_shift, Cdc_fifo_level_16); @@ -1075,6 +1127,10 @@ else return; + // Set the default bus width. + + _bus_width[_cards] = 0; + _cards++; } } @@ -1167,13 +1223,19 @@ _current_rca = _rca[card]; } -#if 0 - // NOTE: SMEM cards should allow bus width setting. + // NOTE: SMEM cards should allow bus width setting with the SCR register + // NOTE: describing the permitted values. // NOTE: SDIO cards have their bus width set in CCCR via CMD52. - printf("set bus width -> %s\n", - send_app_command(App_command_set_bus_width, Bus_width_4bit) ? "set" : "not set"); -#endif + if (!_bus_width[card]) + { + if (send_app_command(App_command_set_bus_width, Bus_width_4bit)) + _bus_width[card] = 4; + else + _bus_width[card] = 1; + } + + _current_bus_width = _bus_width[card]; if (!send_command(Command_set_blocklen, block_size)) return 0;