Go to the documentation of this file.00001
00034 #ifndef F_CPU
00035 #error F_CPU undefined!! Please define in Makefile
00036 #endif
00037
00038 #include <avr/io.h>
00039 #include <avr/pgmspace.h>
00040 #include <util/delay.h>
00041 #include "yack.h"
00042
00043
00044 #define TRAINTIMEOUT 10 // 10 Seconds
00045 #define PITCHREPEAT 10 // 10 e's will be played for pitch adjust
00046 #define FARNSREPEAT 10 // 10 a's will be played for Farnsworth
00047
00048
00049 const char txok[] PROGMEM = "OK";
00050 const char vers[] PROGMEM = "V0.7";
00051
00052 void pitch(void)
00061 {
00062 word timer=PITCHREPEAT;
00063
00064 while (timer)
00065 {
00066 timer--;
00067 yackchar('E');
00068
00069 if(!(KEYINP & (1<<DITPIN)))
00070 {
00071 yackpitch(DOWN);
00072 timer=PITCHREPEAT;
00073 }
00074
00075 if(!(KEYINP & (1<<DAHPIN)))
00076 {
00077 yackpitch(UP);
00078 timer=PITCHREPEAT;
00079 }
00080
00081 }
00082
00083 }
00084
00085
00086
00087 void setfarns(void)
00095 {
00096 byte timer=0;
00097
00098 while (timer++ != FARNSREPEAT)
00099 {
00100
00101 if(!(KEYINP & (1<<DITPIN)))
00102 {
00103 yackspeed(DOWN,FARNSWORTH);
00104 timer=0;
00105 }
00106
00107 else if(!(KEYINP & (1<<DAHPIN)))
00108 {
00109 yackspeed(UP,FARNSWORTH);
00110 timer=0;
00111 }
00112
00113 else
00114 yackdelay(IWGLEN);
00115
00116 }
00117
00118 }
00119
00120
00121
00122
00123 word lfsr(byte n)
00136 {
00137
00138 static word lfsr = 0xACE1;
00139 byte random;
00140
00141 lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xB400u);
00142
00143 random = lfsr >> 8;
00144
00145 while (random >= n) random -= n;
00146
00147 return random;
00148
00149 }
00150
00151
00152
00153
00154
00155 void rndcall(char* call)
00163 {
00164 byte i;
00165
00166
00167
00168 for (i=0;i<5;i++)
00169 {
00170 if (i == 2)
00171 call[i]=lfsr(10) + '0';
00172 else
00173 call[i]=lfsr(26) + 'A';
00174
00175 }
00176 }
00177
00178
00179
00180
00181 void cstrain(void)
00189 {
00190 char call[5];
00191 char c;
00192 byte i;
00193 byte n;
00194 word timer;
00195
00196 while(1)
00197
00198 {
00199 rndcall(call);
00200
00201 i=0;
00202
00203 while(i<5)
00204 {
00205 if (!i)
00206 {
00207 yackdelay(2 * IWGLEN);
00208 for (n=0;n<5;n++)
00209 {
00210 yackchar(call[n]);
00211 yackfarns();
00212 if(yackctrlkey(TRUE))
00213 return;
00214 }
00215 }
00216
00217 timer = YACKSECS(TRAINTIMEOUT);
00218
00219 do
00220 {
00221
00222 c=yackiambic(OFF);
00223 yackbeat();
00224 timer--;
00225
00226 } while ((!c) && timer && !(yackctrlkey(FALSE)));
00227
00228 if (timer == 0 || yackctrlkey(TRUE))
00229 return;
00230
00231 if (call[i] == c)
00232 i++;
00233 else
00234 {
00235 yackerror();
00236 i=0;
00237 }
00238
00239 }
00240
00241 yackchar ('R');
00242
00243 }
00244 }
00245
00246
00247
00248 void beacon(byte mode)
00262 {
00263
00264 static word interval = 65000;
00265 static word timer;
00266 char c;
00267
00268
00269 if (interval == 65000)
00270 interval = yackuser(READ, 1, 0);
00271
00272 if (mode == RECORD)
00273 {
00274 interval = 0;
00275 timer = YACKSECS(DEFTIMEOUT);
00276
00277 yackchar('N');
00278
00279 while(--timer)
00280 {
00281 c=yackiambic(FALSE);
00282 yackbeat();
00283
00284 if (c>='0' && c<='9')
00285 {
00286 interval *= 10;
00287 interval += c - '0';
00288 timer = YACKSECS(DEFTIMEOUT);
00289 }
00290 }
00291
00292 if (interval >= 0 && interval <= 9999)
00293 {
00294 yackuser(WRITE, 1, interval);
00295 yacknumber(interval);
00296 }
00297 else
00298 {
00299 yackerror();
00300 }
00301
00302 }
00303
00304
00305 if ((mode == PLAY) && interval)
00306 {
00307
00308 #ifdef POWERSAVE
00309
00310
00311
00312
00313 yackpower(FALSE);
00314
00315 #endif
00316
00317 if (timer) timer--;
00318 else
00319 {
00320 timer = YACKSECS(1);
00321
00322 if ((--interval)==0)
00323 {
00324
00325 interval = yackuser(READ, 1, 0);
00326 yackmessage(PLAY,2);
00327
00328
00329 }
00330
00331 }
00332
00333 }
00334
00335 }
00336
00337
00338
00339
00340 void commandmode(void)
00348 {
00349
00350 char c;
00351 word timer;
00352
00353 yackinhibit(ON);
00354
00355 yackchar('?');
00356
00357 timer = YACKSECS(DEFTIMEOUT);
00358
00359 while ((yackctrlkey(TRUE)==0) && (timer-- > 0))
00360 {
00361
00362 c=yackiambic(OFF);
00363 if (c) timer = YACKSECS(DEFTIMEOUT);
00364
00365 yackbeat();
00366
00367 lfsr(255);
00368
00369 if (!yackflag(CONFLOCK))
00370 {
00371 switch (c)
00372 {
00373
00374 case 'R':
00375 yackreset();
00376 c = TRUE;
00377 break;
00378
00379 case 'A':
00380 yackmode(IAMBICA);
00381 c = TRUE;
00382 break;
00383
00384 case 'B':
00385 yackmode(IAMBICB);
00386 c = TRUE;
00387 break;
00388
00389 case 'L':
00390 yackmode(ULTIMATIC);
00391 c = TRUE;
00392 break;
00393
00394 case 'D':
00395 yackmode(DAHPRIO);
00396 c = TRUE;
00397 break;
00398
00399 case 'X':
00400 yacktoggle(PDLSWAP);
00401 c = TRUE;
00402 break;
00403
00404 case 'S':
00405 yacktoggle(SIDETONE);
00406 c = TRUE;
00407 break;
00408
00409 case 'K':
00410 yacktoggle(TXKEY);
00411 c = TRUE;
00412 break;
00413
00414 case 'Z':
00415 setfarns();
00416 c = TRUE;
00417 break;
00418
00419 case 'I':
00420 yacktoggle(TXINV);
00421 c = TRUE;
00422 break;
00423
00424 case '1':
00425 yackchar('1');
00426 yackmessage(RECORD,1);
00427 c = TRUE;
00428 break;
00429
00430 case '2':
00431 yackchar('2');
00432 yackmessage(RECORD,2);
00433 c = TRUE;
00434 break;
00435
00436 case 'N':
00437 beacon(RECORD);
00438 c = TRUE;
00439 break;
00440
00441 }
00442
00443 }
00444
00445 switch (c)
00446 {
00447
00448 case 'V':
00449 yackstring(vers);
00450 c = TRUE;
00451 break;
00452
00453
00454 case 'P':
00455 pitch();
00456 c = TRUE;
00457 break;
00458
00459 case 'U':
00460 yackinhibit(OFF);
00461 yacktune();
00462 yackinhibit(ON);
00463 c = TRUE;
00464 break;
00465
00466 case 'C':
00467 cstrain();
00468 c = TRUE;
00469 break;
00470
00471 case '0':
00472 yacktoggle(CONFLOCK);
00473 c = TRUE;
00474 break;
00475
00476 case 'E':
00477 yackinhibit(OFF);
00478 yackmessage(PLAY,1);
00479 yackinhibit(ON);
00480 timer = YACKSECS(MACTIMEOUT);
00481 c = FALSE;
00482 break;
00483
00484 case 'T':
00485 yackinhibit(OFF);
00486 yackmessage(PLAY,2);
00487 yackinhibit(ON);
00488 timer = YACKSECS(MACTIMEOUT);
00489 c = FALSE;
00490 break;
00491
00492 case 'N':
00493 beacon(RECORD);
00494 c = TRUE;
00495 break;
00496
00497 case 'W':
00498 yacknumber(yackwpm());
00499 c = TRUE;
00500 break;
00501
00502
00503 }
00504
00505 if (c == TRUE)
00506 yackstring(txok);
00507 else if (c)
00508 yackerror();
00509
00510
00511 }
00512
00513
00514 yackchar('E');
00515
00516 yackinhibit(OFF);
00517
00518 }
00519
00520
00521
00522 int main(void)
00523
00531 {
00532
00533 yackinit();
00534
00535 while(1)
00536 {
00537
00538 if (yackctrlkey(TRUE))
00539 commandmode();
00540
00541 yackbeat();
00542 beacon(PLAY);
00543 yackiambic(OFF);
00544
00545 }
00546
00547 return 0;
00548 }
00549
00550