@@ -14,6 +14,9 @@ pub const PAGE: u8 = ROW as u8 / 8;
1414// IFRAM space reserved for UDMA channel commands
1515const SIDEBAND_LEN : usize = 256 ;
1616
17+ // 0x4f is a bit too bright
18+ pub const DEFAULT_BRIGHTNESS : u8 = 0x3f ;
19+
1720pub struct MainThreadToken ( ( ) ) ;
1821impl MainThreadToken {
1922 pub fn new ( ) -> Self { MainThreadToken ( ( ) ) }
@@ -465,7 +468,7 @@ impl<'a> Oled128x128<'a> {
465468 SetDCDCSettings ( 0x0 ) ,
466469 SetStartLine ( 0 ) ,
467470 SetDisplayOffset ( 0 ) ,
468- SetContrastControl ( 0x3f ) , // was 0x4f, was a bit too bright
471+ SetContrastControl ( DEFAULT_BRIGHTNESS ) ,
469472 SetAddressMode ( AddressMode :: Column ) ,
470473 SetSegmentReMap ( false ) ,
471474 SetCOMScanDirection ( Direction :: Inverted ) ,
@@ -512,6 +515,61 @@ impl<'a> Oled128x128<'a> {
512515 crate :: board:: assert_periph_reset ( self . iox , false ) ;
513516 self . powerdown = false ;
514517 }
518+
519+ pub fn brightness ( & mut self , level : u8 ) {
520+ let bytes = Command :: SetContrastControl ( level) . encode ( ) ;
521+ self . send_command ( bytes) ;
522+ }
523+
524+ #[ cfg( feature = "std" ) ]
525+ pub fn render_bitmap ( & mut self , bitmap : ux_api:: service:: api:: BaosecBitmap ) {
526+ const W : isize = WIDTH as _ ;
527+ const H : isize = LINES as _ ;
528+
529+ // Clamp bounding box to valid bitmap dimensions.
530+ // If br > 128, truncate. If tl < 0, clamp to 0.
531+ let src_x0 = bitmap. bounding_box . tl . x . max ( 0 ) ;
532+ let src_y0 = bitmap. bounding_box . tl . y . max ( 0 ) ;
533+ let src_x1 = bitmap. bounding_box . br . x . min ( W ) ;
534+ let src_y1 = bitmap. bounding_box . br . y . min ( H ) ;
535+
536+ for src_y in src_y0..src_y1 {
537+ // Map this bitmap row to its destination row in the framebuffer.
538+ let dst_y = src_y + bitmap. top_left . y ;
539+
540+ // Skip rows that land outside the framebuffer.
541+ if dst_y < 0 || dst_y >= H {
542+ continue ;
543+ }
544+
545+ for src_x in src_x0..src_x1 {
546+ // Map this bitmap column to its destination column.
547+ let dst_x = src_x + bitmap. top_left . x ;
548+
549+ // Skip columns that land outside the framebuffer.
550+ if dst_x < 0 || dst_x >= W {
551+ continue ;
552+ }
553+
554+ // --- read source bit ---
555+ let src_linear = ( src_x + src_y * W ) as usize ;
556+ let src_word = src_linear >> 5 ; // / 32
557+ let src_shift = src_linear & 0x1F ; // % 32
558+ let on = ( bitmap. bits [ src_word] >> src_shift) & 1 ;
559+
560+ // --- write destination bit ---
561+ let dst_linear = ( dst_x + dst_y * W ) as usize ;
562+ let dst_word = dst_linear >> 5 ;
563+ let dst_shift = dst_linear & 0x1F ;
564+
565+ if on != 0 {
566+ self . buffer [ dst_word] |= 1 << dst_shift;
567+ } else {
568+ self . buffer [ dst_word] &= !( 1 << dst_shift) ;
569+ }
570+ }
571+ }
572+ }
515573}
516574
517575impl < ' a > FrameBuffer for Oled128x128 < ' a > {
0 commit comments