diff --git a/drivers/rv3028/rv3028.cpp b/drivers/rv3028/rv3028.cpp index be43c44b..7ec7db49 100644 --- a/drivers/rv3028/rv3028.cpp +++ b/drivers/rv3028/rv3028.cpp @@ -528,7 +528,7 @@ namespace pimoroni { { // Reads the number of remaining timer ticks uint8_t r0 =readRegister(RV3028_TIMERSTAT_0); - return(r0 + (readRegister(RV3028_TIMERSTAT_1) >> 8)); + return(r0 + (readRegister(RV3028_TIMERSTAT_1) << 8)); } void RV3028::enableTimerInterrupt() diff --git a/examples/pico_rtc_display/CMakeLists.txt b/examples/pico_rtc_display/CMakeLists.txt index 515a729a..50726a17 100644 --- a/examples/pico_rtc_display/CMakeLists.txt +++ b/examples/pico_rtc_display/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable( ) # Pull in pico libraries that we need -target_link_libraries(rtc_display pico_stdlib pico_display rv3028) +target_link_libraries(rtc_display pico_stdlib pico_explorer pico_display rv3028) # create map/bin/hex file etc. pico_add_extra_outputs(rtc_display) diff --git a/examples/pico_rtc_display/demo.cpp b/examples/pico_rtc_display/demo.cpp index 4afd2c4f..d0613d80 100644 --- a/examples/pico_rtc_display/demo.cpp +++ b/examples/pico_rtc_display/demo.cpp @@ -14,7 +14,17 @@ // (There are on-screen reminders of the active buttons) // ************************************************************************** +// To use PicoExplorer rather than PicoDisplay, uncomment the following line +// #define USE_PICO_EXPLORER 1 +// This: +// - Includes pico_explorer.hpp rather than pico_display.hpp +// - Replaces all PicoDisplay references with PicoExplorer +// - Leaves out the .set_led() calls in flash_led() +#ifdef USE_PICO_EXPLORER +#include "pico_explorer.hpp" +#else #include "pico_display.hpp" +#endif #include "rv3028.hpp" #define MODE_DISP_CLOCK 0 @@ -25,11 +35,46 @@ using namespace pimoroni; +#ifdef USE_PICO_EXPLORER +uint16_t buffer[PicoExplorer::WIDTH * PicoExplorer::HEIGHT]; +PicoExplorer pico_display(buffer); +uint16_t screen_width = PicoExplorer::WIDTH; +uint16_t screen_height = PicoExplorer::HEIGHT; +#else uint16_t buffer[PicoDisplay::WIDTH * PicoDisplay::HEIGHT]; PicoDisplay pico_display(buffer); +uint16_t screen_width = PicoDisplay::WIDTH; +uint16_t screen_height = PicoDisplay::HEIGHT; +#endif RV3028 rv3028; +#define LOW_COUNT_MOD 40 +#define HIGH_COUNT_MOD 20 +bool repeat_count_reached(uint16_t curr_count) { + // Check whether the current counter means that a key has repeated + if (curr_count <= 10*LOW_COUNT_MOD) { + return (0 == (curr_count % LOW_COUNT_MOD)); + } else { + return (0 == (curr_count % HIGH_COUNT_MOD)); + } +} + +#define FLASH_MOD 20 +void flash_led(uint32_t curr_count) { + // Flash the LED based on the current loop counter + // curr_count=0 will turn LED off +#ifndef USE_PICO_EXPLORER + if ((curr_count % FLASH_MOD) < (FLASH_MOD / 2)) { + // value less than half modded number - LED off + pico_display.set_led(0, 0, 0); + } else { + // value more than half modded number - LED on + pico_display.set_led(128, 128, 128); + } +#endif +} + int main() { pico_display.init(); @@ -40,10 +85,12 @@ int main() { if (rv3028.is12Hour()) rv3028.set24Hour(); // Use these variables to make the buttons single-shot - bool a_pressed = false; - bool b_pressed = false; - bool x_pressed = false; - bool y_pressed = false; + // Counts number of loops pressed, 0 if not pressed + // Only for x and y - a and b are single-shot + uint16_t a_pressed = 0; + uint16_t b_pressed = 0; + uint16_t x_pressed = 0; + uint16_t y_pressed = 0; struct pt { float x; @@ -61,8 +108,8 @@ int main() { while(true) { - if (a_pressed == false && pico_display.is_pressed(pico_display.A)) { - a_pressed = true; + if (a_pressed == 0 && pico_display.is_pressed(pico_display.A)) { + a_pressed = 1; if (display_mode == MODE_DISP_CLOCK) { // We were displaying clock = set up timer display_mode = MODE_SET_TIMER; @@ -80,12 +127,12 @@ int main() { rv3028.clearTimerInterruptFlag(); display_mode = MODE_SET_TIMER; } - } else if (a_pressed == true && !pico_display.is_pressed(pico_display.A)) { - a_pressed = false; + } else if (a_pressed >= 1 && !pico_display.is_pressed(pico_display.A)) { + a_pressed = 0; } - if (b_pressed == false && pico_display.is_pressed(pico_display.B)) { - b_pressed = true; + if (b_pressed == 0 && pico_display.is_pressed(pico_display.B)) { + b_pressed = 1; if ((display_mode == MODE_DISP_TIMER) || (display_mode == MODE_SET_TIMER)) { // We were setting or displaying timer - revert to clock @@ -95,31 +142,41 @@ int main() { display_mode = MODE_DISP_CLOCK; timer_count = DEFAULT_TIMER_COUNT; } - } else if (b_pressed == true && !pico_display.is_pressed(pico_display.B)) { - b_pressed = false; + } else if (b_pressed >= 1 && !pico_display.is_pressed(pico_display.B)) { + b_pressed = 0; } - if (x_pressed == false && pico_display.is_pressed(pico_display.X)) { - x_pressed = true; + if (x_pressed == 0 && pico_display.is_pressed(pico_display.X)) { + x_pressed = 1; if (display_mode == MODE_SET_TIMER) { // Setting timer - Increment count timer_count++; } - } else if (x_pressed == true && !pico_display.is_pressed(pico_display.X)) { - x_pressed = false; + } else if (x_pressed >= 1 && pico_display.is_pressed(pico_display.X)) { + // Button still pressed - check if has reached repeat count + if (repeat_count_reached(x_pressed++)) { + timer_count++; + } + } else if (x_pressed >= 1 && !pico_display.is_pressed(pico_display.X)) { + x_pressed = 0; } - if (y_pressed == false && pico_display.is_pressed(pico_display.Y)) { - y_pressed = true; + if (y_pressed == 0 && pico_display.is_pressed(pico_display.Y)) { + y_pressed = 1; if (display_mode == MODE_SET_TIMER) { // Setting timer - Decrement count if (timer_count >= 1) timer_count--; } - } else if (y_pressed == true && !pico_display.is_pressed(pico_display.Y)) { - y_pressed = false; + } else if (y_pressed >= 1 && pico_display.is_pressed(pico_display.Y)) { + // Button still pressed - check if has reached repeat count + if (repeat_count_reached(y_pressed++)) { + if (timer_count >= 1) timer_count--; + } + } else if (y_pressed >= 1 && !pico_display.is_pressed(pico_display.Y)) { + y_pressed = 0; } - Rect text_box(5, 5, PicoDisplay::WIDTH-10, PicoDisplay::HEIGHT-10); + Rect text_box(5, 5, screen_width-10, screen_height-10); pico_display.set_pen(55, 65, 75); pico_display.rectangle(text_box); // text_box.deflate(10); @@ -128,6 +185,7 @@ int main() { switch (display_mode) { case MODE_DISP_CLOCK: // Show the clock face + flash_led(0); if (rv3028.updateTime()) { pico_display.text("Set Timer", Point(text_box.x, text_box.y+2), 230, 1); @@ -139,7 +197,7 @@ int main() { Point(text_box.x, text_box.y+60), 230, 6); pico_display.set_pen(255, 255, 255); pico_display.text("Clock", - Point(text_box.x, text_box.y+PicoDisplay::HEIGHT-20), 230, 1); + Point(text_box.x, text_box.y+screen_height-20), 230, 1); } else { sprintf(buf, "Time: rv3028.updateTime() ret err"); pico_display.text(buf, @@ -156,27 +214,29 @@ int main() { pico_display.text(buf, Point(text_box.x, text_box.y+30), 230, 4); pico_display.set_pen(255, 255, 255); + flash_led(i); } else { sprintf(buf, "%s %d", "Timer running", rv3028.getTimerCount()); pico_display.text(buf, - Point(text_box.x, text_box.y+30), 230, 4); + Point(text_box.x, text_box.y+30), 230, 3); } pico_display.text("Clock", - Point(text_box.x, text_box.y+PicoDisplay::HEIGHT-20), 230, 1); + Point(text_box.x, text_box.y+screen_height-20), 230, 1); break; case MODE_SET_TIMER: + flash_led(0); pico_display.text("Run Timer", Point(text_box.x, text_box.y+2), 230, 1); pico_display.text("+ Time", - Point(text_box.x+PicoDisplay::WIDTH-42, text_box.y+2), 230, 1); + Point(text_box.x+screen_width-42, text_box.y+2), 230, 1); sprintf(buf, "Time %d secs", timer_count); pico_display.text(buf, Point(text_box.x, text_box.y+30), 230, 3); pico_display.text("Clock", - Point(text_box.x, text_box.y+PicoDisplay::HEIGHT-20), 230, 1); + Point(text_box.x, text_box.y+screen_height-20), 230, 1); pico_display.text("- Time", - Point(text_box.x+PicoDisplay::WIDTH-42, - text_box.y+PicoDisplay::HEIGHT-20), 230, 1); + Point(text_box.x+screen_width-42, + text_box.y+screen_height-20), 230, 1); break; }