PageRenderTime 25ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/700353_Zeiterfassung/src/firmware/lcd.c

http://embeddedprojects.googlecode.com/
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
  1. #include <avr/io.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <avr/pgmspace.h>
  5. #include "board.h"
  6. #include "lcd.h"
  7. #include "time.h"
  8. #include "utils.h"
  9. const char init[] PROGMEM = { 0x31, 0x14, 0x55, 0x6d, 0x70, 0x38, 0x0f, 0x00 };
  10. marquee_t project, message;
  11. static void lcd_hhmm(uint8_t value, char pad)
  12. {
  13. char string[3];
  14. itoa(value, string, 10);
  15. if(strlen(string) < 2)
  16. {
  17. lcd_write_char(pad);
  18. lcd_write_char(string[0]);
  19. }
  20. else
  21. {
  22. lcd_write_char(string[0]);
  23. lcd_write_char(string[1]);
  24. }
  25. }
  26. void lcd_marquee_set(char *buffer, uint8_t x, uint8_t y, uint8_t width, uint8_t len)
  27. {
  28. memset(message.text, 0, sizeof(message.text));
  29. memcpy(message.text, buffer, len);
  30. message.len = len;
  31. message.pos = 0;
  32. message.width = width;
  33. message.xy = (y << 4) | x;
  34. }
  35. void lcd_project_set(char *buffer, uint8_t x, uint8_t y, uint8_t width, uint8_t len)
  36. {
  37. memset(project.text, 0, sizeof(project.text));
  38. memcpy(project.text, buffer, len);
  39. project.len = len;
  40. project.pos = 0;
  41. project.width = width;
  42. project.xy = (y << 4) | x;
  43. }
  44. void lcd_task(void)
  45. {
  46. int8_t hour, min;
  47. lcd_marquee(&project);
  48. lcd_marquee(&message);
  49. lcd_goto(0, 10);
  50. lcd_write_char(' ');
  51. if(time_get())
  52. {
  53. timestamp2hhmm(time_get(), NULL, NULL, &hour, &min, NULL, NULL);
  54. lcd_hhmm(hour, ' ');
  55. lcd_write_char(':');
  56. lcd_hhmm(min, '0');
  57. }
  58. else
  59. {
  60. lcd_write_char('?');
  61. lcd_write_char('?');
  62. lcd_write_char(':');
  63. lcd_write_char('?');
  64. lcd_write_char('?');
  65. }
  66. }
  67. void static lcd_toggle_RS(void)
  68. {
  69. LCD_PORT_RS ^= (1 << LCD_RS);
  70. LCD_PORT_RS ^= (1 << LCD_RS);
  71. }
  72. void lcd_send_command(uint8_t command)
  73. {
  74. LCD_PORT_RS &= ~(1 << LCD_RS); // RS -> Low
  75. SPDR = command;
  76. while(!(SPSR & (1<<SPIF)));
  77. lcd_toggle_RS();
  78. sleep_us(13);
  79. }
  80. // cursor ausschalten
  81. void lcd_set_cursor_off(void)
  82. {
  83. lcd_send_command(0x0C);
  84. }
  85. void lcd_marquee(marquee_t *m)
  86. {
  87. uint8_t i,x,y;
  88. char *ptr;
  89. x = m->xy & 0xF0;
  90. y = m->xy & 0x0F;
  91. if(m->len == 0)
  92. return;
  93. lcd_goto(x, y);
  94. if(m->len <= m->width)
  95. {
  96. for(i = 0; i < m->width; i++)
  97. lcd_write_char(m->text[i]);
  98. return;
  99. }
  100. ptr = &m->text[m->pos % m->len];
  101. for(i = 0; i < m->width; i++)
  102. {
  103. if(*ptr != 0)
  104. {
  105. lcd_write_char(*ptr);
  106. ptr++;
  107. }
  108. else
  109. {
  110. lcd_write_char(' ');
  111. ptr = m->text;
  112. }
  113. }
  114. m->pos = (m->pos+1) % m->len;
  115. }
  116. // goto
  117. void lcd_goto(uint8_t line, uint8_t pos)
  118. {
  119. uint8_t command;
  120. if(line)
  121. pos += 0x40;
  122. command = 0x80 + pos;
  123. lcd_send_command(command);
  124. }
  125. // cursor: unterstrich
  126. void lcd_set_cursor_underline(void)
  127. {
  128. lcd_send_command(0x0E);
  129. }
  130. // cursor blinkend
  131. void lcd_set_cursor_blink(void)
  132. {
  133. lcd_send_command(0x0D);
  134. }
  135. // lcd an pos setzen
  136. void lcd_set_cursor (uint8_t pos)
  137. {
  138. lcd_send_command(128+pos);
  139. }
  140. // clear display, cursor zuruecksetzen
  141. void lcd_clear(void)
  142. {
  143. lcd_send_command(0x01);
  144. sleep_us(650);
  145. lcd_send_command(0x06);
  146. }
  147. // display loeschen, cursor an letzte position setzen
  148. void lcd_clear_lastpos (void)
  149. {
  150. lcd_send_command(0x02);
  151. }
  152. // zeichen schreiben
  153. void lcd_write_char (char c) // Byte an Cursorposition ausgeben
  154. {
  155. LCD_PORT_RS |= (1 << LCD_RS); // CTRL_RS -> HIGH
  156. SPDR = c;
  157. while(!(SPSR & (1<<SPIF)));
  158. lcd_toggle_RS();
  159. sleep_us(15);
  160. LCD_PORT_RS &= ~(1 << LCD_RS); // CTRL_RS -> HIGH
  161. }
  162. // zeichenkette schreiben
  163. void lcd_write(char *s, uint8_t len)
  164. {
  165. while(len-- != 0)
  166. lcd_write_char(*s++);
  167. }
  168. // init
  169. void lcd_init (void)
  170. {
  171. uint8_t i;
  172. // init SPI
  173. LCD_SPI_DDR |= (1 << LCD_SPI_MOSI | 1 << LCD_SPI_SCK);
  174. DDRB |= (1 << PB0 | 1 << PB1 | 1 << PB2 | 1 << PB3);
  175. SPSR |= (1 << SPI2X); /* No doubled clock frequency */
  176. SPCR |= (0 << SPIE) | /* SPI Interrupt disable */
  177. (1 << SPE) | /* SPI Enable */
  178. (0 << DORD) | /* Data Order: MSB first */
  179. (1 << MSTR) | /* Master mode */
  180. (0 << CPOL) | /* Clock Polarity: CTRL_SCK low when idle */
  181. (0 << CPHA) | /* Clock Phase: sample on rising CTRL_SCK edge */
  182. (0 << SPR1) | /* Clock Frequency: f_OSC / 4 => 4Mbit */
  183. (1 << SPR0);
  184. SPSR |= (1 << SPI2X); /* No doubled clock frequency */
  185. LCD_DDR_RS |= (1 << LCD_RS);
  186. LCD_PORT_RS |= (1 << LCD_RS);
  187. // auf display warten
  188. sleep_ms(50);
  189. LCD_PORT_RS &= ~(1 << LCD_RS);
  190. sleep_ms(30);
  191. for(i = 0; i < strlen_P(init); i++)
  192. lcd_send_command(pgm_read_byte(init+i));
  193. lcd_clear();
  194. lcd_set_cursor_off();
  195. }