kopia lustrzana https://github.com/pimoroni/pimoroni-pico
				
				
				
			Inky 7.3: C++ library and JPEG example compatibility.
							rodzic
							
								
									1317f2e04e
								
							
						
					
					
						commit
						d3a1a571d3
					
				|  | @ -1,14 +1,28 @@ | |||
| set(OUTPUT_NAME inky_frame_jpeg_image) | ||||
| 
 | ||||
| add_executable( | ||||
|   ${OUTPUT_NAME} | ||||
|   inky_frame_jpeg_image | ||||
|   inky_frame_jpeg_image.cpp | ||||
| ) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(${OUTPUT_NAME} pico_stdlib jpegdec inky_frame fatfs hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics) | ||||
| target_link_libraries(inky_frame_jpeg_image pico_stdlib jpegdec inky_frame fatfs hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics) | ||||
| 
 | ||||
| pico_enable_stdio_usb(${OUTPUT_NAME} 1) | ||||
| pico_enable_stdio_usb(inky_frame_jpeg_image 1) | ||||
| 
 | ||||
| # create map/bin/hex file etc. | ||||
| pico_add_extra_outputs(${OUTPUT_NAME}) | ||||
| pico_add_extra_outputs(inky_frame_jpeg_image) | ||||
| 
 | ||||
| 
 | ||||
| add_executable( | ||||
|   inky_frame_7_jpeg_image | ||||
|   inky_frame_jpeg_image.cpp | ||||
| ) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(inky_frame_7_jpeg_image pico_stdlib jpegdec inky_frame_7 fatfs hardware_pwm hardware_spi hardware_i2c hardware_rtc fatfs sdcard pico_graphics) | ||||
| 
 | ||||
| pico_enable_stdio_usb(inky_frame_7_jpeg_image 1) | ||||
| 
 | ||||
| # create map/bin/hex file etc. | ||||
| pico_add_extra_outputs(inky_frame_7_jpeg_image) | ||||
| 
 | ||||
| target_compile_definitions(inky_frame_7_jpeg_image PUBLIC INKY_FRAME_7) | ||||
|  |  | |||
|  | @ -7,7 +7,11 @@ | |||
| 
 | ||||
| #include "JPEGDEC.h" | ||||
| 
 | ||||
| #ifdef INKY_FRAME_7 | ||||
| #include "libraries/inky_frame_7/inky_frame_7.hpp" | ||||
| #else | ||||
| #include "libraries/inky_frame/inky_frame.hpp" | ||||
| #endif | ||||
| 
 | ||||
| using namespace pimoroni; | ||||
| 
 | ||||
|  | @ -169,7 +173,7 @@ int main() { | |||
|   printf("done!\n"); | ||||
| 
 | ||||
|   printf("Displaying file: %s\n", filename.c_str()); | ||||
|   draw_jpeg(filename, 0, 0, 600, 448); | ||||
|   draw_jpeg(filename, 0, 0, inky.width, inky.height); | ||||
|   printf("done!\n"); | ||||
| 
 | ||||
|   inky.update(); | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ add_subdirectory(inventor2040w) | |||
| add_subdirectory(adcfft) | ||||
| add_subdirectory(jpegdec) | ||||
| add_subdirectory(inky_frame) | ||||
| add_subdirectory(inky_frame_7) | ||||
| add_subdirectory(galactic_unicorn) | ||||
| add_subdirectory(gfx_pack) | ||||
| add_subdirectory(interstate75) | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| include(inky_frame_7.cmake) | ||||
|  | @ -0,0 +1,13 @@ | |||
| set(LIB_NAME inky_frame_7) | ||||
| add_library(${LIB_NAME} INTERFACE) | ||||
| 
 | ||||
| target_sources(${LIB_NAME} INTERFACE | ||||
|   ${CMAKE_CURRENT_LIST_DIR}/${LIB_NAME}.cpp | ||||
| ) | ||||
| 
 | ||||
| target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}) | ||||
| 
 | ||||
