Rev 2214 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1793 | arune | 1 | #include "dotmatrix.h" |
| 2 | #include <avr/io.h> |
||
| 3 | #include <stdio.h> |
||
| 4 | #include <stdlib.h> |
||
| 5 | |||
| 6 | #include <avr/pgmspace.h> |
||
| 7 | |||
| 8 | //Some parts of the code is from proycon avrlib written by Pascal Stang: |
||
| 9 | //***************************************************************************** |
||
| 10 | // |
||
| 11 | // File Name : 'glcd.c' |
||
| 12 | // Title : Graphic LCD API functions |
||
| 13 | // Author : Pascal Stang - Copyright (C) 2002 |
||
| 14 | // Date : 5/30/2002 |
||
| 15 | // Revised : 5/30/2002 |
||
| 16 | // Version : 0.5 |
||
| 17 | // Target MCU : Atmel AVR |
||
| 18 | // Editor Tabs : 4 |
||
| 19 | // |
||
| 20 | // NOTE: This code is currently below version 1.0, and therefore is considered |
||
| 21 | // to be lacking in some functionality or documentation, or may not be fully |
||
| 22 | // tested. Nonetheless, you can expect most functions to work. |
||
| 23 | // |
||
| 24 | // This code is distributed under the GNU Public License |
||
| 25 | // which can be found at http://www.gnu.org/licenses/gpl.txt |
||
| 26 | // |
||
| 27 | //***************************************************************************** |
||
| 2214 | linlun | 28 | #ifndef dotmatrixSIZEX |
| 29 | #error dotmatrixSIZEX, dotmatrixSIZEY must be defined |
||
| 1793 | arune | 30 | #endif |
| 31 | |||
| 32 | #define OUTPUT 0 |
||
| 33 | #define INPUT 1 |
||
| 34 | |||
| 35 | volatile GrLcdStateType GrLcdState; |
||
| 2213 | linlun | 36 | uint8_t dotmatrixFramebuf[dotmatrixSIZEY/8][dotmatrixSIZEX]; |
| 1796 | arune | 37 | uint8_t dotmatrixRowCounter=0; |
| 1793 | arune | 38 | |
| 1796 | arune | 39 | /* Write a byte on SPI */ |
| 40 | void dotmatrixSPIWrite(uint8_t data) { |
||
| 41 | uint8_t dummy = 0; |
||
| 42 | /* Wait for empty transmit buffer */ |
||
| 43 | while ( !( UCSR0A & (1<<UDRE0)) ); |
||
| 44 | // write data |
||
| 45 | dummy = UDR0; |
||
| 46 | UDR0 = data; |
||
| 47 | waitspi(); |
||
| 1793 | arune | 48 | } |
| 49 | |||
| 50 | void dotmatrixSetColor(uint8_t color){ |
||
| 51 | GrLcdState.color=color; |
||
| 52 | } |
||
| 1798 | arune | 53 | |
| 1793 | arune | 54 | uint8_t dotmatrixGetColor(void){ |
| 55 | return GrLcdState.color; |
||
| 56 | } |
||
| 1798 | arune | 57 | |
| 1805 | arune | 58 | /* Sets data into framebuffer, data arrives in a byte as a column */ |
| 1798 | arune | 59 | void dotmatrixSetData(uint8_t Data) |
| 60 | { |
||
| 1799 | arune | 61 | /* Which ledmodule */ |
| 2213 | linlun | 62 | uint8_t module = GrLcdState.lcdXAddr; |
| 1799 | arune | 63 | /* Which column in ledmodule */ |
| 2214 | linlun | 64 | uint8_t column = GrLcdState.lcdYAddr/8; |
| 2213 | linlun | 65 | //uint8_t column = GrLcdState.lcdXAddr%8; |
| 1799 | arune | 66 | /* Which row */ |
| 1805 | arune | 67 | // uint8_t row = GrLcdState.lcdYAddr%8; |
| 68 | |||
| 69 | /* Check panel size */ |
||
| 2213 | linlun | 70 | if ((column < dotmatrixSIZEY/8) && (module < dotmatrixSIZEX)) |
| 1799 | arune | 71 | { |
| 1805 | arune | 72 | dotmatrixFramebuf[column][module] = Data; |
| 1799 | arune | 73 | } |
| 1798 | arune | 74 | } |
| 75 | |||
| 76 | uint8_t dotmatrixGetData(void){ |
||
| 1803 | arune | 77 | /* Which ledmodule */ |
| 2213 | linlun | 78 | uint8_t module = GrLcdState.lcdXAddr; |
| 1803 | arune | 79 | /* Which column in ledmodule */ |
| 2214 | linlun | 80 | uint8_t column = GrLcdState.lcdYAddr/8; |
| 1803 | arune | 81 | /* Which row */ |
| 1805 | arune | 82 | // uint8_t row = GrLcdState.lcdYAddr%8; |
| 1803 | arune | 83 | |
| 1805 | arune | 84 | /* Check panel size */ |
| 2213 | linlun | 85 | if ((column < dotmatrixSIZEY/8) && (module < dotmatrixSIZEX)) |
| 1803 | arune | 86 | { |
| 1805 | arune | 87 | return (dotmatrixFramebuf[column][module]); |
| 1803 | arune | 88 | } |
| 1805 | arune | 89 | else |
| 90 | { |
||
| 91 | return 0; |
||
| 92 | } |
||
| 1798 | arune | 93 | } |
| 94 | |||
| 1793 | arune | 95 | void dotmatrixWriteData(uint8_t data, uint8_t color){ |
| 96 | if (color == GLCD_COLOR_CLEAR) |
||
| 1801 | arune | 97 | { |
| 1793 | arune | 98 | data = ~data; |
| 1801 | arune | 99 | } |
| 1793 | arune | 100 | if (GrLcdState.color == GLCD_COLOR_BLACK) |
| 1801 | arune | 101 | { |
| 1793 | arune | 102 | dotmatrixSetData(data); |
| 1801 | arune | 103 | } |
| 1793 | arune | 104 | else |
| 1801 | arune | 105 | { |
| 1793 | arune | 106 | dotmatrixSetData(~data); |
| 1801 | arune | 107 | } |
| 108 | |||
| 1793 | arune | 109 | GrLcdState.lcdXAddr++; |
| 110 | |||
| 2214 | linlun | 111 | if (GrLcdState.lcdXAddr > dotmatrixSIZEX ){ |
| 1801 | arune | 112 | dotmatrixSetXY(0,GrLcdState.lcdYAddr+8); |
| 1793 | arune | 113 | } |
| 114 | } |
||
| 1802 | arune | 115 | |
| 1793 | arune | 116 | void dotmatrixWriteDataTransparent(uint8_t inputdata, uint8_t color){ |
| 1802 | arune | 117 | uint8_t data = dotmatrixGetData(); |
| 118 | if (GrLcdState.color != GLCD_COLOR_BLACK) |
||
| 119 | { |
||
| 120 | data = ~data; |
||
| 121 | } |
||
| 1801 | arune | 122 | |
| 1793 | arune | 123 | if (color == GLCD_COLOR_CLEAR) |
| 1802 | arune | 124 | { |
| 1793 | arune | 125 | data = data&(~inputdata); |
| 1802 | arune | 126 | } |
| 1793 | arune | 127 | else |
| 1802 | arune | 128 | { |
| 1793 | arune | 129 | data = data|inputdata; |
| 1802 | arune | 130 | } |
| 131 | |||
| 1793 | arune | 132 | if (GrLcdState.color == GLCD_COLOR_BLACK) |
| 1802 | arune | 133 | { |
| 1793 | arune | 134 | dotmatrixSetData(data); |
| 1802 | arune | 135 | } |
| 1793 | arune | 136 | else |
| 1802 | arune | 137 | { |
| 1793 | arune | 138 | dotmatrixSetData(~data); |
| 1802 | arune | 139 | } |
| 140 | |||
| 1793 | arune | 141 | GrLcdState.lcdXAddr++; |
| 142 | |||
| 2214 | linlun | 143 | if (GrLcdState.lcdXAddr > dotmatrixSIZEX ){ |
| 1802 | arune | 144 | dotmatrixSetXY(0,GrLcdState.lcdYAddr+8); |
| 1793 | arune | 145 | } |
| 146 | } |
||
| 147 | |||
| 148 | uint8_t dotmatrixReadData(void){ |
||
| 149 | uint8_t data = 0; |
||
| 150 | if (GrLcdState.color == GLCD_COLOR_BLACK) |
||
| 1802 | arune | 151 | { |
| 1793 | arune | 152 | data = dotmatrixGetData(); |
| 1802 | arune | 153 | } |
| 1793 | arune | 154 | else |
| 1802 | arune | 155 | { |
| 1793 | arune | 156 | data = ~dotmatrixGetData(); |
| 1802 | arune | 157 | } |
| 158 | |||
| 1793 | arune | 159 | return data; |
| 160 | } |
||
| 161 | |||
| 1796 | arune | 162 | /* Callback run periodically to manage rows. |
| 163 | For each time callback is run, the next row is enabled and the last disabled |
||
| 164 | */ |
||
| 1794 | arune | 165 | void dotmatrixRefresh() |
| 166 | { |
||
| 2213 | linlun | 167 | uint8_t col = 0; |
| 1796 | arune | 168 | /* Increase row counter */ |
| 169 | if (dotmatrixRowCounter++ == 8) {dotmatrixRowCounter = 0;} |
||
| 1794 | arune | 170 | |
| 2213 | linlun | 171 | |
| 172 | /* Write one column of frame buffer to shift registers */ |
||
| 173 | for (col = 0; col < (dotmatrixSIZEX/8*dotmatrixSIZEY/8); col++) { |
||
| 2214 | linlun | 174 | dotmatrixSPIWrite(dotmatrixFramebuf[(col*8+dotmatrixRowCounter)/dotmatrixSIZEX][(col*8+dotmatrixRowCounter)%dotmatrixSIZEX]); |
| 2213 | linlun | 175 | } |
| 176 | |||
| 1796 | arune | 177 | /* Disable all rows */ |
| 178 | gpio_clr_pin(dotmatrixROW_IO1); |
||
| 179 | gpio_clr_pin(dotmatrixROW_IO2); |
||
| 180 | gpio_clr_pin(dotmatrixROW_IO3); |
||
| 181 | gpio_clr_pin(dotmatrixROW_IO4); |
||
| 182 | gpio_clr_pin(dotmatrixROW_IO5); |
||
| 183 | gpio_clr_pin(dotmatrixROW_IO6); |
||
| 184 | gpio_clr_pin(dotmatrixROW_IO7); |
||
| 185 | gpio_clr_pin(dotmatrixROW_IO8); |
||
| 186 | |||
| 2213 | linlun | 187 | |
| 1796 | arune | 188 | /* Toggle shift register latch */ |
| 189 | gpio_clr_pin(dotmatrixLATCHCLOCK_IO); |
||
| 190 | gpio_set_pin(dotmatrixLATCHCLOCK_IO); |
||
| 191 | |||
| 192 | /* Enable one row */ |
||
| 193 | switch (dotmatrixRowCounter) |
||
| 194 | { |
||
| 195 | case 0: |
||
| 196 | gpio_set_pin(dotmatrixROW_IO1); |
||
| 197 | break; |
||
| 198 | case 1: |
||
| 199 | gpio_set_pin(dotmatrixROW_IO2); |
||
| 200 | break; |
||
| 201 | case 2: |
||
| 202 | gpio_set_pin(dotmatrixROW_IO3); |
||
| 203 | break; |
||
| 204 | case 3: |
||
| 205 | gpio_set_pin(dotmatrixROW_IO4); |
||
| 206 | break; |
||
| 207 | case 4: |
||
| 208 | gpio_set_pin(dotmatrixROW_IO5); |
||
| 209 | break; |
||
| 210 | case 5: |
||
| 211 | gpio_set_pin(dotmatrixROW_IO6); |
||
| 212 | break; |
||
| 213 | case 6: |
||
| 214 | gpio_set_pin(dotmatrixROW_IO7); |
||
| 215 | break; |
||
| 216 | case 7: |
||
| 217 | gpio_set_pin(dotmatrixROW_IO8); |
||
| 218 | break; |
||
| 219 | |||
| 220 | default: |
||
| 221 | break; |
||
| 222 | } |
||
| 1794 | arune | 223 | } |
| 224 | |||
| 1793 | arune | 225 | void dotmatrixInit(){ |
| 1796 | arune | 226 | /* Set up row driver IO as low output */ |
| 227 | gpio_clr_pin(dotmatrixROW_IO1); |
||
| 228 | gpio_set_out(dotmatrixROW_IO1); |
||
| 229 | gpio_clr_pin(dotmatrixROW_IO2); |
||
| 230 | gpio_set_out(dotmatrixROW_IO2); |
||
| 231 | gpio_clr_pin(dotmatrixROW_IO3); |
||
| 232 | gpio_set_out(dotmatrixROW_IO3); |
||
| 233 | gpio_clr_pin(dotmatrixROW_IO4); |
||
| 234 | gpio_set_out(dotmatrixROW_IO4); |
||
| 235 | gpio_clr_pin(dotmatrixROW_IO5); |
||
| 236 | gpio_set_out(dotmatrixROW_IO5); |
||
| 237 | gpio_clr_pin(dotmatrixROW_IO6); |
||
| 238 | gpio_set_out(dotmatrixROW_IO6); |
||
| 239 | gpio_clr_pin(dotmatrixROW_IO7); |
||
| 240 | gpio_set_out(dotmatrixROW_IO7); |
||
| 241 | gpio_clr_pin(dotmatrixROW_IO8); |
||
| 242 | gpio_set_out(dotmatrixROW_IO8); |
||
| 243 | |||
| 244 | /* Set up PWM controlling brightness */ |
||
| 245 | // TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00); |
||
| 246 | // TCCR0B |= (1<<CS00); |
||
| 247 | // OCR0B = 0xff-act_DotMatrix_INITIAL_BRIGHTNESS; |
||
| 248 | // DDRD |= (1<<PD5); |
||
| 249 | |||
| 250 | /* Set up output latch clock */ |
||
| 251 | gpio_clr_pin(dotmatrixLATCHCLOCK_IO); |
||
| 252 | gpio_set_out(dotmatrixLATCHCLOCK_IO); |
||
| 253 | |||
| 254 | /* Initialize USART in SPI-mode */ |
||
| 255 | UBRR0 = 0; |
||
| 256 | USART_SPI_XCK_DDR |= (1<<USART_SPI_XCK); // xck (sck) output |
||
| 257 | UCSR0C = (1<<UMSEL01)|(1<<UMSEL00)|(0<<UCPHA0)|(0<<UCPOL0); |
||
| 258 | UCSR0B = (1<<RXEN0)|(1<<TXEN0); |
||
| 2236 | linlun | 259 | UBRR0 = 1; |
| 1796 | arune | 260 | |
| 261 | dotmatrixClear(); |
||
| 1798 | arune | 262 | |
| 1805 | arune | 263 | GrLcdState.color = GLCD_COLOR_BLACK; |
| 1793 | arune | 264 | } |
| 265 | |||
| 266 | void dotmatrixClear(){ |
||
| 1796 | arune | 267 | /* Clear buffer memory */ |
| 2214 | linlun | 268 | for (uint8_t i=0; i<dotmatrixSIZEY/8; i++) |
| 1796 | arune | 269 | { |
| 2214 | linlun | 270 | for (uint8_t j=0; j<(dotmatrixSIZEX); j++) |
| 1796 | arune | 271 | { |
| 272 | dotmatrixFramebuf[i][j] = dotmatrixINITIAL_ROW; |
||
| 1793 | arune | 273 | } |
| 274 | } |
||
| 275 | } |
||
| 276 | |||
| 277 | void dotmatrixSetXY(uint8_t x, uint8_t y){ |
||
| 1798 | arune | 278 | GrLcdState.lcdXAddr = x; |
| 1793 | arune | 279 | GrLcdState.lcdYAddr = y; |
| 1802 | arune | 280 | } |
| 1793 | arune | 281 | |
| 282 | uint8_t dotmatrixGetX(void){ |
||
| 283 | return GrLcdState.lcdXAddr; |
||
| 284 | } |
||
| 1802 | arune | 285 | |
| 1793 | arune | 286 | uint8_t dotmatrixGetY(void){ |
| 287 | return GrLcdState.lcdYAddr; |
||
| 288 | } |
||
| 289 |