1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <stdio.h>
|
4 |
|
5 | #include "board.h"
|
6 | #include "t6963c.h"
|
7 | #include "sw_uart/uart.h"
|
8 |
|
9 | // LCD init routine
|
10 | void t6963c_init(void)
|
11 | {
|
12 | // Define contorl ports and set them as high
|
13 | T6963C_CTRL_DDR |= (1 << T6963C_WR) | (1 << T6963C_RD) | (1 << T6963C_CE) | (1 << T6963C_CD) | (1 << T6963C_RST);
|
14 | T6963C_CTRL_PORT |= (1 << T6963C_WR) | (1 << T6963C_RD) | (1 << T6963C_CE) | (1 << T6963C_CD) | (1 << T6963C_RST);
|
15 |
|
16 | // Set data lines as input ports
|
17 | T6963C_DATA_DDR = 0x00;
|
18 |
|
19 | /* Hold Reset Line for 1ms */
|
20 | T6963C_CTRL_PORT &= ~(1 << T6963C_RST);
|
21 | _delay_ms(2000);
|
22 | T6963C_CTRL_PORT |= (1 << T6963C_RST);
|
23 |
|
24 | /* Set Char Gen Up */
|
25 | uartPutString("t6963c - write command\r\n");
|
26 | t6963c_write_command(T6963C_CG_ROM_MODE_TEXT);
|
27 | uartPutString("t6963c - write done\r\n");
|
28 |
|
29 | /* Set Graphic Home Address */
|
30 | t6963c_write_data(T6963C_GRAPHICS_HOME);
|
31 | t6963c_write_data(T6963C_GRAPHICS_HOME >> 8);
|
32 | t6963c_write_command(T6963C_GRAPHIC_HOME_ADDRESS_SET);
|
33 |
|
34 | /* Set Graphic Area */
|
35 | t6963c_write_data(T6963C_GRAPHICS_AREA);
|
36 | t6963c_write_data(0x00);
|
37 | t6963c_write_command(T6963C_GRAPHIC_AREA_SET);
|
38 |
|
39 | /* Set Text Home Address */
|
40 | t6963c_write_data(T6963C_TEXT_HOME);
|
41 | t6963c_write_data(T6963C_TEXT_HOME >> 8);
|
42 | t6963c_write_command(T6963C_TEXT_HOME_ADDRESS_SET);
|
43 |
|
44 | /* Set Text Area */
|
45 | t6963c_write_data(T6963C_TEXT_AREA);
|
46 | t6963c_write_data(0x00);
|
47 | t6963c_write_command(T6963C_TEXT_AREA_SET);
|
48 |
|
49 | }
|
50 |
|
51 |
|
52 | void t6963c_write_data(unsigned char data)
|
53 | {
|
54 | /* While BUSY1 and BUSY2 are not 1 */
|
55 | while ( (t6963c_read_status() & (T6963C_STATUS_BUSY1 | T6963C_STATUS_BUSY2)) != (T6963C_STATUS_BUSY1 | T6963C_STATUS_BUSY2));
|
56 |
|
57 | /* Clear C/D# */
|
58 | T6963C_CTRL_PORT &= ~(1 << T6963C_CD);
|
59 |
|
60 | /* Set Data Lines to Output */
|
61 | T6963C_DATA_DDR = 0xff;
|
62 | T6963C_DATA_PORT = data;
|
63 |
|
64 | /* Clear CE and WR, set RD */
|
65 | T6963C_CTRL_PORT |= (1 << T6963C_RD);
|
66 | T6963C_CTRL_PORT &= ~(1 << T6963C_WR);
|
67 | T6963C_CTRL_PORT &= ~(1 << T6963C_CE);
|
68 | _delay_us(20);
|
69 |
|
70 | /* Set CE and RD*/
|
71 | T6963C_CTRL_PORT |= (1 << T6963C_CE) | (1 << T6963C_WR) | (1 << T6963C_CD);
|
72 |
|
73 | /* Set Data Lines to Input */
|
74 | T6963C_DATA_DDR = 0x00;
|
75 |
|
76 | }
|
77 |
|
78 | /********************************************
|
79 | * Function name: lcd_read_data *
|
80 | * Description: Read Data From LCD *
|
81 | *******************************************/
|
82 | unsigned char t6963c_read_data(void)
|
83 | {
|
84 | unsigned char data;
|
85 |
|
86 | /* While BUSY1 and BUSY2 are not 1 */
|
87 | while ( (t6963c_read_status() & (T6963C_STATUS_BUSY1 | T6963C_STATUS_BUSY2)) != (T6963C_STATUS_BUSY1 | T6963C_STATUS_BUSY2));
|
88 |
|
89 | /* Clear C/D# */
|
90 | T6963C_CTRL_PORT &= ~(1 << T6963C_CD);
|
91 |
|
92 | /* Clear CE and RD, set WR */
|
93 | T6963C_CTRL_PORT |= (1 << T6963C_RD);
|
94 | T6963C_CTRL_PORT &= ~(1 << T6963C_WR);
|
95 | T6963C_CTRL_PORT &= ~(1 << T6963C_CE);
|
96 |
|
97 | /* Set Data Lines to Input */
|
98 | T6963C_DATA_DDR = 0x00;
|
99 |
|
100 | _delay_us(20);
|
101 | /* Read Data Bus */
|
102 | data = T6963C_DATA_PIN;
|
103 |
|
104 | /* Set CE and RD*/
|
105 | T6963C_CTRL_PORT |= (1 << T6963C_CE) | (1 << T6963C_WR) | (1 << T6963C_CD);
|
106 |
|
107 | return data;
|
108 | }
|
109 |
|
110 | /********************************************
|
111 | * Function name: lcd_write_command *
|
112 | * Description: Write Command to LCD *
|
113 | *******************************************/
|
114 | void t6963c_write_command(unsigned char data)
|
115 | {
|
116 |
|
117 | /* While BUSY1 and BUSY2 are not 1 */
|
118 | while ( (t6963c_read_status() & (T6963C_STATUS_BUSY1 | T6963C_STATUS_BUSY2)) != (T6963C_STATUS_BUSY1 | T6963C_STATUS_BUSY2));
|
119 |
|
120 | /* Set C/D# */
|
121 | T6963C_CTRL_PORT |= (1 << T6963C_CD);
|
122 |
|
123 | /* Set Data Lines to Output */
|
124 | T6963C_DATA_DDR = 0xff;
|
125 | T6963C_DATA_PORT = data;
|
126 |
|
127 | /* Clear CE and WR, set RD */
|
128 | T6963C_CTRL_PORT |= (1 << T6963C_RD);
|
129 | T6963C_CTRL_PORT &= ~(1 << T6963C_WR);
|
130 | T6963C_CTRL_PORT &= ~(1 << T6963C_CE);
|
131 |
|
132 | _delay_us(40);
|
133 |
|
134 | /* Set CE and RD*/
|
135 | T6963C_CTRL_PORT |= (1 << T6963C_CE) | (1 << T6963C_WR) | (1 << T6963C_CD);
|
136 |
|
137 | /* Set Data Lines to Input */
|
138 | T6963C_DATA_DDR = 0x00;
|
139 | }
|
140 |
|
141 | /********************************************
|
142 | * Function name: lcd_read_status *
|
143 | * Description: Read Status From LCD *
|
144 | *******************************************/
|
145 | unsigned char t6963c_read_status(void)
|
146 | {
|
147 | unsigned char data;
|
148 |
|
149 | /* Set C/D# */
|
150 | T6963C_CTRL_PORT |= (1 << T6963C_CD);
|
151 |
|
152 | /* Set Data Lines to Input */
|
153 | T6963C_DATA_DDR = 0x00;
|
154 |
|
155 | /* Clear CE and RD */
|
156 | T6963C_CTRL_PORT &= ~(1 << T6963C_WR);
|
157 | T6963C_CTRL_PORT &= ~(1 << T6963C_CE);
|
158 |
|
159 | _delay_us(20);
|
160 | /* Read Data Bus */
|
161 | data = T6963C_DATA_PIN;
|
162 |
|
163 | /* Set All Bits */
|
164 | T6963C_CTRL_PORT |= (1 << T6963C_CE) | (1 << T6963C_RD) | (1 << T6963C_CD);
|
165 | // char buffer[50];
|
166 | // _delay_ms(200);
|
167 | // sprintf(buffer, "t6963c - data: %x \r\n", data);
|
168 | // uartPutString(buffer);
|
169 |
|
170 | return data;
|
171 | }
|
172 |
|
173 | void t6963c_clear_text(void)
|
174 | {
|
175 | unsigned char address_l, address_h;
|
176 | unsigned int address, address_limit;
|
177 |
|
178 | /* Set Address Pointer */
|
179 | address = T6963C_TEXT_HOME;
|
180 | address_l = address & 0xff;
|
181 | address_h = address >> 8;
|
182 | t6963c_write_data(address_l);
|
183 | t6963c_write_data(address_h);
|
184 | t6963c_write_command(T6963C_ADDRESS_POINTER_SET);
|
185 |
|
186 | address_limit = (T6963C_TEXT_HOME + T6963C_TEXT_SIZE);
|
187 | while (address < address_limit)
|
188 | {
|
189 | t6963c_write_data(0x00);
|
190 | t6963c_write_command(T6963C_DATA_WRITE_INCREMENT);
|
191 | address = address + 1;
|
192 | }
|
193 |
|
194 | if (T6963C_NUMBER_OF_SCREENS == 0x02)
|
195 | {
|
196 | /* Set Address Pointer */
|
197 | address = T6963C_TEXT_HOME + 0x8000;
|
198 | address_l = address & 0xff;
|
199 | address_h = address >> 8;
|
200 | t6963c_write_data(address_l);
|
201 | t6963c_write_data(address_h);
|
202 | t6963c_write_command(T6963C_ADDRESS_POINTER_SET);
|
203 |
|
204 | address_limit = (T6963C_TEXT_HOME + T6963C_TEXT_SIZE + 0x8000);
|
205 | t6963c_write_command(T6963C_DATA_AUTO_WRITE);
|
206 | while (address < address_limit)
|
207 | {
|
208 | t6963c_write_data(0x00);
|
209 | address = address + 1;
|
210 | }
|
211 | t6963c_write_command(T6963C_DATA_MODE_RESET);
|
212 | }
|
213 | }
|
214 |
|
215 | /********************************************
|
216 | * Function name: lcd_write_text *
|
217 | * Description: Write Character to X, Y *
|
218 | * 0 <= X <= LCD Text Width *
|
219 | * 0 <= Y <= LCD Text Height *
|
220 | *******************************************/
|
221 | uint8_t t6963c_write_text(unsigned char data, unsigned char x, unsigned char y)
|
222 | {
|
223 | unsigned int address;
|
224 |
|
225 | address = (y * T6963C_TEXT_AREA) + x + T6963C_TEXT_HOME;
|
226 | if (y > 63 && T6963C_NUMBER_OF_SCREENS == 2) /* If we are on the second screen and it exists */
|
227 | {
|
228 | address = address + 0x8000;
|
229 | }
|
230 |
|
231 | data = data - 0x20; /* Adjust standard ASCII to T6963 ASCII */
|
232 |
|
233 | t6963c_write_data(address & 0xff);
|
234 | t6963c_write_data(address >> 0x08);
|
235 | t6963c_write_command(T6963C_ADDRESS_POINTER_SET);
|
236 | t6963c_write_data(data);
|
237 | t6963c_write_command(T6963C_DATA_WRITE_INCREMENT);
|
238 | return x+1;
|
239 | }
|