00001
00025
00026 #define F_CPU 16000000UL
00027
00028
00029 #ifndef __DELAY_BACKWARD_COMPATIBLE__
00030 #define __DELAY_BACKWARD_COMPATIBLE__
00031 #endif
00032
00033 #include <avr/io.h>
00034 #include <string.h>
00035 #include <util/delay.h>
00036 #include <avr/interrupt.h>
00037 #include <stdlib.h>
00038 #include <avr/eeprom.h>
00039
00040 #include "scd_io.h"
00041
00042
00043 static uint8_t lcd_count;
00044 static uint8_t lcd_state;
00045
00046
00047
00048
00049
00050
00051 void Led1On()
00052 {
00053 DDRE |= _BV(PE7);
00054 PORTE |= _BV(PE7);
00055 }
00056
00057 void Led2On()
00058 {
00059 DDRE |= _BV(PE6);
00060 PORTE |= _BV(PE6);
00061 }
00062
00063 void Led3On()
00064 {
00065 DDRE |= _BV(PE5);
00066 PORTE |= _BV(PE5);
00067 }
00068
00069 void Led4On()
00070 {
00071 DDRE |= _BV(PE4);
00072 PORTE |= _BV(PE4);
00073 }
00074
00075 void Led1Off()
00076 {
00077
00078
00079
00080 DDRE &= ~(_BV(PE7));
00081 PORTE &= ~(_BV(PE7));
00082 }
00083
00084 void Led2Off()
00085 {
00086
00087
00088
00089 DDRE &= ~(_BV(PE6));
00090 PORTE &= ~(_BV(PE6));
00091 }
00092
00093 void Led3Off()
00094 {
00095
00096
00097
00098 DDRE &= ~(_BV(PE5));
00099 PORTE &= ~(_BV(PE5));
00100 }
00101
00102 void Led4Off()
00103 {
00104
00105
00106
00107 DDRE &= ~(_BV(PE4));
00108 PORTE &= ~(_BV(PE4));
00109 }
00110
00111
00112
00113
00114
00115
00121 uint8_t GetButtonA()
00122 {
00123 DDRF &= ~(_BV(PF3));
00124 return bit_is_set(PINF, PF3);
00125 }
00126
00132 uint8_t GetButtonB()
00133 {
00134 DDRF &= ~(_BV(PF2));
00135 return bit_is_set(PINF, PF2);
00136 }
00137
00138
00144 uint8_t GetButtonC()
00145 {
00146 DDRF &= ~(_BV(PF1));
00147 return bit_is_set(PINF, PF1);
00148 }
00149
00150
00156 uint8_t GetButtonD()
00157 {
00158 DDRF &= ~(_BV(PF0));
00159 return bit_is_set(PINF, PF0);
00160 }
00161
00172 uint8_t GetButton()
00173 {
00174 uint8_t result = 0;
00175
00176 if(bit_is_clear(PINF, PF3)) result |= BUTTON_A;
00177 if(bit_is_clear(PINF, PF2)) result |= BUTTON_B;
00178 if(bit_is_clear(PINF, PF1)) result |= BUTTON_C;
00179 if(bit_is_clear(PINF, PF0)) result |= BUTTON_D;
00180
00181 return result;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 uint8_t GetLCDStatus()
00196 {
00197 uint8_t status;
00198
00199 PORTC &= 0xF8;
00200 DDRC |= 0x07;
00201 DDRA = 0;
00202 PORTC |= _BV(PC1);
00203 PORTC |= _BV(PC2);
00204 _delay_us(10);
00205 status = PINA;
00206 PORTC &= ~(_BV(PC2));
00207 DDRC &= 0xF8;
00208
00209 return status;
00210 }
00211
00215 uint8_t GetLCDState()
00216 {
00217 return lcd_state;
00218 }
00219
00220
00221
00222
00223
00224 void SetLCDState(uint8_t state)
00225 {
00226 lcd_state = state;
00227 }
00228
00229
00230
00231 uint8_t SendLCDCommand(uint8_t RS, uint8_t RW, uint8_t data, uint16_t delay_us)
00232 {
00233 uint8_t result, busy;
00234
00235 do{
00236 result = GetLCDStatus();
00237 busy = result & 0x80;
00238 }while(busy);
00239
00240 DDRC |= 0x07;
00241 if(RS) PORTC |= _BV(PC0);
00242 else PORTC &= ~(_BV(PC0));
00243
00244 if(RW)
00245 {
00246 PORTC |= _BV(PC1);
00247 DDRA = 0x00;
00248 }
00249 else
00250 {
00251 PORTC &= ~(_BV(PC1));
00252 DDRA = 0xFF;
00253 PORTA = data;
00254 }
00255
00256 PORTC |= _BV(PC2);
00257 _delay_us(delay_us);
00258 data = PINA;
00259 PORTC &= ~(_BV(PC2));
00260 DDRC &= 0xF8;
00261
00262 return data;
00263 }
00264
00265 void FillScreen()
00266 {
00267 uint8_t i;
00268 char *str = "12";
00269
00270
00271 SendLCDCommand(0, 0, 0x01, LCD_COMMAND_DELAY);
00272
00273
00274 for(i = 0; i < 40; i++)
00275 SendLCDCommand(1, 0, str[0], LCD_COMMAND_DELAY);
00276
00277
00278 SendLCDCommand(0, 0, 0xc0, 37);
00279
00280 for(i = 0; i < 40; i++)
00281 SendLCDCommand(1, 0, str[1], LCD_COMMAND_DELAY);
00282 }
00283
00290 void WriteStringLCD(char *string, uint8_t len)
00291 {
00292 uint8_t i;
00293
00294
00295 SendLCDCommand(0, 0, 0x01, LCD_COMMAND_DELAY);
00296
00297 i = 0;
00298 while(i < len && i < 8)
00299 {
00300
00301 SendLCDCommand(1, 0, string[i], LCD_COMMAND_DELAY);
00302 i++;
00303 }
00304
00305 if(len > 8)
00306 {
00307
00308 SendLCDCommand(0, 0, 0xc0, LCD_COMMAND_DELAY);
00309
00310 while(i < len && i < 16)
00311 {
00312
00313 SendLCDCommand(1, 0, string[i], LCD_COMMAND_DELAY);
00314 i++;
00315 }
00316 }
00317
00318 lcd_count = 0;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 uint8_t LcdPutchar(uint8_t c, FILE *unused)
00334 {
00335 static uint8_t nl_seen;
00336
00337 if (nl_seen && c != '\n')
00338 {
00339
00340 SendLCDCommand(0, 0, 0x01, LCD_COMMAND_DELAY);
00341 nl_seen = 0;
00342 lcd_count = 0;
00343 }
00344
00345 if(c == '\n')
00346 {
00347 nl_seen = 1;
00348 }
00349 else
00350 {
00351
00352 SendLCDCommand(1, 0, c, LCD_COMMAND_DELAY);
00353 }
00354
00355 lcd_count++;
00356 if(lcd_count == 8)
00357 SendLCDCommand(0, 0, 0xc0, LCD_COMMAND_DELAY);
00358 else if(lcd_count == 16)
00359 SendLCDCommand(0, 0, 0x02, LCD_COMMAND_DELAY);
00360
00361 return 0;
00362 }
00363
00364
00369 void InitLCD()
00370 {
00371
00372 DDRC |= _BV(PC5);
00373 PORTC |= _BV(PC5);
00374
00375
00376
00377
00378
00379 SendLCDCommand(0, 0, 0x38, LCD_COMMAND_DELAY);
00380
00381
00382 SendLCDCommand(0, 0, 0x0E, LCD_COMMAND_DELAY);
00383
00384
00385 SendLCDCommand(0, 0, 0x06, LCD_COMMAND_DELAY);
00386
00387
00388 SendLCDCommand(0, 0, 0x01, LCD_COMMAND_DELAY);
00389
00390 lcd_state = 1;
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 }
00401
00407 uint8_t CheckLCD()
00408 {
00409
00410
00411
00412
00413 uint8_t tmp;
00414
00415
00416
00417 DDRA = 0xFF;
00418 PORTA = 0xAA;
00419 tmp = GetLCDStatus();
00420
00421 if(tmp == 0xAA) return 1;
00422
00423 return 0;
00424 }
00425
00429 void LCDOff()
00430 {
00431 DDRC &= ~(_BV(PC5));
00432 PORTC &= ~(_BV(PC5));
00433 SendLCDCommand(0, 0, 0x08, LCD_COMMAND_DELAY);
00434 lcd_state = 0;
00435 }
00436
00440 void LCDOn()
00441 {
00442 DDRC |= _BV(PC5);
00443 PORTC |= _BV(PC5);
00444 SendLCDCommand(0, 0, 0x0E, LCD_COMMAND_DELAY);
00445 lcd_state = 1;
00446 }
00447
00448
00449
00450
00451
00452
00465 void WriteSingleByteEEPROM(uint16_t addr, uint8_t data)
00466 {
00467
00468 while(EECR & _BV(EEPE));
00469
00470
00471 EEAR = addr;
00472 EEDR = data;
00473
00474
00475 EECR |= _BV(EEMPE);
00476 EECR |= _BV(EEPE);
00477 }
00478
00491 uint8_t ReadSingleByteEEPROM(uint16_t addr)
00492 {
00493
00494 while(EECR & _BV(EEPE));
00495
00496
00497 EEAR = addr;
00498 EECR |= _BV(EERE);
00499
00500 return EEDR;
00501 }
00502
00503
00513 void WriteBytesEEPROM(uint16_t addr, uint8_t *data, uint16_t len)
00514 {
00515 uint8_t i, sreg;
00516
00517 if(data == NULL || len > 4000) return;
00518
00519 sreg = SREG;
00520 cli();
00521
00522 for(i = 0; i < len; i++)
00523 WriteSingleByteEEPROM(addr++, data[i]);
00524
00525
00526 while(EECR & _BV(EEPE));
00527
00528 SREG = sreg;
00529 }
00530
00543 uint8_t* ReadBytesEEPROM(uint16_t addr, uint16_t len)
00544 {
00545 uint8_t i, sreg;
00546 uint8_t *data;
00547
00548 if(len > 4000) return NULL;
00549 data = (uint8_t*)malloc(len*sizeof(uint8_t));
00550 if(data == NULL) return NULL;
00551
00552 sreg = SREG;
00553 cli();
00554
00555 for(i = 0; i < len; i++)
00556 data[i] = ReadSingleByteEEPROM(addr++);
00557
00558 SREG = sreg;
00559
00560 return data;
00561 }
00562
00567 void EraseEEPROM()
00568 {
00569 uint8_t sreg, i;
00570 uint16_t addr;
00571 uint8_t clear[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
00572 uint8_t data[8];
00573
00574 sreg = SREG;
00575 cli();
00576
00577
00578
00579
00580
00581
00582
00583 for(addr = 0; addr < EEPROM_END; addr += 8)
00584 {
00585 eeprom_read_block((void *)&data[0], (const void *)addr, 8);
00586 for(i = 0; i < 8; i++)
00587 if(data[i] != 0xFF)
00588 {
00589 eeprom_write_block((void*)&clear[0], (void*)addr, 8);
00590 break;
00591 }
00592 }
00593
00594
00595
00596
00597
00598 SREG = sreg;
00599 }