mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
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:
parent
650aacfaa7
commit
309f2fbd2c
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
7
firmware/chibios/os/hal/include/hal.h
Executable file → Normal 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
|
||||
|
@ -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]");
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user