diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 3225ce47..2f947870 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -44,6 +44,8 @@ using namespace lpc43xx; #include "ui_navigation.hpp" +static int delayed_error = 0; + extern "C" { CH_IRQ_HANDLER(M4Core_IRQHandler) { @@ -161,6 +163,10 @@ void EventDispatcher::dispatch(const eventmask_t events) { } if (events & EVT_MASK_RTC_TICK) { + // delay error message by 2 seconds to wait for LCD being ready + if (portapack::init_error != nullptr && ++delayed_error > 1) + draw_guru_meditation(CORTEX_M4, portapack::init_error); + handle_rtc_tick(); } diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 5d215207..fab21c7a 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -170,24 +170,31 @@ int main(void) { config_mode_set(); first_if.init(); /* To avoid initial short Ant_DC_Bias pulse ,we need quick set up GP01_RFF507X =1 */ - if (portapack::init()) { - portapack::display.init(); - config_mode_clear(); - // sdcStart(&SDCD1, nullptr); // Commented out as now happens in portapack.cpp + switch (portapack::init()) { + case portapack::init_status_t::INIT_HACKRF_CPLD_FAILED: + portapack::init_error = "HACKRF CPLD FAILED"; + [[fallthrough]]; - // controls_init(); // Commented out as now happens in portapack.cpp - lcd_frame_sync_configure(); - rtc_interrupt_enable(); + case portapack::init_status_t::INIT_SUCCESS: + portapack::display.init(); + config_mode_clear(); - event_loop(); + lcd_frame_sync_configure(); + rtc_interrupt_enable(); - sdcDisconnect(&SDCD1); - sdcStop(&SDCD1); + event_loop(); - portapack::shutdown(); - } else { - config_mode_clear(); + sdcDisconnect(&SDCD1); + sdcStop(&SDCD1); + + portapack::shutdown(); + break; + + case portapack::init_status_t::INIT_NO_PORTAPACK: + case portapack::init_status_t::INIT_PORTAPACK_CPLD_FAILED: + config_mode_clear(); + break; } m4_init(portapack::spi_flash::image_tag_hackrf, portapack::memory::map::m4_code_hackrf, true); diff --git a/firmware/application/portapack.cpp b/firmware/application/portapack.cpp index 7bf32d17..2293b4b4 100644 --- a/firmware/application/portapack.cpp +++ b/firmware/application/portapack.cpp @@ -53,6 +53,8 @@ using asahi_kasei::ak4951::AK4951; namespace portapack { +const char* init_error = nullptr; + portapack::IO io{ portapack::gpio_dir, portapack::gpio_lcd_rdx, @@ -389,7 +391,7 @@ static void shutdown_base() { * everything else = IRC */ -bool init() { +init_status_t init() { set_idivc_base_clocks(cgu::CLK_SEL::IDIVC); i2c0.start(i2c_config_boot_clock); @@ -481,7 +483,7 @@ bool init() { chThdSleepMilliseconds(10); if (i2c0.transmit(0x12 /* ak4951 */, ak4951_init_command, 2, timeout) == false) { shutdown_base(); - return false; + return init_status_t::INIT_NO_PORTAPACK; } } @@ -506,12 +508,14 @@ bool init() { // Mode center (autodetect), up (R1) and down (R2,H2,H2+) will go into hackrf mode after failing CPLD update if (load_config() != 3 /* left */ && load_config() != 4 /* right */) { shutdown_base(); - return false; + return init_status_t::INIT_PORTAPACK_CPLD_FAILED; } } + init_status_t return_code = init_status_t::INIT_SUCCESS; + if (!hackrf::cpld::load_sram()) { - chSysHalt(); + return_code = init_status_t::INIT_HACKRF_CPLD_FAILED; } chThdSleepMilliseconds(10); // This delay seems to solve white noise audio issues @@ -523,7 +527,7 @@ bool init() { audio::init(portapack_audio_codec()); - return true; + return return_code; } void shutdown(const bool leave_screen_on) { diff --git a/firmware/application/portapack.hpp b/firmware/application/portapack.hpp index 3457365c..24eae598 100644 --- a/firmware/application/portapack.hpp +++ b/firmware/application/portapack.hpp @@ -41,6 +41,15 @@ * guardrails on setting properties. */ namespace portapack { +enum class init_status_t { + INIT_SUCCESS, + INIT_NO_PORTAPACK, + INIT_PORTAPACK_CPLD_FAILED, + INIT_HACKRF_CPLD_FAILED, +}; + +extern const char* init_error; + extern portapack::IO io; extern lcd::ILI9341 display; @@ -65,7 +74,7 @@ extern TemperatureLogger temperature_logger; void set_antenna_bias(const bool v); bool get_antenna_bias(); -bool init(); +init_status_t init(); void shutdown(const bool leave_screen_on = false); void setEventDispatcherToUSBSerial(EventDispatcher* evt);