Skip to content

Commit

Permalink
Merge pull request #191 from MikroElektronika/hotfix/lcd-timeout
Browse files Browse the repository at this point in the history
Fixed LCD implementation
  • Loading branch information
StrahinjaJacimovic authored Dec 26, 2024
2 parents 7748313 + 6c92809 commit 664f7e0
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 83 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

**VERSIONS:**

+ **[v2.13.1](./changelog/v2.13.1/changelog.md)**
+ **[v2.13.0](./changelog/v2.13.0/changelog.md)**
+ **[v2.12.2](./changelog/v2.12.2/changelog.md)**
+ **[v2.12.1](./changelog/v2.12.1/changelog.md)**
Expand Down
39 changes: 39 additions & 0 deletions changelog/v2.13.1/changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<p align="center">
<img src="http://www.mikroe.com/img/designs/beta/logo_small.png?raw=true" alt="MikroElektronika"/>
</p>

---

**[BACK TO MAIN FILE](../../changelog.md)**

---

# `v2.13.1`

+ released: 2024-12-27

## Changes

+ [`v2.13.1`](#v2131)
+ [Changes](#changes)
+ [Fixes](#fixes)

### Fixes

#### mikroSDK

+ Fixed LCD implementation for all architectures
+ Issue with timing after optimizing (speeding up) SDK

### NEW HARDWARE

> NOTE:
>> If any new hardware was added to current version, it will be listed here.
Support added for following hardware:

---

**[BACK TO MAIN FILE](../../changelog.md)**

---
30 changes: 11 additions & 19 deletions middleware/lcd/lib/src/drivers/controller/hd44780_lcd_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@

#include "lcd.h"
#include "assembly.h"
#include "delays.h"

/**
* @brief: Macro used for timeout between pulses.
* @note: If needed.
*/
#define timeout(_x) while(_x--) assembly(NOP);

Expand All @@ -55,41 +57,31 @@ void hd44780_lcd_init( uint32_t lcd_handle ) {
lcd_handle_t lcd_handle_local;
memcpy(&lcd_handle_local, (void *)lcd_handle, sizeof(lcd_handle_t));

uint16_t timeout_value = lcd_handle_local.config.waitBetweenWrites;

if ( LCD_MODE_BIT_4 == lcd_handle_local.config.mode ) {
// 4-bit mode.
lcd_write( lcd_handle_local, LCD_CMD_FUNCTION_SET | LCD_CMD_MODE_4BIT, LCD_SELECT_CMD );
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 5 );
lcd_write( lcd_handle_local, LCD_CMD_FUNCTION_SET | LCD_CMD_MODE_4BIT, LCD_SELECT_CMD );
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 5 );
lcd_write( lcd_handle_local, LCD_CMD_FUNCTION_SET | LCD_CMD_MODE_4BIT, LCD_SELECT_CMD );
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 1 );
} else {
// 8-bit mode - default state.
lcd_write( lcd_handle_local, LCD_CMD_FUNCTION_SET, LCD_SELECT_CMD );
timeout( timeout_value );
Delay_ms( 5 );
lcd_write( lcd_handle_local, LCD_CMD_FUNCTION_SET, LCD_SELECT_CMD );
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 5 );
lcd_write( lcd_handle_local, LCD_CMD_FUNCTION_SET, LCD_SELECT_CMD );
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 1 );
}

// Standard LCD initialization.
lcd_write( lcd_handle_local, LCD_CMD_CLEAR, LCD_SELECT_CMD ); // Clear LCD first.
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 2 );
lcd_write( lcd_handle_local, LCD_CMD_CURSOR_OFF, LCD_SELECT_CMD ); // Don't show cursor.
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 2 );
lcd_write( lcd_handle_local, LCD_ROW_1, LCD_SELECT_CMD ); // Set first row as active initially.
timeout_value = lcd_handle_local.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 2 );
}

// ------------------------------------------------------------------------ END
41 changes: 22 additions & 19 deletions middleware/lcd/lib/src/lcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,18 @@
#include "lcd.h"
#include "board.h"
#include "assembly.h"
#include "delays.h"

/**
* @brief: Macro used for timeout between pulses.
*/
#define timeout(_x) while(_x--) assembly(NOP);

