Merge branch 'main' of github.com:pimoroni/pimoroni-pico into main

pull/10/head
Jonathan Williamson 2021-01-20 06:00:37 +00:00
commit 4846240daa
25 zmienionych plików z 903 dodań i 31 usunięć

Wyświetl plik

@ -1,4 +1,5 @@
add_subdirectory(pico_display)
add_subdirectory(pico_unicorn)
add_subdirectory(pico_scroll)
add_subdirectory(pico_explorer)
add_subdirectory(pico_explorer)
add_subdirectory(pico_rgb_keypad)

Wyświetl plik

@ -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)

Wyświetl plik

@ -0,0 +1,76 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#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;
}

Wyświetl plik

@ -0,0 +1,64 @@
# This is a copy of <PICO_SDK_PATH>/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})

Wyświetl plik

@ -2,4 +2,5 @@ add_subdirectory(pico_graphics)
add_subdirectory(pico_display)
add_subdirectory(pico_unicorn)
add_subdirectory(pico_scroll)
add_subdirectory(pico_explorer)
add_subdirectory(pico_explorer)
add_subdirectory(pico_rgb_keypad)

Wyświetl plik

@ -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)

Wyświetl plik

@ -0,0 +1,93 @@
#include <string.h>
#include <math.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "hardware/spi.h"
#include "pico_rgb_keypad.hpp"
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, &reg, 1, true);
i2c_read_blocking(i2c0, KEYPAD_ADDRESS, i2c_read_buffer, 2, false);
return ~((i2c_read_buffer[0]) | (i2c_read_buffer[1] << 8));
}
}

Wyświetl plik

@ -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();
};
}

Wyświetl plik

