From dcf2520ae8e325a62ec339265956aee179eb219b Mon Sep 17 00:00:00 2001 From: Raj Nakarja Date: Mon, 7 Aug 2023 14:25:15 +0200 Subject: [PATCH 1/4] Bugfix for fpga.version() when no image is running --- modules/fpga.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/modules/fpga.c b/modules/fpga.c index 09bb84d1..0dfde056 100644 --- a/modules/fpga.c +++ b/modules/fpga.c @@ -105,41 +105,60 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fpga_run_obj, 0, 1, fpga_run); STATIC mp_obj_t fpga_version(void) { - uint8_t target_device[4]; - uint8_t application_version[12]; - uint8_t chip_revision[4]; + uint8_t target_device[8]; + uint8_t application_version[13]; + uint8_t chip_revision[8]; + + memset(target_device, 0, sizeof(target_device)); + memset(application_version, 0, sizeof(application_version)); + memset(chip_revision, 0, sizeof(chip_revision)); uint8_t target_device_address[2] = {(uint8_t)(0x0001 >> 8), (uint8_t)0x0001}; uint8_t application_version_address[2] = {(uint8_t)(0x0002 >> 8), (uint8_t)0x0002}; uint8_t chip_revision_address[2] = {(uint8_t)(0x0003 >> 8), (uint8_t)0x0003}; monocle_spi_write(FPGA, target_device_address, 2, true); - monocle_spi_read(FPGA, target_device, sizeof(target_device), false); + monocle_spi_read(FPGA, target_device, 4, false); monocle_spi_write(FPGA, application_version_address, 2, true); - monocle_spi_read(FPGA, application_version, sizeof(application_version), false); + monocle_spi_read(FPGA, application_version, 12, false); monocle_spi_write(FPGA, chip_revision_address, 2, true); - monocle_spi_read(FPGA, chip_revision, sizeof(chip_revision), false); + monocle_spi_read(FPGA, chip_revision, 4, false); + + // In case the chip is off, or has no image, nothing will be returned + if (target_device[0] == 0xff) + { + strcpy((char *)target_device, "unknown"); + } + if (application_version[0] == 0xff) + { + strcpy((char *)application_version, "unknown"); + } + if (chip_revision[0] == 0xff) + { + strcpy((char *)chip_revision, "unknown"); + } - if (memcmp(chip_revision, "ffff", sizeof(chip_revision)) == 0) + // In case of legacy revC images, the register will return 'f' characters + if (memcmp(chip_revision, "ffff", 4) == 0) { - memcpy(chip_revision, "revC", sizeof(chip_revision)); + strcpy((char *)chip_revision, "revC"); } mp_obj_t return_dict = mp_obj_new_dict(0); mp_obj_dict_store(return_dict, MP_OBJ_NEW_QSTR(MP_QSTR_target_device), - mp_obj_new_str((char *)target_device, sizeof(target_device))); + mp_obj_new_str((char *)target_device, strlen((char *)target_device))); mp_obj_dict_store(return_dict, MP_OBJ_NEW_QSTR(MP_QSTR_application_version), - mp_obj_new_str((char *)application_version, sizeof(application_version))); + mp_obj_new_str((char *)application_version, strlen((char *)application_version))); mp_obj_dict_store(return_dict, MP_OBJ_NEW_QSTR(MP_QSTR_chip_revision), - mp_obj_new_str((char *)chip_revision, sizeof(chip_revision))); + mp_obj_new_str((char *)chip_revision, strlen((char *)chip_revision))); return return_dict; } From ff278baa023417f956fcecee21300c8ccef04bb6 Mon Sep 17 00:00:00 2001 From: Raj Nakarja Date: Mon, 7 Aug 2023 15:28:19 +0200 Subject: [PATCH 2/4] Fixed lockup if led.on/.off is called in an infinite loop NRFX_ERROR_BUSY during reads is no longer n app_err, but rather a high level .fail Interrupts using i2c can skip their function if i2c is busy --- main.c | 7 ++++++- modules/led.c | 7 +++++++ monocle-core/monocle-critical.c | 7 ++++++- monocle-core/monocle-drivers.c | 6 ++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/main.c b/main.c index 2fb80c22..c2fd96e6 100644 --- a/main.c +++ b/main.c @@ -296,7 +296,12 @@ static void touch_interrupt_handler(nrfx_gpiote_pin_t pin, (void)polarity; i2c_response_t interrupt = monocle_i2c_read(TOUCH_I2C_ADDRESS, 0x12, 0xFF); - app_err(interrupt.fail); + + // Throw away interrupt if i2c is busy in another thread + if (interrupt.fail) + { + return; + } switch (interrupt.value) { diff --git a/modules/led.c b/modules/led.c index 1016ba5f..8f51d3b6 100644 --- a/modules/led.c +++ b/modules/led.c @@ -22,6 +22,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#include "py/mphal.h" #include "py/runtime.h" #include "monocle.h" @@ -42,6 +43,9 @@ static mp_obj_t led_on(mp_obj_t led_in) MP_ERROR_TEXT("must be led.RED or led.GREEN")); } + // Unblocks i2c interrupts if led.on if called in an infinite loop + mp_hal_delay_ms(10); + if (led == MP_QSTR_RED) { monocle_set_led(RED_LED, true); @@ -65,6 +69,9 @@ static mp_obj_t led_off(mp_obj_t led_in) MP_ERROR_TEXT("must be led.RED or led.GREEN")); } + // Unblocks i2c interrupts if led.on if called in an infinite loop + mp_hal_delay_ms(10); + if (led == MP_QSTR_RED) { monocle_set_led(RED_LED, false); diff --git a/monocle-core/monocle-critical.c b/monocle-core/monocle-critical.c index ed1c3d13..71bad7a9 100644 --- a/monocle-core/monocle-critical.c +++ b/monocle-core/monocle-critical.c @@ -82,7 +82,12 @@ static void check_if_battery_charging_and_sleep(nrf_timer_event_t event_type, // Get the CHG value from STAT_CHG_B i2c_response_t charging_response = monocle_i2c_read(PMIC_I2C_ADDRESS, 0x03, 0x0C); - app_err(charging_response.fail); + + // Avoid sleeping if i2c is busy in another thread . We can't handle this + if (charging_response.fail) + { + return; + } bool charging = charging_response.value; diff --git a/monocle-core/monocle-drivers.c b/monocle-core/monocle-drivers.c index 6b3647ac..85e5f762 100644 --- a/monocle-core/monocle-drivers.c +++ b/monocle-core/monocle-drivers.c @@ -104,8 +104,7 @@ i2c_response_t monocle_i2c_read(uint8_t device_address_7bit, { nrfx_err_t tx_err = nrfx_twim_xfer(&i2c_handle, &i2c_tx, 0); - if (tx_err == NRFX_ERROR_BUSY || - tx_err == NRFX_ERROR_NOT_SUPPORTED || + if (tx_err == NRFX_ERROR_NOT_SUPPORTED || tx_err == NRFX_ERROR_INTERNAL || tx_err == NRFX_ERROR_INVALID_ADDR || tx_err == NRFX_ERROR_DRV_TWI_ERR_OVERRUN) @@ -115,8 +114,7 @@ i2c_response_t monocle_i2c_read(uint8_t device_address_7bit, nrfx_err_t rx_err = nrfx_twim_xfer(&i2c_handle, &i2c_rx, 0); - if (rx_err == NRFX_ERROR_BUSY || - rx_err == NRFX_ERROR_NOT_SUPPORTED || + if (rx_err == NRFX_ERROR_NOT_SUPPORTED || rx_err == NRFX_ERROR_INTERNAL || rx_err == NRFX_ERROR_INVALID_ADDR || rx_err == NRFX_ERROR_DRV_TWI_ERR_OVERRUN) From e3eb1e8dee0ff16374a154f4983f960ec86bc284 Mon Sep 17 00:00:00 2001 From: Raj Nakarja Date: Mon, 7 Aug 2023 15:37:09 +0200 Subject: [PATCH 3/4] Disabled camera tests to tests can continue without driver --- modules/_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/_test.py b/modules/_test.py index abc59585..a37f35b1 100644 --- a/modules/_test.py +++ b/modules/_test.py @@ -24,7 +24,8 @@ import device import display -import camera + +# import camera import microphone import touch import led @@ -203,11 +204,12 @@ def microphone_module(): def touch_module(): __test("touch.state('A')", False) __test("touch.state('B')", False) + __test("touch.state('EITHER')", False) __test("touch.state('BOTH')", False) __test("touch.state(touch.A)", False) __test("touch.state(touch.B)", False) + __test("touch.state(touch.EITHER)", False) __test("touch.state(touch.BOTH)", False) - __test("touch.state('B')", False) __test("callable(touch.callback)", True) From 2ef2673ac99325d231d6c184b04ec79aed8e231c Mon Sep 17 00:00:00 2001 From: Raj Nakarja Date: Mon, 7 Aug 2023 17:46:24 +0200 Subject: [PATCH 4/4] Added colorful splash screen --- modules/_splashscreen.py | 69 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/modules/_splashscreen.py b/modules/_splashscreen.py index 3e52054f..ee09b91c 100644 --- a/modules/_splashscreen.py +++ b/modules/_splashscreen.py @@ -1,8 +1,69 @@ import fpga, display + +def __splashscreen(): + logo = display.Text( + "MONOCLE", 320, 200, display.WHITE, justify=display.MIDDLE_CENTER + ) + bars_top = [] + bars_bottom = [] + + starting_location = 185 + + ax = 68 + starting_location + 70 + bx = 40 + starting_location + 70 + cx = 0 + starting_location + 70 + dx = 28 + starting_location + 70 + + for i in range(6): + if i == 0: + color = 0xFF0000 + elif i == 1: + color = 0xFFAA00 + elif i == 2: + color = 0xFFFF00 + elif i == 3: + color = 0x008800 + elif i == 4: + color = 0x0000FF + else: + color = 0xAA00FF + + bars_top.append(display.Polygon([ax, 100, bx, 100, cx, 170, dx, 170], color)) + ax += 28 + bx += 28 + cx += 28 + dx += 28 + + ax = 68 + starting_location + bx = 40 + starting_location + cx = 0 + starting_location + dx = 28 + starting_location + + for i in range(6): + if i == 0: + color = 0xFF0000 + elif i == 1: + color = 0xFFAA00 + elif i == 2: + color = 0xFFFF00 + elif i == 3: + color = 0x008800 + elif i == 4: + color = 0x0000FF + else: + color = 0xAA00FF + + bars_bottom.append(display.Polygon([ax, 230, bx, 230, cx, 300, dx, 300], color)) + ax += 28 + bx += 28 + cx += 28 + dx += 28 + + display.show(logo, bars_top, bars_bottom) + + if fpga.read(1, 4) == b"Mncl": - t = display.Text("MONOCLE", 320, 200, display.WHITE, justify=display.MIDDLE_CENTER) - display.show(t) - del t + __splashscreen() -del fpga, display +del fpga, display, __splashscreen