@@ -201,45 +201,35 @@ static esp_err_t _write_to_expander(const i2c_lcd1602_info_t * i2c_lcd1602_info,
201201 return smbus_send_byte (i2c_lcd1602_info -> smbus_info , data | i2c_lcd1602_info -> backlight_flag );
202202}
203203
204+ // IMPORTANT - for the display to stay "in sync" it is important that errors do not interrupt the
205+ // 2 x nibble sequence.
206+
204207// clock data from expander to LCD by causing a falling edge on Enable
205208static esp_err_t _strobe_enable (const i2c_lcd1602_info_t * i2c_lcd1602_info , uint8_t data )
206209{
207- esp_err_t err = _write_to_expander (i2c_lcd1602_info , data | FLAG_ENABLE );
208- if (err == ESP_OK )
209- {
210- ets_delay_us (DELAY_ENABLE_PULSE_WIDTH );
211- err = _write_to_expander (i2c_lcd1602_info , data & ~FLAG_ENABLE );
212- if (err == ESP_OK )
213- {
214- ets_delay_us (DELAY_ENABLE_PULSE_SETTLE );
215- ESP_LOGD (TAG , "enable strobed" );
216- }
217- }
218- return err ;
210+ esp_err_t err1 = _write_to_expander (i2c_lcd1602_info , data | FLAG_ENABLE );
211+ ets_delay_us (DELAY_ENABLE_PULSE_WIDTH );
212+ esp_err_t err2 = _write_to_expander (i2c_lcd1602_info , data & ~FLAG_ENABLE );
213+ ets_delay_us (DELAY_ENABLE_PULSE_SETTLE );
214+ return err1 ? err1 : err2 ;
219215}
220216
221217// send top nibble to the LCD controller
222218static esp_err_t _write_top_nibble (const i2c_lcd1602_info_t * i2c_lcd1602_info , uint8_t data )
223219{
224220 ESP_LOGD (TAG , "_write_top_nibble 0x%02x" , data );
225- esp_err_t err = _write_to_expander (i2c_lcd1602_info , data );
226- if (err == ESP_OK )
227- {
228- err = _strobe_enable (i2c_lcd1602_info , data );
229- }
230- return err ;
221+ esp_err_t err1 = _write_to_expander (i2c_lcd1602_info , data );
222+ esp_err_t err2 = _strobe_enable (i2c_lcd1602_info , data );
223+ return err1 ? err1 : err2 ;
231224}
232225
233226// send command or data to controller
234227static esp_err_t _write (const i2c_lcd1602_info_t * i2c_lcd1602_info , uint8_t value , uint8_t register_select_flag )
235228{
236229 ESP_LOGD (TAG , "_write 0x%02x | 0x%02x" , value , register_select_flag );
237- esp_err_t err = _write_top_nibble (i2c_lcd1602_info , (value & 0xf0 ) | register_select_flag );
238- if (err == ESP_OK )
239- {
240- err = _write_top_nibble (i2c_lcd1602_info , ((value & 0x0f ) << 4 ) | register_select_flag );
241- }
242- return err ;
230+ esp_err_t err1 = _write_top_nibble (i2c_lcd1602_info , (value & 0xf0 ) | register_select_flag );
231+ esp_err_t err2 = _write_top_nibble (i2c_lcd1602_info , ((value & 0x0f ) << 4 ) | register_select_flag );
232+ return err1 ? err1 : err2 ;
243233}
244234
245235// send command to controller
@@ -309,51 +299,7 @@ esp_err_t i2c_lcd1602_init(i2c_lcd1602_info_t * i2c_lcd1602_info, smbus_info_t *
309299 // Wait at least 40ms after power rises above 2.7V before sending commands.
310300 ets_delay_us (DELAY_POWER_ON );
311301
312- // put Expander into known state - Register Select and Read/Write both low
313- err = _write_to_expander (i2c_lcd1602_info , 0 );
314- if (err == ESP_OK )
315- {
316- ets_delay_us (1000 );
317-
318- // select 4-bit mode on LCD controller - see datasheet page 46, figure 24.
319- err = _write_top_nibble (i2c_lcd1602_info , 0x03 << 4 );
320- if (err == ESP_OK )
321- {
322- ets_delay_us (DELAY_INIT_1 );
323- err = _write_top_nibble (i2c_lcd1602_info , 0x03 << 4 ); // repeat
324- if (err == ESP_OK )
325- {
326- ets_delay_us (DELAY_INIT_2 );
327- err = _write_top_nibble (i2c_lcd1602_info , 0x03 << 4 ); // repeat
328- if (err == ESP_OK )
329- {
330- ets_delay_us (DELAY_INIT_3 );
331- err = _write_top_nibble (i2c_lcd1602_info , 0x02 << 4 ); // select 4-bit mode
332- if (err == ESP_OK )
333- {
334- // now we can use the command()/write() functions
335- err = _write_command (i2c_lcd1602_info , COMMAND_FUNCTION_SET | FLAG_FUNCTION_SET_MODE_4BIT | FLAG_FUNCTION_SET_LINES_2 | FLAG_FUNCTION_SET_DOTS_5X8 );
336- if (err == ESP_OK )
337- {
338- err = _write_command (i2c_lcd1602_info , COMMAND_DISPLAY_CONTROL | i2c_lcd1602_info -> display_control_flags );
339- if (err == ESP_OK )
340- {
341- err = i2c_lcd1602_clear (i2c_lcd1602_info );
342- if (err == ESP_OK )
343- {
344- err = _write_command (i2c_lcd1602_info , COMMAND_ENTRY_MODE_SET | i2c_lcd1602_info -> entry_mode_flags );
345- if (err == ESP_OK )
346- {
347- err = i2c_lcd1602_home (i2c_lcd1602_info );
348- }
349- }
350- }
351- }
352- }
353- }
354- }
355- }
356- }
302+ err = i2c_lcd1602_reset (i2c_lcd1602_info );
357303 }
358304 else
359305 {
@@ -363,6 +309,98 @@ esp_err_t i2c_lcd1602_init(i2c_lcd1602_info_t * i2c_lcd1602_info, smbus_info_t *
363309 return err ;
364310}
365311
312+ esp_err_t i2c_lcd1602_reset (const i2c_lcd1602_info_t * i2c_lcd1602_info )
313+ {
314+ esp_err_t first_err = ESP_OK ;
315+ esp_err_t last_err = ESP_FAIL ;
316+
317+ // put Expander into known state - Register Select and Read/Write both low
318+ if ((last_err = _write_to_expander (i2c_lcd1602_info , 0 )) != ESP_OK )
319+ {
320+ if (first_err == ESP_OK )
321+ first_err = last_err ;
322+ ESP_LOGE (TAG , "reset: _write_to_expander 1 failed: %d" , last_err );
323+ }
324+
325+ ets_delay_us (1000 );
326+
327+ // select 4-bit mode on LCD controller - see datasheet page 46, figure 24.
328+ if ((last_err = _write_top_nibble (i2c_lcd1602_info , 0x03 << 4 )) != ESP_OK )
329+ {
330+ if (first_err == ESP_OK )
331+ first_err = last_err ;
332+ ESP_LOGE (TAG , "reset: _write_top_nibble 1 failed: %d" , last_err );
333+ }
334+
335+ ets_delay_us (DELAY_INIT_1 );
336+
337+ // repeat
338+ if ((last_err = _write_top_nibble (i2c_lcd1602_info , 0x03 << 4 )) != ESP_OK )
339+ {
340+ if (first_err == ESP_OK )
341+ first_err = last_err ;
342+ ESP_LOGE (TAG , "reset: _write_top_nibble 2 failed: %d" , last_err );
343+ }
344+
345+ ets_delay_us (DELAY_INIT_2 );
346+
347+ // repeat
348+ if ((last_err = _write_top_nibble (i2c_lcd1602_info , 0x03 << 4 )) != ESP_OK )
349+ {
350+ if (first_err == ESP_OK )
351+ first_err = last_err ;
352+ ESP_LOGE (TAG , "reset: _write_top_nibble 3 failed: %d" , last_err );
353+ }
354+
355+ ets_delay_us (DELAY_INIT_3 );
356+
357+ // select 4-bit mode
358+ if ((last_err = _write_top_nibble (i2c_lcd1602_info , 0x02 << 4 )) != ESP_OK )
359+ {
360+ if (first_err == ESP_OK )
361+ first_err = last_err ;
362+ ESP_LOGE (TAG , "reset: _write_top_nibble 4 failed: %d" , last_err );
363+ }
364+
365+ // now we can use the command()/write() functions
366+ if ((last_err = _write_command (i2c_lcd1602_info , COMMAND_FUNCTION_SET | FLAG_FUNCTION_SET_MODE_4BIT | FLAG_FUNCTION_SET_LINES_2 | FLAG_FUNCTION_SET_DOTS_5X8 )) != ESP_OK )
367+ {
368+ if (first_err == ESP_OK )
369+ first_err = last_err ;
370+ ESP_LOGE (TAG , "reset: _write_command 1 failed: %d" , last_err );
371+ }
372+
373+ if ((last_err = _write_command (i2c_lcd1602_info , COMMAND_DISPLAY_CONTROL | i2c_lcd1602_info -> display_control_flags )) != ESP_OK )
374+ {
375+ if (first_err == ESP_OK )
376+ first_err = last_err ;
377+ ESP_LOGE (TAG , "reset: _write_command 2 failed: %d" , last_err );
378+ }
379+
380+ if ((last_err = i2c_lcd1602_clear (i2c_lcd1602_info )) != ESP_OK )
381+ {
382+ if (first_err == ESP_OK )
383+ first_err = last_err ;
384+ ESP_LOGE (TAG , "reset: i2c_lcd1602_clear failed: %d" , last_err );
385+ }
386+
387+ if ((last_err = _write_command (i2c_lcd1602_info , COMMAND_ENTRY_MODE_SET | i2c_lcd1602_info -> entry_mode_flags )) != ESP_OK )
388+ {
389+ if (first_err == ESP_OK )
390+ first_err = last_err ;
391+ ESP_LOGE (TAG , "reset: _write_command 3 failed: %d" , last_err );
392+ }
393+
394+ if ((last_err = i2c_lcd1602_home (i2c_lcd1602_info )) != ESP_OK )
395+ {
396+ if (first_err == ESP_OK )
397+ first_err = last_err ;
398+ ESP_LOGE (TAG , "reset: i2c_lcd1602_home failed: %d" , last_err );
399+ }
400+
401+ return first_err ;
402+ }
403+
366404esp_err_t i2c_lcd1602_clear (const i2c_lcd1602_info_t * i2c_lcd1602_info )
367405{
368406 esp_err_t err = ESP_FAIL ;
0 commit comments