@ -32,13 +32,6 @@ enum reg {
COLOR_OFFSET = 0x24
};
void i2c_write(uint8_t reg, const char *data, uint8_t len) {
uint8_t buffer[256];
buffer[0] = reg;
memcpy(&buffer[1], data, len);
i2c_write_blocking(i2c0, 0x74, buffer, len + 1, true);
}
namespace pimoroni {
void PicoScroll::init() {
@ -65,17 +58,17 @@ namespace pimoroni {
}
void PicoScroll::set_pixel(uint8_t x, uint8_t y, uint8_t v) {
if(x < 0 || x > 16 || y < 0 || y > 6) return;
if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return;
y = 6 - y;
y = (HEIGHT - 1) - y;
if(x > 8) {
x = x - 8;
y = 6 - (y + 8);
y = (HEIGHT - 1) - (y + 8);
}else{
x = 8 - x;
}
uint8_t o = x * 16 + y;
uint8_t o = x * (WIDTH - 1) + y;
__fb[o] = v;
}
@ -84,10 +77,17 @@ namespace pimoroni {
}
void PicoScroll::clear() {
memset(__fb, 0, 144);
memset(__fb, 0, BUFFER_SIZE);
}
void PicoScroll::update() {
i2c_write(COLOR_OFFSET, (const char *)__fb, 144);
i2c_write(COLOR_OFFSET, (const char *)__fb, BUFFER_SIZE);
}
void PicoScroll::i2c_write(uint8_t reg, const char *data, uint8_t len) {
uint8_t buffer[256];
buffer[0] = reg;
memcpy(&buffer[1], data, len);
i2c_write_blocking(i2c0, DEFAULT_ADDRESS, buffer, len + 1, true);
}
}

Wyświetl plik

@ -3,8 +3,20 @@
namespace pimoroni {
class PicoScroll {
uint8_t __fb[144];
private:
static const uint8_t DEFAULT_ADDRESS = 0x74;
static const uint BUFFER_SIZE = 144;
public:
static const int WIDTH = 17;
static const int HEIGHT = 7;
static const uint8_t A = 12;
static const uint8_t B = 13;
static const uint8_t X = 14;
static const uint8_t Y = 15;
private:
uint8_t __fb[BUFFER_SIZE];
public:
void init();
void update();
@ -12,10 +24,8 @@ namespace pimoroni {
void clear();
bool is_pressed(uint8_t button);
static const uint8_t A = 12;
static const uint8_t B = 13;
static const uint8_t X = 14;
static const uint8_t Y = 15;
private:
void i2c_write(uint8_t reg, const char *data, uint8_t len);
};
}

Wyświetl plik

@ -143,7 +143,7 @@ namespace pimoroni {
}
// initialise the bcd timing values and row selects in the bitstream
for(uint8_t row = 0; row < 7; row++) {
for(uint8_t row = 0; row < HEIGHT; row++) {
for(uint8_t frame = 0; frame < BCD_FRAMES; frame++) {
// determine offset in the buffer for this row/frame
uint16_t offset = (row * ROW_BYTES * BCD_FRAMES) + (ROW_BYTES * frame);
@ -198,18 +198,18 @@ namespace pimoroni {
}
void PicoUnicorn::clear() {
for(uint8_t y = 0; y < 7; y++) {
for(uint8_t x = 0; x < 16; x++) {
for(uint8_t y = 0; y < HEIGHT; y++) {
for(uint8_t x = 0; x < WIDTH; x++) {
set_pixel(x, y, 0);
}
}
}
void PicoUnicorn::set_pixel(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) {
if(x < 0 || x > 15 || y < 0 || y > 6) return;
if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return;
// make those coordinates sane
x = 15 - x;
x = (WIDTH - 1) - x;
// work out the byte offset of this pixel
uint8_t byte_offset = x / 2;

Wyświetl plik

@ -5,7 +5,15 @@
namespace pimoroni {
class PicoUnicorn {
uint32_t __fb[16 * 7];
public:
static const int WIDTH = 16;
static const int HEIGHT = 7;
static const uint8_t A = 12;
static const uint8_t B = 13;
static const uint8_t X = 14;
static const uint8_t Y = 15;
private:
uint32_t __fb[WIDTH * HEIGHT];
PIO bitstream_pio = pio0;
uint bitstream_sm = 0;
@ -17,11 +25,6 @@ namespace pimoroni {
void set_pixel(uint8_t x, uint8_t y, uint8_t v);
bool is_pressed(uint8_t button);
static const uint8_t A = 12;
static const uint8_t B = 13;
static const uint8_t X = 14;
static const uint8_t Y = 15;
};
}

Wyświetl plik

@ -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)

Wyświetl plik

@ -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)

Wyświetl plik

@ -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);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -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());
}
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -0,0 +1,12 @@
PICOSCROLL_MOD_DIR := $(USERMOD_DIR)
# Add our source files to the respective variables.
SRC_USERMOD += $(PICOSCROLL_MOD_DIR)/pico_scroll.c
SRC_USERMOD_CXX += $(PICOSCROLL_MOD_DIR)/pico_scroll.cpp
# Add our module directory to the include path.
CFLAGS_USERMOD += -I$(PICOSCROLL_MOD_DIR)
CXXFLAGS_USERMOD += -I$(PICOSCROLL_MOD_DIR)
# We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++

Wyświetl plik

@ -0,0 +1,52 @@
#include "pico_scroll.h"
/***** Constants *****/
enum buttons
{
BUTTON_A = 0,
BUTTON_B,
BUTTON_X,
BUTTON_Y,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// picoscroll Module
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** Module Functions *****/
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_init_obj, picoscroll_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_get_width_obj, picoscroll_get_width);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_get_height_obj, picoscroll_get_height);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_update_obj, picoscroll_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picoscroll_set_pixel_obj, picoscroll_set_pixel);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picoscroll_clear_obj, picoscroll_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picoscroll_is_pressed_obj, picoscroll_is_pressed);
/***** Globals Table *****/
STATIC const mp_map_elem_t picoscroll_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picoscroll) },
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picoscroll_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picoscroll_get_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picoscroll_get_height_obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picoscroll_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pixel), MP_ROM_PTR(&picoscroll_set_pixel_obj) },
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picoscroll_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picoscroll_is_pressed_obj) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(BUTTON_A) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(BUTTON_B) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_INT(BUTTON_X) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_Y), MP_ROM_INT(BUTTON_Y) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_picoscroll_globals, picoscroll_globals_table);
/***** Module Definition *****/
const mp_obj_module_t picoscroll_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_picoscroll_globals,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
MP_REGISTER_MODULE(MP_QSTR_picoscroll, picoscroll_user_cmodule, MODULE_PICOSCROLL_ENABLED);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -0,0 +1,85 @@
#include "hardware/spi.h"
#include "hardware/sync.h"
#include "pico/binary_info.h"
#include "../../../pimoroni-pico/libraries/pico_scroll/pico_scroll.hpp"
using namespace pimoroni;
PicoScroll scroll;
extern "C" {
#include "pico_scroll.h"
mp_obj_t picoscroll_init() {
scroll.init();
return mp_const_none;
}
mp_obj_t picoscroll_get_width() {
return mp_obj_new_int(PicoScroll::WIDTH);
}
mp_obj_t picoscroll_get_height() {
return mp_obj_new_int(PicoScroll::HEIGHT);
}
mp_obj_t picoscroll_update() {
scroll.update();
return mp_const_none;
}
mp_obj_t picoscroll_set_pixel(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t v_obj) {
int x = mp_obj_get_int(x_obj);
int y = mp_obj_get_int(y_obj);
int val = mp_obj_get_int(v_obj);
if(x < 0 || x >= PicoScroll::WIDTH || y < 0 || y >= PicoScroll::HEIGHT)
mp_raise_ValueError("x or y out of range.");
else
{
if(val < 0 || val > 255)
mp_raise_ValueError("val out of range. Expected 0 to 255");
else
scroll.set_pixel(x, y, val);
}
return mp_const_none;
}
mp_obj_t picoscroll_clear() {
scroll.clear();
return mp_const_none;
}
mp_obj_t picoscroll_is_pressed(mp_obj_t button_obj) {
int buttonID = mp_obj_get_int(button_obj);
bool buttonPressed = false;
switch(buttonID)
{
case 0:
buttonPressed = scroll.is_pressed(PicoScroll::A);
break;
case 1:
buttonPressed = scroll.is_pressed(PicoScroll::B);
break;
case 2:
buttonPressed = scroll.is_pressed(PicoScroll::X);
break;
case 3:
buttonPressed = scroll.is_pressed(PicoScroll::Y);
break;
default:
mp_raise_ValueError("button not valid. Expected 0 to 3");
break;
}
return buttonPressed ? mp_const_true : mp_const_false;
}
}

