kopia lustrzana https://github.com/pimoroni/pimoroni-pico
				
				
				
			ST7789/PicoGraphics: Refactor & make modes more explicit.
							rodzic
							
								
									1cd58ed298
								
							
						
					
					
						commit
						ef6179e77d
					
				|  | @ -195,8 +195,26 @@ namespace pimoroni { | |||
|     gpio_put(cs, 1); | ||||
|   } | ||||
| 
 | ||||
|   void ST7735::update(bool dont_block) { | ||||
|     ST7735::command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)frame_buffer); | ||||
|   // Native 16-bit framebuffer update
 | ||||
|   void ST7735::update() { | ||||
|     command(reg::RAMWR, width * height * sizeof(uint16_t), (const char*)frame_buffer); | ||||
|   } | ||||
| 
 | ||||
|   // 8-bit framebuffer with palette conversion update
 | ||||
|   void ST7735::update(uint16_t *palette) { | ||||
|     command(reg::RAMWR); | ||||
|     uint16_t row[width]; | ||||
|     gpio_put(dc, 1); // data mode
 | ||||
|     gpio_put(cs, 0); | ||||
|     for(auto y = 0u; y < height; y++) { | ||||
|       for(auto x = 0u; x < width; x++) { | ||||
|         auto i = y * width + x; | ||||
|         row[x] = palette[((uint8_t *)frame_buffer)[i]]; | ||||
|       } | ||||
|       // TODO: Add DMA->SPI / PIO while we prep the next row
 | ||||
|       spi_write_blocking(spi, (const uint8_t*)row, width * sizeof(uint16_t)); | ||||
|     } | ||||
|     gpio_put(cs, 1); | ||||
|   } | ||||
| 
 | ||||
