altos/telefireone-v1.0: Track ao_led_init API change
[fw/altos] / src / stm / ao_lcd_font.c
1 /*
2  * Copyright © 2012 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include <ao.h>
20 #include "ao_lcd_font.h"
21
22 static const uint16_t ao_lcd_font[] = {
23 #include "ao_lcd_font_bits.h"
24 };
25
26 /*
27          -----          0
28         |\ | /|         1 2 3 4 5
29         | \|/ | @               14
30          -- --          6 7
31         | /|\ |         8 9 10 11 12    
32         |/ | \| @               14
33          -----          13
34                 @               15
35 */
36
37 static const uint8_t    ao_bit_src[] = {
38          8,  7,  5,  6,
39         13, 12,  0,  1,
40         10, 14,  4,  9,
41         11, 15,  3,  2
42 };
43
44 static const uint8_t    ao_bit_dst[6][4] = {
45         {  0,  1, 28, 29 },
46         {  2,  7, 26, 27 },
47         {  8,  9, 24, 25 },
48         { 10, 11, 20, 21 },
49         { 12, 13, 18, 19 },
50         { 14, 15, 17, 16 },
51 };
52
53 static void
54 ao_draw_glyph(uint8_t pos, uint16_t glyph) {
55         uint8_t         col, seg, src, dst;
56         uint32_t        ram;
57
58         for (col = 0; col < 4; col++) {
59                 for (seg = 0; seg < 4; seg++) {
60                         src = ao_bit_src[(col << 2) | seg];
61                         dst = ao_bit_dst[pos][seg];
62                         ram = stm_lcd.ram[col * 2];
63                         ram &= ~(1 << dst);
64                         ram |= (uint32_t) ((glyph >> src) & 1) << dst;
65                         stm_lcd.ram[col*2] = ram;
66                 }
67         }
68 }
69
70 #define AO_LCD_FONT_COLON       (1 << 14)
71 #define AO_LCD_FONT_DECIMAL     (1 << 15)
72
73 void
74 ao_lcd_font_char(uint8_t pos, char c, uint16_t flags) {
75         if (pos > 5)
76                 pos = 5;
77         if (c < ' ' || c > 127)
78                 c = 127;
79         ao_draw_glyph(pos, ao_lcd_font[c - ' '] | flags);
80 }
81
82 void
83 ao_lcd_font_string(char *s) {
84         uint8_t pos = 0;
85         uint16_t flags;
86         char c;
87
88         while (pos < 6 && (c = *s++)) {
89                 flags = 0;
90                 for (;;) {
91                         if (*s == ':')
92                                 flags |= AO_LCD_FONT_COLON;
93                         else if (*s == '.')
94                                 flags |= AO_LCD_FONT_DECIMAL;
95                         else
96                                 break;
97                         s++;
98                 }
99                 ao_lcd_font_char(pos++, c, flags);
100         }
101         while (pos < 6)
102                 ao_lcd_font_char(pos++, ' ', 0);
103         stm_lcd.sr = (1 << STM_LCD_SR_UDR);
104 }
105
106 static void
107 ao_lcd_font_text(void)
108 {
109         char    string[20];
110         uint8_t c = 0;
111         ao_cmd_white();
112         while (ao_cmd_lex_c != '\n' && c < sizeof (string) - 1) {
113                 string[c++] = ao_cmd_lex_c;
114                 ao_cmd_lex();
115         }
116         string[c++] = '\0';
117         ao_lcd_font_string(string);
118 }
119
120 static const struct ao_cmds ao_lcd_font_cmds[] = {
121         { ao_lcd_font_text,     "t <string>\0Write <string> to LCD" },
122         { 0, NULL }
123 };
124
125 void
126 ao_lcd_font_init(void)
127 {
128         ao_cmd_register(ao_lcd_font_cmds);
129 }