Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- BUTTLCD -- Butterfly LCD Driver
- ButterflyLCD.h
- */
- #ifndef LCDDRIVER_H
- #define LCDDRIVER_H
- // INCLUDES:
- #include <avr/io.h>
- #include <avr/pgmspace.h>
- #include <avr/interrupt.h>
- #include <stdbool.h>
- // EXTERNAL VARIABLES:
- extern volatile uint8_t ScrollFlags;
- // DEFINES:
- #define LCD_LCDREGS_START ((uint8_t*)&LCDDR0)
- #define LCD_SPACE_OR_INVALID_CHAR 0xFF
- #define LCD_CONTRAST_LEVEL(level) do{ LCDCCR = (0x0F & level); }while(0)
- #define LCD_WAIT_FOR_SCROLL_DONE() do{ while (!(ScrollFlags & LCD_FLAG_SCROLL_DONE)) {} }while(0)
- #define LCD_SCROLLCOUNT_DEFAULT 6
- #define LCD_DELAYCOUNT_DEFAULT 20
- // #define LCD_TEXTBUFFER_SIZE 20
- #define LCD_SEGBUFFER_SIZE 19
- #define LCD_DISPLAY_SIZE 6
- #define LCD_FLAG_SCROLL (1 << 0)
- #define LCD_FLAG_SCROLL_DONE (1 << 1)
- // PROTOTYPES:
- void LCD_puts_f(const char *FlashData);
- void LCD_puts(const char *Data);
- void LCD_Init(void);
- void LCD_ShowColons(const uint8_t ColonsOn);
- #if defined(INC_FROM_DRIVER)
- static inline void LCD_WriteChar(const uint8_t Byte, const uint8_t Digit);
- #endif
- #endif
- /*
- BUTTLCD -- Butterfly LCD Driver
- ButterflyLCD.c
- */
- #define LCD_TEXTBUFFER_SIZE 20
- static volatile char TextBuffer[LCD_TEXTBUFFER_SIZE + LCD_DISPLAY_SIZE + 1] = {};
- static volatile uint8_t StrStart = 0;
- static volatile uint8_t StrEnd = 0;
- static volatile uint8_t ScrollCount = 0;
- static volatile uint8_t UpdateDisplay = false;
- static volatile uint8_t ShowColons = false;
- volatile uint8_t ScrollFlags = 0;
- const uint16_t LCD_SegTable[] PROGMEM =
- {
- 0xEAA8, // '*'
- 0x2A80, // '+'
- 0x4000, // ','
- 0x0A00, // '-'
- 0x0A51, // '.' Degree sign
- 0x4008, // '/'
- 0x5559, // '0'
- 0x0118, // '1'
- 0x1e11, // '2
- 0x1b11, // '3
- 0x0b50, // '4
- 0x1b41, // '5
- 0x1f41, // '6
- 0x0111, // '7
- 0x1f51, // '8
- 0x1b51, // '9'
- 0x0000, // ':' (Not defined)
- 0x0000, // ';' (Not defined)
- 0x8008, // '<'
- 0x1A00, // '='
- 0x4020, // '>'
- 0x0000, // '?' (Not defined)
- 0x0000, // '@' (Not defined)
- 0x0f51, // 'A' (+ 'a')
- 0x3991, // 'B' (+ 'b')
- 0x1441, // 'C' (+ 'c')
- 0x3191, // 'D' (+ 'd')
- 0x1e41, // 'E' (+ 'e')
- 0x0e41, // 'F' (+ 'f')
- 0x1d41, // 'G' (+ 'g')
- 0x0f50, // 'H' (+ 'h')
- 0x2080, // 'I' (+ 'i')
- 0x1510, // 'J' (+ 'j')
- 0x8648, // 'K' (+ 'k')
- 0x1440, // 'L' (+ 'l')
- 0x0578, // 'M' (+ 'm')
- 0x8570, // 'N' (+ 'n')
- 0x1551, // 'O' (+ 'o')
- 0x0e51, // 'P' (+ 'p')
- 0x9551, // 'Q' (+ 'q')
- 0x8e51, // 'R' (+ 'r')
- 0x9021, // 'S' (+ 's')
- 0x2081, // 'T' (+ 't')
- 0x1550, // 'U' (+ 'u')
- 0x4448, // 'V' (+ 'v')
- 0xc550, // 'W' (+ 'w')
- 0xc028, // 'X' (+ 'x')
- 0x2028, // 'Y' (+ 'y')
- 0x5009, // 'Z' (+ 'z')
- 0x1441, // '['
- 0x8020, // '\'
- 0x1111, // ']'
- 0x0000, // '^' (Not defined)
- 0x1000 // '_'
- };
- static inline void LCD_WriteChar(const uint8_t Byte, const uint8_t Digit)
- {
- uint8_t* BuffPtr = (uint8_t*)(LCD_LCDREGS_START + (Digit >> 1));
- uint16_t SegData = 0x0000;
- if (Byte != LCD_SPACE_OR_INVALID_CHAR) // Null indicates invalid character or space
- SegData = pgm_read_word(&LCD_SegTable[Byte]);
- for (uint8_t BNib = 0; BNib < 4; BNib++)
- {
- uint8_t MaskedSegData = (SegData & 0x0000F);
- if (Digit & 0x01)
- *BuffPtr = ((*BuffPtr & 0x0F) | (MaskedSegData << 4));
- else
- *BuffPtr = ((*BuffPtr & 0xF0) | MaskedSegData);
- BuffPtr += 5;
- SegData >>= 4;
- }
- }
- void LCD_ShowColons(const uint8_t ColonsOn)
- {
- ShowColons = ColonsOn;
- UpdateDisplay = true;
- }
- ISR(LCD_vect)
- {
- if (ScrollFlags & LCD_FLAG_SCROLL)
- {
- if (!(ScrollCount--))
- {
- UpdateDisplay = true;
- ScrollCount = LCD_SCROLLCOUNT_DEFAULT;
- }
- }
- if (UpdateDisplay)
- {
- for (uint8_t Character = 0; Character < LCD_DISPLAY_SIZE; Character++)
- {
- uint8_t Byte = (StrStart + Character);
- if (Byte >= StrEnd)
- Byte -= StrEnd;
- LCD_WriteChar(TextBuffer[Byte], Character);
- }
- if ((StrStart + LCD_DISPLAY_SIZE) == StrEnd)
- ScrollFlags |= LCD_FLAG_SCROLL_DONE;
- if (StrStart++ == StrEnd)
- StrStart = 1;
- if (ShowColons)
- *((uint8_t*)(LCD_LCDREGS_START + 8)) = 0x01;
- else
- *((uint8_t*)(LCD_LCDREGS_START + 8)) = 0x00;
- UpdateDisplay = false;
- }
- }
- void LCD_Init(void)
- {
- // Set the initial contrast level to maximum:
- LCD_CONTRAST_LEVEL(0x0F);
- //clck externo assyncrono, 1/4duty e 1/3bias, 25segmentos
- LCDCRB = (1<<LCDCS) | (3<<LCDMUX0) | (7<<LCDPM0);//LCDCS=1, LCDMUX1/LCDMUX0=11, LCDPM2/LCDPM1/LCDPM0=111
- // Set LCD prescaler to give a framerate of 64Hz:
- LCDFRR = (0<<LCDPS0) | (3<<LCDCD0);
- // Enable LCD and set low power waveform, enable start of frame interrupt:
- //
- LCDCRA = (1<<LCDEN) | (1<<LCDAB) | (1<<LCDIE);
- }
- void LCD_puts(const char *Data)
- {
- uint8_t LoadB = 0;
- uint8_t CurrByte;
- do
- {
- CurrByte = *(Data++);
- switch (CurrByte)
- {
- case 'a'...'z':
- CurrByte &= ~(1 << 5); // Translate to upper-case character
- case '*'...'_': // Valid character, load it into the array
- TextBuffer[LoadB++] = (CurrByte - '*');
- break;
- case 0x00:
- break;
- default: // Space or invalid character, use 0xFF to display a blank
- TextBuffer[LoadB++] = LCD_SPACE_OR_INVALID_CHAR;
- }
- }
- while (CurrByte && (LoadB < LCD_TEXTBUFFER_SIZE));
- ScrollFlags = ((LoadB > LCD_DISPLAY_SIZE)? LCD_FLAG_SCROLL : 0x00);
- for (uint8_t Nulls = 0; Nulls < 7; Nulls++)
- TextBuffer[LoadB++] = LCD_SPACE_OR_INVALID_CHAR; // Load in nulls to ensure that when scrolling, the display clears before wrapping
- TextBuffer[LoadB] = 0x00; // Null-terminate string
- StrStart = 0;
- StrEnd = LoadB;
- ScrollCount = LCD_SCROLLCOUNT_DEFAULT + LCD_DELAYCOUNT_DEFAULT;
- UpdateDisplay = true;
- }
Add Comment
Please, Sign In to add comment