|   void ST7735::set_backlight(uint8_t brightness) { | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ namespace pimoroni { | |||
| 
 | ||||
|   public: | ||||
|     // frame buffer where pixel data is stored
 | ||||
|     uint16_t *frame_buffer; | ||||
|     void *frame_buffer; | ||||
| 
 | ||||
|   private: | ||||
|     spi_inst_t *spi = spi0; | ||||
|  | @ -58,7 +58,7 @@ namespace pimoroni { | |||
|     // Constructors/Destructor
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     ST7735(uint16_t width, uint16_t height, uint16_t *frame_buffer, BG_SPI_SLOT slot) : | ||||
|     ST7735(uint16_t width, uint16_t height, void *frame_buffer, BG_SPI_SLOT slot) : | ||||
|       width(width), height(height), frame_buffer(frame_buffer) { | ||||
|       switch(slot) { | ||||
|         case PICO_EXPLORER_ONBOARD: // Don't read too much into this, the case is just here to avoid a compile error
 | ||||
|  | @ -76,10 +76,10 @@ namespace pimoroni { | |||
|       } | ||||
|     } | ||||
| 
 | ||||
|     ST7735(uint16_t width, uint16_t height, uint16_t *frame_buffer) : | ||||
|     ST7735(uint16_t width, uint16_t height, void *frame_buffer) : | ||||
|       width(width), height(height), frame_buffer(frame_buffer) {} | ||||
| 
 | ||||
|     ST7735(uint16_t width, uint16_t height, uint16_t *frame_buffer, | ||||
|     ST7735(uint16_t width, uint16_t height, void *frame_buffer, | ||||
|            spi_inst_t *spi, | ||||
|            uint8_t cs, uint8_t dc, uint8_t sck, uint8_t mosi, uint8_t miso = -1, uint8_t bl = -1) : | ||||
|       width(width), height(height), frame_buffer(frame_buffer), | ||||
|  | @ -100,7 +100,8 @@ namespace pimoroni { | |||
|     int get_bl() const; | ||||
|      | ||||
|     void command(uint8_t command, size_t len = 0, const char *data = NULL); | ||||
|     void update(bool dont_block = false); | ||||
|     void update(); | ||||
|     void update(uint16_t *palette); | ||||
|     void set_backlight(uint8_t brightness); | ||||
|   }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,20 +5,23 @@ | |||
| 
 | ||||
| using namespace pimoroni; | ||||
| 
 | ||||
| uint16_t buffer[BreakoutColourLCD160x80::WIDTH * BreakoutColourLCD160x80::HEIGHT]; | ||||
| BreakoutColourLCD160x80 lcd(buffer); | ||||
| uint8_t buffer[BreakoutColourLCD160x80::WIDTH * BreakoutColourLCD160x80::HEIGHT]; | ||||
| BreakoutColourLCD160x80 lcd((void *)buffer); | ||||
| 
 | ||||
| int main() { | ||||
|   lcd.init(); | ||||
|   lcd.set_backlight(255); | ||||
| 
 | ||||
|   // Delete the default palette and allow us to create up to 256 of our own RGB565 colours
 | ||||
|   lcd.set_palette_mode(BreakoutColourLCD160x80::PaletteModeUSER); | ||||
| 
 | ||||
|   struct pt { | ||||
|     float      x; | ||||
|     float      y; | ||||
|     uint8_t    r; | ||||
|     float     dx; | ||||
|     float     dy; | ||||
|     uint16_t pen; | ||||
|     Pen      pen; | ||||
|   }; | ||||
| 
 | ||||
|   std::vector<pt> shapes; | ||||
|  | @ -33,8 +36,10 @@ int main() { | |||
|     shapes.push_back(shape); | ||||
|   } | ||||
| 
 | ||||
|   uint8_t bg = lcd.create_pen(120, 40, 60); | ||||
| 
 | ||||
|   while(true) { | ||||
|     lcd.set_pen(120, 40, 60); | ||||
|     lcd.set_pen(bg); | ||||
|     lcd.clear(); | ||||
| 
 | ||||
|     for(auto &shape : shapes) { | ||||
|  |  | |||
|  | @ -14,13 +14,16 @@ int main() { | |||
|   //lcd.configure_display(false);
 | ||||
|   lcd.set_backlight(255); | ||||
| 
 | ||||
|   // Delete the default palette and allow us to create up to 256 of our own RGB565 colours
 | ||||
|   lcd.set_palette_mode(ST7789Generic::PaletteModeUSER); | ||||
| 
 | ||||
|   struct pt { | ||||
|     float      x; | ||||
|     float      y; | ||||
|     uint8_t    r; | ||||
|     float     dx; | ||||
|     float     dy; | ||||
|     uint16_t pen; | ||||
|     Pen      pen; | ||||
|   }; | ||||
| 
 | ||||
|   std::vector<pt> shapes; | ||||
|  | @ -37,8 +40,11 @@ int main() { | |||
|     shapes.push_back(shape); | ||||
|   } | ||||
| 
 | ||||
|   Pen BG = lcd.create_pen(120, 40, 60); | ||||
|   Pen WHITE = lcd.create_pen(255, 255, 255); | ||||
| 
 | ||||
|   while(true) { | ||||
|     lcd.set_pen(120, 40, 60); | ||||
|     lcd.set_pen(BG); | ||||
|     lcd.clear(); | ||||
| 
 | ||||
|     for(auto &shape : shapes) { | ||||
|  | @ -53,7 +59,7 @@ int main() { | |||
|       lcd.circle(Point(shape.x, shape.y), shape.r); | ||||
|     } | ||||
| 
 | ||||
|     lcd.set_pen(255, 255, 255); | ||||
|     lcd.set_pen(WHITE); | ||||
|     lcd.text("Hello World", Point(0, 0), 240); | ||||
| 
 | ||||
|     // update screen
 | ||||
|  |  | |||
|  | @ -43,17 +43,23 @@ Pen from_hsv(float h, float s, float v) { | |||
| int main() { | ||||
|     display.set_backlight(255); | ||||
| 
 | ||||
|     // Delete the default palette and allow us to create up to 256 of our own RGB565 colours
 | ||||
|     // display.set_palette_mode(ST7789Generic::PaletteModeUSER);
 | ||||
| 
 | ||||
|     uint32_t steps = 70; | ||||
|     float angle_step = 0.5f; | ||||
| 
 | ||||
|     Pen BLACK = display.create_pen(0, 0, 0); | ||||
|     Pen WHITE = display.create_pen(255, 255, 255); | ||||
| 
 | ||||
|     while(1) { | ||||
|         absolute_time_t at = get_absolute_time(); | ||||
|         uint64_t t = to_us_since_boot(at) / 100000; | ||||
|         float angle = (t % 360) * M_PI / 180.0f; | ||||
| 
 | ||||
|         display.set_pen(0, 0, 0); | ||||
|         display.set_pen(BLACK); | ||||
|         display.clear(); | ||||
|         display.set_pen(255, 255, 255); | ||||
|         display.set_pen(WHITE); | ||||
| 
 | ||||
|         for(auto step = 0u; step < steps; step++) { | ||||
|           auto distance = RADIUS / steps * step; | ||||
|  |  | |||
|  | @ -43,8 +43,13 @@ int main() { | |||
|   } | ||||
| 
 | ||||
|   uint32_t i = 0; | ||||
|   Pen BG = pico_display.create_pen(120, 40, 60); | ||||
|   Pen YELLOW = pico_display.create_pen(255, 255, 0); | ||||
|   Pen TEAL = pico_display.create_pen(0, 255, 255); | ||||
|   Pen WHITE = pico_display.create_pen(255, 255, 255); | ||||
| 
 | ||||
|   while(true) { | ||||
|     pico_display.set_pen(120, 40, 60); | ||||
|     pico_display.set_pen(BG); | ||||
|     pico_display.clear(); | ||||
| 
 | ||||
|     for(auto &shape : shapes) { | ||||
|  | @ -72,14 +77,14 @@ int main() { | |||
|     poly.push_back(Point(50, 85)); | ||||
|     poly.push_back(Point(30, 45)); | ||||
| 
 | ||||
|     pico_display.set_pen(255, 255, 0); | ||||
|     pico_display.set_pen(YELLOW); | ||||
|     //pico_display.pixel(Point(0, 0));
 | ||||
|     pico_display.polygon(poly); | ||||
| 
 | ||||
|     pico_display.set_pen(0, 255, 255); | ||||
|     pico_display.set_pen(TEAL); | ||||
|     pico_display.triangle(Point(50, 50), Point(130, 80), Point(80, 110)); | ||||
| 
 | ||||
|     pico_display.set_pen(255, 255, 255); | ||||
|     pico_display.set_pen(WHITE); | ||||
|     pico_display.line(Point(50, 50), Point(120, 80)); | ||||
|     pico_display.line(Point(20, 20), Point(120, 20)); | ||||
|     pico_display.line(Point(20, 20), Point(20, 120)); | ||||
|  |  | |||
|  | @ -69,6 +69,9 @@ int main() { | |||
| 
 | ||||
|   Point text_location(0, 0); | ||||
| 
 | ||||
|   Pen BG = pico_display.create_pen(120, 40, 60); | ||||
|   Pen WHITE = pico_display.create_pen(255, 255, 255); | ||||
| 
 | ||||
|   while(true) { | ||||
|     if(button_a.raw()) text_location.x -= 1; | ||||
|     if(button_b.raw()) text_location.x += 1; | ||||
|  | @ -76,7 +79,7 @@ int main() { | |||
|     if(button_x.raw()) text_location.y -= 1; | ||||
|     if(button_y.raw()) text_location.y += 1; | ||||
|    | ||||
|     pico_display.set_pen(120, 40, 60); | ||||
|     pico_display.set_pen(BG); | ||||
|     pico_display.clear(); | ||||
| 
 | ||||
|     for(auto &shape : shapes) { | ||||
|  | @ -112,7 +115,7 @@ int main() { | |||
|     led.set_rgb(r, g, b); | ||||
| 
 | ||||
| 
 | ||||
|     pico_display.set_pen(255, 255, 255); | ||||
|     pico_display.set_pen(WHITE); | ||||
|     pico_display.text("Hello World", text_location, 320); | ||||
| 
 | ||||
|     // update screen
 | ||||
|  |  | |||
|  | @ -81,9 +81,14 @@ int main() { | |||
| 
 | ||||
|   pico_explorer.set_audio_pin(pico_explorer.GP0); | ||||
| 
 | ||||
|   Pen BG = pico_explorer.create_pen(120, 40, 60); | ||||
|   Pen WHITE = pico_explorer.create_pen(255, 255, 255); | ||||
|   Pen BOX = pico_explorer.create_pen(55, 65, 75); | ||||
|   Pen PURPLE = pico_explorer.create_pen(255, 0, 255); | ||||
| 
 | ||||
|   uint32_t i = 0; | ||||
|   while(true) { | ||||
|     pico_explorer.set_pen(120, 40, 60); | ||||
|     pico_explorer.set_pen(BG); | ||||
|     pico_explorer.clear(); | ||||
| 
 | ||||
|     for(auto &shape : shapes) { | ||||
|  | @ -99,21 +104,21 @@ int main() { | |||
|     } | ||||
| 
 | ||||
|     float rv = pico_explorer.get_adc(pico_explorer.ADC0); | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.circle(Point(rv * 140 + 50, 110), 20); | ||||
|     pico_explorer.set_pen(rv * 255, 0, 0); | ||||
|     pico_explorer.set_pen(pico_explorer.create_pen(rv * 255, 0, 0)); | ||||
|     pico_explorer.circle(Point(rv * 140 + 50, 110), 15); | ||||
| 
 | ||||
|     float gv = pico_explorer.get_adc(pico_explorer.ADC1); | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.circle(Point(gv * 140 + 50, 160), 20); | ||||
|     pico_explorer.set_pen(0, gv * 255, 0); | ||||
|     pico_explorer.set_pen(pico_explorer.create_pen(0, gv * 255, 0)); | ||||
|     pico_explorer.circle(Point(gv * 140 + 50, 160), 15); | ||||
| 
 | ||||
|     float bv = pico_explorer.get_adc(pico_explorer.ADC2); | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.circle(Point(bv * 140 + 50, 210), 20); | ||||
|     pico_explorer.set_pen(0, 0, bv * 255); | ||||
|     pico_explorer.set_pen(pico_explorer.create_pen(0, 0, bv * 255)); | ||||
|     pico_explorer.circle(Point(bv * 140 + 50, 210), 15); | ||||
| 
 | ||||
|     pico_explorer.set_motor(pico_explorer.MOTOR1, pico_explorer.FORWARD, bv); | ||||
|  | @ -122,32 +127,32 @@ int main() { | |||
|     pico_explorer.set_tone(440, 0.5); | ||||
| 
 | ||||
|     if(pico_explorer.is_pressed(pico_explorer.A)) { | ||||
|       pico_explorer.set_pen(255, 255, 255); | ||||
|       pico_explorer.set_pen(WHITE); | ||||
|       pico_explorer.character('A', Point(120, 180), 5); | ||||
|     } | ||||
| 
 | ||||
|     if(pico_explorer.is_pressed(pico_explorer.B)) { | ||||
|       pico_explorer.set_pen(255, 255, 255); | ||||
|       pico_explorer.set_pen(WHITE); | ||||
|       pico_explorer.character('B', Point(120, 180), 5); | ||||
|     } | ||||
| 
 | ||||
|     if(pico_explorer.is_pressed(pico_explorer.X)) { | ||||
|       pico_explorer.set_pen(255, 255, 255); | ||||
|       pico_explorer.set_pen(WHITE); | ||||
|       pico_explorer.character('X', Point(120, 180), 5); | ||||
|     } | ||||
| 
 | ||||
|     if(pico_explorer.is_pressed(pico_explorer.Y)) { | ||||
|       pico_explorer.set_pen(255, 255, 255); | ||||
|       pico_explorer.set_pen(WHITE); | ||||
|       pico_explorer.character('Y', Point(120, 180), 5); | ||||
|     } | ||||
| 
 | ||||
|     float tyoff = cos(i / 20.0f) * 50.0f - 50.0f; | ||||
|     Rect text_box(10, 10, 150, 150); | ||||
|     pico_explorer.set_pen(55, 65, 75); | ||||
|     pico_explorer.set_pen(BOX); | ||||
|     pico_explorer.rectangle(text_box); | ||||
|     text_box.deflate(10); | ||||
|     pico_explorer.set_clip(text_box); | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.text("This is a test of some text data that should wrap nicely onto multiple lines which is dead useful like.", Point(text_box.x, text_box.y + tyoff), 100); | ||||
| 
 | ||||
|     float xoff = sin(i / 20.0f) * 50.0f; | ||||
|  | @ -169,16 +174,16 @@ int main() { | |||
| 
 | ||||
|     pico_explorer.remove_clip(); | ||||
| 
 | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.text("x: " + std::to_string(int(msa301.get_axis(msa301.X, 16) * 100)), Point(10, 190), 100); | ||||
|     pico_explorer.text("y: " + std::to_string(int(msa301.get_axis(msa301.Y, 16) * 100)), Point(10, 205), 100); | ||||
|     pico_explorer.text("z: " + std::to_string(int(msa301.get_axis(msa301.Z, 16) * 100)), Point(10, 220), 100); | ||||
| 
 | ||||
|     uint16_t xpos = (msa301.get_axis(msa301.X, 16) * 120) + 120; | ||||
|     uint16_t ypos = (msa301.get_axis(msa301.Z, 16) * 120) + 120; | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.circle(Point(xpos, ypos), 20); | ||||
|     pico_explorer.set_pen(255, 0, 255); | ||||
|     pico_explorer.set_pen(PURPLE); | ||||
|     pico_explorer.circle(Point(xpos, ypos), 15); | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,12 +21,15 @@ int main() { | |||
|   pico_explorer.set_font(&font8); | ||||
|   msa301.init(); | ||||
| 
 | ||||
|   Pen BG = pico_explorer.create_pen(120, 40, 60); | ||||
|   Pen WHITE = pico_explorer.create_pen(255, 255, 255); | ||||
| 
 | ||||
|   uint32_t i = 0; | ||||
|   while(true) { | ||||
|     pico_explorer.set_pen(120, 40, 60); | ||||
|     pico_explorer.set_pen(BG); | ||||
|     pico_explorer.clear(); | ||||
| 
 | ||||
|     pico_explorer.set_pen(255, 255, 255); | ||||
|     pico_explorer.set_pen(WHITE); | ||||
|     pico_explorer.set_font(&font6); | ||||
|     pico_explorer.text("6x6: The quick, brown fox jumps over the lazy dog! UPPER. lower.", Point(10, 10), 220); | ||||
|     pico_explorer.text("0123456789 !$%^&*()", Point(10, 70), 220); | ||||
|  |  | |||
|  | @ -2,18 +2,18 @@ | |||
| 
 | ||||
| namespace pimoroni { | ||||
| 
 | ||||
|   BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf) | ||||
|   BreakoutColourLCD160x80::BreakoutColourLCD160x80(void *buf) | ||||
|     : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf) { | ||||
|     __fb = buf; | ||||
|   } | ||||
| 
 | ||||
|   BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, spi_inst_t *spi, | ||||
|   BreakoutColourLCD160x80::BreakoutColourLCD160x80(void *buf, spi_inst_t *spi, | ||||
|       uint cs, uint dc, uint sck, uint mosi, uint miso, uint bl) | ||||
|     : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, spi, cs, dc, sck, mosi, miso, bl) { | ||||
|     __fb = buf; | ||||
|   } | ||||
| 
 | ||||
|   BreakoutColourLCD160x80::BreakoutColourLCD160x80(uint16_t *buf, BG_SPI_SLOT slot) | ||||
|   BreakoutColourLCD160x80::BreakoutColourLCD160x80(void *buf, BG_SPI_SLOT slot) | ||||
|     : PicoGraphics(WIDTH, HEIGHT, buf), screen(WIDTH, HEIGHT, buf, slot) { | ||||
|     __fb = buf; | ||||
|   } | ||||
|  | @ -48,7 +48,7 @@ namespace pimoroni { | |||
|   } | ||||
| 
 | ||||
|   void BreakoutColourLCD160x80::update() { | ||||
|     screen.update(); | ||||
|     screen.update(palette); | ||||
|   } | ||||
| 
 | ||||
|   void BreakoutColourLCD160x80::set_backlight(uint8_t brightness) { | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ namespace pimoroni { | |||
|     // Variables
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     uint16_t *__fb; | ||||
|     void *__fb; | ||||
|   private: | ||||
|     ST7735 screen; | ||||
| 
 | ||||
|  | @ -27,10 +27,10 @@ namespace pimoroni { | |||
|     // Constructors/Destructor
 | ||||
|     //--------------------------------------------------
 | ||||
|   public: | ||||
|     BreakoutColourLCD160x80(uint16_t *buf); | ||||
|     BreakoutColourLCD160x80(uint16_t *buf, spi_inst_t *spi, | ||||
|     BreakoutColourLCD160x80(void *buf); | ||||
|     BreakoutColourLCD160x80(void *buf, spi_inst_t *spi, | ||||
|       uint cs, uint dc, uint sck, uint mosi, uint miso = PIN_UNUSED, uint bl = PIN_UNUSED); | ||||
|     BreakoutColourLCD160x80(uint16_t *buf, BG_SPI_SLOT slot); | ||||
|     BreakoutColourLCD160x80(void *buf, BG_SPI_SLOT slot); | ||||
| 
 | ||||
| 
 | ||||
|     //--------------------------------------------------
 | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ namespace pimoroni { | |||
|       st7789(width, height, round, frame_buffer, PIMORONI_SPI_DEFAULT_INSTANCE, SPI_BG_FRONT_CS, SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, SPI_BG_FRONT_PWM) { | ||||
|             this->frame_buffer = (Pen *)st7789.frame_buffer; | ||||
|             this->st7789.init(); | ||||
|             this->st7789.update(palette); | ||||
|            }; | ||||
| 
 | ||||
|     ST7789Generic(uint16_t width, uint16_t height, bool round, void *frame_buffer, BG_SPI_SLOT slot) : | ||||
|  | @ -22,6 +23,7 @@ namespace pimoroni { | |||
|       st7789(width, height, round, frame_buffer, PIMORONI_SPI_DEFAULT_INSTANCE, st7789.get_slot_cs(slot), SPI_DEFAULT_MISO, SPI_DEFAULT_SCK, SPI_DEFAULT_MOSI, st7789.get_slot_bl(slot)) { | ||||
|             this->frame_buffer = (Pen *)st7789.frame_buffer; | ||||
|             this->st7789.init(); | ||||
|             this->st7789.update(palette); | ||||
|            }; | ||||
| 
 | ||||
|     ST7789Generic(uint16_t width, uint16_t height, bool round, void *frame_buffer, | ||||
|  | @ -31,6 +33,7 @@ namespace pimoroni { | |||
|       st7789(width, height, round, frame_buffer, spi, cs, dc, sck, mosi, bl) { | ||||
|             this->frame_buffer = (Pen *)st7789.frame_buffer; | ||||
|             this->st7789.init(); | ||||
|             this->st7789.update(palette); | ||||
|            }; | ||||
| 
 | ||||
|     ST7789Generic(uint16_t width, uint16_t height, void *frame_buffer, | ||||
|  | @ -39,6 +42,7 @@ namespace pimoroni { | |||
|       st7789(width, height, frame_buffer, cs, dc, wr_sck, rd_sck, d0, bl) { | ||||
|             this->frame_buffer = (Pen *)st7789.frame_buffer; | ||||
|             this->st7789.init(); | ||||
|             this->st7789.update(palette); | ||||
|            }; | ||||
| 
 | ||||
|     spi_inst_t* get_spi() const; | ||||
|  | @ -52,6 +56,10 @@ namespace pimoroni { | |||
|     [[deprecated("Use configure_display(true) instead.")]] void flip(); | ||||
|     void set_backlight(uint8_t brightness); | ||||
|     void configure_display(bool rotate180); | ||||
|     void set_framebuffer(void* frame_buffer) { | ||||
|       this->frame_buffer = (Pen *)frame_buffer; | ||||
|       st7789.frame_buffer = frame_buffer; | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -4,43 +4,74 @@ namespace pimoroni { | |||
|   PicoGraphics::PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer) | ||||
|   : frame_buffer((Pen *)frame_buffer), bounds(0, 0, width, height), clip(0, 0, width, height) { | ||||
|     set_font(&font6); | ||||
|     default_palette(); | ||||
|     set_palette_mode(PaletteModeRGB332); | ||||
|   }; | ||||
| 
 | ||||
|   void PicoGraphics::set_font(const bitmap::font_t *font){ | ||||
|     this->font = font; | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::set_pen(uint8_t r, uint8_t g, uint8_t b, bool truncate) { | ||||
|     pen = put_palette(truncate ? create_pen_rgb332(r, g, b) : create_pen_rgb565(r, g, b)); | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::set_pen(Pen p) { | ||||
|     pen = p; | ||||
|   } | ||||
| 
 | ||||
|   uint16_t PicoGraphics::get_palette(uint8_t i) { | ||||
|     return palette[i]; | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::put_palette(uint16_t p, uint8_t i) { | ||||
|     palette[i] = p; | ||||
|     if (i > palette_entries) { | ||||
|       palette_entries = i; | ||||
|   void PicoGraphics::set_palette_mode(PaletteMode mode) { | ||||
|     palette_mode = mode; | ||||
|     if(mode == PaletteModeRGB332) { | ||||
|       rgb332_palette(); | ||||
|     } else { | ||||
|       empty_palette(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   uint8_t PicoGraphics::put_palette(uint16_t p) { | ||||
|     for(auto i=0u; i < palette_entries; i++) { | ||||
|       if(palette[i] == p) return i; | ||||
|     } | ||||
|   int PicoGraphics::create_pen(uint8_t r, uint8_t g, uint8_t b) { | ||||
|     RGB565 c = palette_mode == PaletteModeRGB332 ? create_pen_rgb332(r, g, b) : create_pen_rgb565(r, g, b); | ||||
|     int result = search_palette(c); | ||||
| 
 | ||||
|     if(palette_entries < 256) { | ||||
|       palette[palette_entries] = p; | ||||
|       palette_entries += 1; | ||||
|     if (result == -1 && palette_mode == PaletteModeUSER) { | ||||
|       result = put_palette(create_pen_rgb565(r, g, b)); | ||||
|     } | ||||
|     return palette_entries - 1; | ||||
|   }; | ||||
|    | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   int PicoGraphics::search_palette(RGB565 c) { | ||||
|     for(auto i = 0u; i < 256; i++) { | ||||
|       if(palette_status[i] && palette[i] == c) return i; | ||||
|     } | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   int PicoGraphics::put_palette(RGB565 c) { | ||||
|     for(auto i = 0u; i < 256; i++) { | ||||
|       if(!palette_status[i]) { | ||||
|         palette[i] = c; | ||||
|         palette_status[i] = true; | ||||
|         return i; | ||||
|       } | ||||
|     } | ||||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::set_palette(uint8_t i, uint16_t c) { | ||||
|     palette[i] = c; | ||||
|     palette_status[i] = true; | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::empty_palette() {  | ||||
|     for (auto i = 0u; i < 255; i++) { | ||||
|       palette[i] = 0; | ||||
|       palette_status[i] = false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::rgb332_palette() { | ||||
|     for (auto i = 0u; i < 255; i++) { | ||||
|       palette[i] = ((i & 0b11100000) << 8) | ((i & 0b00011100) << 6) | ((i & 0b00000011) << 3); | ||||
|       palette[i] = __builtin_bswap16(palette[i]); | ||||
|       palette_status[i] = true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void PicoGraphics::set_clip(const Rect &r) { | ||||
|     clip = bounds.intersection(r); | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
| namespace pimoroni { | ||||
| 
 | ||||
|   typedef uint8_t Pen; | ||||
|   typedef uint16_t RGB565; | ||||
| 
 | ||||
|   struct Rect; | ||||
| 
 | ||||
|  | @ -55,15 +56,22 @@ namespace pimoroni { | |||
|     const bitmap::font_t *font; | ||||
| 
 | ||||
|     uint16_t palette[256]; | ||||
|     uint16_t palette_entries = 0; | ||||
|     bool palette_status[256]; | ||||
| 
 | ||||
|     enum PaletteMode { | ||||
|       PaletteModeRGB332 = 0, | ||||
|       PaletteModeUSER = 1 | ||||
|     }; | ||||
| 
 | ||||
|     PaletteMode palette_mode = PaletteModeRGB332; | ||||
| 
 | ||||
|   public: | ||||
|     PicoGraphics(uint16_t width, uint16_t height, void *frame_buffer); | ||||
|     void set_font(const bitmap::font_t *font); | ||||
|     void set_pen(uint8_t r, uint8_t g, uint8_t b, bool truncate=true); | ||||
|     void set_pen(Pen p); | ||||
|     void set_palette_mode(PaletteMode mode); | ||||
| 
 | ||||
|     constexpr uint16_t create_pen_rgb565(uint8_t r, uint8_t g, uint8_t b) { | ||||
|     static constexpr RGB565 create_pen_rgb565(uint8_t r, uint8_t g, uint8_t b) { | ||||
|       uint16_t p = ((r & 0b11111000) << 8) | | ||||
|                    ((g & 0b11111100) << 3) | | ||||
|                    ((b & 0b11111000) >> 3); | ||||
|  | @ -71,7 +79,7 @@ namespace pimoroni { | |||
|       return __builtin_bswap16(p); | ||||
|     } | ||||
|    | ||||
|     constexpr uint16_t create_pen_rgb332(uint8_t r, uint8_t g, uint8_t b) { | ||||
|     static constexpr RGB565 create_pen_rgb332(uint8_t r, uint8_t g, uint8_t b) { | ||||
|       uint16_t p = ((r & 0b11100000) << 8) | | ||||
|                    ((g & 0b11100000) << 3) | | ||||
|                    ((b & 0b11000000) >> 3); | ||||
|  | @ -79,25 +87,15 @@ namespace pimoroni { | |||
|       return __builtin_bswap16(p); | ||||
|     } | ||||
| 
 | ||||
|     Pen create_pen(uint8_t r, uint8_t g, uint8_t b, bool truncate=true) { | ||||
|       return put_palette(truncate ? create_pen_rgb332(r, g, b) : create_pen_rgb565(r, g, b)); | ||||
|     } | ||||
|     int create_pen(uint8_t r, uint8_t g, uint8_t b); | ||||
| 
 | ||||
|     void flush_palette() { | ||||
|       palette_entries = 0; | ||||
|     } | ||||
|     void empty_palette(); | ||||
|     void rgb332_palette(); | ||||
| 
 | ||||
|     void default_palette() { | ||||
|       for (auto i = 0u; i < 255; i++) { | ||||
|         palette[i] = ((i & 0b11100000) << 8) | ((i & 0b00011100) << 6) | ((i & 0b00000011) << 3); | ||||
|         palette[i] = __builtin_bswap16(palette[i]); | ||||
|       } | ||||
|       palette_entries = 255; | ||||
|     } | ||||
| 
 | ||||
|     uint8_t put_palette(uint16_t p); | ||||
|     uint16_t get_palette(uint8_t i); | ||||
|     void put_palette(uint16_t p, uint8_t i); | ||||
|     int search_palette(RGB565 c); | ||||
|     int get_palette(uint8_t i); | ||||
|     void set_palette(uint8_t i, RGB565 c); | ||||
|     int put_palette(RGB565 c); | ||||
| 
 | ||||
|     void set_clip(const Rect &r); | ||||
|     void remove_clip(); | ||||
|  |  | |||
|  | @ -64,7 +64,7 @@ mp_obj_t BreakoutColourLCD160x80_make_new(const mp_obj_type_t *type, size_t n_ar | |||
|             mp_buffer_info_t bufinfo; | ||||
|             mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); | ||||
| 
 | ||||
|             self->breakout = m_new_class(BreakoutColourLCD160x80, (uint16_t *)bufinfo.buf, (BG_SPI_SLOT)slot); | ||||
|             self->breakout = m_new_class(BreakoutColourLCD160x80, bufinfo.buf, (BG_SPI_SLOT)slot); | ||||
|         } | ||||
|         else { | ||||
|             mp_raise_ValueError("slot not a valid value. Expected 0 to 1"); | ||||
|  | @ -113,7 +113,7 @@ mp_obj_t BreakoutColourLCD160x80_make_new(const mp_obj_type_t *type, size_t n_ar | |||
|         self->base.type = &breakout_colourlcd160x80_BreakoutColourLCD160x80_type; | ||||
| 
 | ||||
|         spi_inst_t *spi = (spi_id == 0) ? spi0 : spi1; | ||||
|         self->breakout = m_new_class(BreakoutColourLCD160x80, (uint16_t *)bufinfo.buf, spi, | ||||
|         self->breakout = m_new_class(BreakoutColourLCD160x80, bufinfo.buf, spi, | ||||
|             args[ARG_cs].u_int, args[ARG_dc].u_int, sck, mosi, PIN_UNUSED, args[ARG_bl].u_int); | ||||
|     } | ||||
| 
 | ||||
|  | @ -154,52 +154,23 @@ mp_obj_t BreakoutColourLCD160x80_set_backlight(size_t n_args, const mp_obj_t *po | |||
| 
 | ||||
| mp_obj_t BreakoutColourLCD160x80_set_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
| 
 | ||||
|     if(n_args <= 2) { | ||||
|         enum { ARG_self, ARG_pen }; | ||||
|         static const mp_arg_t allowed_args[] = { | ||||
|             { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|             { MP_QSTR_pen, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         }; | ||||
|     enum { ARG_self, ARG_pen }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_pen, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|     }; | ||||
| 
 | ||||
|         mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|         mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
|     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|     mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
| 
 | ||||
|         breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t); | ||||
|     breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t); | ||||
| 
 | ||||
|         int pen = args[ARG_pen].u_int; | ||||
|     int pen = args[ARG_pen].u_int; | ||||
| 
 | ||||
|         if(pen < 0 || pen > 0xffff) | ||||
|             mp_raise_ValueError("p is not a valid pen."); | ||||
|         else | ||||
|             self->breakout->set_pen(pen); | ||||
|     } | ||||
|     else { | ||||
|         enum { ARG_self, ARG_r, ARG_g, ARG_b }; | ||||
|         static const mp_arg_t allowed_args[] = { | ||||
|             { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|             { MP_QSTR_r, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_g, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_b, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         }; | ||||
| 
 | ||||
|         mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|         mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
| 
 | ||||
|         breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, breakout_colourlcd160x80_BreakoutColourLCD160x80_obj_t); | ||||
| 
 | ||||
|         int r = args[ARG_r].u_int; | ||||
|         int g = args[ARG_g].u_int; | ||||
|         int b = args[ARG_b].u_int; | ||||
| 
 | ||||
|         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 | ||||
|             self->breakout->set_pen(r, g, b); | ||||
|     } | ||||
|     if(pen < 0 || pen > 0xffff) | ||||
|         mp_raise_ValueError("p is not a valid pen."); | ||||
|     else | ||||
|         self->breakout->set_pen(pen); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ include(breakout_vl53l5cx/micropython) | |||
| include(pico_scroll/micropython) | ||||
| include(pico_rgb_keypad/micropython) | ||||
| include(pico_unicorn/micropython) | ||||
| include(pico_explorer/micropython) | ||||
| include(pico_wireless/micropython) | ||||
| 
 | ||||
| include(bitmap_fonts/micropython) | ||||
|  |  | |||
|  | @ -19,4 +19,10 @@ target_compile_definitions(usermod_${MOD_NAME} INTERFACE | |||
|     -DMODULE_${MOD_NAME_UPPER}_ENABLED=1 | ||||
| ) | ||||
| 
 | ||||
| target_link_libraries(usermod INTERFACE usermod_${MOD_NAME}) | ||||
| target_link_libraries(usermod INTERFACE usermod_${MOD_NAME}) | ||||
| 
 | ||||
| set_source_files_properties( | ||||
|     ${CMAKE_CURRENT_LIST_DIR}/${MOD_NAME}.c | ||||
|     PROPERTIES COMPILE_FLAGS | ||||
|     "-Wno-discarded-qualifiers" | ||||
| ) | ||||
|  | @ -1,15 +1,27 @@ | |||
| #include "st7789.h" | ||||
| 
 | ||||
| // Module functions
 | ||||
| STATIC MP_DEFINE_CONST_FUN_OBJ_3(GenericST7789_module_RGB332_obj, GenericST7789_module_RGB332); | ||||
| STATIC MP_DEFINE_CONST_FUN_OBJ_3(GenericST7789_module_RGB565_obj, GenericST7789_module_RGB565); | ||||
| 
 | ||||
| // Class Methods
 | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_update_obj, GenericST7789_update); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_flush_palette_obj, GenericST7789_flush_palette); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_default_palette_obj, GenericST7789_default_palette); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_set_backlight_obj, 1, GenericST7789_set_backlight); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_set_pen_obj, 1, GenericST7789_set_pen); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_create_pen_obj, 1, GenericST7789_create_pen); | ||||
| MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_backlight_obj, GenericST7789_set_backlight); | ||||
| MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_framebuffer_obj, GenericST7789_set_framebuffer); | ||||
| 
 | ||||
| // Palette management
 | ||||
| MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_palette_mode_obj, GenericST7789_set_palette_mode); | ||||
| MP_DEFINE_CONST_FUN_OBJ_3(GenericST7789_set_palette_obj, GenericST7789_set_palette); | ||||
| 
 | ||||
| // Pen
 | ||||
| MP_DEFINE_CONST_FUN_OBJ_2(GenericST7789_set_pen_obj, GenericST7789_set_pen); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_create_pen_obj, 3, GenericST7789_create_pen); | ||||
| 
 | ||||
| // Primitives
 | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_set_clip_obj, 1, GenericST7789_set_clip); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_remove_clip_obj, GenericST7789_remove_clip); | ||||
| MP_DEFINE_CONST_FUN_OBJ_1(GenericST7789_clear_obj, GenericST7789_clear); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_pixel_obj, 1, GenericST7789_pixel); | ||||
| MP_DEFINE_CONST_FUN_OBJ_3(GenericST7789_pixel_obj, GenericST7789_pixel); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_pixel_span_obj, 1, GenericST7789_pixel_span); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_rectangle_obj, 1, GenericST7789_rectangle); | ||||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_circle_obj, 1, GenericST7789_circle); | ||||
|  | @ -21,11 +33,13 @@ MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_triangle_obj, 1, GenericST7789_triangle | |||
| MP_DEFINE_CONST_FUN_OBJ_KW(GenericST7789_line_obj, 1, GenericST7789_line); | ||||
| 
 | ||||
| STATIC const mp_rom_map_elem_t GenericST7789_locals_dict_table[] = { | ||||
|     { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&GenericST7789_update_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&GenericST7789_pixel_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_pen), MP_ROM_PTR(&GenericST7789_set_pen_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_flush_palette), MP_ROM_PTR(&GenericST7789_flush_palette_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_default_palette), MP_ROM_PTR(&GenericST7789_default_palette_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&GenericST7789_update_obj) }, | ||||
| 
 | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_palette_mode), MP_ROM_PTR(&GenericST7789_set_palette_mode_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_palette), MP_ROM_PTR(&GenericST7789_set_palette_obj) }, | ||||
| 
 | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_backlight), MP_ROM_PTR(&GenericST7789_set_backlight_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_create_pen), MP_ROM_PTR(&GenericST7789_create_pen_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_clip), MP_ROM_PTR(&GenericST7789_set_clip_obj) }, | ||||
|  | @ -40,6 +54,8 @@ STATIC const mp_rom_map_elem_t GenericST7789_locals_dict_table[] = { | |||
|     { MP_ROM_QSTR(MP_QSTR_polygon), MP_ROM_PTR(&GenericST7789_polygon_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_triangle), MP_ROM_PTR(&GenericST7789_triangle_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&GenericST7789_line_obj) }, | ||||
| 
 | ||||
|     { MP_ROM_QSTR(MP_QSTR_set_framebuffer), MP_ROM_PTR(&GenericST7789_set_framebuffer_obj) }, | ||||
| }; | ||||
| STATIC MP_DEFINE_CONST_DICT(GenericST7789_locals_dict, GenericST7789_locals_dict_table); | ||||
| 
 | ||||
|  | @ -62,9 +78,15 @@ const mp_obj_type_t GenericST7789Parallel_type = { | |||
| 
 | ||||
| /***** Module Globals *****/ | ||||
| STATIC const mp_map_elem_t st7789_globals_table[] = { | ||||
|     { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_st7789) }, | ||||
|     { MP_OBJ_NEW_QSTR(MP_QSTR_ST7789), (mp_obj_t)&GenericST7789_type }, | ||||
|     { MP_OBJ_NEW_QSTR(MP_QSTR_ST7789Parallel), (mp_obj_t)&GenericST7789Parallel_type }, | ||||
|     { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_st7789) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_ST7789), (mp_obj_t)&GenericST7789_type }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_ST7789Parallel), (mp_obj_t)&GenericST7789Parallel_type }, | ||||
| 
 | ||||
|     { MP_ROM_QSTR(MP_QSTR_RGB332), MP_ROM_PTR(&GenericST7789_module_RGB332_obj) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_PTR(&GenericST7789_module_RGB565_obj) }, | ||||
| 
 | ||||
|     { MP_ROM_QSTR(MP_QSTR_PALETTE_RGB332), MP_ROM_INT(0) }, | ||||
|     { MP_ROM_QSTR(MP_QSTR_PALETTE_USER), MP_ROM_INT(1) }, | ||||
| }; | ||||
| STATIC MP_DEFINE_CONST_DICT(mp_module_st7789_globals, st7789_globals_table); | ||||
| 
 | ||||
|  |  | |||
|  | @ -166,7 +166,7 @@ mp_obj_t GenericST7789Parallel_make_new(const mp_obj_type_t *type, size_t n_args | |||
|     if (args[ARG_buffer].u_obj != mp_const_none) { | ||||
|         mp_buffer_info_t bufinfo; | ||||
|         mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_RW); | ||||
|         self->buffer = (uint8_t *)bufinfo.buf; | ||||
|         self->buffer = bufinfo.buf; | ||||
|         if(bufinfo.len < (size_t)(width * height)) { | ||||
|             mp_raise_ValueError("Supplied buffer is too small!"); | ||||
|         } | ||||
|  | @ -191,6 +191,23 @@ mp_obj_t GenericST7789Parallel_make_new(const mp_obj_type_t *type, size_t n_args | |||
| } | ||||
| 
 | ||||
| /***** Methods *****/ | ||||
| mp_obj_t GenericST7789_set_framebuffer(mp_obj_t self_in, mp_obj_t framebuffer) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
| 
 | ||||
|     if (framebuffer == mp_const_none) { | ||||
|         m_del(uint8_t, self->buffer, self->st7789->bounds.w * self->st7789->bounds.h); | ||||
|         self->buffer = nullptr; | ||||
|         self->st7789->set_framebuffer(nullptr); | ||||
|     } else { | ||||
|         mp_buffer_info_t bufinfo; | ||||
|         mp_get_buffer_raise(framebuffer, &bufinfo, MP_BUFFER_RW); | ||||
|         self->buffer = bufinfo.buf; | ||||
|         self->st7789->set_framebuffer(self->buffer); | ||||
|     } | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_update(mp_obj_t self_in) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
|     self->st7789->update(); | ||||
|  | @ -198,105 +215,69 @@ mp_obj_t GenericST7789_update(mp_obj_t self_in) { | |||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_flush_palette(mp_obj_t self_in) { | ||||
| mp_obj_t GenericST7789_set_backlight(mp_obj_t self_in, mp_obj_t brightness) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
|     self->st7789->flush_palette(); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
|     float b = mp_obj_get_float(brightness); | ||||
| 
 | ||||
| mp_obj_t GenericST7789_default_palette(mp_obj_t self_in) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
|     self->st7789->default_palette(); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_set_backlight(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_brightness }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_brightness, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|     }; | ||||
| 
 | ||||
|     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|     mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
| 
 | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
| 
 | ||||
|     float brightness = mp_obj_get_float(args[ARG_brightness].u_obj); | ||||
| 
 | ||||
|     if(brightness < 0 || brightness > 1.0f) | ||||
|     if(b < 0 || b > 1.0f) | ||||
|         mp_raise_ValueError("brightness out of range. Expected 0.0 to 1.0"); | ||||
|     else | ||||
|         self->st7789->set_backlight((uint8_t)(brightness * 255.0f)); | ||||
|         self->st7789->set_backlight((uint8_t)(b * 255.0f)); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_set_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
| mp_obj_t GenericST7789_module_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b) { | ||||
|     return mp_obj_new_int(ST7789Generic::create_pen_rgb332( | ||||
|         mp_obj_get_int(r), | ||||
|         mp_obj_get_int(g), | ||||
|         mp_obj_get_int(b) | ||||
|     )); | ||||
| } | ||||
| 
 | ||||
|     if(n_args <= 2) { | ||||
|         enum { ARG_self, ARG_pen }; | ||||
|         static const mp_arg_t allowed_args[] = { | ||||
|             { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|             { MP_QSTR_pen, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         }; | ||||
| mp_obj_t GenericST7789_module_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b) { | ||||
|     return mp_obj_new_int(ST7789Generic::create_pen_rgb565( | ||||
|         mp_obj_get_int(r), | ||||
|         mp_obj_get_int(g), | ||||
|         mp_obj_get_int(b) | ||||
|     )); | ||||
| } | ||||
| 
 | ||||
|         mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|         mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
| mp_obj_t GenericST7789_set_pen(mp_obj_t self_in, mp_obj_t pen) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
| 
 | ||||
|         GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
|     self->st7789->set_pen(mp_obj_get_int(pen) & 0xff); | ||||
| 
 | ||||
|         int pen = args[ARG_pen].u_int; | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
|         if(pen < 0 || pen > 0xff) { | ||||
|             mp_raise_ValueError("p is not a valid pen."); | ||||
|         } else { | ||||
|             self->st7789->set_pen(pen); | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|         enum { ARG_self, ARG_r, ARG_g, ARG_b, ARG_truncate }; | ||||
|         static const mp_arg_t allowed_args[] = { | ||||
|             { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|             { MP_QSTR_r, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_g, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_b, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|             { MP_QSTR_truncate, MP_ARG_OBJ, { .u_obj = mp_const_true } }, | ||||
|         }; | ||||
| mp_obj_t GenericST7789_set_palette_mode(mp_obj_t self_in, mp_obj_t mode) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
| 
 | ||||
|         mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|         mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
|     self->st7789->set_palette_mode((ST7789Generic::PaletteMode)mp_obj_get_int(mode)); | ||||
| 
 | ||||
|         GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
|         int r = args[ARG_r].u_int; | ||||
|         int g = args[ARG_g].u_int; | ||||
|         int b = args[ARG_b].u_int; | ||||
|         bool t = args[ARG_truncate].u_obj == mp_const_true; | ||||
| mp_obj_t GenericST7789_set_palette(mp_obj_t self_in, mp_obj_t index, mp_obj_t colour) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
| 
 | ||||
|         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 | ||||
|             self->st7789->set_pen(r, g, b, t); | ||||
|     } | ||||
|     self->st7789->set_palette( | ||||
|         mp_obj_get_int(index) & 0xff, | ||||
|         mp_obj_get_int(colour) & 0xffff | ||||
|     ); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_create_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_r, ARG_g, ARG_b, ARG_truncate }; | ||||
|     enum { ARG_self, ARG_r, ARG_g, ARG_b }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_r, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         { MP_QSTR_g, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         { MP_QSTR_b, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         { MP_QSTR_truncate, MP_ARG_OBJ, { .u_obj = mp_const_true } }, | ||||
|         { MP_QSTR_b, MP_ARG_REQUIRED | MP_ARG_INT } | ||||
|     }; | ||||
| 
 | ||||
|     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|  | @ -304,21 +285,17 @@ mp_obj_t GenericST7789_create_pen(size_t n_args, const mp_obj_t *pos_args, mp_ma | |||
| 
 | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
| 
 | ||||
|     int r = args[ARG_r].u_int; | ||||
|     int g = args[ARG_g].u_int; | ||||
|     int b = args[ARG_b].u_int; | ||||
|     bool t = args[ARG_truncate].u_obj == mp_const_true; | ||||
|     int result = self->st7789->create_pen( | ||||
|         args[ARG_r].u_int & 0xff, | ||||
|         args[ARG_g].u_int & 0xff, | ||||
|         args[ARG_b].u_int & 0xff | ||||
|     ); | ||||
| 
 | ||||
|     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 | ||||
|         return mp_obj_new_int(self->st7789->create_pen(r, g, b, t)); | ||||
|     if (result == -1) { | ||||
|         mp_raise_ValueError("create_pen failed. No space in palette!"); | ||||
|     } | ||||
| 
 | ||||
|     return mp_const_none; | ||||
|     return mp_obj_new_int(result); | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_set_clip(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|  | @ -361,24 +338,13 @@ mp_obj_t GenericST7789_clear(mp_obj_t self_in) { | |||
|     return mp_const_none; | ||||
| } | ||||
| 
 | ||||
| mp_obj_t GenericST7789_pixel(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { | ||||
|     enum { ARG_self, ARG_x, ARG_y }; | ||||
|     static const mp_arg_t allowed_args[] = { | ||||
|         { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ }, | ||||
|         { MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|         { MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT }, | ||||
|     }; | ||||
| mp_obj_t GenericST7789_pixel(mp_obj_t self_in, mp_obj_t x, mp_obj_t y) { | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(self_in, GenericST7789_obj_t); | ||||
| 
 | ||||
|     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; | ||||
|     mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); | ||||
| 
 | ||||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
| 
 | ||||
|     int x = args[ARG_x].u_int; | ||||
|     int y = args[ARG_y].u_int; | ||||
| 
 | ||||
|     Point p(x, y); | ||||
|     self->st7789->pixel(p); | ||||
|     self->st7789->pixel(Point( | ||||
|         mp_obj_get_int(x), | ||||
|         mp_obj_get_int(y) | ||||
|     )); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
|  | @ -499,21 +465,19 @@ mp_obj_t GenericST7789_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k | |||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
| 
 | ||||
|     mp_obj_t text_obj = args[ARG_text].u_obj; | ||||
|     if(mp_obj_is_str_or_bytes(text_obj)) { | ||||
|         GET_STR_DATA_LEN(text_obj, str, str_len); | ||||
| 
 | ||||
|         std::string t((const char*)str); | ||||
|     if(!mp_obj_is_str_or_bytes(text_obj)) mp_raise_TypeError("text: string required"); | ||||
| 
 | ||||
|         int x = args[ARG_x].u_int; | ||||
|         int y = args[ARG_y].u_int; | ||||
|         int wrap = args[ARG_wrap].u_int; | ||||
|         int scale = args[ARG_scale].u_int; | ||||
|     GET_STR_DATA_LEN(text_obj, str, str_len); | ||||
| 
 | ||||
|         self->st7789->text(t, Point(x, y), wrap, scale); | ||||
|     } | ||||
|     else { | ||||
|         mp_raise_TypeError("text: string required"); | ||||
|     } | ||||
|     std::string t((const char*)str); | ||||
| 
 | ||||
|     int x = args[ARG_x].u_int; | ||||
|     int y = args[ARG_y].u_int; | ||||
|     int wrap = args[ARG_wrap].u_int; | ||||
|     int scale = args[ARG_scale].u_int; | ||||
| 
 | ||||
|     self->st7789->text(t, Point(x, y), wrap, scale); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
|  | @ -532,20 +496,18 @@ mp_obj_t GenericST7789_measure_text(size_t n_args, const mp_obj_t *pos_args, mp_ | |||
|     GenericST7789_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, GenericST7789_obj_t); | ||||
| 
 | ||||
|     mp_obj_t text_obj = args[ARG_text].u_obj; | ||||
|     if(mp_obj_is_str_or_bytes(text_obj)) { | ||||
|         GET_STR_DATA_LEN(text_obj, str, str_len); | ||||
| 
 | ||||
|         std::string t((const char*)str); | ||||
|     if(!mp_obj_is_str_or_bytes(text_obj)) mp_raise_TypeError("text: string required"); | ||||
| 
 | ||||
|         int scale = args[ARG_scale].u_int; | ||||
|     GET_STR_DATA_LEN(text_obj, str, str_len); | ||||
| 
 | ||||
|         int width = self->st7789->measure_text(t, scale); | ||||
|     std::string t((const char*)str); | ||||
| 
 | ||||
|         return mp_obj_new_int(width); | ||||
|     } | ||||
|     else { | ||||
|         mp_raise_TypeError("text: string required"); | ||||
|     } | ||||
|     int scale = args[ARG_scale].u_int; | ||||
| 
 | ||||
|     int width = self->st7789->measure_text(t, scale); | ||||
| 
 | ||||
|     return mp_obj_new_int(width); | ||||
| 
 | ||||
|     return mp_const_none; | ||||
| } | ||||
|  |  | |||
|  | @ -1,26 +1,35 @@ | |||
| // Include MicroPython API.
 | ||||
| #include "py/runtime.h" | ||||
| #include "py/objstr.h" | ||||
| 
 | ||||
| /***** Extern of Class Definition *****/ | ||||
| // Type
 | ||||
| extern const mp_obj_type_t GenericST7789_type; | ||||
| 
 | ||||
| /***** Extern of Class Methods *****/ | ||||
| // Module functions
 | ||||
| extern mp_obj_t GenericST7789_module_RGB332(mp_obj_t r, mp_obj_t g, mp_obj_t b); | ||||
| extern mp_obj_t GenericST7789_module_RGB565(mp_obj_t r, mp_obj_t g, mp_obj_t b); | ||||
| 
 | ||||
| // Class methods
 | ||||
| extern void GenericST7789_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); | ||||
| extern mp_obj_t GenericST7789_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); | ||||
| extern mp_obj_t GenericST7789Parallel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); | ||||
| extern mp_obj_t GenericST7789_set_framebuffer(mp_obj_t self_in, mp_obj_t framebuffer); | ||||
| 
 | ||||
| extern mp_obj_t GenericST7789_update(mp_obj_t self_in); | ||||
| extern mp_obj_t GenericST7789_flush_palette(mp_obj_t self_in); | ||||
| extern mp_obj_t GenericST7789_default_palette(mp_obj_t self_in); | ||||
| extern mp_obj_t GenericST7789_set_backlight(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t GenericST7789_set_backlight(mp_obj_t self_in, mp_obj_t brightness); | ||||
| 
 | ||||
| extern mp_obj_t GenericST7789_set_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| // Palette management
 | ||||
| extern mp_obj_t GenericST7789_set_palette_mode(mp_obj_t self_in, mp_obj_t mode); | ||||
| extern mp_obj_t GenericST7789_set_palette(mp_obj_t self_in, mp_obj_t index, mp_obj_t colour); | ||||
| 
 | ||||
| // Pen
 | ||||
| extern mp_obj_t GenericST7789_set_pen(mp_obj_t self_in, mp_obj_t pen); | ||||
| extern mp_obj_t GenericST7789_create_pen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| 
 | ||||
| // Primitives
 | ||||
| extern mp_obj_t GenericST7789_set_clip(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t GenericST7789_remove_clip(mp_obj_t self_in); | ||||
| extern mp_obj_t GenericST7789_clear(mp_obj_t self_in); | ||||
| extern mp_obj_t GenericST7789_pixel(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t GenericST7789_pixel(mp_obj_t self_in, mp_obj_t x, mp_obj_t y); | ||||
| extern mp_obj_t GenericST7789_pixel_span(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t GenericST7789_rectangle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
| extern mp_obj_t GenericST7789_circle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args); | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 Phil Howard
						Phil Howard