Integrate embeddedgraphics #2

Merged
rafaelcaricio merged 4 commits from integrate_embeddedgraphics into master 2020-04-19 13:40:04 +00:00
Showing only changes of commit 0ddd716735 - Show all commits

View file

@ -4,34 +4,27 @@ use embedded_graphics;
use embedded_graphics::prelude::*; use embedded_graphics::prelude::*;
use embedded_graphics::{drawable, DrawTarget}; use embedded_graphics::{drawable, DrawTarget};
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use embedded_graphics::pixelcolor::{PixelColor, raw::RawData, raw::RawU32}; use embedded_graphics::pixelcolor::PixelColor;
use core::marker::PhantomData; use core::marker::PhantomData;
struct DisplayDriver<F, C> struct DisplayDriver<'a, T, C>
where where
F: FnMut(drawable::Pixel<C>), T: DrawTarget<C>,
rafaelcaricio commented 2020-04-19 13:31:49 +00:00 (Migrated from github.com)
Review

Would be nice to have this type more generic. Not all embedded systems will support that.

Would be nice to have this type more generic. Not all embedded systems will support that.
C: PixelColor C: PixelColor
{ {
pub raw: lvgl_sys::lv_disp_drv_t, pub raw: lvgl_sys::lv_disp_drv_t,
callback: F,
display_buffer: MaybeUninit<lvgl_sys::lv_disp_buf_t>, display_buffer: MaybeUninit<lvgl_sys::lv_disp_buf_t>,
refresh_buffer: [MaybeUninit<lvgl_sys::lv_color_t>; lvgl_sys::LV_HOR_RES_MAX as usize * 10], refresh_buffer: [MaybeUninit<lvgl_sys::lv_color_t>; lvgl_sys::LV_HOR_RES_MAX as usize * 10],
phantom: PhantomData<C>, phantom: &'a PhantomData<T>,
phantom1: PhantomData<C>,
} }
impl<F, C> DisplayDriver<F, C> where impl<'a, T, C> DisplayDriver<'a, T, C> where
F: FnMut(drawable::Pixel<C>), T: DrawTarget<C>,
C: PixelColor { C: PixelColor
{
pub fn new<T>(mut device: T) -> Self pub fn new(device: &'a mut T) -> Self {
where
T: DrawTarget<C>
{
let mut callback = move |pixel: drawable::Pixel<C>| {
let _ = device.draw_pixel(pixel);
};
// Create a display buffer for LittlevGL // Create a display buffer for LittlevGL
let mut display_buffer = MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit(); let mut display_buffer = MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit();
// Declare a buffer for 10 lines // Declare a buffer for 10 lines
@ -53,8 +46,8 @@ impl<F, C> DisplayDriver<F, C> where
// Basic initialization // Basic initialization
lvgl_sys::lv_disp_drv_init(&mut disp_drv); lvgl_sys::lv_disp_drv_init(&mut disp_drv);
// Set your driver function // Set your driver function
disp_drv.flush_cb = Some(display_callback_wrapper::<F, C>); disp_drv.flush_cb = Some(display_callback_wrapper::<T, C>);
disp_drv.user_data = &mut callback as *mut _ as *mut cty::c_void; disp_drv.user_data = device as *mut _ as *mut cty::c_void;
disp_drv disp_drv
}; };
// Assign the buffer to the display // Assign the buffer to the display
@ -65,10 +58,10 @@ impl<F, C> DisplayDriver<F, C> where
} }
Self { Self {
raw: disp_drv, raw: disp_drv,
callback,
display_buffer, display_buffer,
refresh_buffer, refresh_buffer,
phantom: PhantomData, phantom: &PhantomData,
phantom1: PhantomData,
} }
} }
@ -77,12 +70,12 @@ impl<F, C> DisplayDriver<F, C> where
} }
} }
unsafe extern "C" fn display_callback_wrapper<F, C>( unsafe extern "C" fn display_callback_wrapper<T, C>(
disp_drv: *mut lvgl_sys::lv_disp_drv_t, disp_drv: *mut lvgl_sys::lv_disp_drv_t,
area: *const lvgl_sys::lv_area_t, area: *const lvgl_sys::lv_area_t,
color_p: *mut lvgl_sys::lv_color_t, color_p: *mut lvgl_sys::lv_color_t,
) where ) where
F: FnMut(drawable::Pixel<C>), T: DrawTarget<C>,
C: PixelColor C: PixelColor
{ {
// We need to make sure panics can't escape across the FFI boundary. // We need to make sure panics can't escape across the FFI boundary.
@ -91,19 +84,15 @@ unsafe extern "C" fn display_callback_wrapper<F, C>(
let disp = *disp_drv; let disp = *disp_drv;
// Rust code closure reference // Rust code closure reference
let closure = &mut *(disp.user_data as *mut F); let device = &mut *(disp.user_data as *mut T);
for y in (*area).y1..=(*area).y2 { for y in (*area).y1..=(*area).y2 {
rafaelcaricio commented 2020-04-19 13:32:35 +00:00 (Migrated from github.com)
Review

I just could not figure out to make it more generic because of this line. We need a concrete type to instantiate the color.

I just could not figure out to make it more generic because of this line. We need a concrete type to instantiate the color.
for x in (*area).x1..=(*area).x2 { for x in (*area).x1..=(*area).x2 {
// Convert C color representation to high-level Rust // Convert C color representation to high-level Rust
let raw_color = *color_p.add(i); let raw_color = *color_p.add(i);
// let color = Rgb888::new(raw_color.ch.red,
// raw_color.ch.green,
// raw_color.ch.blue);
let color = C::Raw::from_u32(raw_color.full);
i = i + 1; i = i + 1;
// Callback the Rust closure to flush the new points to the screen // Callback the Rust closure to flush the new points to the screen
closure(drawable::Pixel(Point::new(x as i32, y as i32), color)); let _ = device.draw_pixel(drawable::Pixel(Point::new(x as i32, y as i32), raw_color.into()));
} }
} }
// Indicate to LittlevGL that you are ready with the flushing // Indicate to LittlevGL that you are ready with the flushing