From a778a1f6e9089ea08707ba23da33e0f0f733e5d4 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Tue, 15 Jun 2021 16:30:37 +0100 Subject: [PATCH] Added PAA secret sauce --- drivers/pmw3901/pmw3901.cpp | 163 +++++++++++++++++- drivers/pmw3901/pmw3901.hpp | 7 +- examples/CMakeLists.txt | 1 + examples/breakout_paa5100/CMakeLists.txt | 2 + .../frame_capture/CMakeLists.txt | 16 ++ .../frame_capture/frame_capture.cpp | 70 ++++++++ .../breakout_paa5100/motion/CMakeLists.txt | 16 ++ examples/breakout_paa5100/motion/motion.cpp | 26 +++ .../frame_capture/frame_capture.cpp | 1 - 9 files changed, 298 insertions(+), 4 deletions(-) create mode 100644 examples/breakout_paa5100/CMakeLists.txt create mode 100644 examples/breakout_paa5100/frame_capture/CMakeLists.txt create mode 100644 examples/breakout_paa5100/frame_capture/frame_capture.cpp create mode 100644 examples/breakout_paa5100/motion/CMakeLists.txt create mode 100644 examples/breakout_paa5100/motion/motion.cpp diff --git a/drivers/pmw3901/pmw3901.cpp b/drivers/pmw3901/pmw3901.cpp index 9e8eeb57..9ac725bc 100644 --- a/drivers/pmw3901/pmw3901.cpp +++ b/drivers/pmw3901/pmw3901.cpp @@ -313,7 +313,7 @@ namespace pimoroni { if(c1 > 28) c1 += 11; c1 = std::max((uint8_t)0, std::min((uint8_t)0x3F, c1)); - c2 = (c2 * 45); // 100 + c2 = (c2 * 45) / 100; uint8_t buf3[] = { 0x7f, 0x00, @@ -423,4 +423,165 @@ namespace pimoroni { uint32_t PMW3901::millis() { return to_ms_since_boot(get_absolute_time()); } + + void PAA5100::secret_sauce() { + uint8_t buf[] = { + 0x7f, 0x00, + 0x55, 0x01, + 0x50, 0x07, + + 0x7f, 0x0e, + 0x43, 0x10 + }; + write_buffer(buf, sizeof(buf)); + + if(read_register(0x67) & 0b10000000) + write_register(0x48, 0x04); + else + write_register(0x48, 0x02); + + uint8_t buf2[] = { + 0x7f, 0x00, + 0x51, 0x7b, + + 0x50, 0x00, + 0x55, 0x00, + 0x7f, 0x0E + }; + write_buffer(buf2, sizeof(buf2)); + + if(read_register(0x73) == 0x00) { + uint8_t c1 = read_register(0x70); + uint8_t c2 = read_register(0x71); + if(c1 <= 28) + c1 += 14; + if(c1 > 28) + c1 += 11; + c1 = std::max((uint8_t)0, std::min((uint8_t)0x3F, c1)); + c2 = (c2 * 45) / 100; + + uint8_t buf3[] = { + 0x7f, 0x00, + 0x61, 0xad, + 0x51, 0x70, + 0x7f, 0x0e + }; + write_buffer(buf3, sizeof(buf3)); + + write_register(0x70, c1); + write_register(0x71, c2); + } + + uint8_t buf4[] = { + 0x7f, 0x00, + 0x61, 0xad, + + 0x7f, 0x03, + 0x40, 0x00, + + 0x7f, 0x05, + 0x41, 0xb3, + 0x43, 0xf1, + 0x45, 0x14, + + 0x5f, 0x34, + 0x7b, 0x08, + 0x5e, 0x34, + 0x5b, 0x11, + 0x6d, 0x11, + 0x45, 0x17, + 0x70, 0xe5, + 0x71, 0xe5, + + 0x7f, 0x06, + 0x44, 0x1b, + 0x40, 0xbf, + 0x4e, 0x3f, + + 0x7f, 0x08, + 0x66, 0x44, + 0x65, 0x20, + 0x6a, 0x3a, + 0x61, 0x05, + 0x62, 0x05, + + 0x7f, 0x09, + 0x4f, 0xaf, + 0x5f, 0x40, + 0x48, 0x80, + 0x49, 0x80, + 0x57, 0x77, + 0x60, 0x78, + 0x61, 0x78, + 0x62, 0x08, + 0x63, 0x50, + + 0x7f, 0x0a, + 0x45, 0x60, + + 0x7f, 0x00, + 0x4d, 0x11, + 0x55, 0x80, + 0x74, 0x21, + 0x75, 0x1f, + 0x4a, 0x78, + 0x4b, 0x78, + 0x44, 0x08, + + 0x45, 0x50, + 0x64, 0xff, + 0x65, 0x1f, + + 0x7f, 0x14, + 0x65, 0x67, + 0x66, 0x08, + 0x63, 0x70, + 0x6f, 0x1c, + + 0x7f, 0x15, + 0x48, 0x48, + + 0x7f, 0x07, + 0x41, 0x0d, + 0x43, 0x14, + 0x4b, 0x0e, + 0x45, 0x0f, + 0x44, 0x42, + 0x4c, 0x80, + + 0x7f, 0x10, + 0x5b, 0x02, + + 0x7f, 0x07, + 0x40, 0x41, + + WAIT, 0x0a, // Sleep for 10ms + + 0x7f, 0x00, + 0x32, 0x00, + + 0x7f, 0x07, + 0x40, 0x40, + + 0x7f, 0x06, + 0x68, 0xf0, + 0x69, 0x00, + + 0x7f, 0x0d, + 0x48, 0xc0, + 0x6f, 0xd5, + + 0x7f, 0x00, + 0x5b, 0xa0, + 0x4e, 0xa8, + 0x5a, 0x90, + 0x40, 0x80, + 0x73, 0x1f, + + WAIT, 0x0a, // Sleep for 10ms + + 0x73, 0x00 + }; + write_buffer(buf4, sizeof(buf4)); + } } \ No newline at end of file diff --git a/drivers/pmw3901/pmw3901.hpp b/drivers/pmw3901/pmw3901.hpp index 31b17f6f..b95e5f00 100644 --- a/drivers/pmw3901/pmw3901.hpp +++ b/drivers/pmw3901/pmw3901.hpp @@ -15,7 +15,7 @@ namespace pimoroni { public: static const uint8_t FRAME_SIZE = 35; static const uint16_t RAW_DATA_LEN = 1225; - private: + protected: static const uint8_t WAIT = -1; //-------------------------------------------------- @@ -93,7 +93,6 @@ namespace pimoroni { protected: virtual void secret_sauce(); - private: void cs_select(); void cs_deselect(); void write_register(uint8_t reg, uint8_t data); @@ -103,4 +102,8 @@ namespace pimoroni { uint32_t millis(); }; + class PAA5100 : public PMW3901 { + protected: + virtual void secret_sauce(); + }; } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 27716eff..3b2f479c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -7,6 +7,7 @@ add_subdirectory(breakout_roundlcd) add_subdirectory(breakout_rgbmatrix5x5) add_subdirectory(breakout_matrix11x7) add_subdirectory(breakout_mics6814) +add_subdirectory(breakout_paa5100) add_subdirectory(breakout_pmw3901) add_subdirectory(breakout_potentiometer) add_subdirectory(breakout_rtc) diff --git a/examples/breakout_paa5100/CMakeLists.txt b/examples/breakout_paa5100/CMakeLists.txt new file mode 100644 index 00000000..ebf22a54 --- /dev/null +++ b/examples/breakout_paa5100/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(motion) +add_subdirectory(frame_capture) \ No newline at end of file diff --git a/examples/breakout_paa5100/frame_capture/CMakeLists.txt b/examples/breakout_paa5100/frame_capture/CMakeLists.txt new file mode 100644 index 00000000..76efadc3 --- /dev/null +++ b/examples/breakout_paa5100/frame_capture/CMakeLists.txt @@ -0,0 +1,16 @@ +set(OUTPUT_NAME paa5100_framecapture) + +add_executable( + ${OUTPUT_NAME} + frame_capture.cpp +) + +# enable usb output, disable uart output +pico_enable_stdio_usb(${OUTPUT_NAME} 1) +pico_enable_stdio_uart(${OUTPUT_NAME} 1) + +# Pull in pico libraries that we need +target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_paa5100) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${OUTPUT_NAME}) diff --git a/examples/breakout_paa5100/frame_capture/frame_capture.cpp b/examples/breakout_paa5100/frame_capture/frame_capture.cpp new file mode 100644 index 00000000..fb78fb6a --- /dev/null +++ b/examples/breakout_paa5100/frame_capture/frame_capture.cpp @@ -0,0 +1,70 @@ +#include +#include "pico/stdlib.h" +#include + +#include "breakout_paa5100.hpp" + +using namespace pimoroni; + +BreakoutPAA5100 flo(BG_SPI_FRONT); +BreakoutPAA5100::Degrees rotation = BreakoutPAA5100::DEGREES_0; +const uint8_t SIZE = BreakoutPAA5100::FRAME_SIZE; +uint8_t data[BreakoutPAA5100::RAW_DATA_LEN]; + +std::string value_to_char(uint8_t value) { + const std::string charmap = " .:-=+*#%@"; + float val = (float)value / 255.0f; + val *= charmap.length() - 1; + value = (uint8_t)val; + std::string chosen_char = charmap.substr(val, 1); + return chosen_char.append(chosen_char); // Double chars to - sort of - correct aspect ratio +} + +int main() { + stdio_init_all(); + + flo.init(); + flo.set_rotation(rotation); + + uint8_t offset = 0; + uint8_t value = 0; + + while(true) { + printf("Capturing...\n"); + uint16_t data_size = 0; + if(flo.frame_capture(data, data_size)) { + for(uint8_t y = 0; y < SIZE; y++) { + if(rotation == BreakoutPAA5100::DEGREES_180 || rotation == BreakoutPAA5100::DEGREES_270) + y = SIZE - y - 1; + + for(uint8_t x = 0; x < SIZE; x++) { + if(rotation == BreakoutPAA5100::DEGREES_180 || rotation == BreakoutPAA5100::DEGREES_90) + x = SIZE - x - 1; + + if(rotation == BreakoutPAA5100::DEGREES_90 || rotation == BreakoutPAA5100::DEGREES_270) + offset = (x * 35) + y; + else + offset = (y * 35) + x; + + value = data[offset]; + printf("%s", value_to_char(value).c_str()); + } + printf("\n"); + } + } + else { + printf("Capture failed. %d bytes received, of %d. Recapturing in ", data_size, BreakoutPAA5100::RAW_DATA_LEN); + } + printf("5...\n"); + sleep_ms(1000); + printf("4...\n"); + sleep_ms(1000); + printf("3...\n"); + sleep_ms(1000); + printf("2...\n"); + sleep_ms(1000); + printf("Get Ready!\n"); + sleep_ms(1000); + }; + return 0; +} diff --git a/examples/breakout_paa5100/motion/CMakeLists.txt b/examples/breakout_paa5100/motion/CMakeLists.txt new file mode 100644 index 00000000..925ea894 --- /dev/null +++ b/examples/breakout_paa5100/motion/CMakeLists.txt @@ -0,0 +1,16 @@ +set(OUTPUT_NAME paa5100_motion) + +add_executable( + ${OUTPUT_NAME} + motion.cpp +) + +# enable usb output, disable uart output +pico_enable_stdio_usb(${OUTPUT_NAME} 1) +pico_enable_stdio_uart(${OUTPUT_NAME} 1) + +# Pull in pico libraries that we need +target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_paa5100) + +# create map/bin/hex file etc. +pico_add_extra_outputs(${OUTPUT_NAME}) diff --git a/examples/breakout_paa5100/motion/motion.cpp b/examples/breakout_paa5100/motion/motion.cpp new file mode 100644 index 00000000..fc6e8a9b --- /dev/null +++ b/examples/breakout_paa5100/motion/motion.cpp @@ -0,0 +1,26 @@ +#include +#include "pico/stdlib.h" + +#include "breakout_paa5100.hpp" + +using namespace pimoroni; + +BreakoutPAA5100 flo(BG_SPI_FRONT); + +int main() { + stdio_init_all(); + + flo.init(); + flo.set_rotation(BreakoutPAA5100::DEGREES_0); + int16_t tx = 0, ty = 0; + int16_t x = 0, y = 0; + while(true) { + if(flo.get_motion(x, y)) { + tx += x; + ty += y; + printf("Relative: x %6d, y %6d | Absolute: tx %6d, ty %6d\n", x, y, tx, ty); + } + sleep_ms(10); + }; + return 0; +} diff --git a/examples/breakout_pmw3901/frame_capture/frame_capture.cpp b/examples/breakout_pmw3901/frame_capture/frame_capture.cpp index b6c57703..f51aa603 100644 --- a/examples/breakout_pmw3901/frame_capture/frame_capture.cpp +++ b/examples/breakout_pmw3901/frame_capture/frame_capture.cpp @@ -1,6 +1,5 @@ #include #include "pico/stdlib.h" -#include #include #include "breakout_pmw3901.hpp"