/700353_Zeiterfassung/src/firmware/lcd.c
C | 238 lines | 183 code | 43 blank | 12 comment | 12 complexity | 038f5ff1a8366fa356a30034f39e1a63 MD5 | raw file
Possible License(s): GPL-2.0, 0BSD, LGPL-2.1, LGPL-2.0
- #include <avr/io.h>
- #include <string.h>
- #include <stdlib.h>
- #include <avr/pgmspace.h>
-
- #include "board.h"
- #include "lcd.h"
- #include "time.h"
- #include "utils.h"
-
- const char init[] PROGMEM = { 0x31, 0x14, 0x55, 0x6d, 0x70, 0x38, 0x0f, 0x00 };
-
- marquee_t project, message;
-
- static void lcd_hhmm(uint8_t value, char pad)
- {
- char string[3];
-
- itoa(value, string, 10);
-
- if(strlen(string) < 2)
- {
- lcd_write_char(pad);
- lcd_write_char(string[0]);
- }
- else
- {
- lcd_write_char(string[0]);
- lcd_write_char(string[1]);
- }
- }
-
- void lcd_marquee_set(char *buffer, uint8_t x, uint8_t y, uint8_t width, uint8_t len)
- {
- memset(message.text, 0, sizeof(message.text));
- memcpy(message.text, buffer, len);
- message.len = len;
- message.pos = 0;
- message.width = width;
- message.xy = (y << 4) | x;
- }
-
- void lcd_project_set(char *buffer, uint8_t x, uint8_t y, uint8_t width, uint8_t len)
- {
- memset(project.text, 0, sizeof(project.text));
- memcpy(project.text, buffer, len);
- project.len = len;
- project.pos = 0;
- project.width = width;
- project.xy = (y << 4) | x;
- }
-
- void lcd_task(void)
- {
- int8_t hour, min;
-
- lcd_marquee(&project);
- lcd_marquee(&message);
-
- lcd_goto(0, 10);
- lcd_write_char(' ');
- if(time_get())
- {
- timestamp2hhmm(time_get(), NULL, NULL, &hour, &min, NULL, NULL);
-
- lcd_hhmm(hour, ' ');
- lcd_write_char(':');
- lcd_hhmm(min, '0');
- }
- else
- {
- lcd_write_char('?');
- lcd_write_char('?');
- lcd_write_char(':');
- lcd_write_char('?');
- lcd_write_char('?');
- }
- }
-
- void static lcd_toggle_RS(void)
- {
- LCD_PORT_RS ^= (1 << LCD_RS);
- LCD_PORT_RS ^= (1 << LCD_RS);
- }
-
- void lcd_send_command(uint8_t command)
- {
- LCD_PORT_RS &= ~(1 << LCD_RS); // RS -> Low
-
- SPDR = command;
- while(!(SPSR & (1<<SPIF)));
-
- lcd_toggle_RS();
- sleep_us(13);
- }
-
- // cursor ausschalten
- void lcd_set_cursor_off(void)
- {
- lcd_send_command(0x0C);
- }
-
- void lcd_marquee(marquee_t *m)
- {
- uint8_t i,x,y;
- char *ptr;
-
- x = m->xy & 0xF0;
- y = m->xy & 0x0F;
-
- if(m->len == 0)
- return;
-
- lcd_goto(x, y);
-
- if(m->len <= m->width)
- {
- for(i = 0; i < m->width; i++)
- lcd_write_char(m->text[i]);
-
- return;
- }
-
- ptr = &m->text[m->pos % m->len];
- for(i = 0; i < m->width; i++)
- {
- if(*ptr != 0)
- {
- lcd_write_char(*ptr);
- ptr++;
- }
- else
- {
- lcd_write_char(' ');
- ptr = m->text;
- }
- }
-
- m->pos = (m->pos+1) % m->len;
- }
-
- // goto
- void lcd_goto(uint8_t line, uint8_t pos)
- {
- uint8_t command;
-
- if(line)
- pos += 0x40;
-
- command = 0x80 + pos;
- lcd_send_command(command);
- }
-
- // cursor: unterstrich
- void lcd_set_cursor_underline(void)
- {
- lcd_send_command(0x0E);
- }
-
- // cursor blinkend
- void lcd_set_cursor_blink(void)
- {
- lcd_send_command(0x0D);
- }
-
- // lcd an pos setzen
- void lcd_set_cursor (uint8_t pos)
- {
- lcd_send_command(128+pos);
- }
-
- // clear display, cursor zuruecksetzen
- void lcd_clear(void)
- {
- lcd_send_command(0x01);
- sleep_us(650);
- lcd_send_command(0x06);
- }
-
-
- // display loeschen, cursor an letzte position setzen
- void lcd_clear_lastpos (void)
- {
- lcd_send_command(0x02);
- }
-
- // zeichen schreiben
- void lcd_write_char (char c) // Byte an Cursorposition ausgeben
- {
- LCD_PORT_RS |= (1 << LCD_RS); // CTRL_RS -> HIGH
- SPDR = c;
- while(!(SPSR & (1<<SPIF)));
-
- lcd_toggle_RS();
- sleep_us(15);
- LCD_PORT_RS &= ~(1 << LCD_RS); // CTRL_RS -> HIGH
- }
-
- // zeichenkette schreiben
- void lcd_write(char *s, uint8_t len)
- {
- while(len-- != 0)
- lcd_write_char(*s++);
- }
-
- // init
- void lcd_init (void)
- {
- uint8_t i;
-
- // init SPI
- LCD_SPI_DDR |= (1 << LCD_SPI_MOSI | 1 << LCD_SPI_SCK);
- DDRB |= (1 << PB0 | 1 << PB1 | 1 << PB2 | 1 << PB3);
-
- SPSR |= (1 << SPI2X); /* No doubled clock frequency */
- SPCR |= (0 << SPIE) | /* SPI Interrupt disable */
- (1 << SPE) | /* SPI Enable */
- (0 << DORD) | /* Data Order: MSB first */
- (1 << MSTR) | /* Master mode */
- (0 << CPOL) | /* Clock Polarity: CTRL_SCK low when idle */
- (0 << CPHA) | /* Clock Phase: sample on rising CTRL_SCK edge */
- (0 << SPR1) | /* Clock Frequency: f_OSC / 4 => 4Mbit */
- (1 << SPR0);
- SPSR |= (1 << SPI2X); /* No doubled clock frequency */
-
- LCD_DDR_RS |= (1 << LCD_RS);
- LCD_PORT_RS |= (1 << LCD_RS);
- // auf display warten
- sleep_ms(50);
- LCD_PORT_RS &= ~(1 << LCD_RS);
- sleep_ms(30);
-
- for(i = 0; i < strlen_P(init); i++)
- lcd_send_command(pgm_read_byte(init+i));
-
- lcd_clear();
- lcd_set_cursor_off();
- }