Guest User

Untitled

a guest
Jul 19th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.39 KB | None | 0 0
  1. /*
  2. BUTTLCD -- Butterfly LCD Driver
  3. ButterflyLCD.h
  4. */
  5.  
  6. #ifndef LCDDRIVER_H
  7. #define LCDDRIVER_H
  8.  
  9. // INCLUDES:
  10. #include <avr/io.h>
  11. #include <avr/pgmspace.h>
  12. #include <avr/interrupt.h>
  13. #include <stdbool.h>
  14.  
  15. // EXTERNAL VARIABLES:
  16. extern volatile uint8_t ScrollFlags;
  17.  
  18. // DEFINES:
  19. #define LCD_LCDREGS_START ((uint8_t*)&LCDDR0)
  20. #define LCD_SPACE_OR_INVALID_CHAR 0xFF
  21.  
  22. #define LCD_CONTRAST_LEVEL(level) do{ LCDCCR = (0x0F & level); }while(0)
  23. #define LCD_WAIT_FOR_SCROLL_DONE() do{ while (!(ScrollFlags & LCD_FLAG_SCROLL_DONE)) {} }while(0)
  24.  
  25. #define LCD_SCROLLCOUNT_DEFAULT 6
  26. #define LCD_DELAYCOUNT_DEFAULT 20
  27. // #define LCD_TEXTBUFFER_SIZE 20
  28. #define LCD_SEGBUFFER_SIZE 19
  29. #define LCD_DISPLAY_SIZE 6
  30.  
  31. #define LCD_FLAG_SCROLL (1 << 0)
  32. #define LCD_FLAG_SCROLL_DONE (1 << 1)
  33.  
  34. // PROTOTYPES:
  35. void LCD_puts_f(const char *FlashData);
  36. void LCD_puts(const char *Data);
  37. void LCD_Init(void);
  38. void LCD_ShowColons(const uint8_t ColonsOn);
  39.  
  40. #if defined(INC_FROM_DRIVER)
  41. static inline void LCD_WriteChar(const uint8_t Byte, const uint8_t Digit);
  42. #endif
  43.  
  44. #endif
  45.  
  46. /*
  47. BUTTLCD -- Butterfly LCD Driver
  48. ButterflyLCD.c
  49. */
  50.  
  51.  
  52. #define LCD_TEXTBUFFER_SIZE 20
  53. static volatile char TextBuffer[LCD_TEXTBUFFER_SIZE + LCD_DISPLAY_SIZE + 1] = {};
  54. static volatile uint8_t StrStart = 0;
  55. static volatile uint8_t StrEnd = 0;
  56. static volatile uint8_t ScrollCount = 0;
  57. static volatile uint8_t UpdateDisplay = false;
  58. static volatile uint8_t ShowColons = false;
  59. volatile uint8_t ScrollFlags = 0;
  60.  
  61. const uint16_t LCD_SegTable[] PROGMEM =
  62. {
  63. 0xEAA8, // '*'
  64. 0x2A80, // '+'
  65. 0x4000, // ','
  66. 0x0A00, // '-'
  67. 0x0A51, // '.' Degree sign
  68. 0x4008, // '/'
  69. 0x5559, // '0'
  70. 0x0118, // '1'
  71. 0x1e11, // '2
  72. 0x1b11, // '3
  73. 0x0b50, // '4
  74. 0x1b41, // '5
  75. 0x1f41, // '6
  76. 0x0111, // '7
  77. 0x1f51, // '8
  78. 0x1b51, // '9'
  79. 0x0000, // ':' (Not defined)
  80. 0x0000, // ';' (Not defined)
  81. 0x8008, // '<'
  82. 0x1A00, // '='
  83. 0x4020, // '>'
  84. 0x0000, // '?' (Not defined)
  85. 0x0000, // '@' (Not defined)
  86. 0x0f51, // 'A' (+ 'a')
  87. 0x3991, // 'B' (+ 'b')
  88. 0x1441, // 'C' (+ 'c')
  89. 0x3191, // 'D' (+ 'd')
  90. 0x1e41, // 'E' (+ 'e')
  91. 0x0e41, // 'F' (+ 'f')
  92. 0x1d41, // 'G' (+ 'g')
  93. 0x0f50, // 'H' (+ 'h')
  94. 0x2080, // 'I' (+ 'i')
  95. 0x1510, // 'J' (+ 'j')
  96. 0x8648, // 'K' (+ 'k')
  97. 0x1440, // 'L' (+ 'l')
  98. 0x0578, // 'M' (+ 'm')
  99. 0x8570, // 'N' (+ 'n')
  100. 0x1551, // 'O' (+ 'o')
  101. 0x0e51, // 'P' (+ 'p')
  102. 0x9551, // 'Q' (+ 'q')
  103. 0x8e51, // 'R' (+ 'r')
  104. 0x9021, // 'S' (+ 's')
  105. 0x2081, // 'T' (+ 't')
  106. 0x1550, // 'U' (+ 'u')
  107. 0x4448, // 'V' (+ 'v')
  108. 0xc550, // 'W' (+ 'w')
  109. 0xc028, // 'X' (+ 'x')
  110. 0x2028, // 'Y' (+ 'y')
  111. 0x5009, // 'Z' (+ 'z')
  112. 0x1441, // '['
  113. 0x8020, // '\'
  114. 0x1111, // ']'
  115. 0x0000, // '^' (Not defined)
  116. 0x1000 // '_'
  117. };
  118.  
  119. static inline void LCD_WriteChar(const uint8_t Byte, const uint8_t Digit)
  120. {
  121. uint8_t* BuffPtr = (uint8_t*)(LCD_LCDREGS_START + (Digit >> 1));
  122. uint16_t SegData = 0x0000;
  123.  
  124. if (Byte != LCD_SPACE_OR_INVALID_CHAR) // Null indicates invalid character or space
  125. SegData = pgm_read_word(&LCD_SegTable[Byte]);
  126.  
  127. for (uint8_t BNib = 0; BNib < 4; BNib++)
  128. {
  129. uint8_t MaskedSegData = (SegData & 0x0000F);
  130.  
  131. if (Digit & 0x01)
  132. *BuffPtr = ((*BuffPtr & 0x0F) | (MaskedSegData << 4));
  133. else
  134. *BuffPtr = ((*BuffPtr & 0xF0) | MaskedSegData);
  135.  
  136. BuffPtr += 5;
  137. SegData >>= 4;
  138. }
  139. }
  140.  
  141. void LCD_ShowColons(const uint8_t ColonsOn)
  142. {
  143. ShowColons = ColonsOn;
  144. UpdateDisplay = true;
  145. }
  146.  
  147. ISR(LCD_vect)
  148. {
  149. if (ScrollFlags & LCD_FLAG_SCROLL)
  150. {
  151. if (!(ScrollCount--))
  152. {
  153. UpdateDisplay = true;
  154. ScrollCount = LCD_SCROLLCOUNT_DEFAULT;
  155. }
  156. }
  157.  
  158. if (UpdateDisplay)
  159. {
  160. for (uint8_t Character = 0; Character < LCD_DISPLAY_SIZE; Character++)
  161. {
  162. uint8_t Byte = (StrStart + Character);
  163.  
  164. if (Byte >= StrEnd)
  165. Byte -= StrEnd;
  166.  
  167. LCD_WriteChar(TextBuffer[Byte], Character);
  168. }
  169.  
  170. if ((StrStart + LCD_DISPLAY_SIZE) == StrEnd)
  171. ScrollFlags |= LCD_FLAG_SCROLL_DONE;
  172.  
  173. if (StrStart++ == StrEnd)
  174. StrStart = 1;
  175.  
  176. if (ShowColons)
  177. *((uint8_t*)(LCD_LCDREGS_START + 8)) = 0x01;
  178. else
  179. *((uint8_t*)(LCD_LCDREGS_START + 8)) = 0x00;
  180.  
  181. UpdateDisplay = false;
  182. }
  183. }
  184.  
  185. void LCD_Init(void)
  186. {
  187. // Set the initial contrast level to maximum:
  188. LCD_CONTRAST_LEVEL(0x0F);
  189.  
  190.  
  191. //clck externo assyncrono, 1/4duty e 1/3bias, 25segmentos
  192. LCDCRB = (1<<LCDCS) | (3<<LCDMUX0) | (7<<LCDPM0);//LCDCS=1, LCDMUX1/LCDMUX0=11, LCDPM2/LCDPM1/LCDPM0=111
  193.  
  194. // Set LCD prescaler to give a framerate of 64Hz:
  195. LCDFRR = (0<<LCDPS0) | (3<<LCDCD0);
  196.  
  197. // Enable LCD and set low power waveform, enable start of frame interrupt:
  198. //
  199. LCDCRA = (1<<LCDEN) | (1<<LCDAB) | (1<<LCDIE);
  200. }
  201.  
  202. void LCD_puts(const char *Data)
  203. {
  204. uint8_t LoadB = 0;
  205. uint8_t CurrByte;
  206.  
  207. do
  208. {
  209. CurrByte = *(Data++);
  210.  
  211. switch (CurrByte)
  212. {
  213. case 'a'...'z':
  214. CurrByte &= ~(1 << 5); // Translate to upper-case character
  215. case '*'...'_': // Valid character, load it into the array
  216. TextBuffer[LoadB++] = (CurrByte - '*');
  217. break;
  218. case 0x00:
  219. break;
  220. default: // Space or invalid character, use 0xFF to display a blank
  221. TextBuffer[LoadB++] = LCD_SPACE_OR_INVALID_CHAR;
  222. }
  223. }
  224. while (CurrByte && (LoadB < LCD_TEXTBUFFER_SIZE));
  225.  
  226. ScrollFlags = ((LoadB > LCD_DISPLAY_SIZE)? LCD_FLAG_SCROLL : 0x00);
  227.  
  228. for (uint8_t Nulls = 0; Nulls < 7; Nulls++)
  229. TextBuffer[LoadB++] = LCD_SPACE_OR_INVALID_CHAR; // Load in nulls to ensure that when scrolling, the display clears before wrapping
  230.  
  231. TextBuffer[LoadB] = 0x00; // Null-terminate string
  232.  
  233. StrStart = 0;
  234. StrEnd = LoadB;
  235. ScrollCount = LCD_SCROLLCOUNT_DEFAULT + LCD_DELAYCOUNT_DEFAULT;
  236. UpdateDisplay = true;
  237. }
Add Comment
Please, Sign In to add comment