support for a sdcard speed option (#1594)

* support for a sdcard speed option

* trying to link sdio_cclk_set from file

* changed io to IO in checkbox text

* changed order so high speed option is read after pmem is restored from sd

* test button

* took out unneeded comment

* force behavior of test button

---------

Co-authored-by: GullCode <gullradriel@hotmail.com>
This commit is contained in:
gullradriel 2023-11-19 15:08:29 +01:00 committed by GitHub
parent 650aacfaa7
commit 309f2fbd2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 582 additions and 512 deletions

View File

@ -343,6 +343,38 @@ void SetUIView::focus() {
button_save.focus();
}
/* SetSDCardView *********************************************/
SetSDCardView::SetSDCardView(NavigationView& nav) {
add_children({&labels,
&checkbox_sdcard_speed,
&button_test_sdcard_high_speed,
&text_sdcard_test_status,
&button_save,
&button_cancel});
checkbox_sdcard_speed.set_value(pmem::config_sdcard_high_speed_io());
button_test_sdcard_high_speed.on_select = [&nav, this](Button&) {
pmem::set_config_sdcard_high_speed_io(true, false);
text_sdcard_test_status.set("!! HIGH SPEED MODE ON !!");
};
button_save.on_select = [&nav, this](Button&) {
pmem::set_config_sdcard_high_speed_io(checkbox_sdcard_speed.value(), true);
send_system_refresh();
nav.pop();
};
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
};
}
void SetSDCardView::focus() {
button_save.focus();
}
/* SetConverterSettingsView ******************************/
SetConverterSettingsView::SetConverterSettingsView(NavigationView& nav) {
@ -636,6 +668,7 @@ SettingsMenuView::SettingsMenuView(NavigationView& nav) {
{"QR Code", ui::Color::dark_cyan(), &bitmap_icon_qr_code, [&nav]() { nav.push<SetQRCodeView>(); }},
{"Radio", ui::Color::dark_cyan(), &bitmap_icon_options_radio, [&nav]() { nav.push<SetRadioView>(); }},
{"User Interface", ui::Color::dark_cyan(), &bitmap_icon_options_ui, [&nav]() { nav.push<SetUIView>(); }},
{"SD Card", ui::Color::dark_cyan(), &bitmap_icon_sdcard, [&nav]() { nav.push<SetSDCardView>(); }},
});
set_max_rows(2); // allow wider buttons
}

View File

