Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Some improvements and bugfix
  • Loading branch information
firebull committed Dec 19, 2017
1 parent 22ff497 commit 7baaf0e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 59 deletions.
42 changes: 25 additions & 17 deletions Inc/lcd_hd44780_i2c.h
Expand Up @@ -50,23 +50,31 @@ extern "C" {
#define LCD_BIT_SETDDRAMADDR (uint8_t)0x80

#define LCD_BIT_DISPLAY_CONTROL (uint8_t)0x08
#define LCD_BIT_DISPLAY_ON LCD_BIT_DISPLAY_CONTROL | 0x04
#define LCD_BIT_CURSOR_ON LCD_BIT_DISPLAY_CONTROL | 0x02
#define LCD_BIT_CURSOR_OFF LCD_BIT_DISPLAY_CONTROL
#define LCD_BIT_BLINK_ON LCD_BIT_DISPLAY_CONTROL | 0x01
#define LCD_BIT_BLINK_OFF LCD_BIT_DISPLAY_CONTROL
#define LCD_BIT_DISPLAY_ON (uint8_t)0x04
#define LCD_BIT_CURSOR_ON (uint8_t)0x02
#define LCD_BIT_CURSOR_OFF (uint8_t)0x00
#define LCD_BIT_BLINK_ON (uint8_t)0x01
#define LCD_BIT_BLINK_OFF (uint8_t)0x00

#define LCD_BIT_DISP_CLEAR (uint8_t)0x01
#define LCD_BIT_CURSOR_HOME (uint8_t)0x02

#define LCD_BIT_ENTRY_MODE (uint8_t)0x04
#define LCD_BIT_CURSOR_DIR_RIGHT LCD_BIT_ENTRY_MODE | 0x02
#define LCD_BIT_CURSOR_DIR_LEFT LCD_BIT_ENTRY_MODE
#define LCD_BIT_DISPLAY_SHIFT LCD_BIT_ENTRY_MODE | 0x01
#define LCD_BIT_CURSOR_DIR_RIGHT (uint8_t)0x02
#define LCD_BIT_CURSOR_DIR_LEFT (uint8_t)0x00
#define LCD_BIT_DISPLAY_SHIFT (uint8_t)0x01

// TODO: Update commands with this defines
#define LCD_BIT_CURSOR_SHIFT_MODE (uint8_t)0x10
#define LCD_BIT_CURSOR_DISP_SHIFT (uint8_t)0x08
#define LCD_BIT_CURSOR_MOVE (uint8_t)0x00
#define LCD_BIT_CURSOR_SHIFT_DIR_R (uint8_t)0x40
#define LCD_BIT_CURSOR_SHIFT_DIR_L (uint8_t)0x00


/* Function defines */
#define lcdBacklightOn() lcdBacklight(LCD_BIT_BACKIGHT_ON)
#define lcdBacklightOff() lcdBacklight(0x00)
#define lcdBacklightOff() lcdBacklight(LCD_BIT_BACKIGHT_OFF)
#define lcdAutoscrollOn() lcdCommand(LCD_DISPLAY_SHIFT, LCD_PARAM_SET)
#define lcdAutoscrollOff() lcdCommand(LCD_DISPLAY_SHIFT, LCD_PARAM_UNSET)
#define lcdDisplayClear() lcdCommand(LCD_CLEAR, LCD_PARAM_SET)
Expand All @@ -88,13 +96,13 @@ typedef enum {
#endif

typedef struct {
I2C_HandleTypeDef * hi2c;
uint8_t lines;
uint8_t columns;
uint8_t address;
uint8_t backlight;
uint8_t modeBits;
uint8_t entryBits;
I2C_HandleTypeDef * hi2c; // I2C Struct
uint8_t lines; // Lines of the display
uint8_t columns; // Columns
uint8_t address; // I2C address shifted left by 1
uint8_t backlight; // Backlight
uint8_t modeBits; // Display on/off control bits
uint8_t entryBits; // Entry mode set bits
} LCDParams;

typedef enum {
Expand All @@ -116,7 +124,7 @@ typedef enum {


bool lcdInit(I2C_HandleTypeDef *hi2c, uint8_t address, uint8_t lines, uint8_t rows);
bool lcdCommand(uint8_t command, LCDParamsActions action);
bool lcdCommand(LCDCommands command, LCDParamsActions action);
bool lcdBacklight(uint8_t command);
bool lcdSetCursorPosition(uint8_t line, uint8_t row);
bool lcdPrintStr(uint8_t * data, uint8_t length);
Expand Down
77 changes: 35 additions & 42 deletions Src/lcd_hd44780_i2c.c
Expand Up @@ -18,7 +18,7 @@
*/

/*
Hear are some cyrillic symbols that you can use in your code
Here are some cyrillic symbols that you can use in your code
uint8_t symD[8] = { 0x07, 0x09, 0x09, 0x09, 0x09, 0x1F, 0x11 }; // Д
uint8_t symZH[8] = { 0x11, 0x15, 0x15, 0x0E, 0x15, 0x15, 0x11 }; // Ж
Expand Down Expand Up @@ -71,46 +71,27 @@ bool lcdInit(I2C_HandleTypeDef *hi2c, uint8_t address, uint8_t lines, uint8_t co
lcdCommandBuffer[1] = lcdCommandBuffer[0];
lcdCommandBuffer[2] = (0x03 << 4);

/* First init cycle */
if (HAL_I2C_Master_Transmit_DMA(lcdParams.hi2c, lcdParams.address, (uint8_t*)lcdCommandBuffer, 3) != HAL_OK) {
return false;
}

xLastWakeTime = xTaskGetTickCount();

while (HAL_I2C_GetState(lcdParams.hi2c) != HAL_I2C_STATE_READY) {
vTaskDelay(1);
}

vTaskDelayUntil(&xLastWakeTime, (TickType_t)5);

/* Second init cycle */
if (HAL_I2C_Master_Transmit_DMA(lcdParams.hi2c, lcdParams.address, (uint8_t*)lcdCommandBuffer, 3) != HAL_OK) {
return false;
}

xLastWakeTime = xTaskGetTickCount();

while (HAL_I2C_GetState(lcdParams.hi2c) != HAL_I2C_STATE_READY) {
vTaskDelay(1);
}

vTaskDelayUntil(&xLastWakeTime, (TickType_t)5);

/* First 3 steps of init cycles. They are the same. */
for (uint8_t i = 0; i < 3; ++i) {
if (HAL_I2C_Master_Transmit_DMA(lcdParams.hi2c, lcdParams.address, (uint8_t*)lcdCommandBuffer, 3) != HAL_OK) {
return false;
}

/* Third init cycle */
if (HAL_I2C_Master_Transmit_DMA(lcdParams.hi2c, lcdParams.address, (uint8_t*)lcdCommandBuffer, 3) != HAL_OK) {
return false;
}
xLastWakeTime = xTaskGetTickCount();

xLastWakeTime = xTaskGetTickCount();
while (HAL_I2C_GetState(lcdParams.hi2c) != HAL_I2C_STATE_READY) {
vTaskDelay(1);
}

while (HAL_I2C_GetState(lcdParams.hi2c) != HAL_I2C_STATE_READY) {
vTaskDelay(1);
if (i == 2) {
// For the last cycle delay is less then 1 ms (100us by datasheet)
vTaskDelayUntil(&xLastWakeTime, (TickType_t)1);
} else {
// For first 2 cycles delay is less then 5ms (4100us by datasheet)
vTaskDelayUntil(&xLastWakeTime, (TickType_t)5);
}
}

vTaskDelayUntil(&xLastWakeTime, (TickType_t)1);

/* Lets turn to 4-bit at least */
lcdCommandBuffer[0] = LCD_BIT_BACKIGHT_ON | LCD_BIT_E | (LCD_MODE_4BITS << 4);
lcdCommandBuffer[1] = lcdCommandBuffer[0];
Expand Down Expand Up @@ -153,15 +134,15 @@ bool lcdInit(I2C_HandleTypeDef *hi2c, uint8_t address, uint8_t lines, uint8_t co
* @param action LCD_PARAM_SET or LCD_PARAM_UNSET
* @return true if success
*/
bool lcdCommand(uint8_t command, LCDParamsActions action) {
bool lcdCommand(LCDCommands command, LCDParamsActions action) {
uint8_t lcdData = 0x00;

/* First of all lest store the command */
switch (action) {
case LCD_PARAM_SET:
switch (command) {
case LCD_DISPLAY:
lcdParams.modeBits |= LCD_BIT_DISPLAY_ON;
lcdParams.modeBits |= LCD_BIT_DISPLAY_ON;
break;

case LCD_CURSOR:
Expand All @@ -174,11 +155,23 @@ bool lcdCommand(uint8_t command, LCDParamsActions action) {

case LCD_CLEAR:
lcdData = LCD_BIT_DISP_CLEAR;
return lcdWriteByte((uint8_t)0x00, &lcdData);

if (lcdWriteByte((uint8_t)0x00, &lcdData) == false) {
return false;
} else {
vTaskDelay(2);
return true;
}

case LCD_CURSOR_HOME:
lcdData = LCD_BIT_CURSOR_HOME;
return lcdWriteByte((uint8_t)0x00, &lcdData);

if (lcdWriteByte((uint8_t)0x00, &lcdData) == false) {
return false;
} else {
vTaskDelay(2);
return true;
}

case LCD_CURSOR_DIR_RIGHT:
lcdParams.entryBits |= LCD_BIT_CURSOR_DIR_RIGHT;
Expand Down Expand Up @@ -239,13 +232,13 @@ bool lcdCommand(uint8_t command, LCDParamsActions action) {
case LCD_DISPLAY:
case LCD_CURSOR:
case LCD_CURSOR_BLINK:
lcdData = lcdParams.modeBits;
lcdData = LCD_BIT_DISPLAY_CONTROL | lcdParams.modeBits;
break;

case LCD_CURSOR_DIR_RIGHT:
case LCD_CURSOR_DIR_LEFT:
case LCD_DISPLAY_SHIFT:
lcdData = lcdParams.entryBits;
lcdData = LCD_BIT_ENTRY_MODE | lcdParams.entryBits;
break;

default:
Expand Down
4 changes: 4 additions & 0 deletions docs/README.md
Expand Up @@ -22,16 +22,20 @@ This libriary is for STM32 HAL and uses its functions and FreeRTOS. So first of

#### Turn on I2C
PCF8574 supports only Standart 100kHz mode:

![Screenshot](http://blog.bulki.me/assets/img/stm32-lcd-hitachi/i2c-params.png)

Turn on DMA:

![Screenshot](http://blog.bulki.me/assets/img/stm32-lcd-hitachi/i2c-dma.png)

Turn on interrupts:

![Screenshot](http://blog.bulki.me/assets/img/stm32-lcd-hitachi/i2c-nvic.png)

#### FreeRTOS
Turn on FreeRTOS globally and include ```vTaskDelayUntil()``` function:

![Screenshot](http://blog.bulki.me/assets/img/stm32-lcd-hitachi/freertos_include_params.png)

#### Include correct HAL Libriary
Expand Down

0 comments on commit 7baaf0e

Please sign in to comment.