Compare commits

...

11 Commits

Author SHA1 Message Date
Philip Howard 2a8be11945
Merge 88bd71e56f into 32c10482d9 2024-04-19 11:28:20 +00:00
Phil Howard 88bd71e56f TEST: PicoVector: Break things until they work. 2024-04-19 12:28:11 +01:00
Connor Linfoot 32c10482d9
Add support for 96x48 display to Interstate75 (#867)
* Add DISPLAY_INTERSTATE75_96X48
2024-04-17 13:41:02 +01:00
Philip Howard 4c44b77193
Merge pull request #912 from pimoroni/patch-picodisplay-180
PicoDisplay: Fix misalignment on rotated Pico Displays (fixes #562.)
2024-04-17 12:54:18 +01:00
Phil Howard 5510c82564 PicoDisplay: Fix rotation offset for #562.
Pico Display would have a pixel offset at 90 and 180 degree rotations.

Add a special case offset tweak for these, and demystify the rotate_180 variable.
2024-04-17 12:44:40 +01:00
Philip Howard 3a10b29f54
Merge pull request #920 from pimoroni/patch-inky7-update-timeout
inky73: Add busy wait timeout.
2024-04-17 12:42:53 +01:00
Phil Howard 8cf276b992 inky73: Add busy wait timeout.
Add a timeout to fix Inky 7.3" hanging on batteries.

Basically assumes the update has finished if it takes > 45s, and allows a subsequent attempt
rather than hanging indefinitely.

Raised, texted and fixed by w3stbam: https://github.com/pimoroni/pimoroni-pico/pull/900

Rewritten as mentioned in the PR.
2024-04-17 12:33:24 +01:00
Philip Howard f1ea35fbbf
Merge pull request #911 from pimoroni/patch-unicorn-brightness
G/S/C Unicorn: Fix get_brightness to use correct max value.
2024-04-11 17:45:48 +01:00
Philip Howard c066325ca0
Merge pull request #909 from pimoroni/patch-ltr559-interrupt
LTR559: Add interrupt.py demo from #169.
2024-04-11 17:41:58 +01:00
Phil Howard 964cf5eedf G/S/C Unicorn: Fix get_brightness to use correct max value.
Add a comment noting that 256 is the correct maximum brightness.
2024-03-11 21:14:43 +00:00
Phil Howard 5dd76ed31b LTR559: Add interrupt.py demo from #169. 2024-03-11 13:38:07 +00:00
18 changed files with 183 additions and 60 deletions

View File

@ -47,8 +47,9 @@ namespace pimoroni {
return !(sr.read() & 128); return !(sr.read() & 128);
} }
void Inky73::busy_wait() { void Inky73::busy_wait(uint timeout_ms) {
while(is_busy()) { absolute_time_t timeout = make_timeout_time_ms(timeout_ms);
while(is_busy() && !time_reached(timeout)) {
tight_loop_contents(); tight_loop_contents();
} }
} }

View File

@ -70,7 +70,7 @@ namespace pimoroni {
// Methods // Methods
//-------------------------------------------------- //--------------------------------------------------
public: public:
void busy_wait(); void busy_wait(uint timeout_ms=45000);
void reset(); void reset();
void power_off(); void power_off();

View File

@ -133,8 +133,6 @@ namespace pimoroni {
void ST7789::configure_display(Rotation rotate) { void ST7789::configure_display(Rotation rotate) {
bool rotate180 = rotate == ROTATE_180 || rotate == ROTATE_90;
if(rotate == ROTATE_90 || rotate == ROTATE_270) { if(rotate == ROTATE_90 || rotate == ROTATE_270) {
std::swap(width, height); std::swap(width, height);
} }
@ -185,20 +183,30 @@ namespace pimoroni {
// Pico Display // Pico Display
if(width == 240 && height == 135) { if(width == 240 && height == 135) {
caset[0] = 40; // 240 cols caset[0] = 40; // 240 cols
caset[1] = 279; caset[1] = 40 + width - 1;
raset[0] = 53; // 135 rows raset[0] = 52; // 135 rows
raset[1] = 187; raset[1] = 52 + height - 1;
madctl = rotate180 ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER; if (rotate == ROTATE_0) {
raset[0] += 1;
raset[1] += 1;
}
madctl = rotate == ROTATE_180 ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER;
madctl |= MADCTL::SWAP_XY | MADCTL::SCAN_ORDER; madctl |= MADCTL::SWAP_XY | MADCTL::SCAN_ORDER;
} }
// Pico Display at 90 degree rotation // Pico Display at 90 degree rotation
if(width == 135 && height == 240) { if(width == 135 && height == 240) {
caset[0] = 52; // 135 cols caset[0] = 52; // 135 cols
caset[1] = 186; caset[1] = 52 + width - 1;
raset[0] = 40; // 240 rows raset[0] = 40; // 240 rows
raset[1] = 279; raset[1] = 40 + height - 1;
madctl = rotate180 ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0; madctl = 0;
if (rotate == ROTATE_90) {
caset[0] += 1;
caset[1] += 1;
madctl = MADCTL::COL_ORDER | MADCTL::ROW_ORDER;
}
madctl = rotate == ROTATE_90 ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0;
} }
// Pico Display 2.0 // Pico Display 2.0
@ -207,7 +215,7 @@ namespace pimoroni {
caset[1] = 319; caset[1] = 319;
raset[0] = 0; raset[0] = 0;
raset[1] = 239; raset[1] = 239;
madctl = rotate180 ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER; madctl = (rotate == ROTATE_180 || rotate == ROTATE_90) ? MADCTL::ROW_ORDER : MADCTL::COL_ORDER;
madctl |= MADCTL::SWAP_XY | MADCTL::SCAN_ORDER; madctl |= MADCTL::SWAP_XY | MADCTL::SCAN_ORDER;
} }
@ -217,7 +225,7 @@ namespace pimoroni {
caset[1] = 239; caset[1] = 239;
raset[0] = 0; raset[0] = 0;
raset[1] = 319; raset[1] = 319;
madctl = rotate180 ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0; madctl = (rotate == ROTATE_180 || rotate == ROTATE_90) ? (MADCTL::COL_ORDER | MADCTL::ROW_ORDER) : 0;
} }
// Byte swap the 16bit rows/cols values // Byte swap the 16bit rows/cols values

View File

@ -494,11 +494,14 @@ namespace pimoroni {
void CosmicUnicorn::set_brightness(float value) { void CosmicUnicorn::set_brightness(float value) {
value = value < 0.0f ? 0.0f : value; value = value < 0.0f ? 0.0f : value;
value = value > 1.0f ? 1.0f : value; value = value > 1.0f ? 1.0f : value;
// Max brightness is - in fact - 256 since it's applied with:
// result = (channel * brightness) >> 8
// eg: (255 * 256) >> 8 == 255
this->brightness = floor(value * 256.0f); this->brightness = floor(value * 256.0f);
} }
float CosmicUnicorn::get_brightness() { float CosmicUnicorn::get_brightness() {
return this->brightness / 255.0f; return this->brightness / 256.0f;
} }
void CosmicUnicorn::adjust_brightness(float delta) { void CosmicUnicorn::adjust_brightness(float delta) {

View File

@ -488,11 +488,14 @@ namespace pimoroni {
void GalacticUnicorn::set_brightness(float value) { void GalacticUnicorn::set_brightness(float value) {
value = value < 0.0f ? 0.0f : value; value = value < 0.0f ? 0.0f : value;
value = value > 1.0f ? 1.0f : value; value = value > 1.0f ? 1.0f : value;
// Max brightness is - in fact - 256 since it's applied with:
// result = (channel * brightness) >> 8
// eg: (255 * 256) >> 8 == 255
this->brightness = floor(value * 256.0f); this->brightness = floor(value * 256.0f);
} }
float GalacticUnicorn::get_brightness() { float GalacticUnicorn::get_brightness() {
return this->brightness / 255.0f; return this->brightness / 256.0f;
} }
void GalacticUnicorn::adjust_brightness(float delta) { void GalacticUnicorn::adjust_brightness(float delta) {

View File

@ -2,4 +2,5 @@ extern "C" {
void *af_malloc(size_t size); void *af_malloc(size_t size);
void *af_realloc(void *p, size_t size); void *af_realloc(void *p, size_t size);
void af_free(void *p); void af_free(void *p);
void af_debug(const char *fmt, ...);
} }

View File

@ -52,6 +52,10 @@
#define AF_FGETC(stream) fgetc(stream) #define AF_FGETC(stream) fgetc(stream)
#endif #endif
#ifndef AF_DEBUG
#define AF_DEBUG(...)
#endif
#include "pretty-poly.h" #include "pretty-poly.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -99,9 +103,9 @@ typedef struct {
} af_text_metrics_t; } af_text_metrics_t;
bool af_load_font_file(AF_FILE file, af_face_t *face); bool af_load_font_file(AF_FILE file, af_face_t *face);
void af_render_character(af_face_t *face, wchar_t codepoint, af_text_metrics_t *tm); void af_render_character(af_face_t *face, const char codepoint, af_text_metrics_t *tm);
void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm); void af_render(af_face_t *face, const char *text, af_text_metrics_t *tm);
pp_rect_t af_measure(af_face_t *face, const wchar_t *text, af_text_metrics_t *tm); pp_rect_t af_measure(af_face_t *face, const char *text, af_text_metrics_t *tm);
#ifdef AF_USE_PRETTY_POLY #ifdef AF_USE_PRETTY_POLY
#endif #endif
@ -146,6 +150,11 @@ bool af_load_font_file(AF_FILE file, af_face_t *face) {
void *buffer = AF_MALLOC(sizeof(af_glyph_t) * glyph_count + \ void *buffer = AF_MALLOC(sizeof(af_glyph_t) * glyph_count + \
sizeof( af_path_t) * path_count + \ sizeof( af_path_t) * path_count + \
sizeof(af_point_t) * point_count); sizeof(af_point_t) * point_count);
if(!buffer) {
return false; // failed memory allocation
}
af_glyph_t *glyphs = (af_glyph_t *) buffer; af_glyph_t *glyphs = (af_glyph_t *) buffer;
af_path_t *paths = ( af_path_t *)(glyphs + (sizeof(af_glyph_t) * glyph_count)); af_path_t *paths = ( af_path_t *)(glyphs + (sizeof(af_glyph_t) * glyph_count));
af_point_t *points = (af_point_t *)( paths + (sizeof( af_path_t) * path_count)); af_point_t *points = (af_point_t *)( paths + (sizeof( af_path_t) * path_count));
@ -193,7 +202,7 @@ bool af_load_font_file(AF_FILE file, af_face_t *face) {
return true; return true;
} }
af_glyph_t *find_glyph(af_face_t *face, wchar_t c) { af_glyph_t *find_glyph(af_face_t *face, char c) {
for(int i = 0; i < face->glyph_count; i++) { for(int i = 0; i < face->glyph_count; i++) {
if(face->glyphs[i].codepoint == c) { if(face->glyphs[i].codepoint == c) {
return &face->glyphs[i]; return &face->glyphs[i];
@ -223,12 +232,12 @@ void af_render_glyph(af_glyph_t* glyph, af_text_metrics_t *tm) {
for(uint32_t i = 0; i < poly.count; i++) { for(uint32_t i = 0; i < poly.count; i++) {
pp_path_t *path = &poly.paths[i]; pp_path_t *path = &poly.paths[i];
free(path->points); AF_FREE(path->points);
} }
free(poly.paths); AF_FREE(poly.paths);
} }
void af_render_character(af_face_t *face, wchar_t c, af_text_metrics_t *tm) { void af_render_character(af_face_t *face, const char c, af_text_metrics_t *tm) {
af_glyph_t *glyph = find_glyph(face, c); af_glyph_t *glyph = find_glyph(face, c);
if(!glyph) { if(!glyph) {
return; return;
@ -236,10 +245,10 @@ void af_render_character(af_face_t *face, wchar_t c, af_text_metrics_t *tm) {
af_render_glyph(glyph, tm); af_render_glyph(glyph, tm);
} }
int get_line_width(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) { int get_line_width(af_face_t *face, const char *text, af_text_metrics_t *tm) {
int line_width = 0; int line_width = 0;
wchar_t *end = wcschr(text, L'\n'); char *end = strchr(text, '\n');
for(wchar_t c = *text; text < end; text++, c = *text) { for(char c = *text; text < end; text++, c = *text) {
af_glyph_t *glyph = find_glyph(face, c); af_glyph_t *glyph = find_glyph(face, c);
if(!glyph) { if(!glyph) {
continue; continue;
@ -254,22 +263,22 @@ int get_line_width(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
return line_width; return line_width;
} }
int get_max_line_width(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) { int get_max_line_width(af_face_t *face, const char *text, af_text_metrics_t *tm) {
int max_width = 0; int max_width = 0;
wchar_t *end = wcschr(text, L'\n'); char *end = strchr(text, '\n');
while(end) { while(end) {
int width = get_line_width(face, text, tm); int width = get_line_width(face, text, tm);
max_width = max_width < width ? width : max_width; max_width = max_width < width ? width : max_width;
text = end + 1; text = end + 1;
end = wcschr(text, L'\n'); end = strchr(text, '\n');
} }
return max_width; return max_width;
} }
void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) { void af_render(af_face_t *face, const char *text, af_text_metrics_t *tm) {
pp_mat3_t *old = pp_transform(NULL); pp_mat3_t *old = pp_transform(NULL);
float line_height = (tm->line_height * 128.0f) / 100.0f; float line_height = (tm->line_height * 128.0f) / 100.0f;
@ -285,11 +294,11 @@ void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
caret.x = 0; caret.x = 0;
caret.y = 0; caret.y = 0;
wchar_t *end = wcschr(text, L'\n'); char *end = strchr(text, '\n');
while(end) { while(end) {
int line_width = get_line_width(face, text, tm); int line_width = get_line_width(face, text, tm);
for(wchar_t c = *text; text < end; text++, c = *text) { for(char c = *text; text < end; text++, c = *text) {
af_glyph_t *glyph = find_glyph(face, c); af_glyph_t *glyph = find_glyph(face, c);
if(!glyph) { if(!glyph) {
continue; continue;
@ -320,7 +329,7 @@ void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
} }
text = end + 1; text = end + 1;
end = wcschr(text, L'\n'); end = strchr(text, '\n');
caret.x = 0; caret.x = 0;
caret.y += line_height; caret.y += line_height;
@ -331,12 +340,12 @@ void af_render(af_face_t *face, wchar_t *text, af_text_metrics_t *tm) {
pp_transform(old); pp_transform(old);
} }
pp_rect_t af_measure(af_face_t *face, const wchar_t *text, af_text_metrics_t *tm) { pp_rect_t af_measure(af_face_t *face, const char *text, af_text_metrics_t *tm) {
pp_rect_t result; pp_rect_t result;
bool first = true; bool first = true;
pp_mat3_t t = *tm->transform; pp_mat3_t t = *tm->transform;
for(size_t i = 0; i < wcslen(text); i++) { for(size_t i = 0; i < strlen(text); i++) {
af_glyph_t *glyph = find_glyph(face, text[i]); af_glyph_t *glyph = find_glyph(face, text[i]);
if(!glyph) { if(!glyph) {
continue; continue;

View File

@ -56,9 +56,15 @@ namespace pimoroni {
} }
} }
pp_point_t PicoVector::text(std::wstring_view text, pp_point_t offset, pp_mat3_t *t) { pp_point_t PicoVector::text(std::string_view text, pp_mat3_t *t) {
pp_point_t caret = {0, 0}; pp_point_t caret = {0, 0};
text_metrics.transform = t;
af_render(text_metrics.face, text.data(), &text_metrics);
return caret;
/*
// Align text from the bottom left // Align text from the bottom left
caret.y += (PP_COORD_TYPE)text_metrics.line_height; caret.y += (PP_COORD_TYPE)text_metrics.line_height;
@ -69,7 +75,7 @@ namespace pimoroni {
pp_point_t space; pp_point_t space;
pp_point_t carriage_return = {0, -(PP_COORD_TYPE)text_metrics.line_height}; pp_point_t carriage_return = {0, -(PP_COORD_TYPE)text_metrics.line_height};
wchar_t spc = L' '; char spc = ' ';
space.x = af_measure(text_metrics.face, &spc, &text_metrics).w; space.x = af_measure(text_metrics.face, &spc, &text_metrics).w;
if (space.x == 0) { if (space.x == 0) {
@ -110,10 +116,10 @@ namespace pimoroni {
} }
for(size_t j = i; j < std::min(next_break + 1, text.length()); j++) { for(size_t j = i; j < std::min(next_break + 1, text.length()); j++) {
if (text[j] == L'\n') { // Linebreak if (text[j] == '\n') { // Linebreak
caret = pp_point_sub(&caret, &carriage_return); caret = pp_point_sub(&caret, &carriage_return);
carriage_return = initial_carriage_return; carriage_return = initial_carriage_return;
} else if (text[j] == L' ') { // Space } else if (text[j] == ' ') { // Space
caret = pp_point_add(&caret, &space); caret = pp_point_add(&caret, &space);
carriage_return = pp_point_add(&carriage_return, &space); carriage_return = pp_point_add(&carriage_return, &space);
} else { } else {
@ -125,7 +131,7 @@ namespace pimoroni {
af_render_character(text_metrics.face, text[j], &text_metrics); af_render_character(text_metrics.face, text[j], &text_metrics);
} }
pp_point_t advance = { pp_point_t advance = {
(PP_COORD_TYPE)af_measure(text_metrics.face, (const wchar_t *)text[j], &text_metrics).w + text_metrics.letter_spacing, (PP_COORD_TYPE)af_measure(text_metrics.face, &text[j], &text_metrics).w + text_metrics.letter_spacing,
(PP_COORD_TYPE)0 (PP_COORD_TYPE)0
}; };
advance = pp_point_transform(&advance, t); advance = pp_point_transform(&advance, t);
@ -137,5 +143,6 @@ namespace pimoroni {
} }
return {caret.x, caret.y}; return {caret.x, caret.y};
*/
} }
} }

View File

@ -14,6 +14,8 @@
#define PP_REALLOC(p, size) af_realloc(p, size) #define PP_REALLOC(p, size) af_realloc(p, size)
#define PP_FREE(p) af_free(p) #define PP_FREE(p) af_free(p)
#define AF_DEBUG(...) af_debug(__VA_ARGS__)
#include "pretty-poly.h" #include "pretty-poly.h"
#include "alright-fonts.h" #include "alright-fonts.h"
#include "pico_graphics.hpp" #include "pico_graphics.hpp"
@ -40,6 +42,15 @@ namespace pimoroni {
pp_antialias(graphics->supports_alpha_blend() ? PP_AA_X4 : PP_AA_NONE); pp_antialias(graphics->supports_alpha_blend() ? PP_AA_X4 : PP_AA_NONE);
pp_clip(graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h); pp_clip(graphics->clip.x, graphics->clip.y, graphics->clip.w, graphics->clip.h);
text_metrics.align = AF_H_ALIGN_LEFT;
text_metrics.line_height = 110;
text_metrics.letter_spacing = 95;
text_metrics.word_spacing = 200;
text_metrics.size = 48;
// Shoud be set before rendering chars
//text_metrics.transform = (pp_mat3_t *)af_malloc(sizeof(pp_mat3_t));
//*text_metrics.transform = pp_mat3_identity();
} }
static void tile_callback(const pp_tile_t *tile) { static void tile_callback(const pp_tile_t *tile) {
@ -86,17 +97,21 @@ namespace pimoroni {
} }
bool set_font(std::string_view font_path, unsigned int font_size) { bool set_font(std::string_view font_path, unsigned int font_size) {
if(text_metrics.face) {
af_free(text_metrics.face->glyphs);
af_free(text_metrics.face);
}
text_metrics.face = (af_face_t *)af_malloc(sizeof(af_face_t));
//bool result = text_metrics.face.load(font_path); //bool result = text_metrics.face.load(font_path);
void* font = fileio_open(font_path.data()); void* font = fileio_open(font_path.data());
af_load_font_file(font, text_metrics.face); bool result = af_load_font_file(font, text_metrics.face);
bool result = false;
set_font_size(font_size); set_font_size(font_size);
return result; return result;
} }
pp_point_t text(std::wstring_view text, pp_point_t origin, pp_mat3_t *t); pp_point_t text(std::string_view text, pp_mat3_t *t);
void transform(pp_path_t *path, pp_mat3_t *t); void transform(pp_path_t *path, pp_mat3_t *t);
void transform(pp_poly_t *poly, pp_mat3_t *t); void transform(pp_poly_t *poly, pp_mat3_t *t);

View File

@ -485,11 +485,14 @@ namespace pimoroni {
void StellarUnicorn::set_brightness(float value) { void StellarUnicorn::set_brightness(float value) {
value = value < 0.0f ? 0.0f : value; value = value < 0.0f ? 0.0f : value;
value = value > 1.0f ? 1.0f : value; value = value > 1.0f ? 1.0f : value;
// Max brightness is - in fact - 256 since it's applied with:
// result = (channel * brightness) >> 8
// eg: (255 * 256) >> 8 == 255
this->brightness = floor(value * 256.0f); this->brightness = floor(value * 256.0f);
} }
float StellarUnicorn::get_brightness() { float StellarUnicorn::get_brightness() {
return this->brightness / 255.0f; return this->brightness / 256.0f;
} }
void StellarUnicorn::adjust_brightness(float delta) { void StellarUnicorn::adjust_brightness(float delta) {

View File

@ -0,0 +1,30 @@
import time
from machine import Pin
from pimoroni_i2c import PimoroniI2C
from breakout_ltr559 import BreakoutLTR559
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}
PIN_INTERRUPT = 22 # 3 for Breakout Garden
i2c = PimoroniI2C(**PINS_PICO_EXPLORER)
ltr = BreakoutLTR559(i2c, interrupt=PIN_INTERRUPT)
interrupt = Pin(PIN_INTERRUPT, Pin.IN, Pin.PULL_DOWN)
ltr.light_threshold(0, 10) # COUNTS, NOT LUX!!!
ltr.proximity_threshold(0, 10)
def read(pin):
reading = ltr.get_reading()
if reading is not None:
print("T: ", time.ticks_ms(), " Lux: ", reading[BreakoutLTR559.LUX], " Prox: ", reading[BreakoutLTR559.PROXIMITY])
interrupt.irq(trigger=Pin.IRQ_RISING, handler=read)
part_id = ltr.part_id()
print("Found LTR559. Part ID: 0x", '{:02x}'.format(part_id), sep="")
while True:
pass

View File

@ -84,6 +84,7 @@ The available display settings are listed here:
* 32 x 32 Matrix - `DISPLAY_INTERSTATE75_32X32` * 32 x 32 Matrix - `DISPLAY_INTERSTATE75_32X32`
* 64 x 32 Matrix - `DISPLAY_INTERSTATE75_64X32` * 64 x 32 Matrix - `DISPLAY_INTERSTATE75_64X32`
* 96 x 32 Matrix - `DISPLAY_INTERSTATE75_96X32` * 96 x 32 Matrix - `DISPLAY_INTERSTATE75_96X32`
* 96 x 48 Matrix - `DISPLAY_INTERSTATE75_96X48`
* 128 x 32 Matrix - `DISPLAY_INTERSTATE75_128X32` * 128 x 32 Matrix - `DISPLAY_INTERSTATE75_128X32`
* 64 x 64 Matrix - `DISPLAY_INTERSTATE75_64X64` * 64 x 64 Matrix - `DISPLAY_INTERSTATE75_64X64`
* 128 x 64 Matrix - `DISPLAY_INTERSTATE75_128X64` * 128 x 64 Matrix - `DISPLAY_INTERSTATE75_128X64`

View File

@ -145,6 +145,7 @@ STATIC const mp_map_elem_t picographics_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_32X32), MP_ROM_INT(DISPLAY_INTERSTATE75_32X32) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_32X32), MP_ROM_INT(DISPLAY_INTERSTATE75_32X32) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_64X32), MP_ROM_INT(DISPLAY_INTERSTATE75_64X32) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_64X32), MP_ROM_INT(DISPLAY_INTERSTATE75_64X32) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_96X32), MP_ROM_INT(DISPLAY_INTERSTATE75_96X32) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_96X32), MP_ROM_INT(DISPLAY_INTERSTATE75_96X32) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_96X48), MP_ROM_INT(DISPLAY_INTERSTATE75_96X48) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_128X32), MP_ROM_INT(DISPLAY_INTERSTATE75_128X32) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_128X32), MP_ROM_INT(DISPLAY_INTERSTATE75_128X32) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_64X64), MP_ROM_INT(DISPLAY_INTERSTATE75_64X64) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_64X64), MP_ROM_INT(DISPLAY_INTERSTATE75_64X64) },
{ MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_128X64), MP_ROM_INT(DISPLAY_INTERSTATE75_128X64) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY_INTERSTATE75_128X64), MP_ROM_INT(DISPLAY_INTERSTATE75_128X64) },

View File

@ -155,6 +155,14 @@ bool get_display_settings(PicoGraphicsDisplay display, int &width, int &height,
if(rotate == -1) rotate = (int)Rotation::ROTATE_0; if(rotate == -1) rotate = (int)Rotation::ROTATE_0;
if(pen_type == -1) pen_type = PEN_RGB888; if(pen_type == -1) pen_type = PEN_RGB888;
break; break;
case DISPLAY_INTERSTATE75_96X48:
width = 96;
height = 48;
bus_type = BUS_PIO;
// Portrait to match labelling
if(rotate == -1) rotate = (int)Rotation::ROTATE_0;
if(pen_type == -1) pen_type = PEN_RGB888;
break;
case DISPLAY_INTERSTATE75_128X32: case DISPLAY_INTERSTATE75_128X32:
width = 128; width = 128;
height = 32; height = 32;

View File

@ -19,6 +19,7 @@ enum PicoGraphicsDisplay {
DISPLAY_INTERSTATE75_32X32, DISPLAY_INTERSTATE75_32X32,
DISPLAY_INTERSTATE75_64X32, DISPLAY_INTERSTATE75_64X32,
DISPLAY_INTERSTATE75_96X32, DISPLAY_INTERSTATE75_96X32,
DISPLAY_INTERSTATE75_96X48,
DISPLAY_INTERSTATE75_128X32, DISPLAY_INTERSTATE75_128X32,
DISPLAY_INTERSTATE75_64X64, DISPLAY_INTERSTATE75_64X64,
DISPLAY_INTERSTATE75_128X64, DISPLAY_INTERSTATE75_128X64,

View File

@ -10,6 +10,7 @@ extern "C" {
#include "py/stream.h" #include "py/stream.h"
#include "py/reader.h" #include "py/reader.h"
#include "extmod/vfs.h" #include "extmod/vfs.h"
#include <stdarg.h>
typedef struct _ModPicoGraphics_obj_t { typedef struct _ModPicoGraphics_obj_t {
mp_obj_base_t base; mp_obj_base_t base;
@ -29,10 +30,31 @@ typedef struct _PATH_obj_t {
pp_path_t path; pp_path_t path;
} _PATH_obj_t; } _PATH_obj_t;
void __printf_debug_flush() {
for(auto i = 0u; i < 10; i++) {
sleep_ms(1);
mp_event_handle_nowait();
}
}
int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args);
void af_debug(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
int ret = mp_vprintf(&mp_plat_print, fmt, ap);
va_end(ap);
__printf_debug_flush();
(void)ret;
}
void *af_malloc(size_t size) { void *af_malloc(size_t size) {
mp_printf(&mp_plat_print, "af_malloc %lu\n", size); //mp_printf(&mp_plat_print, "af_malloc %lu\n", size);
mp_event_handle_nowait(); //__printf_debug_flush();
return m_tracked_calloc(sizeof(uint8_t), size); void *addr = m_tracked_calloc(sizeof(uint8_t), size);
//mp_printf(&mp_plat_print, "addr %lu\n", addr);
//__printf_debug_flush();
return addr;
} }
void *af_realloc(void *p, size_t size) { void *af_realloc(void *p, size_t size) {
@ -40,16 +62,16 @@ void *af_realloc(void *p, size_t size) {
} }
void af_free(void *p) { void af_free(void *p) {
mp_printf(&mp_plat_print, "af_free\n"); //mp_printf(&mp_plat_print, "af_free\n");
mp_event_handle_nowait(); //__printf_debug_flush();
m_tracked_free(p); m_tracked_free(p);
} }
void* fileio_open(const char *filename) { void* fileio_open(const char *filename) {
mp_obj_t fn = mp_obj_new_str(filename, (mp_uint_t)strlen(filename)); mp_obj_t fn = mp_obj_new_str(filename, (mp_uint_t)strlen(filename));
mp_printf(&mp_plat_print, "Opening file %s\n", filename); //mp_printf(&mp_plat_print, "Opening file %s\n", filename);
mp_event_handle_nowait(); //__printf_debug_flush();
mp_obj_t args[2] = { mp_obj_t args[2] = {
fn, fn,
@ -58,10 +80,10 @@ void* fileio_open(const char *filename) {
// Stat the file to get its size // Stat the file to get its size
// example tuple response: (32768, 0, 0, 0, 0, 0, 5153, 1654709815, 1654709815, 1654709815) // example tuple response: (32768, 0, 0, 0, 0, 0, 5153, 1654709815, 1654709815, 1654709815)
mp_obj_t stat = mp_vfs_stat(fn); //mp_obj_t stat = mp_vfs_stat(fn);
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR2(stat, mp_obj_tuple_t); //mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR2(stat, mp_obj_tuple_t);
int filesize = mp_obj_get_int(tuple->items[6]); //int filesize = mp_obj_get_int(tuple->items[6]);
mp_printf(&mp_plat_print, "Size %lu\n", filesize); //mp_printf(&mp_plat_print, "Size %lu\n", filesize);
mp_obj_t fhandle = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map); mp_obj_t fhandle = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map);
@ -73,14 +95,17 @@ void fileio_close(void* fhandle) {
} }
size_t fileio_read(void* fhandle, void *buf, size_t len) { size_t fileio_read(void* fhandle, void *buf, size_t len) {
mp_printf(&mp_plat_print, "Reading %lu bytes\n", len); //mp_printf(&mp_plat_print, "Reading %lu bytes\n", len);
//__printf_debug_flush();
int error; int error;
return mp_stream_read_exactly((mp_obj_t)fhandle, buf, len, &error); return mp_stream_read_exactly((mp_obj_t)fhandle, buf, len, &error);
} }
int fileio_getc(void* fhandle) { int fileio_getc(void* fhandle) {
unsigned char buf; unsigned char buf;
fileio_read((mp_obj_t)fhandle, &buf, 1); //mp_printf(&mp_plat_print, "Reading char\n");
//__printf_debug_flush();
fileio_read(fhandle, (void *)&buf, 1);
return (int)buf; return (int)buf;
} }
@ -413,7 +438,7 @@ mp_obj_t VECTOR_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
GET_STR_DATA_LEN(text_obj, str, str_len); GET_STR_DATA_LEN(text_obj, str, str_len);
const std::wstring_view t((const wchar_t *)str, str_len); const std::string_view t((const char *)str, str_len);
int x = args[ARG_x].u_int; int x = args[ARG_x].u_int;
int y = args[ARG_y].u_int; int y = args[ARG_y].u_int;
@ -426,7 +451,12 @@ mp_obj_t VECTOR_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
pp_mat3_rotate(&tt, mp_obj_get_float(args[ARG_angle].u_obj)); pp_mat3_rotate(&tt, mp_obj_get_float(args[ARG_angle].u_obj));
} }
self->vector->text(t, {(float)x, (float)y}, &tt); pp_mat3_translate(&tt, (float)x, (float)y);
//mp_printf(&mp_plat_print, "self->vector->text()\n");
//__printf_debug_flush();
self->vector->text(t, &tt);
return mp_const_none; return mp_const_none;
} }

View File

@ -32,6 +32,7 @@ You can choose the HUB75 matrix display size that you wish to use by defining `d
DISPLAY_INTERSTATE75_32X32 DISPLAY_INTERSTATE75_32X32
DISPLAY_INTERSTATE75_64X32 DISPLAY_INTERSTATE75_64X32
DISPLAY_INTERSTATE75_96X32 DISPLAY_INTERSTATE75_96X32
DISPLAY_INTERSTATE75_96X48
DISPLAY_INTERSTATE75_128X32 DISPLAY_INTERSTATE75_128X32
DISPLAY_INTERSTATE75_64X64 DISPLAY_INTERSTATE75_64X64
DISPLAY_INTERSTATE75_128X64 DISPLAY_INTERSTATE75_128X64

View File

@ -1,5 +1,5 @@
from pimoroni import RGBLED, Button from pimoroni import RGBLED, Button
from picographics import PicoGraphics, DISPLAY_INTERSTATE75_32X32, DISPLAY_INTERSTATE75_64X32, DISPLAY_INTERSTATE75_96X32, DISPLAY_INTERSTATE75_128X32, DISPLAY_INTERSTATE75_64X64, DISPLAY_INTERSTATE75_128X64, DISPLAY_INTERSTATE75_192X64, DISPLAY_INTERSTATE75_256X64 from picographics import PicoGraphics, DISPLAY_INTERSTATE75_32X32, DISPLAY_INTERSTATE75_64X32, DISPLAY_INTERSTATE75_96X32, DISPLAY_INTERSTATE75_96X48, DISPLAY_INTERSTATE75_128X32, DISPLAY_INTERSTATE75_64X64, DISPLAY_INTERSTATE75_128X64, DISPLAY_INTERSTATE75_192X64, DISPLAY_INTERSTATE75_256X64
from pimoroni_i2c import PimoroniI2C from pimoroni_i2c import PimoroniI2C
import hub75 import hub75
import sys import sys
@ -23,6 +23,7 @@ class Interstate75:
DISPLAY_INTERSTATE75_32X32 = DISPLAY_INTERSTATE75_32X32 DISPLAY_INTERSTATE75_32X32 = DISPLAY_INTERSTATE75_32X32
DISPLAY_INTERSTATE75_64X32 = DISPLAY_INTERSTATE75_64X32 DISPLAY_INTERSTATE75_64X32 = DISPLAY_INTERSTATE75_64X32
DISPLAY_INTERSTATE75_96X32 = DISPLAY_INTERSTATE75_96X32 DISPLAY_INTERSTATE75_96X32 = DISPLAY_INTERSTATE75_96X32
DISPLAY_INTERSTATE75_96X48 = DISPLAY_INTERSTATE75_96X48
DISPLAY_INTERSTATE75_128X32 = DISPLAY_INTERSTATE75_128X32 DISPLAY_INTERSTATE75_128X32 = DISPLAY_INTERSTATE75_128X32
DISPLAY_INTERSTATE75_64X64 = DISPLAY_INTERSTATE75_64X64 DISPLAY_INTERSTATE75_64X64 = DISPLAY_INTERSTATE75_64X64
DISPLAY_INTERSTATE75_128X64 = DISPLAY_INTERSTATE75_128X64 DISPLAY_INTERSTATE75_128X64 = DISPLAY_INTERSTATE75_128X64