/**
* @brief: Variable used to store data before shifting.
*/
static uint8_t lcd_cmd_data_saved;

/* --------------------------------------------- PRIVATE FUNCTIONS - DECLARATIONS -------------------------------------------*/

/**
Expand Down Expand Up @@ -106,7 +112,7 @@ void lcd_configure_default( lcd_config_t *config ) {
config->mode = LCD_MODE_BIT_4;

/**
* @brief Set 1000 by default.
* @brief Set 10000 by default.
*/
config->waitBetweenWrites = 10000;
}
Expand All @@ -115,7 +121,6 @@ void lcd_configure_default( lcd_config_t *config ) {
lcd_err_t lcd_configure( lcd_handle_t *lcd_handle, lcd_config_t *config ) {
lcd_err_t status = LCD_ERROR;
uint8_t bit_data_err_cnt = 0;
uint16_t timeout_value = config->waitBetweenWrites;

if ( lcd_handle ) {
if ( config ) {
Expand All @@ -127,16 +132,11 @@ lcd_err_t lcd_configure( lcd_handle_t *lcd_handle, lcd_config_t *config ) {
else
digital_out_low( &lcd_handle->cs_pin );

timeout( timeout_value );

if ( DIGITAL_OUT_SUCCESS != digital_out_init( &lcd_handle->rst_pin, lcd_handle->config.pin_rst ) )
return status;
else
digital_out_low( &lcd_handle->rst_pin );

timeout_value = config->waitBetweenWrites;
timeout( timeout_value );

// Backlight pin is optional.
if ( HAL_PIN_NC != lcd_handle->config.pin_backlight ) {
if ( DIGITAL_OUT_SUCCESS != digital_out_init( &lcd_handle->backlight_pin, lcd_handle->config.pin_backlight ) )
Expand All @@ -152,6 +152,13 @@ lcd_err_t lcd_configure( lcd_handle_t *lcd_handle, lcd_config_t *config ) {
data_pin_iteration++;
}

/**
* SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
* according to datasheet, we need at least 40 ms after power rises above 2.7 V
* before sending commands.
*/
Delay_ms( 50 );

if ( ( LCD_MODE_BIT_4 == lcd_handle->config.mode ) && ( 4 == bit_data_err_cnt ) )
status = LCD_SUCCESS;

Expand All @@ -167,18 +174,17 @@ lcd_err_t lcd_configure( lcd_handle_t *lcd_handle, lcd_config_t *config ) {
}

void lcd_init( lcd_handle_t lcd_handle, init_sequence_ptr init_sequence ) {
uint16_t timeout_value = lcd_handle.config.waitBetweenWrites;

if ( true == lcd_handle.init_state ) {
clear_lines( lcd_handle );
timeout( timeout_value );
timeout( lcd_handle.config.waitBetweenWrites );
if (init_sequence) {
(*init_sequence)((uint32_t)&lcd_handle);
}
}
}

void lcd_write( lcd_handle_t lcd_handle, char lcd_cmd_data, lcd_select_t cmd_or_data ) {
lcd_cmd_data_saved = lcd_cmd_data;
if ( false == lcd_handle.init_state ) {
return;
}
Expand All @@ -191,7 +197,7 @@ void lcd_write( lcd_handle_t lcd_handle, char lcd_cmd_data, lcd_select_t cmd_or_
}

// 8-bit mode or lower nibble for 4-bit mode.
lcd_write_bit_of_data( lcd_handle, lcd_cmd_data );
lcd_write_bit_of_data( lcd_handle, lcd_cmd_data_saved );
lcd_pulse( lcd_handle, cmd_or_data );
}

Expand Down Expand Up @@ -317,8 +323,6 @@ void lcd_backlight_on( lcd_handle_t lcd_handle ) {
/* --------------------------------------------- PRIVATE FUNCTIONS - IMPLEMENTATIONS ----------------------------------------*/

static inline void lcd_pulse( lcd_handle_t lcd_handle, lcd_select_t cmd_or_data ) {
uint16_t timeout_value = lcd_handle.config.waitBetweenWrites;

// Send LOW or HIGH pulse on RS/RST pin for selecting adequate register.
if ( LCD_SELECT_CMD == cmd_or_data ) {
digital_out_low( &lcd_handle.rst_pin );
Expand All @@ -327,19 +331,18 @@ static inline void lcd_pulse( lcd_handle_t lcd_handle, lcd_select_t cmd_or_data
}

// Generate a High-to-low pulse on EN/CS pin.
timeout( timeout_value );
Delay_ms( 1 );
digital_out_high( &lcd_handle.cs_pin );
timeout_value = lcd_handle.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 1 );

digital_out_low( &lcd_handle.cs_pin );
timeout_value = lcd_handle.config.waitBetweenWrites;
timeout( timeout_value );
Delay_ms( 10 );
}

static inline void clear_lines( lcd_handle_t lcd_handle ) {
// Write 0 to all data lines.
lcd_write_bit_of_data( lcd_handle, 0x00 );
Delay_ms( 2 );
}

static inline void lcd_write_bit_of_data( lcd_handle_t lcd_handle, uint8_t value ) {
Expand All @@ -348,7 +351,7 @@ static inline void lcd_write_bit_of_data( lcd_handle_t lcd_handle, uint8_t value

for ( uint8_t i = 0; i < 8; i++ ) {
if ( HAL_PIN_NC != *data_pin_iteration ) {
digital_out_write( &lcd_handle.data_pins[i], ( value >> cnt ) & 0x01 );
digital_out_write( &lcd_handle.data_pins[i], ( ( value >> cnt ) & 0x01 ) );
cnt++;
}
data_pin_iteration++;
Expand Down
2 changes: 1 addition & 1 deletion platform/mikrosdk_version/include/mikrosdk_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ extern "C"{
* @note changes in patch version indicate smaller updates,
* bug fixes and improvements
*/
#define mikroSDK_PATCH_VERSION 0
#define mikroSDK_PATCH_VERSION 1

/**
* @brief mikroSDK_GET_VERSION
Expand Down
90 changes: 46 additions & 44 deletions tests/lcd/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,52 +101,54 @@ int main( void ) {
preinit();
#endif

// Expected output is for display to be turned ON.
if (LCD_ERROR == test_1()) {
printf_me("LCD failed initialization!\r\n");
while(1);
while(1) {
// Expected output is for display to be turned ON.
if (LCD_ERROR == test_1()) {
printf_me("LCD failed initialization!\r\n");
while(1);
}

// Expected output is the following text in row 1:
// CHAR:123+-/*@&
test_2();

// Expected output is the following text in row 1:
// Clear and write!
test_3();

// Expected output is the following text in row 1:
// Clear and write!
// And following output in row 2:
// MikroE LCD Test
test_4();

// Expected output is text being shifted to the left.
test_5();

// Expected output is text being shifted to the right.
test_6();

// Expected output is text disappearing and reappearing a couple of times.
test_7();

// Expected output is cursor disappearing and reappearing a couple of times
// at the last position. Next to last character in row 2.
test_8();

// Expected output is cursor moving to the left 3 times,
// then moving to first position and finally moving
// 3 times to the right.
test_9();

// Expected output is the LCD blinking.
test_10();

// Signal END on LCD.
lcd_clear(lcd);
lcd_cursor_off(lcd);
lcd_write_text(lcd, "TEST COMPLETED!", LCD_ROW_1);
}

// Expected output is the following text in row 1:
// CHAR:123+-/*@&
test_2();

// Expected output is the following text in row 1:
// Clear and write!
test_3();

// Expected output is the following text in row 1:
// Clear and write!
// And following output in row 2:
// MikroE LCD Test
test_4();

// Expected output is text being shifted to the left.
test_5();

// Expected output is text being shifted to the right.
test_6();

// Expected output is text disappearing and reappearing a couple of times.
test_7();

// Expected output is cursor disappearing and reappearing a couple of times
// at the last position. Next to last character in row 2.
test_8();

// Expected output is cursor moving to the left 3 times,
// then moving to first position and finally moving
// 3 times to the right.
test_9();

// Expected output is the LCD blinking.
test_10();

// Signal END on LCD.
lcd_clear(lcd);
lcd_cursor_off(lcd);
lcd_write_text(lcd, "TEST COMPLETED!", LCD_ROW_1);

return 0;
}

Expand Down

0 comments on commit 664f7e0

Please sign in to comment.