pico scroll library and example
This commit is contained in:
parent
97706e86df
commit
447eca6bb3
|
@ -1,2 +1,3 @@
|
|||
add_subdirectory(pico_display)
|
||||
add_subdirectory(pico_unicorn)
|
||||
add_subdirectory(pico_scroll)
|
|
@ -0,0 +1,10 @@
|
|||
add_executable(
|
||||
scroll
|
||||
demo.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(scroll pico_stdlib pico_scroll)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(scroll)
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
#include "pico_scroll.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
PicoScroll pico_scroll;
|
||||
|
||||
int main() {
|
||||
|
||||
pico_scroll.init();
|
||||
|
||||
uint32_t i = 0;
|
||||
while(true) {
|
||||
i++;
|
||||
|
||||
pico_scroll.clear();
|
||||
|
||||
for(int y = 0; y < 7; y++) {
|
||||
for(int x = 0; x < 17; x++) {
|
||||
int v = (x + y + (i / 250)) % 2 == 0 ? 0 : 3;
|
||||
pico_scroll.set_pixel(x, y, v);
|
||||
}
|
||||
}
|
||||
|
||||
pico_scroll.update();
|
||||
|
||||
sleep_ms(100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(pico_graphics)
|
||||
add_subdirectory(pico_display)
|
||||
add_subdirectory(pico_unicorn)
|
||||
add_subdirectory(pico_scroll)
|
|
@ -0,0 +1,10 @@
|
|||
add_library(pico_scroll INTERFACE)
|
||||
|
||||
target_sources(pico_scroll INTERFACE
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico_scroll.cpp
|
||||
)
|
||||
|
||||
target_include_directories(pico_scroll INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(pico_scroll INTERFACE pico_stdlib hardware_i2c)
|
|
@ -0,0 +1,93 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/i2c.h"
|
||||
|
||||
#include "pico_scroll.hpp"
|
||||
|
||||
enum pin {
|
||||
SDA = 4,
|
||||
SCL = 5,
|
||||
A = 12,
|
||||
B = 13,
|
||||
X = 14,
|
||||
Y = 15,
|
||||
};
|
||||
|
||||
enum reg {
|
||||
MODE_REGISTER = 0x00,
|
||||
FRAME_REGISTER = 0x01,
|
||||
AUTOPLAY1_REGISTER = 0x02,
|
||||
AUTOPLAY2_REGISTER = 0x03,
|
||||
BLINK_REGISTER = 0x05,
|
||||
AUDIOSYNC_REGISTER = 0x06,
|
||||
BREATH1_REGISTER = 0x08,
|
||||
BREATH2_REGISTER = 0x09,
|
||||
SHUTDOWN_REGISTER = 0x0a,
|
||||
GAIN_REGISTER = 0x0b,
|
||||
ADC_REGISTER = 0x0c,
|
||||
ENABLE_OFFSET = 0x00,
|
||||
BANK_ADDRESS = 0xfd,
|
||||
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() {
|
||||
// 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);
|
||||
|
||||
i2c_write(reg::BANK_ADDRESS, "\x0b", 1);
|
||||
i2c_write(reg::MODE_REGISTER, "\x00", 1);
|
||||
i2c_write(reg::AUDIOSYNC_REGISTER, "\x00", 1);
|
||||
i2c_write(reg::SHUTDOWN_REGISTER, "\x01", 1);
|
||||
i2c_write(reg::BANK_ADDRESS, "\x0b", 1);
|
||||
i2c_write(reg::FRAME_REGISTER, "\x00", 1);
|
||||
i2c_write(reg::BANK_ADDRESS, "\x00", 1);
|
||||
i2c_write(reg::ENABLE_OFFSET, "\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x7f\x00", 18);
|
||||
|
||||
// setup button inputs
|
||||
gpio_set_function(pin::A, GPIO_FUNC_SIO); gpio_set_dir(pin::A, GPIO_IN); gpio_pull_up(pin::A);
|
||||
gpio_set_function(pin::B, GPIO_FUNC_SIO); gpio_set_dir(pin::B, GPIO_IN); gpio_pull_up(pin::B);
|
||||
gpio_set_function(pin::X, GPIO_FUNC_SIO); gpio_set_dir(pin::X, GPIO_IN); gpio_pull_up(pin::X);
|
||||
gpio_set_function(pin::Y, GPIO_FUNC_SIO); gpio_set_dir(pin::Y, GPIO_IN); gpio_pull_up(pin::Y);
|
||||
}
|
||||
|
||||
void PicoScroll::set_pixel(uint8_t x, uint8_t y, uint8_t v) {
|
||||
if(x < 0 || x > 16 || y < 0 || y > 6) return;
|
||||
|
||||
y = 6 - y;
|
||||
if(x > 8) {
|
||||
x = x - 8;
|
||||
y = 6 - (y + 8);
|
||||
}else{
|
||||
x = 8 - x;
|
||||
}
|
||||
|
||||
uint8_t o = x * 16 + y;
|
||||
__fb[o] = v;
|
||||
}
|
||||
|
||||
bool PicoScroll::is_pressed(uint8_t button) {
|
||||
return !gpio_get(button);
|
||||
}
|
||||
|
||||
void PicoScroll::clear() {
|
||||
memset(__fb, 0, 144);
|
||||
}
|
||||
|
||||
void PicoScroll::update() {
|
||||
i2c_write(COLOR_OFFSET, (const char *)__fb, 144);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
class PicoScroll {
|
||||
uint8_t __fb[144];
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update();
|
||||
void set_pixel(uint8_t x, uint8_t y, uint8_t v);
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue