00001
00030 #include <avr/io.h>
00031 #include <avr/pgmspace.h>
00032 #include <avr/eeprom.h>
00033 #include <avr/interrupt.h>
00034 #include <avr/sleep.h>
00035 #include <util/delay.h>
00036 #include <stdint.h>
00037 #include "yack.h"
00038
00039
00040 static void key( byte mode);
00041 static char morsechar(byte buffer);
00042 static void keylatch(void);
00043
00044
00045
00046 enum FSMSTATE {
00047 IDLE,
00048 KEYED,
00049 IEG
00050 };
00051
00052
00053
00054 static byte yackflags;
00055 static byte volflags=0;
00056 static word ctcvalue;
00057 static word wpmcnt;
00058 static byte wpm;
00059 static byte farnsworth;
00060
00061
00062
00063 byte magic EEMEM = MAGPAT;
00064 byte flagstor EEMEM = ( IAMBICB | TXKEY | SIDETONE | TXINV);
00065 word ctcstor EEMEM = DEFCTC;
00066 byte wpmstor EEMEM = DEFWPM;
00067 byte fwstor EEMEM = 0;
00068 word user1 EEMEM = 0;
00069 word user2 EEMEM = 0;
00070
00071 char eebuffer1[100] EEMEM = "message 1";
00072 char eebuffer2[100] EEMEM = "message 2";
00073
00074
00075
00077
00087
00088 const byte morse[] PROGMEM =
00089 {
00090
00091 0b11111100,
00092 0b01111100,
00093 0b00111100,
00094 0b00011100,
00095 0b00001100,
00096 0b00000100,
00097 0b10000100,
00098 0b11000100,
00099 0b11100100,
00100 0b11110100,
00101 0b01100000,
00102 0b10001000,
00103 0b10101000,
00104 0b10010000,
00105 0b01000000,
00106 0b00101000,
00107 0b11010000,
00108 0b00001000,
00109 0b00100000,
00110 0b01111000,
00111 0b10110000,
00112 0b01001000,
00113 0b11100000,
00114 0b10100000,
00115 0b11110000,
00116 0b01101000,
00117 0b11011000,
00118 0b01010000,
00119 0b00010000,
00120 0b11000000,
00121 0b00110000,
00122 0b00011000,
00123 0b01110000,
00124 0b10011000,
00125 0b10111000,
00126 0b11001000,
00127 0b00110010,
00128 0b10001100,
00129 0b01010110,
00130 0b00010110,
00131 0b01010100,
00132 0b10010100
00133
00134 };
00135
00136
00137
00138
00139
00140
00141
00142
00143 const char spechar[6] PROGMEM = "?=.#$/";
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 void yackreset (void)
00161 {
00162
00163 ctcvalue=DEFCTC;
00164 wpm=DEFWPM;
00165 wpmcnt=(1200/YACKBEAT)/DEFWPM;
00166 farnsworth=0;
00167 yackflags = FLAGDEFAULT;
00168
00169 volflags |= DIRTYFLAG;
00170 yacksave();
00171
00172 }
00173
00174
00175 void yackinit (void)
00184 {
00185
00186 byte magval;
00187
00188
00189 SETBIT (OUTDDR,OUTPIN);
00190 SETBIT (STDDR,STPIN);
00191
00192
00193 SETBIT (KEYPORT,DITPIN);
00194 SETBIT (KEYPORT,DAHPIN);
00195 SETBIT (BTNPORT,BTNPIN);
00196
00197 magval = eeprom_read_byte(&magic);
00198
00199 if (magval == MAGPAT)
00200 {
00201 ctcvalue = eeprom_read_word(&ctcstor);
00202 wpm = eeprom_read_byte(&wpmstor);
00203 wpmcnt=(1200/YACKBEAT)/wpm;
00204 farnsworth = eeprom_read_byte(&fwstor);
00205 yackflags = eeprom_read_byte(&flagstor);
00206 }
00207 else
00208 {
00209 yackreset();
00210 }
00211
00212 yackinhibit(OFF);
00213
00214 #ifdef POWERSAVE
00215
00216 PCMSK |= PWRWAKE;
00217 GIMSK |= (1<<PCIE);
00218
00219 #endif
00220
00221
00222
00223
00224
00225 OCR1C = 78;
00226 TCCR1 |= (1<<CTC1) | 0b00000111 ;
00227 OCR1A = 1;
00228
00229 }
00230
00231 #ifdef POWERSAVE
00232
00233 ISR(PCINT0_vect)
00241 {
00242
00243 }
00244
00245
00246 void yackpower(byte n)
00261 {
00262 static uint32_t shdntimer=0;
00263
00264 if (n)
00265 {
00266 if(shdntimer++ == YACKSECS(PSTIME))
00267 {
00268 shdntimer=0;
00269
00270 set_sleep_mode(SLEEP_MODE_PWR_DOWN);
00271 sleep_bod_disable();
00272 sleep_enable();
00273 sei();
00274 sleep_cpu();
00275 cli();
00276
00277
00278
00279
00280 }
00281
00282 }
00283 else
00284 {
00285 shdntimer=0;
00286 }
00287
00288 }
00289
00290 #endif
00291
00292
00293
00294 void yacksave (void)
00304 {
00305
00306 if(volflags & DIRTYFLAG)
00307 {
00308
00309 eeprom_write_byte(&magic, MAGPAT);
00310 eeprom_write_word(&ctcstor, ctcvalue);
00311 eeprom_write_byte(&wpmstor, wpm);
00312 eeprom_write_byte(&flagstor, yackflags);
00313 eeprom_write_byte(&fwstor, farnsworth);
00314
00315 volflags &= ~DIRTYFLAG;
00316 }
00317
00318 }
00319
00320
00321
00322 void yackinhibit (byte mode)
00332 {
00333
00334 if (mode)
00335 {
00336 volflags &= ~(TXKEY | SIDETONE);
00337 volflags |= SIDETONE;
00338 }
00339
00340 else
00341
00342 {
00343 volflags &= ~(TXKEY | SIDETONE);
00344 volflags |= (yackflags & (TXKEY | SIDETONE));
00345 key(UP);
00346 }
00347
00348 }
00349
00350
00351
00352 word yackuser (byte func, byte nr, word content)
00366 {
00367
00368
00369 if (func == READ)
00370 {
00371 if (nr == 1)
00372 return (eeprom_read_word(&user1));
00373 else if (nr == 2)
00374 return (eeprom_read_word(&user2));
00375 }
00376
00377 if (func == WRITE)
00378 {
00379
00380 if (nr == 1)
00381 eeprom_write_word(&user1, content);
00382 else if (nr == 2)
00383 eeprom_write_word(&user2, content);
00384 }
00385
00386 return (FALSE);
00387
00388 }
00389
00390
00391
00392 word yackwpm(void)
00401 {
00402
00403 return wpm;
00404
00405 }
00406
00407
00408 void yackspeed (byte dir, byte mode)
00418 {
00419
00420 if (mode == FARNSWORTH)
00421 {
00422 if ((dir == UP) && (farnsworth > 0))
00423 farnsworth--;
00424
00425 if ((dir == DOWN) && (farnsworth < MAXFARN))
00426 farnsworth++;
00427 }
00428 else
00429 {
00430 if ((dir == UP) && (wpm < MAXWPM))
00431 wpm++;
00432
00433 if ((dir == DOWN) && (wpm > MINWPM))
00434 wpm--;
00435
00436 wpmcnt=(1200/YACKBEAT)/wpm;
00437
00438 }
00439
00440 volflags |= DIRTYFLAG;
00441
00442 yackplay(DIT);
00443 yackdelay(IEGLEN);
00444 yackplay(DAH);
00445 yackdelay(ICGLEN);
00446 yackfarns();
00447
00448 }
00449
00450
00451
00452 void yackbeat (void)
00464 {
00465 while((TIFR & (1<<OCF1A)) == 0);
00466 TIFR |= (1<<OCF1A);
00467 }
00468
00469
00470
00471 void yackpitch (byte dir)
00481 {
00482 if (dir == UP)
00483 ctcvalue--;
00484 if (dir == DOWN)
00485 ctcvalue++;
00486
00487 if (ctcvalue < MAXCTC)
00488 ctcvalue = MAXCTC;
00489
00490 if (ctcvalue > MINCTC)
00491 ctcvalue = MINCTC;
00492
00493 volflags |= DIRTYFLAG;
00494
00495 }
00496
00497
00498
00499
00500 void yacktune (void)
00508 {
00509 word timer = YACKSECS(TUNEDURATION);
00510
00511 key(DOWN);
00512
00513 while(timer && (KEYINP & (1<<DITPIN)) && (KEYINP & (1<<DAHPIN)) && !yackctrlkey(TRUE) )
00514 {
00515 timer--;
00516 yackbeat();
00517 }
00518
00519 key(UP);
00520 }
00521
00522
00523
00524
00525 void yackmode (byte mode)
00536 {
00537
00538 yackflags &= ~MODE;
00539 yackflags |= mode;
00540
00541 volflags |= DIRTYFLAG;
00542
00543 }
00544
00545
00546 byte yackflag(byte flag)
00554 {
00555 return yackflags & flag;
00556 }
00557
00558
00559
00560 void yacktoggle(byte flag)
00571 {
00572
00573 yackflags ^= flag;
00574 volflags |= DIRTYFLAG;
00575
00576 }
00577
00578
00579
00580
00581 void yackerror (void)
00589 {
00590 byte i;
00591
00592 for (i=0;i<8;i++)
00593 {
00594 yackplay(DIT);
00595 yackdelay(DITLEN);
00596 }
00597 yackdelay(DAHLEN);
00598
00599 }
00600
00601
00602
00603
00604
00605
00606
00607
00608 static void key(byte mode)
00609
00621 {
00622
00623 if (mode == DOWN)
00624 {
00625 if (volflags & SIDETONE)
00626 {
00627 OCR0A = ctcvalue;
00628 OCR0B = ctcvalue;
00629
00630
00631 TCCR0A |= (1<<COM0B0 | 1<<WGM01);
00632
00633
00634 TCCR0B = 1<<CS01;
00635 }
00636
00637 if (volflags & TXKEY)
00638 {
00639 if (yackflags & TXINV)
00640 CLEARBIT(OUTPORT,OUTPIN);
00641 else
00642 SETBIT(OUTPORT,OUTPIN);
00643 }
00644
00645 }
00646
00647 if (mode == UP)
00648 {
00649
00650 if (volflags & SIDETONE)
00651 {
00652 TCCR0A = 0;
00653 TCCR0B = 0;
00654 }
00655
00656 if (volflags & TXKEY)
00657 {
00658 if (yackflags & TXINV)
00659 SETBIT(OUTPORT,OUTPIN);
00660 else
00661 CLEARBIT(OUTPORT,OUTPIN);
00662 }
00663
00664 }
00665
00666 }
00667
00668
00669
00670 void yackfarns(void)
00675 {
00676
00677 word i=farnsworth;
00678
00679 while (i--)
00680 {
00681 yackdelay(1);
00682 }
00683
00684 }
00685
00686
00687
00688 void yackdelay(byte n)
00697 {
00698
00699 byte i=n;
00700 byte x;
00701
00702 while (i--)
00703 {
00704 x=wpmcnt;
00705 while (x--)
00706 yackbeat();
00707 }
00708
00709 }
00710
00711
00712
00713
00714 void yackplay(byte i)
00715
00721 {
00722
00723 key(DOWN);
00724
00725 #ifdef POWERSAVE
00726
00727 yackpower(FALSE);
00728
00729 #endif
00730
00731 switch (i)
00732 {
00733 case DAH:
00734 yackdelay(DAHLEN);
00735 break;
00736
00737 case DIT:
00738 yackdelay(DITLEN);
00739 break;
00740 }
00741
00742 key(UP);
00743
00744 }
00745
00746
00747
00748
00749 void yackchar(char c)
00766 {
00767 byte code=0x80;
00768 byte i;
00769
00770
00771
00772 if(c>='0' && c<='9')
00773 code = pgm_read_byte(&morse[c-'0']);
00774
00775 if(c>='a' && c<='z')
00776 code = pgm_read_byte(&morse[c-'a'+10]);
00777
00778 if(c>='A' && c<='Z')
00779 code = pgm_read_byte(&morse[c-'A'+10]);
00780
00781
00782
00783
00784 for(i=0;i<sizeof(spechar);i++)
00785 if (c == pgm_read_byte(&spechar[i]))
00786 code = pgm_read_byte(&morse[i+36]);
00787
00788 if(c==' ')
00789 yackdelay(IWGLEN-ICGLEN);
00790 else
00791 {
00792 while (code != 0x80)
00793 {
00794 if (yackctrlkey(FALSE))
00795 return;
00796
00797 if (code & 0x80)
00798 yackplay(DAH);
00799 else
00800 yackplay(DIT);
00801
00802 yackdelay(IEGLEN);
00803
00804 code = code << 1;
00805 }
00806
00807 yackdelay(ICGLEN - IEGLEN);
00808
00809 yackfarns();
00810
00811 }
00812
00813 }
00814
00815
00816
00817 void yackstring(const char *p)
00827 {
00828
00829 char c;
00830
00831 while ((c = pgm_read_byte(p++))&& !(yackctrlkey(FALSE)) )
00832
00833 yackchar(c);
00834
00835
00836 }
00837
00838
00839
00840 void yacknumber(word n)
00850 {
00851
00852 char buffer[5];
00853 byte i = 0;
00854
00855 while (n)
00856 {
00857 buffer[i++] = n%10+'0';
00858 n /= 10;
00859 }
00860
00861 while (i)
00862 {
00863 yackchar(buffer[--i]);
00864 }
00865
00866 yackchar (' ');
00867
00868 }
00869
00870
00871
00872
00873
00874
00875
00876
00877 static void keylatch(void)
00888 {
00889
00890 byte swap;
00891
00892 swap = ( yackflags & PDLSWAP);
00893
00894 if (!( KEYINP & (1<<DITPIN)))
00895 volflags |= (swap?DAHLATCH:DITLATCH);
00896
00897 if (!( KEYINP & (1<<DAHPIN)))
00898 volflags |= (swap?DITLATCH:DAHLATCH);
00899
00900 }
00901
00902
00903
00904 byte yackctrlkey(byte mode)
00921 {
00922
00923 byte volbfr;
00924
00925 volbfr = volflags;
00926
00927 if (!(BTNINP & (1<<BTNPIN)))
00928 {
00929
00930 volbfr |= CKLATCH;
00931
00932
00933
00934
00935
00936
00937
00938 yackinhibit(ON);
00939
00940 _delay_ms(50);
00941
00942 while(!(BTNINP & (1<<BTNPIN)))
00943 {
00944
00945 if (!( KEYINP & (1<<DITPIN)))
00946 {
00947 yackspeed(DOWN,WPMSPEED);
00948 volbfr &= ~(CKLATCH);
00949 }
00950
00951 if (!( KEYINP & (1<<DAHPIN)))
00952 {
00953 yackspeed(UP,WPMSPEED);
00954 volbfr &= ~(CKLATCH);
00955 }
00956
00957 }
00958
00959 _delay_ms(50);
00960
00961 }
00962
00963 volflags = volbfr;
00964
00965 if (mode==TRUE)
00966 {
00967 volflags &= ~(CKLATCH);
00968 }
00969
00970 yacksave();
00971
00972 return((volbfr&CKLATCH)!=0);
00973
00974 }
00975
00976
00977
00978 static char morsechar(byte buffer)
00992 {
00993 byte i;
00994
00995 for(i=0;i<sizeof(morse);i++)
00996 {
00997
00998 if (pgm_read_byte(&morse[i]) == buffer)
00999 {
01000 if (i < 10) return ('0' + i);
01001 if (i < 36) return ('A' + i - 10);
01002 return (pgm_read_byte(&spechar[i - 36]));
01003 }
01004
01005 }
01006
01007 return '\0';
01008 }
01009
01010
01011
01012 void yackmessage(byte function, byte msgnr)
01030 {
01031 unsigned char rambuffer[RBSIZE];
01032 unsigned char c;
01033
01034 word extimer = 0;
01035
01036 byte i = 0;
01037 byte n;
01038
01039 if (function == RECORD)
01040 {
01041
01042 extimer = YACKSECS(DEFTIMEOUT);
01043 while(extimer--)
01044 {
01045 if (yackctrlkey(FALSE)) return;
01046
01047 if ((c = yackiambic(ON)))
01048 {
01049 rambuffer[i++] = c;
01050 extimer = YACKSECS(DEFTIMEOUT);
01051 }
01052
01053 if (i>=RBSIZE)
01054 {
01055 yackerror();
01056 i = 0;
01057 }
01058
01059 yackbeat();
01060 }
01061
01062
01063
01064 if(i)
01065 {
01066 rambuffer[--i] = 0;
01067
01068
01069 for (n=0;n<i;n++)
01070 yackchar(rambuffer[n]);
01071
01072
01073 if (msgnr == 1)
01074 eeprom_write_block(rambuffer,eebuffer1,RBSIZE);
01075 else
01076 eeprom_write_block(rambuffer,eebuffer2,RBSIZE);
01077 }
01078 else
01079 yackerror();
01080 }
01081
01082
01083 if (function == PLAY)
01084 {
01085
01086 if (msgnr == 1)
01087 eeprom_read_block(rambuffer,eebuffer1,RBSIZE);
01088 else
01089 eeprom_read_block(rambuffer,eebuffer2,RBSIZE);
01090
01091
01092 for (n=0;(c=rambuffer[n]);n++)
01093 yackchar(c);
01094
01095 }
01096
01097 }
01098
01099
01100
01101
01102 char yackiambic(byte ctrl)
01115 {
01116
01117 static enum FSMSTATE fsms = IDLE;
01118 static word timer;
01119 static byte lastsymbol;
01120 static byte buffer = 0;
01121 static byte bcntr = 0;
01122 static byte iwgflag = 0;
01123 static byte ultimem = 0;
01124 char retchar;
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 if (timer) timer--;
01142
01143 if (ctrl == OFF) iwgflag = 0;
01144
01145 switch (fsms)
01146 {
01147
01148 case IDLE:
01149
01150 keylatch();
01151
01152 #ifdef POWERSAVE
01153
01154 yackpower(TRUE);
01155
01156 #endif
01157
01158
01159 switch (yackflags & MODE)
01160 {
01161 case IAMBICA:
01162 case IAMBICB:
01163
01164
01165
01166
01167
01168 volflags &= ~lastsymbol;
01169 lastsymbol = 0;
01170 break;
01171
01172 case ULTIMATIC:
01173
01174
01175 if ((volflags & SQUEEZED) == SQUEEZED)
01176 {
01177 if (ultimem)
01178 volflags &= ~ultimem;
01179 else
01180 volflags &= ~DITLATCH;
01181 }
01182 else
01183 {
01184 ultimem = volflags & SQUEEZED;
01185 }
01186
01187 break;
01188
01189 case DAHPRIO:
01190
01191 if ((volflags & SQUEEZED) == SQUEEZED)
01192 {
01193 volflags &= ~DITLATCH;
01194 }
01195 break;
01196 }
01197
01198
01199
01200
01201
01202 if (timer == 0 && bcntr != 0)
01203
01204 {
01205 buffer = buffer << 1;
01206 buffer |= 1;
01207 buffer = buffer << (7-bcntr);
01208 retchar = morsechar(buffer);
01209 buffer = bcntr = 0;
01210 timer = (IWGLEN - ICGLEN) * wpmcnt;
01211
01212 iwgflag = 1;
01213 return (retchar);
01214 }
01215
01216
01217
01218 if (timer == 0 && iwgflag)
01219 {
01220 iwgflag = 0;
01221 return (' ');
01222 }
01223
01224
01225 if ( volflags & (DITLATCH | DAHLATCH))
01226 {
01227 iwgflag = 0;
01228 bcntr++;
01229 buffer = buffer << 1;
01230
01231 if (volflags & DITLATCH)
01232 {
01233 timer = DITLEN * wpmcnt;
01234 lastsymbol = DITLATCH;
01235 }
01236 else
01237 {
01238 timer = DAHLEN * wpmcnt;
01239 lastsymbol = DAHLATCH;
01240 buffer |= 1;
01241 }
01242
01243 key(DOWN);
01244 volflags &= ~(DITLATCH | DAHLATCH);
01245
01246 fsms = KEYED;
01247 }
01248
01249 break;
01250
01251 case KEYED:
01252
01253 #ifdef POWERSAVE
01254
01255 yackpower(FALSE);
01256
01257 #endif
01258
01259 if ((yackflags & MODE) == IAMBICB)
01260 keylatch();
01261
01262 if(timer == 0)
01263 {
01264 key(UP);
01265 timer = IEGLEN * wpmcnt;
01266 fsms = IEG;
01267 }
01268
01269 break;
01270
01271
01272 case IEG:
01273
01274 keylatch();
01275
01276 if(timer == 0)
01277 {
01278 fsms = IDLE;
01279
01280
01281
01282 timer = (ICGLEN - IEGLEN -1) * wpmcnt;
01283 }
01284 break;
01285
01286 }
01287
01288 return '\0';
01289
01290 }
01291
01292