@ -306,8 +306,43 @@ class SetUIView : public View {
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel",
"Cancel"};
};
class SetSDCardView : public View {
public:
SetSDCardView(NavigationView& nav);
void focus() override;
std::string title() const override { return "SD Card"; };
private:
Labels labels{
// 01234567890123456789012345678
{{1 * 8, 120 - 48}, " HIGH SPEED SDCARD IO ", Color::light_grey()},
{{1 * 8, 120 - 32}, " May or may not work !! ", Color::light_grey()}};
Checkbox checkbox_sdcard_speed{
{2 * 8, 120},
20,
"enable high speed IO"};
Button button_test_sdcard_high_speed{
{2 * 8, 152, 27 * 8, 32},
"TEST BUTTON (NO PMEM SAVE)"};
Text text_sdcard_test_status{
{2 * 8, 198, 28 * 8, 16},
""};
Button button_save{
{2 * 8, 16 * 16, 12 * 8, 32},
"Save"};
Button button_cancel{
{16 * 8, 16 * 16, 12 * 8, 32},
"Cancel"};
};
class SetConverterSettingsView : public View {

View File

@ -171,6 +171,9 @@ SystemStatusView::SystemStatusView(
pmem::load_persistent_settings_from_file();
}
// force apply of selected sdcard speed override at UI startup
pmem::set_config_sdcard_high_speed_io(pmem::config_sdcard_high_speed_io(), false);
button_back.id = -1; // Special ID used by FocusManager
title.set_style(&Styles::bg_dark_grey);

View File

@ -70,7 +70,8 @@ static void sdio_status_command_done_clear(void) {
}
static void sdio_wait_for_command_done(void) {
while( !sdio_status_command_done() );
while (!sdio_status_command_done())
;
sdio_status_command_done_clear();
}
@ -87,8 +88,7 @@ static void sdio_status_hardware_locked_write_error_clear(void) {
}
static bool sdio_status_response_error(void) {
return LPC_SDMMC->RINTSTS & (
(1U << 1) /* RE: Response error */
return LPC_SDMMC->RINTSTS & ((1U << 1) /* RE: Response error */
| (1U << 6) /* RCRC: Response CRC error */
| (1U << 8) /* RTO: Response time-out error */
);
@ -126,14 +126,16 @@ static void sdio_reset_dma_and_fifo(void) {
(1U << 1) /* FIFO */
| (1U << 2) /* DMA */
;
while( LPC_SDMMC->CTRL & ((1U << 1) | (1U << 2)) );
while (LPC_SDMMC->CTRL & ((1U << 1) | (1U << 2)))
;
}
static void sdio_reset(void) {
LPC_SDMMC->BMOD = (1U << 0);
LPC_SDMMC->CTRL = 0x7U;
while( LPC_SDMMC->CTRL & 0x7U );
while (LPC_SDMMC->CTRL & 0x7U)
;
}
static void sdio_reset_card(void) {
@ -152,7 +154,8 @@ static void sdio_interrupts_clear(void) {
}
static void sdio_wait_for_command_accepted(void) {
while( LPC_SDMMC->CMD & (1U << 31) );
while (LPC_SDMMC->CMD & (1U << 31))
;
}
static void sdio_update_clock_registers_only(void) {
@ -174,8 +177,7 @@ static void sdio_cclk_disable(void) {
}
static void sdio_clkdiv_set(
const size_t divider_0
) {
const size_t divider_0) {
LPC_SDMMC->CLKDIV = ((uint32_t)divider_0 & 0xff) << 0;
}
@ -183,7 +185,7 @@ static void sdio_clksrc_set(const size_t divider_index) {
LPC_SDMMC->CLKSRC = ((divider_index & 3) << 0);
}
static void sdio_cclk_set(const size_t divider_value) {
void sdio_cclk_set(const size_t divider_value) {
/* "Before issuing a new data transfer command, the software should
* ensure that the card is not busy due to any previous data
* transfer command. Before changing the card clock frequency, the
@ -272,9 +274,7 @@ static bool_t sdc_llc_prepare_descriptors_chained(LPC_SDMMC_DESC_Type desc[],
uint32_t buffer_2_size = 0;
desc[i].DESC1 =
(buffer_1_size << 0)
| (buffer_2_size << 13)
;
(buffer_1_size << 0) | (buffer_2_size << 13);
desc[i].DESC3 = (uint32_t)&desc[i + 1];
@ -303,9 +303,7 @@ static bool_t sdc_llc_prepare_descriptors_chained(LPC_SDMMC_DESC_Type desc[],
* @retval CH_SUCCESS operation succeeded.
* @retval CH_FAILED operation failed.
*/
static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
uint32_t *resp) {
static bool_t sdc_lld_wait_transaction_end(SDCDriver* sdcp, uint32_t n, uint32_t* resp) {
/* Note the mask is checked before going to sleep because the interrupt
may have occurred before reaching the critical zone.*/
chSysLock();
@ -391,12 +389,10 @@ static void sdc_lld_error_cleanup(SDCDriver *sdcp,
static bool_t sdio_send_command(
SDCDriver* sdcp,
const uint32_t cmd_and_flags,
const uint32_t arg
) {
const uint32_t arg) {
LPC_SDMMC->CMDARG = arg;
LPC_SDMMC->CMD =
cmd_and_flags
| (1U << 13) /* WAIT_PRVDATA_COMPLETE */
cmd_and_flags | (1U << 13) /* WAIT_PRVDATA_COMPLETE */
| (1U << 31) /* START_CMD */
;
@ -429,16 +425,14 @@ static bool_t sdio_send_command(
return CH_SUCCESS;
}
static bool_t sdc_lld_send_cmd_data(SDCDriver *sdcp, uint32_t cmd_and_flags,
uint32_t arg, uint32_t *resp) {
static bool_t sdc_lld_send_cmd_data(SDCDriver* sdcp, uint32_t cmd_and_flags, uint32_t arg, uint32_t* resp) {
(void)sdcp;
const uint32_t status = sdio_send_command(
sdcp,
/* RESPONSE_EXPECT | CHECK_RESPONSE_CRC | DATA_EXPECTED */
cmd_and_flags | (1U << 6) | (1U << 8) | (1U << 9),
arg
);
arg);
if (status == CH_SUCCESS) {
*resp = LPC_SDMMC->RESP0;
@ -447,13 +441,11 @@ static bool_t sdc_lld_send_cmd_data(SDCDriver *sdcp, uint32_t cmd_and_flags,
return status;
}
static bool_t sdc_lld_send_cmd_data_read(SDCDriver *sdcp, uint8_t cmd,
uint32_t arg, uint32_t *resp) {
static bool_t sdc_lld_send_cmd_data_read(SDCDriver* sdcp, uint8_t cmd, uint32_t arg, uint32_t* resp) {
return sdc_lld_send_cmd_data(sdcp, cmd | (0U << 10), arg, resp);
}
static bool_t sdc_lld_send_cmd_data_write(SDCDriver *sdcp, uint8_t cmd,
uint32_t arg, uint32_t *resp) {
static bool_t sdc_lld_send_cmd_data_write(SDCDriver* sdcp, uint8_t cmd, uint32_t arg, uint32_t* resp) {
return sdc_lld_send_cmd_data(sdcp, cmd | (1U << 10), arg, resp);
}
@ -471,9 +463,7 @@ static bool_t sdc_lld_send_cmd_data_write(SDCDriver *sdcp, uint8_t cmd,
*
* @notapi
*/
static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
uint32_t n, uint32_t *resp) {
static bool_t sdc_lld_prepare_read(SDCDriver* sdcp, uint32_t startblk, uint32_t n, uint32_t* resp) {
/* Driver handles data in 512 bytes blocks (just like HC cards). But if we
have not HC card than we must convert address from blocks to bytes.*/
if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
@ -482,13 +472,14 @@ static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
if (n > 1) {
/* Send read multiple blocks command to card.*/
if (sdc_lld_send_cmd_data_read(sdcp, MMCSD_CMD_READ_MULTIPLE_BLOCK,
startblk, resp) || MMCSD_R1_ERROR(resp[0]))
startblk, resp) ||
MMCSD_R1_ERROR(resp[0]))
return CH_FAILED;
}
else{
} else {
/* Send read single block command.*/
if (sdc_lld_send_cmd_data_read(sdcp, MMCSD_CMD_READ_SINGLE_BLOCK,
startblk, resp) || MMCSD_R1_ERROR(resp[0]))
startblk, resp) ||
MMCSD_R1_ERROR(resp[0]))
return CH_FAILED;
}
@ -509,9 +500,7 @@ static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk,
*
* @notapi
*/
static bool_t sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
uint32_t n, uint32_t *resp) {
static bool_t sdc_lld_prepare_write(SDCDriver* sdcp, uint32_t startblk, uint32_t n, uint32_t* resp) {
/* Driver handles data in 512 bytes blocks (just like HC cards). But if we
have not HC card than we must convert address from blocks to bytes.*/
if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY))
@ -520,13 +509,14 @@ static bool_t sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk,
if (n > 1) {
/* Write multiple blocks command.*/
if (sdc_lld_send_cmd_data_write(sdcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
startblk, resp) || MMCSD_R1_ERROR(resp[0]))
startblk, resp) ||
MMCSD_R1_ERROR(resp[0]))
return CH_FAILED;
}
else{
} else {
/* Write single block command.*/
if (sdc_lld_send_cmd_data_write(sdcp, MMCSD_CMD_WRITE_BLOCK,
startblk, resp) || MMCSD_R1_ERROR(resp[0]))
startblk, resp) ||
MMCSD_R1_ERROR(resp[0]))
return CH_FAILED;
}
@ -569,7 +559,6 @@ CH_IRQ_HANDLER(SDIO_IRQHandler) {
* @notapi
*/
void sdc_lld_init(void) {
sdcObjectInit(&SDCD1);
SDCD1.resources = &sdio_resources;
SDCD1.thread = NULL;
@ -587,7 +576,6 @@ void sdc_lld_init(void) {
* @notapi
*/
void sdc_lld_start(SDCDriver* sdcp) {
if (sdcp->state == BLK_STOP) {
base_clock_enable(&sdcp->resources->base);
branch_clock_enable(&sdcp->resources->branch_register_if);
@ -609,8 +597,7 @@ void sdc_lld_start(SDCDriver *sdcp) {
// UM10503 recommendation: SAMPLE_DELAY=0x8, DRV_DELAY=0xF
// Datasheet recommendation: SAMPLE_DELAY=0x9, DRV_DELAY=0xD
LPC_SCU->SDDELAY =
(0x0 << 0)
| (0xa << 8) /* >6ns hold with low clk/dat/cmd output drive */
(0x0 << 0) | (0xa << 8) /* >6ns hold with low clk/dat/cmd output drive */
;
LPC_SDMMC->CTRL =
(1U << 4) /* INT_ENABLE */
@ -648,7 +635,6 @@ void sdc_lld_start(SDCDriver *sdcp) {
* @notapi
*/
void sdc_lld_stop(SDCDriver* sdcp) {
if (sdcp->state != BLK_STOP) {
interrupt_disable(&sdcp->resources->interrupt);
@ -676,7 +662,9 @@ void sdc_lld_start_clk(SDCDriver *sdcp) {
(void)sdcp;
sdio_cclk_set_400khz();
/* TODO: Reset card using CMD0 + init flag? */
if (sdio_send_command(sdcp, 0 | (1U << 15), 0) != CH_SUCCESS) for(;;);
if (sdio_send_command(sdcp, 0 | (1U << 15), 0) != CH_SUCCESS)
for (;;)
;
}
/**
@ -763,16 +751,14 @@ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
*
* @notapi
*/
bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
uint32_t *resp) {
bool_t sdc_lld_send_cmd_short(SDCDriver* sdcp, uint8_t cmd, uint32_t arg, uint32_t* resp) {
(void)sdcp;
const uint32_t status = sdio_send_command(
sdcp,
/* RESPONSE_EXPECT */
cmd | (1U << 6),
arg
);
arg);
if (status == CH_SUCCESS) {
*resp = LPC_SDMMC->RESP0;
@ -795,16 +781,14 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
*
* @notapi
*/
bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
uint32_t *resp) {
bool_t sdc_lld_send_cmd_short_crc(SDCDriver* sdcp, uint8_t cmd, uint32_t arg, uint32_t* resp) {
(void)sdcp;
const uint32_t status = sdio_send_command(
sdcp,
/* RESPONSE_EXPECT | CHECK_RESPONSE_CRC */
cmd | (1U << 6) | (1U << 8),
arg
);
arg);
if (status == CH_SUCCESS) {
*resp = LPC_SDMMC->RESP0;
@ -827,16 +811,14 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
*
* @notapi
*/
bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
uint32_t *resp) {
bool_t sdc_lld_send_cmd_long_crc(SDCDriver* sdcp, uint8_t cmd, uint32_t arg, uint32_t* resp) {
(void)sdcp;
const uint32_t status = sdio_send_command(
sdcp,
/* RESPONSE_EXPECT | RESPONSE_LENGTH | CHECK_RESPONSE_CRC */
cmd | (1U << 6) | (1U << 7) | (1U << 8),
arg
);
arg);
if (status == CH_SUCCESS) {
*(resp++) = LPC_SDMMC->RESP0;
@ -862,9 +844,7 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
*
* @notapi
*/
bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk,
uint8_t *buf, uint32_t n) {
bool_t sdc_lld_read_aligned(SDCDriver* sdcp, uint32_t startblk, uint8_t* buf, uint32_t n) {
chDbgCheck((n <= (LPC_SDC_SDIO_DESCRIPTOR_COUNT * LPC_SDC_SDIO_MAX_DESCRIPTOR_BYTES / MMCSD_BLOCK_SIZE)), "max transaction size");
/* TODO: Handle SDHC block indexing? */
@ -927,9 +907,7 @@ error:
*
* @notapi
*/
bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buf, uint32_t n) {
bool_t sdc_lld_write_aligned(SDCDriver* sdcp, uint32_t startblk, const uint8_t* buf, uint32_t n) {
chDbgCheck((n <= (LPC_SDC_SDIO_DESCRIPTOR_COUNT * LPC_SDC_SDIO_MAX_DESCRIPTOR_BYTES / MMCSD_BLOCK_SIZE)), "max transaction size");
/* Checks for errors and waits for the card to be ready for writing.*/
@ -990,8 +968,7 @@ error:
*
* @notapi
*/
bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
uint8_t *buf, uint32_t n) {
bool_t sdc_lld_read(SDCDriver* sdcp, uint32_t startblk, uint8_t* buf, uint32_t n) {
return sdc_lld_read_aligned(sdcp, startblk, buf, n);
}
@ -1009,8 +986,7 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
*
* @notapi
*/
bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buf, uint32_t n) {
bool_t sdc_lld_write(SDCDriver* sdcp, uint32_t startblk, const uint8_t* buf, uint32_t n) {
return sdc_lld_write_aligned(sdcp, startblk, buf, n);
}
@ -1026,7 +1002,6 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
* @api
*/
bool_t sdc_lld_sync(SDCDriver* sdcp) {
(void)sdcp;
return CH_SUCCESS;

1
firmware/chibios/os/hal/include/hal.h Executable file → Normal file
View File

@ -210,6 +210,7 @@ extern "C" {
bool_t halIsCounterWithin(halrtcnt_t start, halrtcnt_t end);
void halPolledDelay(halrtcnt_t ticks);
#endif /* HAL_IMPLEMENTS_COUNTERS */
void sdio_cclk_set(const size_t divider_value);
#ifdef __cplusplus
}
#endif

View File

@ -40,6 +40,7 @@
#include <utility>
#include <ch.h>
#include <hal.h>
using namespace std;
@ -143,7 +144,7 @@ struct misc_config_t {
bool mute_audio : 1;
bool disable_speaker : 1;
bool config_disable_external_tcxo : 1;
bool UNUSED_3 : 1;
bool config_sdcard_high_speed_io : 1;
bool UNUSED_4 : 1;
bool UNUSED_5 : 1;
bool UNUSED_6 : 1;
@ -394,6 +395,8 @@ void defaults() {
set_recon_update_ranges_when_recon(true);
set_recon_load_hamradios(true);
set_recon_match_mode(0);
set_config_sdcard_high_speed_io(false, true);
}
void init() {
@ -581,6 +584,10 @@ bool config_disable_external_tcxo() {
return data->misc_config.config_disable_external_tcxo;
}
bool config_sdcard_high_speed_io() {
return data->misc_config.config_sdcard_high_speed_io;
}
bool stealth_mode() {
return data->ui_config.stealth_mode;
}
@ -646,6 +653,19 @@ void set_config_disable_external_tcxo(bool v) {
data->misc_config.config_disable_external_tcxo = v;
}
void set_config_sdcard_high_speed_io(bool v, bool save) {
if (v) {
/* 200MHz / (2 * 2) = 50MHz */
/* TODO: Adjust SCU pin configurations: pull-up/down, slew, glitch filter? */
sdio_cclk_set(2);
} else {
/* 200MHz / (2 * 4) = 25MHz */
sdio_cclk_set(4);
}
if (save)
data->misc_config.config_sdcard_high_speed_io = v;
}
void set_stealth_mode(bool v) {
data->ui_config.stealth_mode = v;
}
@ -1015,6 +1035,7 @@ bool debug_dump() {
pmem_dump_file.write_line("misc_config config_audio_mute: " + to_string_dec_int(config_audio_mute()));
pmem_dump_file.write_line("misc_config config_speaker_disable: " + to_string_dec_int(config_speaker_disable()));
pmem_dump_file.write_line("ui_config config_disable_external_tcxo: " + to_string_dec_uint(config_disable_external_tcxo()));
pmem_dump_file.write_line("ui_config config_sdcard_high_speed_io: " + to_string_dec_uint(config_sdcard_high_speed_io()));
// receiver_model
pmem_dump_file.write_line("\n[Receiver Model]");

View File

@ -174,6 +174,7 @@ uint8_t config_cpld();
void set_config_cpld(uint8_t i);
bool config_disable_external_tcxo();
bool config_sdcard_high_speed_io();
bool config_splash();
bool config_converter();
bool config_updown_converter();
@ -193,6 +194,7 @@ void set_load_app_settings(bool v);
void set_save_app_settings(bool v);
void set_show_bigger_qr_code(bool v);
void set_config_disable_external_tcxo(bool v);
void set_config_sdcard_high_speed_io(bool v, bool save);
void set_config_splash(bool v);
bool config_converter();
bool config_updown_converter();