@@ -76,31 +76,50 @@ int oled_display_init(void)
7676
7777 LOG_INF ("Display dimensions: %dx%d" , display_cols , display_rows );
7878
79- /* Setup font */
79+ /* Turn off display first to prevent bright flash */
80+ const struct device * i2c_dev = DEVICE_DT_GET (DT_NODELABEL (i2c1 ));
81+ if (device_is_ready (i2c_dev )) {
82+ uint8_t display_off_cmd [2 ] = {0x00 , 0xAE }; /* Display OFF command */
83+ i2c_write (i2c_dev , display_off_cmd , 2 , 0x3c );
84+ }
85+
86+ /* Setup font first */
8087 ret = oled_display_setup_font ();
8188 if (ret != 0 ) {
8289 LOG_ERR ("Failed to setup font (err %d)" , ret );
8390 return ret ;
8491 }
8592
86- /* Invert display for white text on black background */
93+ /* Clear display while it's off */
94+ ret = cfb_framebuffer_clear (display_dev , true);
95+ if (ret != 0 ) {
96+ LOG_ERR ("Failed to clear framebuffer (err %d)" , ret );
97+ return ret ;
98+ }
99+
100+ /* Finalize the clear */
101+ ret = cfb_framebuffer_finalize (display_dev );
102+ if (ret != 0 ) {
103+ LOG_ERR ("Failed to finalize clear (err %d)" , ret );
104+ return ret ;
105+ }
106+
107+ /* Set display to inverted mode while still off */
87108 ret = oled_display_invert ();
88109 if (ret != 0 ) {
89110 LOG_WRN ("Failed to invert display (err %d) - continuing with normal display" , ret );
90- /* Continue anyway - inversion is not critical */
91111 } else {
92112 LOG_INF ("Display inverted: white text on black background" );
93113 }
94114
95- /* Clear display completely */
96- ret = cfb_framebuffer_clear (display_dev , true);
97- if (ret != 0 ) {
98- LOG_ERR ("Failed to clear framebuffer (err %d)" , ret );
99- return ret ;
115+ /* Turn display back on - now it should be dark/inverted */
116+ if (device_is_ready (i2c_dev )) {
117+ uint8_t display_on_cmd [2 ] = {0x00 , 0xAF }; /* Display ON command */
118+ i2c_write (i2c_dev , display_on_cmd , 2 , 0x3c );
100119 }
101120
102- /* Small delay to ensure display clears */
103- k_sleep (K_MSEC (100 ));
121+ /* Small delay to ensure display is ready */
122+ k_sleep (K_MSEC (50 ));
104123
105124 display_ready = true;
106125 LOG_INF ("OLED display initialized successfully" );
@@ -320,6 +339,42 @@ static int oled_display_setup_font(void)
320339 return 0 ;
321340}
322341
342+ /* Private function to set normal (non-inverted) SSD1306 display via I2C command */
343+ static int oled_display_normal (void )
344+ {
345+ const struct device * i2c_dev ;
346+ uint8_t cmd_buffer [2 ] = {0x00 , 0xA6 }; /* Command prefix + SSD1306 normal display command */
347+ int ret ;
348+
349+ if (!display_available || !display_ready ) {
350+ return 0 ; /* Silently skip if no display */
351+ }
352+
353+ /* Get I2C device */
354+ i2c_dev = DEVICE_DT_GET (DT_NODELABEL (i2c1 ));
355+ if (!device_is_ready (i2c_dev )) {
356+ LOG_ERR ("I2C device not ready for display normal mode" );
357+ return - ENODEV ;
358+ }
359+
360+ /* Send normal display command to SSD1306 with proper command format */
361+ /* 0x00 = Command byte, 0xA6 = Normal display command */
362+ ret = i2c_write (i2c_dev , cmd_buffer , 2 , 0x3c );
363+ if (ret != 0 ) {
364+ LOG_ERR ("Failed to send normal display command via I2C (err %d)" , ret );
365+ /* Try again once after a brief delay */
366+ k_sleep (K_MSEC (1 ));
367+ ret = i2c_write (i2c_dev , cmd_buffer , 2 , 0x3c );
368+ if (ret != 0 ) {
369+ LOG_ERR ("Normal display command failed again (err %d)" , ret );
370+ return ret ;
371+ }
372+ }
373+
374+ LOG_DBG ("SSD1306 normal display command sent successfully (0x00 0xA6)" );
375+ return 0 ;
376+ }
377+
323378/* Private function to invert the SSD1306 display via I2C command */
324379static int oled_display_invert (void )
325380{
@@ -407,13 +462,12 @@ static void oled_display_invert_bitmap(const uint8_t *src, uint8_t *dst, size_t
407462int oled_display_splash_screen (uint32_t duration_ms )
408463{
409464 int ret ;
410- static uint8_t inverted_logo [AUGMENTAL_LOGO_WIDTH * AUGMENTAL_LOGO_HEIGHT / 8 ];
411465
412466 if (!display_available || !display_ready ) {
413467 return 0 ; /* Silently skip if no display */
414468 }
415469
416- LOG_INF ("Displaying Augmental logo splash screen with fade effects ..." );
470+ LOG_INF ("Displaying Augmental logo splash screen..." );
417471
418472 /* Clear display first using CFB */
419473 ret = cfb_framebuffer_clear (display_dev , false);
@@ -429,10 +483,7 @@ int oled_display_splash_screen(uint32_t duration_ms)
429483 return ret ;
430484 }
431485
432- /* Invert the bitmap for white-on-black display */
433- oled_display_invert_bitmap (augmental_logo_bitmap , inverted_logo ,
434- AUGMENTAL_LOGO_WIDTH * AUGMENTAL_LOGO_HEIGHT / 8 );
435-
486+ /* Use original bitmap since display is in inverted mode (shows white on dark) */
436487 /* Prepare buffer descriptor */
437488 struct display_buffer_descriptor desc = {
438489 .buf_size = AUGMENTAL_LOGO_WIDTH * AUGMENTAL_LOGO_HEIGHT / 8 ,
@@ -442,8 +493,8 @@ int oled_display_splash_screen(uint32_t duration_ms)
442493 .frame_incomplete = false
443494 };
444495
445- /* Write the inverted bitmap to the display */
446- ret = display_write (display_dev , 0 , 0 , & desc , inverted_logo );
496+ /* Write the original bitmap to the display instantly */
497+ ret = display_write (display_dev , 0 , 0 , & desc , augmental_logo_bitmap );
447498 if (ret != 0 ) {
448499 LOG_ERR ("Failed to write logo bitmap (err %d)" , ret );
449500 /* Fall back to text display on error */
@@ -460,18 +511,11 @@ int oled_display_splash_screen(uint32_t duration_ms)
460511 }
461512 }
462513
463- /* Fade in effect */
464- LOG_INF ("Starting fade in..." );
465- for (int contrast = 0 ; contrast <= 255 ; contrast += 15 ) {
466- oled_display_set_contrast (contrast );
467- k_sleep (K_MSEC (20 )); /* 20ms per step for smooth fade */
468- }
469- oled_display_set_contrast (255 ); /* Ensure full brightness */
470-
514+ /* Set full brightness immediately - no fade in */
515+ oled_display_set_contrast (255 );
516+
471517 /* Hold splash screen at full brightness */
472- if (duration_ms > 500 ) {
473- k_sleep (K_MSEC (duration_ms - 500 )); /* Account for fade time */
474- }
518+ k_sleep (K_MSEC (duration_ms ));
475519
476520 /* Fast fade out effect */
477521 LOG_INF ("Starting fast fade out..." );
@@ -480,21 +524,56 @@ int oled_display_splash_screen(uint32_t duration_ms)
480524 k_sleep (K_MSEC (25 )); /* Slightly longer per step but fewer steps */
481525 }
482526
483- /* Ensure fully black */
484- oled_display_set_contrast (0 );
485- k_sleep (K_MSEC (50 )); /* Brief black screen */
527+ /* Turn display OFF completely to avoid any flashing */
528+ const struct device * i2c_dev = DEVICE_DT_GET (DT_NODELABEL (i2c1 ));
529+ if (device_is_ready (i2c_dev )) {
530+ uint8_t display_off_cmd [2 ] = {0x00 , 0xAE }; /* Display OFF command */
531+ i2c_write (i2c_dev , display_off_cmd , 2 , 0x3c );
532+ }
533+
534+ k_sleep (K_MSEC (50 )); /* Brief pause while off */
486535
487- /* Clear the bitmap completely */
536+ /* Clear the bitmap completely and prepare status display while display is OFF */
488537 ret = cfb_framebuffer_clear (display_dev , false);
489- if (ret == 0 ) {
490- cfb_framebuffer_finalize (display_dev );
538+ if (ret != 0 ) {
539+ LOG_ERR ("Failed to clear framebuffer (err %d)" , ret );
540+ return ret ;
491541 }
492542
493- /* Restore normal contrast for regular display */
543+ /* Render the status display content while display is OFF */
544+ uint16_t line_spacing = 16 ;
545+ uint16_t y_pos = 0 ;
546+
547+ /* Line 1: MouthPad^USB title */
548+ cfb_print (display_dev , "MouthPad^USB" , 0 , y_pos );
549+ y_pos += line_spacing ;
550+
551+ /* Line 2: Scanning status */
552+ cfb_print (display_dev , "Scanning..." , 0 , y_pos );
553+
554+ /* Finalize the content while display is still OFF */
555+ ret = cfb_framebuffer_finalize (display_dev );
556+ if (ret != 0 ) {
557+ LOG_ERR ("Failed to finalize status display (err %d)" , ret );
558+ return ret ;
559+ }
560+
561+ /* Restore full contrast first */
494562 oled_display_set_contrast (255 );
563+
564+ /* Small delay to ensure all settings are applied */
565+ k_sleep (K_MSEC (10 ));
566+
567+ /* Now turn display back ON - content is already rendered and inverted */
568+ if (device_is_ready (i2c_dev )) {
569+ uint8_t display_on_cmd [2 ] = {0x00 , 0xAF }; /* Display ON command */
570+ i2c_write (i2c_dev , display_on_cmd , 2 , 0x3c );
571+ }
495572
496- /* Immediately show initial status after splash screen */
497- oled_display_update_status (0xFF , false); /* Show "Scanning..." state */
573+ /* Display remains in inverted mode - no need to restore */
574+
575+ /* Reset the display state so the next update will work properly */
576+ oled_display_reset_state ();
498577
499578 LOG_INF ("Splash screen complete - transitioned to status display" );
500579
0 commit comments