Wyświetl plik

@ -0,0 +1,11 @@
// Include MicroPython API.
#include "py/runtime.h"
// Declare the functions we'll make available in Python
extern mp_obj_t picoscroll_init();
extern mp_obj_t picoscroll_get_width();
extern mp_obj_t picoscroll_get_height();
extern mp_obj_t picoscroll_update();
extern mp_obj_t picoscroll_set_pixel(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t v_obj);
extern mp_obj_t picoscroll_clear();
extern mp_obj_t picoscroll_is_pressed(mp_obj_t button_obj);

Wyświetl plik

@ -0,0 +1,12 @@
PICOUNICORN_MOD_DIR := $(USERMOD_DIR)
# Add our source files to the respective variables.
SRC_USERMOD += $(PICOUNICORN_MOD_DIR)/pico_unicorn.c
SRC_USERMOD_CXX += $(PICOUNICORN_MOD_DIR)/pico_unicorn.cpp
# Add our module directory to the include path.
CFLAGS_USERMOD += -I$(PICOUNICORN_MOD_DIR)
CXXFLAGS_USERMOD += -I$(PICOUNICORN_MOD_DIR)
# We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++

Wyświetl plik

@ -0,0 +1,55 @@
#include "pico_unicorn.h"
/***** Constants *****/
enum buttons
{
BUTTON_A = 0,
BUTTON_B,
BUTTON_X,
BUTTON_Y,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// picounicorn Module
////////////////////////////////////////////////////////////////////////////////////////////////////
/***** Module Functions *****/
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picounicorn_init_obj, picounicorn_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picounicorn_get_width_obj, picounicorn_get_width);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picounicorn_get_height_obj, picounicorn_get_height);
//STATIC MP_DEFINE_CONST_FUN_OBJ_0(picounicorn_update_obj, picounicorn_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(picounicorn_set_pixel_obj, 5, 5, picounicorn_set_pixel);
STATIC MP_DEFINE_CONST_FUN_OBJ_3(picounicorn_set_pixel_value_obj, picounicorn_set_pixel_value);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(picounicorn_clear_obj, picounicorn_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(picounicorn_is_pressed_obj, picounicorn_is_pressed);
/***** Globals Table *****/
STATIC const mp_rom_map_elem_t picounicorn_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_picounicorn) },
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&picounicorn_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_width), MP_ROM_PTR(&picounicorn_get_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_height), MP_ROM_PTR(&picounicorn_get_height_obj) },
//{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&picounicorn_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pixel), MP_ROM_PTR(&picounicorn_set_pixel_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pixel_value), MP_ROM_PTR(&picounicorn_set_pixel_value_obj) },
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&picounicorn_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_is_pressed), MP_ROM_PTR(&picounicorn_is_pressed_obj) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_INT(BUTTON_A) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_INT(BUTTON_B) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_INT(BUTTON_X) },
{ MP_ROM_QSTR(MP_QSTR_BUTTON_Y), MP_ROM_INT(BUTTON_Y) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_picounicorn_globals, picounicorn_globals_table);
/***** Module Definition *****/
const mp_obj_module_t picounicorn_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_picounicorn_globals,
};
////////////////////////////////////////////////////////////////////////////////////////////////////
MP_REGISTER_MODULE(MP_QSTR_picounicorn, picounicorn_user_cmodule, MODULE_PICOUNICORN_ENABLED);
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -0,0 +1,111 @@
#include "hardware/spi.h"
#include "hardware/sync.h"
#include "pico/binary_info.h"
#include "../../../pimoroni-pico/libraries/pico_unicorn/pico_unicorn.hpp"
using namespace pimoroni;
PicoUnicorn unicorn;
extern "C" {
#include "pico_unicorn.h"
mp_obj_t picounicorn_init() {
unicorn.init();
return mp_const_none;
}
mp_obj_t picounicorn_get_width() {
return mp_obj_new_int(PicoUnicorn::WIDTH);
}
mp_obj_t picounicorn_get_height() {
return mp_obj_new_int(PicoUnicorn::HEIGHT);
}
// mp_obj_t picounicorn_update() {
// unicorn.update();
// return mp_const_none;
// }
mp_obj_t picounicorn_set_pixel(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 >= PicoUnicorn::WIDTH || y < 0 || y >= PicoUnicorn::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
unicorn.set_pixel(x, y, r, g, b);
}
return mp_const_none;
}
mp_obj_t picounicorn_set_pixel_value(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t v_obj) {
int x = mp_obj_get_int(x_obj);
int y = mp_obj_get_int(y_obj);
int val = mp_obj_get_int(v_obj);
if(x < 0 || x >= PicoUnicorn::WIDTH || y < 0 || y >= PicoUnicorn::HEIGHT)
mp_raise_ValueError("x or y out of range.");
else
{
if(val < 0 || val > 255)
mp_raise_ValueError("val out of range. Expected 0 to 255");
else
unicorn.set_pixel(x, y, val);
}
return mp_const_none;
}
mp_obj_t picounicorn_clear() {
unicorn.clear();
return mp_const_none;
}
mp_obj_t picounicorn_is_pressed(mp_obj_t button_obj) {
int buttonID = mp_obj_get_int(button_obj);
bool buttonPressed = false;
switch(buttonID)
{
case 0:
buttonPressed = unicorn.is_pressed(PicoUnicorn::A);
break;
case 1:
buttonPressed = unicorn.is_pressed(PicoUnicorn::B);
break;
case 2:
buttonPressed = unicorn.is_pressed(PicoUnicorn::X);
break;
case 3:
buttonPressed = unicorn.is_pressed(PicoUnicorn::Y);
break;
default:
mp_raise_ValueError("button not valid. Expected 0 to 3");
break;
}
return buttonPressed ? mp_const_true : mp_const_false;
}
}

Wyświetl plik

@ -0,0 +1,13 @@
// Include MicroPython API.
//#include "py/obj.h"
#include "py/runtime.h"
// Declare the functions we'll make available in Python
extern mp_obj_t picounicorn_init();
extern mp_obj_t picounicorn_get_width();
extern mp_obj_t picounicorn_get_height();
//extern mp_obj_t picounicorn_update();
extern mp_obj_t picounicorn_set_pixel(mp_uint_t n_args, const mp_obj_t *args);
extern mp_obj_t picounicorn_set_pixel_value(mp_obj_t x_obj, mp_obj_t y_obj, mp_obj_t v_obj);
extern mp_obj_t picounicorn_clear();
extern mp_obj_t picounicorn_is_pressed(mp_obj_t button_obj);