| # Pull in pico libraries that we need | ||||
| target_link_libraries(${LIB_NAME} INTERFACE hardware_i2c pico_graphics hardware_spi hardware_pwm bitmap_fonts hershey_fonts pico_stdlib sdcard fatfs pcf85063a psram_display inky73 jpegdec) | ||||
| 
 | ||||
| target_compile_options(${LIB_NAME} INTERFACE -Wno-error=reorder) | ||||
|  | @ -0,0 +1,166 @@ | |||
| #include <string.h> | ||||
| #include <math.h> | ||||
| #include <functional> | ||||
| 
 | ||||
| #include "hardware/pwm.h" | ||||
| #include "hardware/watchdog.h" | ||||
| 
 | ||||
| #include "inky_frame_7.hpp" | ||||
| 
 | ||||
| namespace pimoroni { | ||||
|   void gpio_configure(uint gpio, bool dir, bool value = false) { | ||||
|     gpio_set_function(gpio, GPIO_FUNC_SIO); gpio_set_dir(gpio, dir); gpio_put(gpio, value); | ||||
|   } | ||||
| 
 | ||||
|   void gpio_configure_pwm(uint gpio) { | ||||
|     pwm_config cfg = pwm_get_default_config(); | ||||
|     pwm_set_wrap(pwm_gpio_to_slice_num(gpio), 65535); | ||||
|     pwm_init(pwm_gpio_to_slice_num(gpio), &cfg, true); | ||||
|     gpio_set_function(gpio, GPIO_FUNC_PWM); | ||||
|   } | ||||
| 
 | ||||
|   void InkyFrame::init() { | ||||
|     // keep the pico awake by holding vsys_en high
 | ||||
|     gpio_set_function(HOLD_VSYS_EN, GPIO_FUNC_SIO); | ||||
|     gpio_set_dir(HOLD_VSYS_EN, GPIO_OUT); | ||||
|     gpio_put(HOLD_VSYS_EN, true); | ||||
| 
 | ||||
|     // setup the shift register
 | ||||
|     gpio_configure(SR_CLOCK, GPIO_OUT, true); | ||||
|     gpio_configure(SR_LATCH, GPIO_OUT, true); | ||||
|     gpio_configure(SR_OUT, GPIO_IN); | ||||
| 
 | ||||
|     // determine wake up event
 | ||||
|     if(read_shift_register_bit(BUTTON_A)) {_wake_up_event = BUTTON_A_EVENT;} | ||||
|     if(read_shift_register_bit(BUTTON_B)) {_wake_up_event = BUTTON_B_EVENT;} | ||||
|     if(read_shift_register_bit(BUTTON_C)) {_wake_up_event = BUTTON_C_EVENT;} | ||||
|     if(read_shift_register_bit(BUTTON_D)) {_wake_up_event = BUTTON_D_EVENT;} | ||||
|     if(read_shift_register_bit(BUTTON_E)) {_wake_up_event = BUTTON_E_EVENT;} | ||||
|     if(read_shift_register_bit(RTC_ALARM)) {_wake_up_event = RTC_ALARM_EVENT;} | ||||
|     if(read_shift_register_bit(EXTERNAL_TRIGGER)) {_wake_up_event = EXTERNAL_TRIGGER_EVENT;} | ||||
|     // there are other reasons a wake event can occur: connect power via usb,
 | ||||
|     // connect a battery, or press the reset button. these cannot be
 | ||||
|     // disambiguated so we don't attempt to report them
 | ||||
| 
 | ||||
|     // Disable display update busy wait, we'll handle it ourselves
 | ||||
|     inky73.set_blocking(false); | ||||
| 
 | ||||
|     // initialise the rtc
 | ||||
|     rtc.init(); | ||||
| 
 | ||||
|     // setup led pwm
 | ||||
|     gpio_configure_pwm(LED_A); | ||||
|     gpio_configure_pwm(LED_B); | ||||
|     gpio_configure_pwm(LED_C); | ||||
|     gpio_configure_pwm(LED_D); | ||||
|     gpio_configure_pwm(LED_E); | ||||
|     gpio_configure_pwm(LED_ACTIVITY); | ||||
|     gpio_configure_pwm(LED_CONNECTION); | ||||
|   } | ||||
| 
 | ||||
|   bool InkyFrame::is_busy() { | ||||
|     // check busy flag on shift register
 | ||||
|     bool busy = !read_shift_register_bit(Flags::EINK_BUSY); | ||||
|     return busy; | ||||
|   } | ||||
| 
 | ||||
|   void InkyFrame::update(bool blocking) { | ||||
|     while(is_busy()) { | ||||
|       tight_loop_contents(); | ||||
|     } | ||||
|     inky73.update((PicoGraphics_PenInky7 *)this); | ||||
|     while(is_busy()) { | ||||
|       tight_loop_contents(); | ||||
|     } | ||||
|     inky73.power_off(); | ||||
|   } | ||||
| 
 | ||||
|   bool InkyFrame::pressed(Button button) { | ||||
|     return read_shift_register_bit(button); | ||||
|   } | ||||
| 
 | ||||
|   // set the LED brightness by generating a gamma corrected target value for
 | ||||
|   // the 16-bit pwm channel. brightness values are from 0 to 100.
 | ||||
|   void InkyFrame::led(LED led, uint8_t brightness) { | ||||
|     uint16_t value = | ||||
|       (uint16_t)(pow((float)(brightness) / 100.0f, 2.8) * 65535.0f + 0.5f); | ||||
|     pwm_set_gpio_level(led, value); | ||||
|   } | ||||
| 
 | ||||
|   uint8_t InkyFrame::read_shift_register() { | ||||
|     gpio_put(SR_LATCH, false); sleep_us(1); | ||||
|     gpio_put(SR_LATCH, true); sleep_us(1); | ||||
| 
 | ||||
|     uint8_t result = 0; | ||||
|     uint8_t bits = 8; | ||||
|     while(bits--) { | ||||
|       result <<= 1; | ||||
|       result |= gpio_get(SR_OUT) ? 1 : 0; | ||||
| 
 | ||||
|       gpio_put(SR_CLOCK, false); sleep_us(1); | ||||
|       gpio_put(SR_CLOCK, true); sleep_us(1); | ||||
|     } | ||||
| 
 | ||||
|     return result; | ||||
|   } | ||||
| 
 | ||||
|   bool InkyFrame::read_shift_register_bit(uint8_t index) { | ||||
|     return read_shift_register() & (1U << index); | ||||
|   } | ||||
| 
 | ||||
|   void InkyFrame::sleep(int wake_in_minutes) { | ||||
|     if(wake_in_minutes != -1) { | ||||
|       // set an alarm to wake inky up in wake_in_minutes - the maximum sleep
 | ||||
|       // is 255 minutes or around 4.5 hours which is the longest timer the RTC
 | ||||
|       // supports, to sleep any longer we need to specify a date and time to
 | ||||
|       // wake up
 | ||||
|       rtc.set_timer(wake_in_minutes, PCF85063A::TIMER_TICK_1_OVER_60HZ); | ||||
|       rtc.enable_timer_interrupt(true, false); | ||||
|     } | ||||
| 
 | ||||
|     // release the vsys hold pin so that inky can go to sleep
 | ||||
|     gpio_put(HOLD_VSYS_EN, false); | ||||
|     while(true){}; | ||||
|   } | ||||
| 
 | ||||
|   void InkyFrame::sleep_until(int second, int minute, int hour, int day) { | ||||
|     if(second != -1 || minute != -1 || hour != -1 || day != -1) { | ||||
|       // set an alarm to wake inky up at the specified time and day
 | ||||
|       rtc.set_alarm(second, minute, hour, day); | ||||
|       rtc.enable_alarm_interrupt(true); | ||||
|     } | ||||
| 
 | ||||
|     // release the vsys hold pin so that inky can go to sleep
 | ||||
|     gpio_put(HOLD_VSYS_EN, false); | ||||
|   } | ||||
| 
 | ||||
|   // Display a portion of an image (icon sheet) at dx, dy
 | ||||
|   void InkyFrame::icon(const uint8_t *data, int sheet_width, int icon_size, int index, int dx, int dy) { | ||||
|     image(data, sheet_width, icon_size * index, 0, icon_size, icon_size, dx, dy); | ||||
|   } | ||||
| 
 | ||||
|   // Display an image that fills the screen (286*128)
 | ||||
|   void InkyFrame::image(const uint8_t* data) { | ||||
|     image(data, width, 0, 0, width, height, 0, 0); | ||||
|   } | ||||
| 
 | ||||
|   // Display an image smaller than the screen (sw*sh) at dx, dy
 | ||||
|   void InkyFrame::image(const uint8_t *data, int w, int h, int x, int y) { | ||||
|     image(data, w, 0, 0, w, h, x, y); | ||||
|   } | ||||
| 
 | ||||
|   void InkyFrame::image(const uint8_t *data, int stride, int sx, int sy, int dw, int dh, int dx, int dy) { | ||||
|     for(auto y = 0; y < dh; y++) { | ||||
|       for(auto x = 0; x < dw; x++) { | ||||
| 
 | ||||
|         uint32_t o = ((y + sy) * (stride / 2)) + ((x + sx) / 2); | ||||
|         uint8_t  d = ((x + sx) & 0b1) ? data[o] >> 4 : data[o] & 0xf; | ||||
| 
 | ||||
|         // draw the pixel
 | ||||
|         set_pen(d); | ||||
|         pixel({dx + x, dy + y}); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,135 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| #include "drivers/inky73/inky73.hpp" | ||||
| #include "drivers/psram_display/psram_display.hpp" | ||||
| #include "drivers/pcf85063a/pcf85063a.hpp" | ||||
| #include "drivers/fatfs/ff.h" | ||||
| 
 | ||||
| #include "libraries/pico_graphics/pico_graphics.hpp" | ||||
| 
 | ||||
| namespace pimoroni { | ||||
| 
 | ||||
|   class InkyFrame : public PicoGraphics_PenInky7 { | ||||
|   public: | ||||
|     enum Button : uint8_t { | ||||
|       BUTTON_A = 0, | ||||
|       BUTTON_B = 1, | ||||
|       BUTTON_C = 2, | ||||
|       BUTTON_D = 3, | ||||
|       BUTTON_E = 4 | ||||
|     }; | ||||
| 
 | ||||
|     enum LED : uint8_t { | ||||
|       LED_ACTIVITY    = 6, | ||||
|       LED_CONNECTION  = 7, | ||||
|       LED_A           = 11, | ||||
|       LED_B           = 12, | ||||
|       LED_C           = 13, | ||||
|       LED_D           = 14, | ||||
|       LED_E           = 15 | ||||
|     }; | ||||
| 
 | ||||
|     enum Flags : uint8_t { | ||||
|       RTC_ALARM = 5, | ||||
|       EXTERNAL_TRIGGER = 6, | ||||
|       EINK_BUSY = 7 | ||||
|     }; | ||||
| 
 | ||||
|     enum WakeUpEvent : uint8_t { | ||||
|       UNKNOWN_EVENT = 0, | ||||
|       BUTTON_A_EVENT = 1, | ||||
|       BUTTON_B_EVENT = 2, | ||||
|       BUTTON_C_EVENT = 3, | ||||
|       BUTTON_D_EVENT = 4, | ||||
|       BUTTON_E_EVENT = 5, | ||||
|       RTC_ALARM_EVENT = 6, | ||||
|       EXTERNAL_TRIGGER_EVENT = 7, | ||||
|     }; | ||||
| 
 | ||||
|     enum Pen : uint8_t { | ||||
|       BLACK  = 0, | ||||
|       WHITE  = 1, | ||||
|       GREEN  = 2, | ||||
|       BLUE   = 3, | ||||
|       RED    = 4, | ||||
|       YELLOW = 5, | ||||
|       ORANGE = 6, | ||||
|       CLEAN  = 7, | ||||
|       TAUPE  = 7 | ||||
|     }; | ||||
| 
 | ||||
|   protected: | ||||
|     WakeUpEvent _wake_up_event = UNKNOWN_EVENT; | ||||
| 
 | ||||
|     enum Pin { | ||||
|       HOLD_VSYS_EN  =  2, | ||||
|       I2C_INT       =  3, | ||||
|       I2C_SDA       =  4, | ||||
|       I2C_SCL       =  5, | ||||
|       SR_CLOCK      =  8, | ||||
|       SR_LATCH      =  9, | ||||
|       SR_OUT        = 10, | ||||
|       MISO          = 16, | ||||
|       EINK_CS       = 17, | ||||
|       CLK           = 18, | ||||
|       MOSI          = 19, | ||||
|       SD_DAT0       = 19, | ||||
|       SD_DAT1       = 20, | ||||
|       SD_DAT2       = 21, | ||||
|       SD_DAT3       = 22, | ||||
|       SD_CS         = 22, | ||||
|       ADC0          = 26, | ||||
|       EINK_RESET    = 27, | ||||
|       EINK_DC       = 28 | ||||
|     }; | ||||
| 
 | ||||
|   public: | ||||
|     PSRamDisplay ramDisplay; | ||||
|     Inky73 inky73; | ||||
|     I2C i2c; | ||||
|     PCF85063A rtc; | ||||
| 
 | ||||
|     int width; | ||||
|     int height; | ||||
| 
 | ||||
|     // Default 7.3" constructor
 | ||||
|     InkyFrame() : InkyFrame(800, 480) {}; | ||||
| 
 | ||||
|     // 600x448 for 5.7"
 | ||||
|     // 640x400 for 4.0"
 | ||||
|     InkyFrame(int width, int height) : | ||||
|       ramDisplay(width, height), | ||||
|       PicoGraphics_PenInky7(width, height, ramDisplay), | ||||
|       inky73(width, height), | ||||
|       i2c(4, 5), | ||||
|       rtc(&i2c), | ||||
|       width(width), | ||||
|       height(height) { | ||||
|     } | ||||
| 
 | ||||
|     void init(); | ||||
| 
 | ||||
|     // wake/sleep management
 | ||||
|     void sleep(int wake_in_minutes = -1); | ||||
|     void sleep_until(int second = -1, int minute = -1, int hour = -1, int day = -1); | ||||
|     WakeUpEvent get_wake_up_event() {return _wake_up_event;} | ||||
| 
 | ||||
|     // screen management
 | ||||
|     void update(bool blocking=false); | ||||
|     static bool is_busy(); | ||||
| 
 | ||||
|     // state
 | ||||
|     bool pressed(Button button); | ||||
|     static uint8_t read_shift_register(); | ||||
|     static bool read_shift_register_bit(uint8_t index); | ||||
|     void led(LED led, uint8_t brightness); | ||||
| 
 | ||||
|     void icon(const uint8_t *data, int sheet_width, int icon_size, int index, int dx, int dy); | ||||
|     void image(const uint8_t* data); | ||||
|     void image(const uint8_t *data, int w, int h, int x, int y); | ||||
|     void image(const uint8_t *data, int stride, int sx, int sy, int dw, int dh, int dx, int dy); | ||||
|   }; | ||||
| 
 | ||||
| } | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Phil Howard
						Phil Howard