This is a part of the Kinetiszer project.

Dependencies:   inc

Dependents:   kinetisizer

Committer:
Clemo
Date:
Tue Oct 28 20:09:12 2014 +0000
Revision:
1:8ae4ab73ca6a
Parent:
0:cb80470434eb
First publication (untested)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Clemo 0:cb80470434eb 1 /**
Clemo 0:cb80470434eb 2 * @file
Clemo 0:cb80470434eb 3 * Implementation of a portable LCD driver.
Clemo 0:cb80470434eb 4 *
Clemo 0:cb80470434eb 5 * You have to provide two functions to interface this driver
Clemo 0:cb80470434eb 6 * to the actual hardware:
Clemo 0:cb80470434eb 7 *
Clemo 0:cb80470434eb 8 * void lcd_4bit_write_port(uint8_t value);
Clemo 0:cb80470434eb 9 *
Clemo 0:cb80470434eb 10 * uint8_t lcd_4bit_read_port(void);
Clemo 0:cb80470434eb 11 *
Clemo 0:cb80470434eb 12 * void lcd_backlight(uint8_t on);
Clemo 0:cb80470434eb 13 *
Clemo 0:cb80470434eb 14 * Author: Clemens Valens
Clemo 0:cb80470434eb 15 * License: GNU General Public License
Clemo 0:cb80470434eb 16 *
Clemo 0:cb80470434eb 17 * History
Clemo 0:cb80470434eb 18 * 2011.04.11 ver 1.00 Preliminary version, first release
Clemo 0:cb80470434eb 19 */
Clemo 0:cb80470434eb 20
Clemo 0:cb80470434eb 21 #include "lcd.h"
Clemo 0:cb80470434eb 22 #include "systick.h"
Clemo 0:cb80470434eb 23 #include "string.h"
Clemo 0:cb80470434eb 24
Clemo 0:cb80470434eb 25
Clemo 0:cb80470434eb 26 const uint8_t custom_characters[8][8] =
Clemo 0:cb80470434eb 27 {
Clemo 0:cb80470434eb 28 /*{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f },
Clemo 0:cb80470434eb 29 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f },
Clemo 0:cb80470434eb 30 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f },
Clemo 0:cb80470434eb 31 { 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f },
Clemo 0:cb80470434eb 32 { 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f },
Clemo 0:cb80470434eb 33 { 0x00, 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f },
Clemo 0:cb80470434eb 34 { 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f },
Clemo 0:cb80470434eb 35 { 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }*/
Clemo 0:cb80470434eb 36 { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 },
Clemo 0:cb80470434eb 37 { 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x04 },
Clemo 0:cb80470434eb 38 { 0x04, 0x04, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x04 },
Clemo 0:cb80470434eb 39 { 0x04, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x04 },
Clemo 0:cb80470434eb 40 { 0x04, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x04, 0x04 },
Clemo 0:cb80470434eb 41 // { 0x04, 0x04, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04 },
Clemo 0:cb80470434eb 42 { 0x04, 0x04, 0x04, 0x0e, 0x0e, 0x1f, 0x1f, 0x04 },
Clemo 0:cb80470434eb 43 { 0x04, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 },
Clemo 0:cb80470434eb 44 { 0x1f, 0x1f, 0x0e, 0x0e, 0x04, 0x04, 0x04, 0x04 }
Clemo 0:cb80470434eb 45 };
Clemo 0:cb80470434eb 46
Clemo 0:cb80470434eb 47 typedef uint8_t I2C_ID_T;
Clemo 0:cb80470434eb 48 #define I2C0 (0)
Clemo 0:cb80470434eb 49
Clemo 0:cb80470434eb 50 // State machine handler for I2C0 and I2C1.
Clemo 0:cb80470434eb 51 static void i2c_state_handling(I2C_ID_T id)
Clemo 0:cb80470434eb 52 {
Clemo 0:cb80470434eb 53 /*if (Chip_I2C_IsMasterActive(id))
Clemo 0:cb80470434eb 54 {
Clemo 0:cb80470434eb 55 Chip_I2C_MasterStateHandler(id);
Clemo 0:cb80470434eb 56 }
Clemo 0:cb80470434eb 57 else
Clemo 0:cb80470434eb 58 {
Clemo 0:cb80470434eb 59 Chip_I2C_SlaveStateHandler(id);
Clemo 0:cb80470434eb 60 }*/
Clemo 0:cb80470434eb 61 }
Clemo 0:cb80470434eb 62
Clemo 0:cb80470434eb 63
Clemo 0:cb80470434eb 64 void I2C_IRQHandler(void)
Clemo 0:cb80470434eb 65 {
Clemo 0:cb80470434eb 66 i2c_state_handling(I2C0);
Clemo 0:cb80470434eb 67 }
Clemo 0:cb80470434eb 68
Clemo 0:cb80470434eb 69
Clemo 0:cb80470434eb 70 void st7032i_write_byte(uint8_t cmd_or_data, uint8_t value)
Clemo 0:cb80470434eb 71 {
Clemo 0:cb80470434eb 72 // buffer must be static because the I2C engine does not copy the data,
Clemo 0:cb80470434eb 73 // but uses a pointer to buffer.
Clemo 0:cb80470434eb 74 //static uint8_t buffer[2];
Clemo 0:cb80470434eb 75 //buffer[0] = cmd_or_data;
Clemo 0:cb80470434eb 76 //buffer[1] = value;
Clemo 0:cb80470434eb 77 //Chip_I2C_MasterSend(I2C0,LCD_I2C_ADDRESS,buffer,2);
Clemo 0:cb80470434eb 78 }
Clemo 0:cb80470434eb 79
Clemo 0:cb80470434eb 80
Clemo 0:cb80470434eb 81 void st7032i_write_data(uint8_t value)
Clemo 0:cb80470434eb 82 {
Clemo 0:cb80470434eb 83 // Bit 6 (the RS bit) must be set (1) in order to write the Data Register (DR).
Clemo 0:cb80470434eb 84 // With bit 7 cleared (the Co bit) only one control byte can be sent.
Clemo 0:cb80470434eb 85 st7032i_write_byte(0x40,value);
Clemo 0:cb80470434eb 86 }
Clemo 0:cb80470434eb 87
Clemo 0:cb80470434eb 88
Clemo 0:cb80470434eb 89 void st7032i_write_command(uint8_t cmd, uint8_t value)
Clemo 0:cb80470434eb 90 {
Clemo 0:cb80470434eb 91 // Bit 6 (the RS bit) must be cleared (0) in order to write the Instruction Register (IR).
Clemo 0:cb80470434eb 92 // With bit 7 cleared (the Co bit) only one control byte can be sent.
Clemo 0:cb80470434eb 93 st7032i_write_byte(0x00,cmd|value);
Clemo 0:cb80470434eb 94 }
Clemo 0:cb80470434eb 95
Clemo 0:cb80470434eb 96
Clemo 0:cb80470434eb 97 uint8_t lcd_putc(char ch)
Clemo 0:cb80470434eb 98 {
Clemo 0:cb80470434eb 99 st7032i_write_data(ch);
Clemo 0:cb80470434eb 100 return 1;
Clemo 0:cb80470434eb 101 }
Clemo 0:cb80470434eb 102
Clemo 0:cb80470434eb 103
Clemo 0:cb80470434eb 104 uint8_t lcd_puts(char *p_str)
Clemo 0:cb80470434eb 105 {
Clemo 0:cb80470434eb 106 uint8_t result = 0;
Clemo 0:cb80470434eb 107
Clemo 0:cb80470434eb 108 while (*p_str!=0)
Clemo 0:cb80470434eb 109 {
Clemo 0:cb80470434eb 110 st7032i_write_data(*p_str++);
Clemo 0:cb80470434eb 111 result += 1;
Clemo 0:cb80470434eb 112 }
Clemo 0:cb80470434eb 113
Clemo 0:cb80470434eb 114 return result;
Clemo 0:cb80470434eb 115 }
Clemo 0:cb80470434eb 116
Clemo 0:cb80470434eb 117
Clemo 0:cb80470434eb 118 void lcd_clear(void)
Clemo 0:cb80470434eb 119 {
Clemo 0:cb80470434eb 120 st7032i_write_command(ST7032_CMD_CLEAR,0);
Clemo 0:cb80470434eb 121 SysTick_Delay(2);
Clemo 0:cb80470434eb 122 }
Clemo 0:cb80470434eb 123
Clemo 0:cb80470434eb 124
Clemo 0:cb80470434eb 125 void lcd_cursor(uint8_t line, uint8_t column)
Clemo 0:cb80470434eb 126 {
Clemo 0:cb80470434eb 127 st7032i_write_command(ST7032_CMD_DDRAM_ADDRESS,(line==0?0:0x40)+column);
Clemo 0:cb80470434eb 128 lcd_display_cursor_blink(1,0,0);
Clemo 0:cb80470434eb 129 }
Clemo 0:cb80470434eb 130
Clemo 0:cb80470434eb 131
Clemo 0:cb80470434eb 132 void lcd_display_cursor_blink(uint8_t display, uint8_t cursor, uint8_t blink)
Clemo 0:cb80470434eb 133 {
Clemo 0:cb80470434eb 134 uint8_t cmd = 0;
Clemo 0:cb80470434eb 135 if (display!=0) cmd |= ST7032_DISPLAY_ON;
Clemo 0:cb80470434eb 136 // Beware of auto-increment. If you don't see the cursor, maybe it fell off the screen?
Clemo 0:cb80470434eb 137 if (cursor!=0) cmd |= ST7032_CURSOR_ON;
Clemo 0:cb80470434eb 138 if (blink!=0) cmd |= ST7032_BLINK_ON;
Clemo 0:cb80470434eb 139 st7032i_write_command(ST7032_CMD_ON_OFF,cmd);
Clemo 0:cb80470434eb 140 }
Clemo 0:cb80470434eb 141
Clemo 0:cb80470434eb 142
Clemo 0:cb80470434eb 143 void lcd_clear_to_eol(int line, int column)
Clemo 0:cb80470434eb 144 {
Clemo 0:cb80470434eb 145 uint8_t i;
Clemo 0:cb80470434eb 146 lcd_cursor(line,column);
Clemo 0:cb80470434eb 147 for (i=column; i<BOARD_LCD_CHARS_PER_LINE; i++)
Clemo 0:cb80470434eb 148 {
Clemo 0:cb80470434eb 149 lcd_putc(' ');
Clemo 0:cb80470434eb 150 }
Clemo 0:cb80470434eb 151 lcd_cursor(line,column);
Clemo 0:cb80470434eb 152 }
Clemo 0:cb80470434eb 153
Clemo 0:cb80470434eb 154
Clemo 0:cb80470434eb 155 void lcd_contrast(uint8_t contrast)
Clemo 0:cb80470434eb 156 {
Clemo 0:cb80470434eb 157 // Set contrast low bits.
Clemo 0:cb80470434eb 158 st7032i_write_command(ST7032_CMD_CONTRAST_LO,contrast&ST7032_CONTRAST_LO_MASK);
Clemo 0:cb80470434eb 159 // Set contrast high bits.
Clemo 0:cb80470434eb 160 // When LCD is powered from 3V the booster must be on.
Clemo 0:cb80470434eb 161 st7032i_write_command(ST7032_CMD_POWER_ICON_CONTRAST,ST7032_BOOSTER_ON|((contrast>>4)&ST7032_CONTRAST_HI_MASK));
Clemo 0:cb80470434eb 162 }
Clemo 0:cb80470434eb 163
Clemo 0:cb80470434eb 164
Clemo 0:cb80470434eb 165 void lcd_font(uint8_t font)
Clemo 0:cb80470434eb 166 {
Clemo 0:cb80470434eb 167 st7032i_write_command(ST7032_CMD_FUNCTION,ST7032_FUNC_CONFIG_EXTENDED|(font&ST7032_FUNC_HEIGHT_DOUBLE));
Clemo 0:cb80470434eb 168 }
Clemo 0:cb80470434eb 169
Clemo 0:cb80470434eb 170
Clemo 0:cb80470434eb 171 void lcd_set_custom_character(uint8_t index, const uint8_t *p_data)
Clemo 0:cb80470434eb 172 {
Clemo 0:cb80470434eb 173 int i;
Clemo 0:cb80470434eb 174 // Up to 8 custom characters may be defined.
Clemo 0:cb80470434eb 175 // Select function table 0.
Clemo 0:cb80470434eb 176 st7032i_write_command(ST7032_CMD_FUNCTION,ST7032_FUNC_CONFIG_NORMAL);
Clemo 0:cb80470434eb 177 // Set CGRAM address.
Clemo 0:cb80470434eb 178 st7032i_write_command(ST7032_CMD_CGRAM_ADDRESS,(8*index)&0x3f);
Clemo 0:cb80470434eb 179 // 8 bytes per character.
Clemo 0:cb80470434eb 180 for (i=0; i<7; i++)
Clemo 0:cb80470434eb 181 {
Clemo 0:cb80470434eb 182 st7032i_write_data(p_data[i]&0x1f);
Clemo 0:cb80470434eb 183 }
Clemo 0:cb80470434eb 184 }
Clemo 0:cb80470434eb 185
Clemo 0:cb80470434eb 186
Clemo 0:cb80470434eb 187 void lcd_bar_graph(uint8_t position, uint8_t value, uint8_t value_max)
Clemo 0:cb80470434eb 188 {
Clemo 0:cb80470434eb 189 //st7032i_write_command(ST7032_CMD_ON_OFF,ST7032_DISPLAY_ON|ST7032_CURSOR_OFF|ST7032_BLINK_OFF);
Clemo 0:cb80470434eb 190 uint16_t v = value;
Clemo 0:cb80470434eb 191 v = 14*v/value_max; // map [1,255] to 14 possibilities, 0 is possibility 15.
Clemo 0:cb80470434eb 192 lcd_cursor(1,position);
Clemo 0:cb80470434eb 193 if (v<=6)
Clemo 0:cb80470434eb 194 {
Clemo 0:cb80470434eb 195 if (value==0)
Clemo 0:cb80470434eb 196 {
Clemo 0:cb80470434eb 197 v = 5; //'0';
Clemo 0:cb80470434eb 198 }
Clemo 0:cb80470434eb 199 else
Clemo 0:cb80470434eb 200 {
Clemo 0:cb80470434eb 201 v += 1;
Clemo 0:cb80470434eb 202 if (v==5) v = 0x11;
Clemo 0:cb80470434eb 203 else if (v==7) v = 'T';
Clemo 0:cb80470434eb 204 }
Clemo 0:cb80470434eb 205 lcd_putc(v);
Clemo 0:cb80470434eb 206 lcd_cursor(0,position);
Clemo 0:cb80470434eb 207 lcd_putc(0);
Clemo 0:cb80470434eb 208 }
Clemo 0:cb80470434eb 209 else
Clemo 0:cb80470434eb 210 {
Clemo 0:cb80470434eb 211 lcd_putc(0);
Clemo 0:cb80470434eb 212 lcd_cursor(0,position);
Clemo 0:cb80470434eb 213 v -= 6;
Clemo 0:cb80470434eb 214 if (v==5) v = 0x11;
Clemo 0:cb80470434eb 215 else if (v==7) v = 'T';
Clemo 0:cb80470434eb 216 else if (v>7) v = 7; //'M';
Clemo 0:cb80470434eb 217 lcd_putc(v);
Clemo 0:cb80470434eb 218 }
Clemo 0:cb80470434eb 219 }
Clemo 0:cb80470434eb 220
Clemo 0:cb80470434eb 221
Clemo 0:cb80470434eb 222 void lcd_init(void)
Clemo 0:cb80470434eb 223 {
Clemo 0:cb80470434eb 224 int i;
Clemo 0:cb80470434eb 225
Clemo 0:cb80470434eb 226 Board_LCD_SetBacklight(true);
Clemo 0:cb80470434eb 227 // Liberate LCD.
Clemo 0:cb80470434eb 228 SysTick_Delay(10);
Clemo 0:cb80470434eb 229 Board_LCD_ResetDeassert();
Clemo 0:cb80470434eb 230 SysTick_Delay(ST7032_RESET_RECOVERY_TIME);
Clemo 0:cb80470434eb 231
Clemo 0:cb80470434eb 232 // Setup I2C port.
Clemo 0:cb80470434eb 233 // Chip_SYSCTL_DeassertPeriphReset(RESET_I2C0);
Clemo 0:cb80470434eb 234 // Chip_I2C_Init(I2C0);
Clemo 0:cb80470434eb 235 // Chip_I2C_SetClockRate(I2C0,400000); // ST7032 can handle 400 kHz.
Clemo 0:cb80470434eb 236 // Chip_I2C_SetMasterEventHandler(I2C0,Chip_I2C_EventHandler);
Clemo 0:cb80470434eb 237 // Enable I2C interrupts.
Clemo 0:cb80470434eb 238 // NVIC_EnableIRQ(I2C0_IRQn);
Clemo 0:cb80470434eb 239 // Low interrupt priority.
Clemo 0:cb80470434eb 240 // NVIC_SetPriority(I2C0_IRQn,7);
Clemo 0:cb80470434eb 241
Clemo 0:cb80470434eb 242 // Initialize LCD module.
Clemo 0:cb80470434eb 243 // Set custom characters.
Clemo 0:cb80470434eb 244 for (i=0; i<8; i++)
Clemo 0:cb80470434eb 245 {
Clemo 0:cb80470434eb 246 lcd_set_custom_character(i,(const uint8_t *)&custom_characters[i]);
Clemo 0:cb80470434eb 247 }
Clemo 0:cb80470434eb 248 // Set our default config and enable extended functions.
Clemo 0:cb80470434eb 249 st7032i_write_command(ST7032_CMD_FUNCTION,ST7032_FUNC_CONFIG_EXTENDED);
Clemo 0:cb80470434eb 250 // Set internal oscillator.
Clemo 0:cb80470434eb 251 st7032i_write_command(ST7032_CMD_BIAS_OSC,ST7032_BIAS_020|4);
Clemo 0:cb80470434eb 252 // Set contrast. 4 is a good value for 3V displays.
Clemo 0:cb80470434eb 253 lcd_contrast(4);
Clemo 0:cb80470434eb 254 // Follower on, amplifier max. (Why? From the Midas datasheet)
Clemo 0:cb80470434eb 255 st7032i_write_command(ST7032_CMD_FOLLOWER,ST7032_FOLLOWER_ON|7);
Clemo 0:cb80470434eb 256 // A 200 ms delay is recommended for the power to stabilize.
Clemo 0:cb80470434eb 257 SysTick_Delay(200);
Clemo 0:cb80470434eb 258 // Display on.
Clemo 0:cb80470434eb 259 //st7032i_write_command(ST7032_CMD_ON_OFF,ST7032_DISPLAY_ON|ST7032_CURSOR_OFF|ST7032_BLINK_OFF);
Clemo 0:cb80470434eb 260 lcd_display_cursor_blink(1,0,0);
Clemo 0:cb80470434eb 261 // Clear display.
Clemo 0:cb80470434eb 262 lcd_clear();
Clemo 0:cb80470434eb 263
Clemo 0:cb80470434eb 264 // Check custom characters.
Clemo 0:cb80470434eb 265 /*lcd_display_cursor_blink(1,1,0);
Clemo 0:cb80470434eb 266 for (i=0; i<8; i++)
Clemo 0:cb80470434eb 267 {
Clemo 0:cb80470434eb 268 lcd_putc((char)i);
Clemo 0:cb80470434eb 269 }
Clemo 0:cb80470434eb 270 SysTick_Delay(5000);*/
Clemo 0:cb80470434eb 271 }