From 710337757522970ac692daef20b099d028fa14fe Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Tue, 19 Jan 2021 18:40:51 +0000 Subject: [PATCH] Added c++ code and mpy wrapper for pico_rgb_keypad, with examples --- examples/CMakeLists.txt | 3 +- examples/pico_rgb_keypad/CMakeLists.txt | 10 ++ examples/pico_rgb_keypad/demo.cpp | 76 +++++++++++++ .../pico_rgb_keypad/pico_sdk_import.cmake | 64 +++++++++++ libraries/CMakeLists.txt | 3 +- libraries/pico_rgb_keypad/CMakeLists.txt | 10 ++ libraries/pico_rgb_keypad/pico_rgb_keypad.cpp | 95 ++++++++++++++++ libraries/pico_rgb_keypad/pico_rgb_keypad.hpp | 29 +++++ micropython/examples/pico_rgb_keypad/demo.py | 53 +++++++++ .../modules/pico_rgb_keypad/micropython.mk | 6 + .../modules/pico_rgb_keypad/pico_rgb_keypad.c | 44 +++++++ .../pico_rgb_keypad/pico_rgb_keypad.cpp | 107 ++++++++++++++++++ .../modules/pico_rgb_keypad/pico_rgb_keypad.h | 14 +++ 13 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 examples/pico_rgb_keypad/CMakeLists.txt create mode 100644 examples/pico_rgb_keypad/demo.cpp create mode 100644 examples/pico_rgb_keypad/pico_sdk_import.cmake create mode 100644 libraries/pico_rgb_keypad/CMakeLists.txt create mode 100644 libraries/pico_rgb_keypad/pico_rgb_keypad.cpp create mode 100644 libraries/pico_rgb_keypad/pico_rgb_keypad.hpp create mode 100644 micropython/examples/pico_rgb_keypad/demo.py create mode 100755 micropython/modules/pico_rgb_keypad/micropython.mk create mode 100644 micropython/modules/pico_rgb_keypad/pico_rgb_keypad.c create mode 100644 micropython/modules/pico_rgb_keypad/pico_rgb_keypad.cpp create mode 100644 micropython/modules/pico_rgb_keypad/pico_rgb_keypad.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3cf6d2d0..a0c405e8 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(pico_display) add_subdirectory(pico_unicorn) add_subdirectory(pico_scroll) -add_subdirectory(pico_explorer) \ No newline at end of file +add_subdirectory(pico_explorer) +add_subdirectory(pico_rgb_keypad) \ No newline at end of file diff --git a/examples/pico_rgb_keypad/CMakeLists.txt b/examples/pico_rgb_keypad/CMakeLists.txt new file mode 100644 index 00000000..d910997e --- /dev/null +++ b/examples/pico_rgb_keypad/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable( + rgb_keypad + demo.cpp +) + +# Pull in pico libraries that we need +target_link_libraries(rgb_keypad pico_stdlib pico_rgb_keypad) + +# create map/bin/hex file etc. +pico_add_extra_outputs(rgb_keypad) diff --git a/examples/pico_rgb_keypad/demo.cpp b/examples/pico_rgb_keypad/demo.cpp new file mode 100644 index 00000000..4db7416f --- /dev/null +++ b/examples/pico_rgb_keypad/demo.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include "pico/stdlib.h" + +#include "pico_rgb_keypad.hpp" + +using namespace pimoroni; + +PicoRGBKeypad pico_keypad; + +int main() { + + pico_keypad.init(); + pico_keypad.set_brightness(1.0f); + + uint16_t lit = 0; + uint16_t last_button_states = 0; + uint8_t colour_index = 0; + + while(true) { + // read button states from i2c expander + uint16_t button_states = pico_keypad.get_button_states(); + + if(last_button_states != button_states && button_states) { + last_button_states = button_states; + if(button_states) { + if(lit == 0xffff) { + // all buttons are already lit, reset the test + lit = 0; + colour_index++; + if(colour_index >= 6) { + colour_index = 0; + } + }else{ + uint8_t button = 0; + for(uint8_t find = 0; find < pico_keypad.NUM_PADS; find++) { + // check if this button is pressed and no other buttons are pressed + if(button_states & 0x01) { + if(!(button_states & (~0x01))) { + lit |= 1 << button; + } + break; + } + button_states >>= 1; + button++; + } + } + } + } + + last_button_states = button_states; + + for(uint8_t i = 0; i < PicoRGBKeypad::NUM_PADS; i++) { + if((lit >> i) & 0x01) { + switch(colour_index) + { + case 0: pico_keypad.illuminate(i, 0x00, 0x20, 0x00); break; + case 1: pico_keypad.illuminate(i, 0x20, 0x20, 0x00); break; + case 2: pico_keypad.illuminate(i, 0x20, 0x00, 0x00); break; + case 3: pico_keypad.illuminate(i, 0x20, 0x00, 0x20); break; + case 4: pico_keypad.illuminate(i, 0x00, 0x00, 0x20); break; + case 5: pico_keypad.illuminate(i, 0x00, 0x20, 0x20); break; + } + }else{ + pico_keypad.illuminate(i, 0x05, 0x05, 0x05); + } + } + + pico_keypad.update(); + + sleep_ms(100); + } + + return 0; +} diff --git a/examples/pico_rgb_keypad/pico_sdk_import.cmake b/examples/pico_rgb_keypad/pico_sdk_import.cmake new file mode 100644 index 00000000..f63ee3f8 --- /dev/null +++ b/examples/pico_rgb_keypad/pico_sdk_import.cmake @@ -0,0 +1,64 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +# todo document + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the PICO SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of PICO SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading PICO SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "PICO SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the PICO SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the PICO SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 106d0741..1ba5ce81 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(pico_graphics) add_subdirectory(pico_display) add_subdirectory(pico_unicorn) add_subdirectory(pico_scroll) -add_subdirectory(pico_explorer) \ No newline at end of file +add_subdirectory(pico_explorer) +add_subdirectory(pico_rgb_keypad) \ No newline at end of file diff --git a/libraries/pico_rgb_keypad/CMakeLists.txt b/libraries/pico_rgb_keypad/CMakeLists.txt new file mode 100644 index 00000000..59560f63 --- /dev/null +++ b/libraries/pico_rgb_keypad/CMakeLists.txt @@ -0,0 +1,10 @@ +add_library(pico_rgb_keypad INTERFACE) + +target_sources(pico_rgb_keypad INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/pico_rgb_keypad.cpp +) + +target_include_directories(pico_rgb_keypad INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +# Pull in pico libraries that we need +target_link_libraries(pico_rgb_keypad INTERFACE pico_stdlib hardware_i2c hardware_spi) \ No newline at end of file diff --git a/libraries/pico_rgb_keypad/pico_rgb_keypad.cpp b/libraries/pico_rgb_keypad/pico_rgb_keypad.cpp new file mode 100644 index 00000000..fb66b17a --- /dev/null +++ b/libraries/pico_rgb_keypad/pico_rgb_keypad.cpp @@ -0,0 +1,95 @@ +#include +#include + +#include "pico/stdlib.h" +#include "hardware/i2c.h" + +#include "pico_rgb_keypad.hpp" + +#include "hardware/i2c.h" +#include "hardware/spi.h" + +enum pin { + SDA = 4, + SCL = 5, + CS = 17, + SCK = 18, + MOSI = 19 +}; + +namespace pimoroni { + + void PicoRGBKeypad::init() { + memset(buffer, 0, sizeof(buffer)); + led_data = buffer + 4; + + set_brightness(DEFAULT_BRIGHTNESS); //Must be called to init each LED frame + + // setup i2c interface + i2c_init(i2c0, 400000); + gpio_set_function(pin::SDA, GPIO_FUNC_I2C); gpio_pull_up(pin::SDA); + gpio_set_function(pin::SCL, GPIO_FUNC_I2C); gpio_pull_up(pin::SCL); + + spi_init(spi0, 4 * 1024 * 1024); + gpio_set_function(pin::CS, GPIO_FUNC_SIO); + gpio_set_dir(pin::CS, GPIO_OUT); + gpio_put(pin::CS, 1); + gpio_set_function(pin::SCK, GPIO_FUNC_SPI); + gpio_set_function(pin::MOSI, GPIO_FUNC_SPI); + + update(); + } + + void PicoRGBKeypad::update() { + gpio_put(pin::CS, 0); + spi_write_blocking(spi0, buffer, sizeof(buffer)); + gpio_put(pin::CS, 1); + } + + void PicoRGBKeypad::set_brightness(float brightness) { + if(brightness < 0.0f || brightness > 1.0f) { + return; + } + + for(uint16_t i = 0; i < NUM_PADS; i++) + led_data[i * 4] = 0b11100000 | (uint8_t)(brightness * (float)0b11111); + } + + void PicoRGBKeypad::illuminate(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) { + if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) { + return; + } + + uint16_t offset = (x + (y * WIDTH)) * 4; + //led_data[offset + 0] = 0xff; //Not needed as set at init + led_data[offset + 1] = b; + led_data[offset + 2] = g; + led_data[offset + 3] = r; + } + + void PicoRGBKeypad::illuminate(uint8_t i, uint8_t r, uint8_t g, uint8_t b) { + if(i < 0 || i >= NUM_PADS) { + return; + } + + uint16_t offset = i * 4; + //led_data[offset + 0] = 0xff; //Not needed as set at init + led_data[offset + 1] = b; + led_data[offset + 2] = g; + led_data[offset + 3] = r; + } + + void PicoRGBKeypad::clear() { + for(uint16_t i = 0; i < NUM_PADS; i++) + illuminate(i, 0, 0, 0); + } + + uint16_t PicoRGBKeypad::get_button_states() { + uint8_t i2c_read_buffer[2]; + uint8_t reg = 0; + i2c_write_blocking(i2c0, KEYPAD_ADDRESS, ®, 1, true); + i2c_read_blocking(i2c0, KEYPAD_ADDRESS, i2c_read_buffer, 2, false); + return ~((i2c_read_buffer[0]) | (i2c_read_buffer[1] << 8)); + } + +} \ No newline at end of file diff --git a/libraries/pico_rgb_keypad/pico_rgb_keypad.hpp b/libraries/pico_rgb_keypad/pico_rgb_keypad.hpp new file mode 100644 index 00000000..0f7ec356 --- /dev/null +++ b/libraries/pico_rgb_keypad/pico_rgb_keypad.hpp @@ -0,0 +1,29 @@ +#pragma once + +namespace pimoroni { + + class PicoRGBKeypad { + private: + static const uint8_t KEYPAD_ADDRESS = 0x20; + static constexpr float DEFAULT_BRIGHTNESS = 0.5f; + public: + static const int WIDTH = 4; + static const int HEIGHT = 4; + static const int NUM_PADS = WIDTH * HEIGHT; + + private: + uint8_t buffer[(NUM_PADS * 4) + 8]; + uint8_t *led_data; + + public: + void init(); + void update(); + void set_brightness(float brightness); + void illuminate(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b); + void illuminate(uint8_t i, uint8_t r, uint8_t g, uint8_t b); + + void clear(); + uint16_t get_button_states(); + }; + +} \ No newline at end of file diff --git a/micropython/examples/pico_rgb_keypad/demo.py b/micropython/examples/pico_rgb_keypad/demo.py new file mode 100644 index 00000000..f57aa945 --- /dev/null +++ b/micropython/examples/pico_rgb_keypad/demo.py @@ -0,0 +1,53 @@ +import time +import picokeypad as keypad + +keypad.init() +keypad.set_brightness(1.0) + +lit = 0 +last_button_states = 0 +colour_index = 0 + +NUM_PADS = keypad.get_num_pads() +while True: + button_states = keypad.get_button_states() + if last_button_states != button_states: + last_button_states = button_states + if button_states > 0: + if lit == 0xffff: + # all buttons are already lit, reset the test + lit = 0 + colour_index += 1 + if colour_index >= 6: + colour_index = 0 + else: + button = 0 + for find in range (0, NUM_PADS): + # check if this button is pressed and no other buttons are pressed + if button_states & 0x01 > 0: + if not (button_states & (~0x01)) > 0: + lit = lit | (1 << button) + break + button_states >>= 1 + button += 1 + + for i in range (0, NUM_PADS): + if (lit >> i) & 0x01: + if colour_index == 0: + keypad.illuminate(i, 0x00, 0x20, 0x00) + elif colour_index == 1: + keypad.illuminate(i, 0x20, 0x20, 0x00) + elif colour_index == 2: + keypad.illuminate(i, 0x20, 0x00, 0x00) + elif colour_index == 3: + keypad.illuminate(i, 0x20, 0x00, 0x20) + elif colour_index == 4: + keypad.illuminate(i, 0x00, 0x00, 0x20) + elif colour_index == 5: + keypad.illuminate(i, 0x00, 0x20, 0x20) + else: + keypad.illuminate(i, 0x05, 0x05, 0x05) + + keypad.update() + + time.sleep(0.1) \ No newline at end of file diff --git a/micropython/modules/pico_rgb_keypad/micropython.mk b/micropython/modules/pico_rgb_keypad/micropython.mk new file mode 100755 index 00000000..1d4e061a --- /dev/null +++ b/micropython/modules/pico_rgb_keypad/micropython.mk @@ -0,0 +1,6 @@ +RGBKEYPAD_MOD_DIR := $(USERMOD_DIR) +# Add all C files to SRC_USERMOD. +SRC_USERMOD += $(RGBKEYPAD_MOD_DIR)/pico_rgb_keypad.c +# # We can add our module folder to include paths if needed +# # This is not actually needed in this example. +CFLAGS_USERMOD += -I$(RGBKEYPAD_MOD_DIR) diff --git a/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.c b/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.c new file mode 100644 index 00000000..1f843fcd --- /dev/null +++ b/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.c @@ -0,0 +1,44 @@ +#include "pico_rgb_keypad.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// picokeypad Module +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/***** Module Functions *****/ +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_init_obj, picokeypad_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_get_width_obj, picokeypad_get_width); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_get_height_obj, picokeypad_get_height); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_get_num_pads_obj, picokeypad_get_num_pads); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_update_obj, picokeypad_update); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(picokeypad_set_brightness_obj, picokeypad_set_brightness); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picokeypad_illuminate_xy_obj, 5, 5, picokeypad_illuminate_xy); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picokeypad_illuminate_obj, 4, 4, picokeypad_illuminate); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_clear_obj, picokeypad_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(picokeypad_get_button_states_obj, picokeypad_get_button_states); + +/***** Globals Table *****/ +STATIC const mp_map_elem_t picokeypad_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picokeypad) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picokeypad_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picokeypad_get_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picokeypad_get_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_num_pads), MP_ROM_PTR(&picokeypad_get_num_pads_obj) }, + { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picokeypad_update_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_brightness), MP_ROM_PTR(&picokeypad_set_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_illuminate_xy), MP_ROM_PTR(&picokeypad_illuminate_xy_obj) }, + { MP_ROM_QSTR(MP_QSTR_illuminate), MP_ROM_PTR(&picokeypad_illuminate_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picokeypad_clear_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_button_states), MP_ROM_PTR(&picokeypad_get_button_states_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_picokeypad_globals, picokeypad_globals_table); + +/***** Module Definition *****/ +const mp_obj_module_t picokeypad_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_picokeypad_globals, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +MP_REGISTER_MODULE(MP_QSTR_picokeypad, picokeypad_user_cmodule, MODULE_PICOKEYPAD_ENABLED); +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.cpp b/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.cpp new file mode 100644 index 00000000..fa3c93c1 --- /dev/null +++ b/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.cpp @@ -0,0 +1,107 @@ +#include "hardware/spi.h" +#include "hardware/sync.h" +#include "pico/binary_info.h" + +#include "../../../pimoroni-pico/libraries/pico_rgb_keypad/pico_rgb_keypad.hpp" + +using namespace pimoroni; + +PicoRGBKeypad keypad; + + +extern "C" { +#include "pico_rgb_keypad.h" + +mp_obj_t picokeypad_init() { + keypad.init(); + return mp_const_none; +} + +mp_obj_t picokeypad_get_width() { + return mp_obj_new_int(PicoRGBKeypad::WIDTH); +} + +mp_obj_t picokeypad_get_height() { + return mp_obj_new_int(PicoRGBKeypad::HEIGHT); +} + +mp_obj_t picokeypad_get_num_pads() { + return mp_obj_new_int(PicoRGBKeypad::NUM_PADS); +} + +mp_obj_t picokeypad_update() { + keypad.update(); + return mp_const_none; +} + +mp_obj_t picokeypad_set_brightness(mp_obj_t brightness_obj) { + float brightness = mp_obj_get_float(brightness_obj); + + if(brightness < 0 || brightness > 1.0f) + mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0"); + else + keypad.set_brightness(brightness); + + return mp_const_none; +} + +mp_obj_t picokeypad_illuminate_xy(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 5 + + int x = mp_obj_get_int(args[0]); + int y = mp_obj_get_int(args[1]); + int r = mp_obj_get_int(args[2]); + int g = mp_obj_get_int(args[3]); + int b = mp_obj_get_int(args[4]); + + if(x < 0 || x >= PicoRGBKeypad::WIDTH || y < 0 || y >= PicoRGBKeypad::HEIGHT) + mp_raise_ValueError("x or y out of range."); + else + { + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + keypad.illuminate(x, y, r, g, b); + } + + return mp_const_none; +} + +mp_obj_t picokeypad_illuminate(mp_uint_t n_args, const mp_obj_t *args) { + (void)n_args; //Unused input parameter, we know it's 5 + + int i = mp_obj_get_int(args[0]); + int r = mp_obj_get_int(args[1]); + int g = mp_obj_get_int(args[2]); + int b = mp_obj_get_int(args[3]); + + if(i < 0 || i >= PicoRGBKeypad::NUM_PADS) + mp_raise_ValueError("x or y out of range."); + else + { + if(r < 0 || r > 255) + mp_raise_ValueError("r out of range. Expected 0 to 255"); + else if(g < 0 || g > 255) + mp_raise_ValueError("g out of range. Expected 0 to 255"); + else if(b < 0 || b > 255) + mp_raise_ValueError("b out of range. Expected 0 to 255"); + else + keypad.illuminate(i, r, g, b); + } + + return mp_const_none; +} + +mp_obj_t picokeypad_clear() { + keypad.clear(); + return mp_const_none; +} + +mp_obj_t picokeypad_get_button_states() { + return mp_obj_new_int(keypad.get_button_states()); +} +} \ No newline at end of file diff --git a/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.h b/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.h new file mode 100644 index 00000000..0d9e083c --- /dev/null +++ b/micropython/modules/pico_rgb_keypad/pico_rgb_keypad.h @@ -0,0 +1,14 @@ +// Include MicroPython API. +#include "py/runtime.h" + +// Declare the functions we'll make available in Python +extern mp_obj_t picokeypad_init(); +extern mp_obj_t picokeypad_get_width(); +extern mp_obj_t picokeypad_get_height(); +extern mp_obj_t picokeypad_get_num_pads(); +extern mp_obj_t picokeypad_update(); +extern mp_obj_t picokeypad_set_brightness(mp_obj_t brightness_obj); +extern mp_obj_t picokeypad_illuminate_xy(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picokeypad_illuminate(mp_uint_t n_args, const mp_obj_t *args); +extern mp_obj_t picokeypad_clear(); +extern mp_obj_t picokeypad_get_button_states(); \ No newline at end of file