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

@ -49,11 +49,11 @@ SDCDriver SDCD1;
#if LPC_SDC_USE_SDC1
static const sdio_resources_t sdio_resources = {
.base = { .clk = &LPC_CGU->BASE_SDIO_CLK, .stat = &LPC_CCU2->BASE_STAT, .stat_mask = 0 },
.branch_register_if = { .cfg = &LPC_CCU1->CLK_M4_SDIO_CFG, .stat = &LPC_CCU1->CLK_M4_SDIO_STAT },
.branch_peripheral = { .cfg = &LPC_CCU2->CLK_SDIO_CFG, .stat = &LPC_CCU2->CLK_SDIO_STAT },
.reset = { .output_index = 20 },
.interrupt = { .irq = SDIO_IRQn, .priority_mask = CORTEX_PRIORITY_MASK(LPC_SDC_SDIO_IRQ_PRIORITY) },
.base = {.clk = &LPC_CGU->BASE_SDIO_CLK, .stat = &LPC_CCU2->BASE_STAT, .stat_mask = 0},
.branch_register_if = {.cfg = &LPC_CCU1->CLK_M4_SDIO_CFG, .stat = &LPC_CCU1->CLK_M4_SDIO_STAT},
.branch_peripheral = {.cfg = &LPC_CCU2->CLK_SDIO_CFG, .stat = &LPC_CCU2->CLK_SDIO_STAT},
.reset = {.output_index = 20},
.interrupt = {.irq = SDIO_IRQn, .priority_mask = CORTEX_PRIORITY_MASK(LPC_SDC_SDIO_IRQ_PRIORITY)},
};
#endif
@ -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
@ -264,7 +266,7 @@ static bool_t sdc_llc_prepare_descriptors_chained(LPC_SDMMC_DESC_Type desc[],
const uint32_t buffer_size = LPC_SDC_SDIO_MAX_DESCRIPTOR_BYTES;
uint32_t p = (uint32_t)buffer;
for(uint32_t i=0; i<desc_count; i++) {
for (uint32_t i = 0; i < desc_count; i++) {
uint32_t buffer_1_size = (byte_count > buffer_size) ? buffer_size : byte_count;
desc[i].DESC2 = p; //(buffer_1_size == 0) ? 0 : p;
p += buffer_1_size;
@ -272,11 +274,9 @@ 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];
desc[i].DESC3 = (uint32_t)&desc[i + 1];
const bool_t first_descriptor = (i == 0);
const bool_t last_descriptor = (byte_count == 0);
@ -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();
@ -317,7 +315,7 @@ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
chDbgAssert(sdcp->thread == NULL,
"sdc_lld_start_data_transaction(), #2", "not NULL");
}
if( !sdio_status_data_transfer_over() ) {
if (!sdio_status_data_transfer_over()) {
chSysUnlock();
return CH_FAILED;
}
@ -342,22 +340,22 @@ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n,
*
* @notapi
*/
static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
static void sdc_lld_collect_errors(SDCDriver* sdcp, uint32_t sta) {
uint32_t errors = SDC_NO_ERROR;
if (sta & (1U << 6) )
if (sta & (1U << 6))
errors |= SDC_CMD_CRC_ERROR;
if (sta & (1U << 7) )
if (sta & (1U << 7))
errors |= SDC_DATA_CRC_ERROR;
if (sta & (1U << 8) )
if (sta & (1U << 8))
errors |= SDC_COMMAND_TIMEOUT;
if (sta & (1U << 9) )
if (sta & (1U << 9))
errors |= SDC_DATA_TIMEOUT;
if (sta & (1U << 11) )
if (sta & (1U << 11))
errors |= (SDC_TX_UNDERRUN | SDC_RX_OVERRUN);
if (sta & (1U << 13) )
if (sta & (1U << 13))
errors |= SDC_STARTBIT_ERROR;
if (sta & ((1U << 10) | (1U << 12) | (1U << 15)) ) /* HTO, HLE, EBE */
if (sta & ((1U << 10) | (1U << 12) | (1U << 15))) /* HTO, HLE, EBE */
errors |= SDC_UNHANDLED_ERROR;
sdcp->errors |= errors;
@ -372,9 +370,9 @@ static void sdc_lld_collect_errors(SDCDriver *sdcp, uint32_t sta) {
*
* @notapi
*/
static void sdc_lld_error_cleanup(SDCDriver *sdcp,
static void sdc_lld_error_cleanup(SDCDriver* sdcp,
uint32_t n,
uint32_t *resp) {
uint32_t* resp) {
uint32_t sta = LPC_SDMMC->RINTSTS;
sdio_dma_interrupts_clear();
@ -389,14 +387,12 @@ static void sdc_lld_error_cleanup(SDCDriver *sdcp,
}
static bool_t sdio_send_command(
SDCDriver *sdcp,
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 */
;
@ -410,7 +406,7 @@ static bool_t sdio_send_command(
/* TODO: Is HLE even possible if the stack is correct? Maybe make this a
* debug-only block of code?
*/
if( sdio_status_hardware_locked_write_error() ) {
if (sdio_status_hardware_locked_write_error()) {
sdc_lld_collect_errors(sdcp, LPC_SDMMC->RINTSTS);
sdio_status_hardware_locked_write_error_clear();
return CH_FAILED;
@ -419,7 +415,7 @@ static bool_t sdio_send_command(
sdio_wait_for_command_done();
/* TODO: If no response expected, why check for response errors? */
if( sdio_status_response_error() ) {
if (sdio_status_response_error()) {
sdc_lld_collect_errors(sdcp, LPC_SDMMC->RINTSTS);
sdio_status_response_error_clear();
return CH_FAILED;
@ -429,31 +425,27 @@ 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 ) {
if (status == CH_SUCCESS) {
*resp = LPC_SDMMC->RESP0;
}
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;
}
@ -550,7 +540,7 @@ CH_IRQ_HANDLER(SDIO_IRQHandler) {
sdio_interrupts_set_mask(0);
chSysLockFromIsr();
if( SDCD1.thread != NULL ) {
if (SDCD1.thread != NULL) {
chSchReadyI(SDCD1.thread);
SDCD1.thread = NULL;
}
@ -569,7 +559,6 @@ CH_IRQ_HANDLER(SDIO_IRQHandler) {
* @notapi
*/
void sdc_lld_init(void) {
sdcObjectInit(&SDCD1);
SDCD1.resources = &sdio_resources;
SDCD1.thread = NULL;
@ -586,8 +575,7 @@ void sdc_lld_init(void) {
*
* @notapi
*/
void sdc_lld_start(SDCDriver *sdcp) {
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 */
@ -621,7 +608,7 @@ void sdc_lld_start(SDCDriver *sdcp) {
LPC_SDMMC->FIFOTH =
(((fifo_depth / 2) - 0) << 0) /* TX watermark */
| (((fifo_depth / 2) - 1) << 16) /* RX watermark */
| ( 1U << 28) /* DMA multiple transaction burst size: 4 transfers */
| (1U << 28) /* DMA multiple transaction burst size: 4 transfers */
;
LPC_SDMMC->BMOD =
@ -647,8 +634,7 @@ void sdc_lld_start(SDCDriver *sdcp) {
*
* @notapi
*/
void sdc_lld_stop(SDCDriver *sdcp) {
void sdc_lld_stop(SDCDriver* sdcp) {
if (sdcp->state != BLK_STOP) {
interrupt_disable(&sdcp->resources->interrupt);
@ -672,11 +658,13 @@ void sdc_lld_stop(SDCDriver *sdcp) {
*
* @notapi
*/
void sdc_lld_start_clk(SDCDriver *sdcp) {
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 (;;)
;
}
/**
@ -686,7 +674,7 @@ void sdc_lld_start_clk(SDCDriver *sdcp) {
*
* @notapi
*/
void sdc_lld_set_data_clk(SDCDriver *sdcp) {
void sdc_lld_set_data_clk(SDCDriver* sdcp) {
(void)sdcp;
sdio_cclk_set_fast();
}
@ -698,7 +686,7 @@ void sdc_lld_set_data_clk(SDCDriver *sdcp) {
*
* @notapi
*/
void sdc_lld_stop_clk(SDCDriver *sdcp) {
void sdc_lld_stop_clk(SDCDriver* sdcp) {
(void)sdcp;
sdio_cclk_disable();
}
@ -711,7 +699,7 @@ void sdc_lld_stop_clk(SDCDriver *sdcp) {
*
* @notapi
*/
void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
void sdc_lld_set_bus_mode(SDCDriver* sdcp, sdcbusmode_t mode) {
(void)sdcp;
switch (mode) {
@ -738,12 +726,12 @@ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
*
* @notapi
*/
void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
void sdc_lld_send_cmd_none(SDCDriver* sdcp, uint8_t cmd, uint32_t arg) {
(void)sdcp;
const uint32_t status = sdio_send_command(sdcp, cmd, arg);
if( status != CH_SUCCESS ) {
if (status != CH_SUCCESS) {
chSysHalt();
}
}
@ -763,18 +751,16 @@ 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 ) {
if (status == CH_SUCCESS) {
*resp = LPC_SDMMC->RESP0;
}
@ -795,18 +781,16 @@ 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 ) {
if (status == CH_SUCCESS) {
*resp = LPC_SDMMC->RESP0;
}
@ -827,22 +811,20 @@ 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 ) {
if (status == CH_SUCCESS) {
*(resp++) = LPC_SDMMC->RESP0;
*(resp++) = LPC_SDMMC->RESP1;
*(resp++) = LPC_SDMMC->RESP2;
*(resp ) = LPC_SDMMC->RESP3;
*(resp) = LPC_SDMMC->RESP3;
}
return status;
@ -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);
}
@ -1025,19 +1001,18 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
*
* @api
*/
bool_t sdc_lld_sync(SDCDriver *sdcp) {
bool_t sdc_lld_sync(SDCDriver* sdcp) {
(void)sdcp;
return CH_SUCCESS;
}
bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) {
bool_t sdc_lld_is_card_inserted(SDCDriver* sdcp) {
(void)sdcp;
return (LPC_SDMMC->CDETECT & (1U << 0)) ? FALSE : TRUE;
}
bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) {
bool_t sdc_lld_is_write_protected(SDCDriver* sdcp) {
(void)sdcp;
return (LPC_SDMMC->WRTPRT & (1U << 0)) ? TRUE : FALSE;
}

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

@ -205,11 +205,12 @@
#ifdef __cplusplus
extern "C" {
#endif
void halInit(void);
void halInit(void);
#if HAL_IMPLEMENTS_COUNTERS
bool_t halIsCounterWithin(halrtcnt_t start, halrtcnt_t end);
void halPolledDelay(halrtcnt_t ticks);
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();