Tinybug TB-9, verze 2

Stáhněte si soubor se zdrojovým kódem a soubor register.asm

  1:; Project-name:         TB-9
  2:; Project-description:  Semi-automatic keyer
  3:; Original author:      Burkhard John, DK5JG (C) Copyright 2002
  4:; Redesign:             Jindrich Vavruska, OK1FOU (C) Copyright 2004, 2005
  5:; Release-date:         15 November 2005
  6:; Based-on:             Nanobug, a small keyer using AT90S2343 by Burkhard John, DK5JG 
  7:;
  8:; Developed as derivative of:
  9:;
 10:;				Nanobug / Picobug
 11:;	Eine der kleinsten elektronischen Morsetasten der Welt
 12:;			Burkhard John, DK5JG
 13:;                           15. Mai 2002
 14:;
 15:;*************************************************************
 16:; LICENSE
 17:;
 18:;    This program is free software; you can redistribute it and/or modify
 19:;    it under the terms of the GNU General Public License as published by
 20:;    the Free Software Foundation; either version 2 of the License, or
 21:;    (at your option) any later version.
 22:
 23:;    This program is distributed in the hope that it will be useful,
 24:;    but WITHOUT ANY WARRANTY; without even the implied warranty of
 25:;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 26:;    GNU General Public License for more details.
 27:
 28:;    You should have received a copy of the GNU General Public License
 29:;    along with this program; if not, write to the Free Software
 30:;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 31:
 32:;*************************************************************
 33:
 34:	.include	"register.asm"
 35:
 36:;  ATtiny12
 37:
 38:    .equ    FLASHTOP  =     $1ff    ; Nejvyssi adresa ve FLASH EPROM programu
 39:    .equ    EEPROMTOP =      $3f    ; Nejvyssi adresa datove EEPROM
 40:
 41:
 42:;******* Deklarace konstant a promennych ****
 43:
 44:; Konstanty
 45:
 46:; verze Original
 47:
 48:    ; pokud pouzijete jiny plosny spoj, zde zmente piny
 49:
 50:	.equ    DIT_BIT=1       ; Bit PB1, vstup tecky  ...  
 51:	.equ    DAH_BIT=0       ; Bit PB0, vstup carky  ---  
 52:	.equ	MEM_BIT=2	; Bit PB2, pamet, vstup MEM
 53:	.equ    SPEED_BIT=3     ; Bit PB3 (pin2), rychlost, vstup TEMPO
 54:	.equ    KEY_BIT=4       ; Bit PB4 (pin3), klicovani
 55:	.equ    SOUND_BIT=7     ; Bit PB7, tonovy vystup (nepouzito)
 56:
 57:	.equ	inPort=PINB
 58:	.equ	outport=PORTB
 59:
 60:; Deklarace registrovych promennych
 61:
 62:    .def    SaveSREG=r7
 63:    .def    SaveGIMSK=r6
 64:    .def    SaveDummy=r5
 65:
 66:	.def    ton=r13         ; Pamet pro prepinani tonoveho vystupu
 67:	.def	memAddr=r14		; Adresa aktualniho cteneho bajtu v EEPROM
 68:	.def	memData=r15		; Aktualni zpracovavana data z pameti
 69:	.def	memBitCount=r31 ; Citac bitu v pametovem bajtu
 70:	.def	memStatus=r30	; Stav zpracovani pameti
 71:
 72:	.def    dataReg=r16     ; registr pro predavani 8 a 16 bitovych parametru, nizsi bajt
 73:	.def    dataRegh=r17    ; registr pro predavani 16 bitovych parametru, horni bajt
 74:
 75:	.def    opStatus=r18     ; Vnitrni stav stavoveho automatu
 76:	.def    ditLenLow=r19 ; Delka tecky (pocet smycek), nizsich 8 bitu
 77:	.def    ditLenHi=r20 ;   -- hornich 8 bitu
 78:	.def    dummy=r21        ; pomocna promenna, 8 nebo 16 bitu, nizsi bajt
 79:	.def    dummyH=r22       ;   -- hornich 8 bitu
 80:	.def    dahMemory=r23    ; 0, neni-li v pameti carka; jinak <>0
 81:	.def    ditMemory=r24    ; 0, neni-li v pameti tecka; jinak <>0
 82:	.def    opMode=r25       ; Pouziti pameti carek a tecek
 83:                    ; -- opMode = 0: pamet tecek i carek
 84:					; -- opMode = 1: jen pamet tecek
 85:					; -- opMode = 2: jen pamet carek
 86:					; -- opMode = 3: zadna pamet
 87:	.def    TimerEndL=r26       ; 16 bitova hodnota citace: nizsi bajt
 88:	.def    TimerEndH=r27       ; 16 bitova hodnota citace: vyssi bajt
 89:	.def	keyStatus=r28       ; stav klicovaciho vystupu
 90:	.def	deltaDelay=r29      ; prirustek pro zmenu rychlosti
 91:
 92:; Definice stavu stavoveho automatu
 93:
 94:	.equ    ST_BASIC=0      ; Klidovy stav
 95:	.equ    ST_DIT_OUT=1    ; Vysilani tecky
 96:	.equ    ST_DIT_WAIT=2   ; Vysilani mezery po tecce
 97:	.equ    ST_DAH_OUT=3    ; Vysilani carky
 98:	.equ    ST_DAH_WAIT=4   ; Vysilani mezery po carce
 99:	.equ	ST_SEND_MEM=7   ; Vysilani textu z pameti
100:	.equ    ST_SLEEP=6      ; Priprava na prechod do stavu SLEEP
101:
102:; Casovaci konstanty
103:
104:	.equ    DIT_UNITS=1     ; Delka tecky v zakladnich jednotkach
105:	.equ    DAH_UNITS=3     ; Delka carky v zakladnich jednotkach
106:	.equ    DIT_TICKS=70    ; Pocatecni rychlost (po resetu)
107:
108:	.equ    RATE=1          ; Rychlost bez obsluhy preruseni casovace
109:	.equ    RATE_STEP=1     ; Delka kroku pri zmene rychlosti
110:;******************************************************************
111:; Zacatek programu
112:;******************************************************************
113:
114:	.cseg
115:	.org     0               
116:	.device ATtiny12
117:
118:				; Vektory preruseni
119:
120:    	rjmp	  Start               ; Reset 
121:    	rjmp	  Int0HandlerIgnore   ; Externi preruseni - nepouzito
122:    	rjmp	  PinChangeHandler    ; Zmena stavu na vstupnim pinu
123:    	rjmp	  Int0HandlerIgnore   ; Casovac - nepouzito
124:    	rjmp	  Int0HandlerIgnore   ; EEPROM - nepouzito
125:    	rjmp	  Int0HandlerIgnore   ; Stav komparatoru - nepouzito
126:
127:;***************** Start s inicializaci ******************
128:
129:Start:
130:
131:	; Vypnuti hlidace (watchdog)
132:    ; Viz datasheet ATtiny11/12 [1006C-09/01] str. 35
133:	ldi		dataReg, 0b00011000
134:	out		WDTCR,dataReg
135:	clr		dataReg
136:	out		WDTCR,dataReg
137:
138:	; Nastaveni stavu v rezimu SLEEP na Power Down (minimalni odber)
139:	ldi		dataReg,0b01100000
140:	out		MCUCR,dataReg
141:
142:	; Nastaveni pinu klicovaciho vystupu a odposlechu na vystup
143:    ; (pozn.: SOUND_BIT u ATtiny12 nepouzit, zachovano pro kompatibilitu 
144:    ; a uplnost programu s jinymi typy AVR v jinem zapojeni)
145:	ldi	    dataReg,(1<<KEY_BIT)|(1<<SOUND_BIT)
146:	out	    DDRB,dataReg
147:
148:	;Port B, KEY_BIT nastavit na 0,
149:	;SOUND_BIT na 1, zapnout pull-up odpory na vstupech
150:	ldi	    dataReg,~(1<<KEY_BIT)
151:	out	    PORTB,dataReg
152:
153:;--------------------------------------------------------
154:	; Pocatecni vynulovani promennych 
155:	clr	    ditMemory
156:	clr	    dahMemory
157:	clr	    memStatus
158:	rcall	  SetOpMode
159:			; Nastaveni pocatecni delky tecek a kroku zmeny rychlosti
160:	ldi	    ditLenLow,low(DIT_TICKS)
161:	ldi	    ditLenHi,high(DIT_TICKS)
162:	ldi	    deltaDelay,RATE_STEP
163:			; Nastaveni pocatecniho stavu stavoveho automatu
164:	ldi	    opStatus,ST_BASIC
165:
166:;*********** HLAVNI SMYCKA PROGRAMU *************
167:
168:			; Obsluha jednotlivych stavu stavoveho automatu
169:
170:MainLoop:
171:	cpi	    opStatus,ST_BASIC
172:	breq	   DoBasicState
173:	cpi	    opStatus,ST_DIT_OUT
174:	breq	   z1_ST_DIT_OUT
175:	cpi	    opStatus,ST_DIT_WAIT
176:	breq	   z1_ST_DIT_WAIT
177:	cpi	    opStatus,ST_DAH_OUT
178:	breq	   z1_ST_DAH_OUT
179:	cpi	    opStatus,ST_DAH_WAIT
180:	breq	   z1_ST_DAH_WAIT
181:	cpi	    opStatus,ST_SLEEP
182:	breq	   z1_ST_SLEEP
183:	cpi	    opStatus,ST_SEND_MEM
184:	breq	z1_ST_SEND_MEM
185:	ldi	    opStatus,ST_BASIC
186:	rjmp	   MainLoop
187:
188:;-------------------------------------------------------
189:				; Tabulka skoku
190:				; Prikaz 'breq' nedokaze skocit dost daleko
191:				; musi se "nastavovat"
192:z1_ST_DIT_OUT:
193:	rjmp	   DoDitOut
194:
195:z1_ST_DIT_WAIT:
196:	rjmp	  DoDitWait
197:
198:z1_ST_DAH_OUT:
199:	rjmp	   z_ST_DAH_OUT
200:
201:z1_ST_DAH_WAIT:
202:	rjmp	   z_ST_DAH_WAIT
203:
204:z1_ST_SLEEP:
205:	rjmp	   DoSleep
206:
207:z1_ST_SEND_MEM:
208:	rjmp	DoSendMemory
209:
210:DoDitOut1:
211:	rjmp	SendDit
212:
213:PostSendDah1:
214:	rjmp	PostSendDah
215:
216:;-------------------------------------------------------
217:
218:			; Stav: ST_BASIC
219:			; zjisti se stav padel a tlacitek a podle toho
220:			; bude nastaven nasledujici stav
221:DoBasicState:
222:	brts	DahFirst
223:	or	     ditMemory,ditMemory
224:	brne	   DoDitOut1
225:	or	     dahMemory,dahMemory
226:	brne	   PostSendDah1
227:	rjmp	TestRate
228:
229:DahFirst:
230:	or	     dahMemory,dahMemory
231:	brne	   PostSendDah1
232:	or	     ditMemory,ditMemory
233:	brne	   DoDitOut1
234:
235:TestRate:
236:			; Zmena tempa
237:	rcall	AdjustRate
238:
239:
240:memtesting:			; Tlacitko pameti
241:
242:            ; Jestlize pri predchozim testu nebylo tlacitko stisknuto,
243:            ; je memStatus=0.
244:            ; Pokud je nyni tlacitko stisknuto, zahajit zpracovani stavu "PAMET"
245:
246:	cpi	    memStatus,0
247:	breq	memnew
248:	cpi	    memStatus,1		; Je-li memStatus=1, ale tlacitko neni stisknuto
249:					        ; pak to byl kratky stisk, takze se odvysila 
250:	breq	status1			; obsah pameti
251:
252:            ; Je-li memStatus=2, probiha nahravani textu do pameti
253:			; jakmile je zjisteno, ze tlacitko MEM neni stisknuto,
254:            ; nahravani se ukonci a prejde se do pocatecniho stavu.
255:	cpi	    memStatus,2
256:	breq	status2
257:            ; jinak -> Chybovy stav, vynulovat
258:	clr	    memStatus
259:	rjmp	pstesting
260:
261:status2:
262:	rcall	readmemkey
263:	or	    dataReg,dataReg
264:            ; Pokud je tlacitko dale stisknuto, 
265:            ; pokracuj v nahravani
266:	breq	   pstesting
267:            ; Jinak - tlacitko uvolneno, konec nahravani.
268:            ; Zapsat znak "konec textu" (dva bity: 11)
269:            ; nejpozdeji po ctvrte koncove znacce 
270:            ; bude dopsan posledni bajt pameti
271:	rcall	   memstopmark
272:	rcall	   memstopmark
273:	rcall	   memstopmark
274:	rcall	   memstopmark
275:                ; vynulovat memStatus
276:   	clr	     memStatus
277:
278:	rjmp	EndBasicStatus
279:
280:status1:
281:	rcall	readmemkey
282:	or	    dataReg,dataReg
283:	brne	memsendtext
284:					; Jinak otestovat, jestli je stisknuta tecka nebo carka
285:					; a zahajit ulozeni do pameti
286:	rcall	GetDitDahPins
287:	or	    dataReg,dataReg
288:					; Pokud je aspon jedno padlo stisknute
289:					; zahajit ulozeni
290:	brne	saveit
291:					; jinak ukoncit zpracovani cyklu
292:	rjmp	EndBasicStatus
293:
294:memsendtext:
295:	clr	    memStatus
296:	ldi	    dataReg,ST_SEND_MEM
297:	mov	    opStatus, dataReg
298:	rjmp	EndBasicStatus
299:
300:memnew:
301:	rcall	readmemkey
302:	or	    dataReg,dataReg
303:	brne	pstesting		; neni-li stisknuto tlacitko MEM, konec
304:
305:	ldi	    memStatus,1
306:	rjmp	EndBasicStatus
307:
308:saveit:
309:	ldi	    memStatus,2		; nastavit stav "nahravani"
310:	clr	    memAddr
311:	inc	    memAddr
312:	ldi	    memBitCount,4
313:	clr	    memData
314:	rjmp	EndBasicStatus
315:
316:pstesting:
317:					; Pokud neni tecka nebo carka v pameti klicovani
318:					; zjistit, jestli se ma ulozit tecka nebo carka.
319:					; Pokud ano, aktivovat zakladni stav ST_BASIC
320:	rcall		GetDitDahPins
321:	brne	EndBasicStatus
322:					; kdyz ne, zjistit, jestli se zapisuje do textove pameti
323:	cpi	    memStatus,2
324:					; kdyz ani to ne, uspat procesor (PostSleepStatus)
325:	brne	PostSleepStatus
326:					; jinak se ulozi pauza (00)
327:					; a nastavi se casova prodleva jedne pauzy
328:	rcall	mempause
329:	ldi	    dataReg,2*DIT_UNITS
330:	rcall		SetTimer
331:
332:elempause:			; jednotkova pauza nasledujici po kazdem elementu
333:	rcall		GetDitDahPins
334:	rcall		StopTimer
335:	or	    dataReg,dataReg
336:	brne	   elempause
337:
338:	rjmp	EndBasicStatus
339:
340:PostSleepStatus:
341:					;       CPU se uvede do stavu SLEEP, ze ktereho se dostava az
342:					;       teprve vyvolanim preruseni na padlech nebo
343:					;       na tlacitcich MEM, TEMPO
344:	ldi	    opStatus,ST_SLEEP
345:	rjmp	   EndBasicStatus
346:
347:PostSendDah:		; nastartuj odeslani carky
348:	ldi	    opStatus,ST_DAH_OUT
349:	rjmp	   EndBasicStatus
350:
351:SendDit:			; nastartuj odeslani tecky
352:	ldi	    opStatus,ST_DIT_OUT
353:
354:EndBasicStatus:
355:	rjmp	   MainLoop
356:
357:
358:;-----------------------------------------------------
359:			; Stav: ST_SEND_MEM
360:			; odvysilani obsahu textove pameti
361:DoSendMemory:
362:	clr	    memAddr
363:	inc	    memAddr	; EEPROM adresa 1
364:	out	    EEAR,memAddr
365:memloop:
366:
367:	out	    EEAR,memAddr
368:	ldi	    dataReg,1
369:	out	    EECR,dataReg	; precist jeden bajt z EEPROM
370:	in	    memData,EEDR
371:
372:							; odvysilani jednoho bajtu (4 elementy)
373:	ldi	    memBitCount,4
374:
375:membloop:
376:	mov	    dummy,memData
377:	add	    memData,memData
378:	add	    memData,memData	; 4x posun doleva = nasledujici element je v nejvyssich 2 bitech
379:	andi	dummy,0b11000000 ; prebytecna instrukce :) 4x ADD nenechava v dolnich bitech jednicky!
380:	cpi	    dummy,0b01000000 ; porovnani zda element je 01 => tecka
381:	breq	dotout
382:	cpi	    dummy,0b10000000 ; porovnani zda element je 10 => carka
383:	breq	dashout
384:	cpi	    dummy,0b00000000 ; porovnani zda element je 00 => meziznakova mezera
385:	breq	pauseout
386:	rjmp	memdone
387:
388:dashout:
389:	rcall	SetKeyerOn
390:	ldi	    dataReg,DAH_UNITS
391:	rjmp	elemout
392:
393:dotout:
394:	rcall	SetKeyerOn
395:	ldi	    dataReg,DIT_UNITS
396:	rjmp	elemout
397:
398:pauseout:
399:	rcall	SetKeyerOff
400:	ldi	    dataReg,DIT_UNITS
401:
402:elemout:
403:	rcall		SetTimer
404:
405:memopause:
406:	rcall		GetDitDahPins
407:	or	    dataReg,dataReg
408:	brne	memdone		; pokud se stiskne jakekoliv padlo, prehravani se ukonci
409:	rcall		StopTimer
410:	or	    dataReg,dataReg
411:	brne	   memopause
412:
413:	rcall	SetKeyerOff
414:					; nasleduje jednotkova pauza po elementu
415:	ldi	    dataReg,DIT_UNITS
416:	rcall	  SetTimer
417:
418:memapause:
419:	rcall	  GetDitDahPins
420:	brne	   memdone		; pokud se stiskne jakekoliv padlo, prehravani se ukonci
421:	rcall	  StopTimer
422:	or	     dataReg,dataReg
423:	brne	   memapause
424:
425:	dec	    memBitCount
426:	brne	membloop
427:
428:	inc	    memAddr		; dalsi adresa v EEPROM
429:	ldi	    dummy,EEPROMTOP+1
430:	cp	    memAddr,dummy
431:	brne	memloop		; zastavi automaticky se na poslednim bajtu EEPROM
432:
433:memdone:
434:	rcall	SetKeyerOff
435:	ldi	    dataReg,ST_BASIC
436:	mov	    opStatus, dataReg
437:	rjmp	   MainLoop
438:
439:;-----------------------------------------------------
440:			; Stav: ST_DIT_OUT
441:			; odvysilani tecky
442:DoDitOut:
443:	rcall	memdit
444:	rcall		SetKeyerOn
445:
446:	ldi	    dataReg,DIT_UNITS
447:	rcall		SetTimer
448:
449:dotpause:
450:	rcall		GetDitDahPins
451:	rcall		StopTimer
452:	or	    dataReg,dataReg
453:	brne	   dotpause
454:
455:	rcall		SetKeyerOff
456:
457:	ldi	    opStatus,ST_DIT_WAIT
458:
459:	rjmp	  	MainLoop
460:
461:;-------------------------------------------------------
462:			; Stav: ST_DIT_WAIT
463:			; odvysilani pauzy
464:DoDitWait:
465:	ldi	    dataReg,DIT_UNITS
466:	rcall		SetTimer
467:
468:dotpause2:
469:	rcall	  GetDitDahPins
470:	rcall	  StopTimer
471:	or	     dataReg,dataReg
472:	brne	   dotpause2
473:
474:	mov	    dataReg,opMode
475:	sbrc	dataReg,1
476:	clr	    dahMemory	; pouze v rezimu 2 nebo 3
477:	clr	    ditMemory
478:	set	
479:	ldi	    dataReg,ST_BASIC
480:	mov	    opStatus, dataReg
481:
482:	rjmp	  	MainLoop
483:
484:;-------------------------------------------------------
485:			; Stav: ST_DAH_OUT
486:			; odvysilani carky
487:z_ST_DAH_OUT:
488:	rcall	memdash
489:	rcall	  SetKeyerOn
490:
491:	ldi	    dataReg,DAH_UNITS
492:	rcall	  SetTimer
493:
494:dashpause:
495:	rcall	 	GetDitDahPins
496:	rcall	 	StopTimer
497:	or	   	dataReg,dataReg
498:	brne	  	dashpause
499:
500:	rcall		SetKeyerOff
501:
502:	ldi	    dataReg,ST_DAH_WAIT
503:	mov	    opStatus, dataReg
504:
505:	rjmp	  	MainLoop
506:
507:;---------------------------------------------------------
508:			; Stav: ST_DAH_WAIT
509:			; Pauza po odvysilani tecky
510:z_ST_DAH_WAIT:
511:	ldi	    dataReg,DIT_UNITS
512:	rcall		SetTimer
513:
514:dashpause2:
515:	rcall		GetDitDahPins
516:	rcall		StopTimer
517:	or	    dataReg,dataReg
518:	brne	   dashpause2
519:
520:	mov	    dataReg,opMode
521:	sbrc	dataReg,0
522:	clr	    ditMemory	; pouze v rezimu 1 nebo 3
523:	clr	    dahMemory
524:	clt	
525:	ldi	    dataReg,ST_BASIC
526:	mov	    opStatus, dataReg
527:
528:	rjmp	  	MainLoop
529:
530:;--------------------------------------------------
531:				; Stav DoSleep
532:				; Prepnuti MCU do stavu SLEEP s nizkou spotrebou
533:DoSleep:
534:	in	    dummy,MCUCR
535:	ori	    dummy,$20	; aktivace SLEEP modu
536:	out	    MCUCR,dummy	
537:	in	    dummy,GIMSK
538:	ori	    dummy,$20	; nastaveni moznosti preruseni zmenou stavu pinu 
539:	out	    GIMSK,dummy ; (v beznem stavu zakazano, protoze se cte ve smycce a nechceme preruseni)
540:	sei	
541:	sleep	  ; tady procesor "usne"
542:	cli		; prvni instrukce po "probuzeni"
543:	in	    dummy,MCUCR
544:	andi	dummy,$df
545:	out	    MCUCR,dummy	; vypnout SLEEP
546:	ldi	    dataReg,ST_BASIC
547:	mov	    opStatus,dataReg
548:	rjmp	  	MainLoop
549:
550:;***************** Systemova smycka *******************************
551:
552:system:
553:
554:;------------------------------------------------------------
555:			; Funkce GetDitPin
556:			; pokud je stisknuto padlo tecek, promenna dataReg = 0
557:			; jinak dataReg <> 0
558:GetDitPin:
559:
560:	in	     dataReg,inPort
561:	andi	   dataReg,1<<DIT_BIT
562:	ret	
563:
564:;------------------------------------------------------------
565:			; Funkce GetDahPin
566:			; pokud je stisknuto padlo carek, promenna dataReg = 0
567:			; jinak dataReg <> 0
568:GetDahPin:
569:	in	     dataReg,inPort
570:	andi	   dataReg,1<<DAH_BIT
571:	ret	
572:
573:;------------------------------------------------------------
574:			; Funkce GetSpeedPin
575:			; Pokud je stisknuto tlacitko TEMPO (+/-)
576:			; bude dataReg = 0,
577:			; jinak dataReg <> 0
578:GetSpeedPin:
579:	in	     dataReg,inPort
580:	andi	   dataReg,1<<SPEED_BIT
581:	ret	
582:
583:
584:;-------------------------------------------------------------
585:			; Funkce SetKeyerOn
586:			; Zapne 1 na klicovacim vystupu
587:SetKeyerOn:
588:	sbr	    keyStatus,(1<<KEY_BIT)
589:	sbi	    outport,KEY_BIT
590:	ret	
591:
592:;--------------------------------------------------------------
593:			; Funkce SetKeyerOff
594:			; Zapne 0 na klicovacim vystupu
595:SetKeyerOff:
596:	cbr	    keyStatus,(1<<KEY_BIT)
597:	cbi	    outport,KEY_BIT
598:	ret	
599:
600:;---------------------------------------------------------------
601:			;Funkce GetDitDahPins
602:			; Precte se pin carek a tecek 
603:			; a prislusna promenna se nastavi na 0xFF 
604:			; pokud je prislusny vstup aktivni (log. 0)
605:			; jinak (vstup je na log.1) se nedeje nic
606:			; Pokud je zaklicovano libovolnym padlem, 
607:			; bude tudiz dataReg <> 0, jinak 0
608:GetDitDahPins:
609:
610:	in	     dataReg,inPort
611:   	sbrs	   dataReg, DIT_BIT
612:	ser	    ditMemory
613:   	sbrs	   dataReg, DAH_BIT
614:	ser	    dahMemory
615:   	mov	    dataReg,ditMemory
616:	or	    dataReg,dahMemory
617:	ret	
618:
619:;---------------------------------------------------------------
620:			;Funkce readmemkey
621:			; Jestlize je memStatus 0:
622:			;    pokud je pouze stisknuto tlacitko M, ale neni kontakt na padle,
623:			;    bude dataReg = 0, jinak <> 0
624:			; Pro memStatus <> 0
625:			;    pokud je pouze stisknuto tlacitko M, 
626:			; 	 bude dataReg = 0, jinak <> 0
627:readmemkey:
628:	cpi	    memStatus,0
629:	brne	memactive
630:	in	    dataReg,inPort
631:	andi	dataReg,(1<<MEM_BIT)|(1<<DIT_BIT)|(1<<DAH_BIT)
632:	cpi	    dataReg,(1<<DIT_BIT)|(1<<DAH_BIT)
633:	breq	memonly
634:	ser	    dataReg
635:	rjmp	memreadstop
636:memonly:
637:	clr	    dataReg
638:	rjmp	memreadstop
639:
640:memactive:
641:	in	    dataReg,inPort
642:	andi	dataReg,(1<<MEM_BIT)
643:
644:memreadstop:
645:	ret	
646:
647:;----------------------------------------------------------------
648:			;Funkce testallkeys
649:			; Je-li stisknute jakekoliv tlacitko
650:			; vraci dataReg = 0, jinak <> 0
651:testallkeys:
652:	in	    dataReg,inPort
653:	andi	dataReg,(1<<MEM_BIT)|(1<<DIT_BIT)|(1<<DAH_BIT)|(1<<SPEED_BIT)
654:	ret	
655:;---------------------------------------------------------------
656:			; Procedury memdit, memdash, mempause, memstopmark
657:            ; Kodovani:
658:            ;	00 : pauza
659:            ;	01 : tecka
660:            ;	10 : carka
661:            ;	11 : konec textove pameti
662:            ;		(na konci textove pameti musi byt koncova znacka)
663:memdit:
664:	ldi	    dataReg,1
665:	rjmp	bitsaveit
666:memdash:
667:	ldi	    dataReg,2
668:	rjmp	bitsaveit
669:memstopmark:
670:	ldi	    dataReg,3
671:	rjmp	bitsaveit
672:mempause:
673:	clr	    dataReg
674:
675:bitsaveit:
676:	cpi	    memStatus,2
677:	breq	bsaveit
678:	rjmp	savedone
679:
680:bsaveit:
681:					; jestlize je memAddr > EEPROMTOP,
682:					; pak je pamet plna a uz se dale
683:					; nezapisuje
684:	ldi	    dummy,EEPROMTOP+1
685:	cp	    memAddr,dummy
686:	brne	memfree
687:	rjmp	savedone
688:
689:memfree:
690:					;memData posunout o dva bity doleva
691:	add	    memData,memData
692:	add	    memData,memData
693:					; do dolnich dvou bitu pricist novou hodnotu
694:	add	    memData,dataReg
695:	dec	    memBitCount
696:					; jestlize jsou zaplneny vsechny bity
697:					; cely bajt se zapise do EEPROM
698:					; a pripravi se nasledujici adresa pro zapis
699:	breq	nextbyte
700:	rjmp	savedone
701:
702:nextbyte:
703:	in	    dataReg,EECR
704:	andi	dataReg,2
705:	brne	nextbyte
706:	out	    EEAR,memAddr
707:	out	    EEDR,memData
708:	sbi	    EECR,2		; Priprava na zapis (enable)
709:	sbi	    EECR,1		; Zapsat (write)
710:
711:					; nasledujici pametova pozice
712:	clr	    memData
713:	ldi	    memBitCount,4
714:	inc	    memAddr
715:
716:savedone:
717:	ret	
718:
719:
720:;---------------------------------------------------------------
721:			; Funkce timerStart
722:			; Casovac se spusti na dobu nastavenou v promenne
723:timerStart:
724:	; v teto verzi se nepouzije preruseni casovacem
725:	ret	
726:
727:;---------------------------------------------------------------
728:			;Funkce SetTimer
729:			; do TimerEnd{L,H} se ulozi casova konstanta
730:			; dataReg * DIT_TICKS (={ditLenLow,ditLenHi})
731:SetTimer:
732:	clr	    TimerEndL
733:	clr	    TimerEndH
734:
735:SetTimerLoop:
736:	or	     dataReg,dataReg
737:	breq	   SetTimerDone
738:	add	    TimerEndL,ditLenLow
739:	adc	    TimerEndH,ditLenHi
740:	dec	    dataReg
741:	rjmp	   SetTimerLoop
742:
743:SetTimerDone:
744:	ret	
745:
746:;---------------------------------------------------------------
747:			; Funkce StopTimer
748:			; vraci dataReg > 0, pokud jeste neuplynul nastaveny cas
749:			; jinak dataReg = 0
750:StopTimer:
751:			; v teto verzi je to bez preruseni casovacem
752:	ldi	    dataRegH,RATE
753:timerloop1:
754:	clr	    dataReg
755:timerloop:
756:	dec	    dataReg
757:	brne	   timerloop
758:	dec	    dataRegH
759:	brne	   timerloop1
760:
761:				; tonovy vystup
762:	in	     dummy,outport
763:				; pokud je nastaven tonovy vystup, nastavit na 0
764:	sbrs	   keyStatus,KEY_BIT
765:	rjmp	   toneoff
766:				; jinak tonovy bit vypnout
767:	inc	    ton
768:	ldi	    dataReg,1
769:	and	    ton,dataReg
770:	breq	   toneoff
771:	andi	dummy,low(~(1<<SOUND_BIT))
772:	rjmp	   tonedone
773:
774:toneoff:
775:	ori	    dummy,1<<SOUND_BIT
776:
777:tonedone:
778:	out	    outport,dummy
779:
780:			; pokud je cas < TimerEnd,
781:			; pak jeste neuplynul cas.
782:			; Pokud je rozdil >= 0,
783:			; cas uz uplynul.
784:	subi	   TimerEndL,1
785:	sbci	   TimerEndH,0
786:	brne	notyet
787:	clr	    dataReg
788:	rjmp	   timerdone
789:
790:notyet:
791:	ser	    dataReg
792:
793:timerdone:
794:	ret	
795:
796:;---------------------------------------------------------------
797:				; Funkce nastaveni rezimu klicovani
798:				; Pokud pri resetu neni stisknuty zadny kontakt padla
799:				; pouzije se rezim 0 (pamet tecek a carek)
800:				; 
801:				; Pokud je stisknute padlo tecek,
802:				; nastavi se rezim 1 - pamet tecek
803:				; Pokud je stisknute padlo carek,
804:				; nastavi se rezim 2 - pamet carek
805:				; Pokud jsou stisknute obe paky, nastavi se 
806:				; rezim 3 - zadna pamet
807:SetOpMode:
808:	clr	    opMode
809:	rcall	  GetDitDahPins
810:
811:	breq	   OpModeReady
812:
813:	or	     ditMemory,ditMemory     ; tecky
814:					; rezim 1 
815:	breq	   opMode2
816:	ori	    opMode,1
817:
818:opMode2:
819:	or	     dahMemory,dahMemory
820:	breq	   OpModeReady               ; carky 
821:					; rezim 2
822:	ori	    opMode,2
823:
824:					; jinak obe paky =>,
825:					; rezim 3
826:OpModeReady:
827:	ret	
828:
829:;-------------------------------------------------------
830:			;Funkce WhichOpMode
831:			;vraci nastaveny rezim klicovani
832:WhichOpMode:
833:	mov	    dataReg,opMode
834:	ret	
835:
836:;-------------------------------------------------------
837:			; Pri stisku tlacitka TEMPO a paky tecek
838:			; se zkrati doba zakladniho elementu o 
839:			; "RATE_STEP".
840:			; Pri stisku tlacitka TEMPO a paky carek
841:			; se prodlouzi doba zakladniho elementu o 
842:			; "RATE_STEP".
843:AdjustRate:
844:	cpi	    ditLenLow,50
845:	brsh	deltabig
846:	ldi	    deltaDelay,RATE_STEP
847:	rjmp	makerate
848:
849:deltabig:
850:	cpi	    ditLenLow,70
851:	brsh	deltahuge
852:	ldi	    deltaDelay,2*RATE_STEP
853:	rjmp	makerate
854:
855:deltahuge:
856:	cpi	    ditLenLow,90
857:	brsh	deltagiant
858:	ldi	    deltaDelay,4*RATE_STEP
859:	rjmp	makerate
860:
861:deltagiant:
862:	cpi	    ditLenLow,110
863:	brsh	deltaveryverybig
864:	ldi	    deltaDelay,8*RATE_STEP
865:	rjmp	makerate
866:
867:deltaveryverybig:
868:	ldi	    deltaDelay,16*RATE_STEP
869:
870:makerate:
871:	rcall	GetDahPin
872:	or	    dataReg,dataReg
873:	breq	rateslower
874:	rcall	GetDitPin
875:	or	    dataReg,dataReg
876:	breq	ratefaster
877:	rjmp	ratedone
878:
879:rateslower:
880:	sbic	   inPort,SPEED_BIT
881:	rjmp	   ratedone
882:
883:	add	    ditLenLow,deltaDelay
884:	cpi	    ditLenLow,200
885:	brlo	ratedone
886:	ldi	    ditLenLow,200
887:	rjmp	   ratedone
888:
889:ratefaster:
890:	sbic	inPort,SPEED_BIT
891:	rjmp	ratedone
892:	sub	    ditLenLow,deltaDelay
893:	cpi	    ditLenLow,30
894:	brsh	ratedone
895:	ldi	    ditLenLow,30
896:
897:ratedone:
898:	ret	
899:			
900:;*********************************************************
901:
902:			;Pin Change Interrupt
903:
904:PinChangeHandler:
905:
906:    ; zde neni potreba zadny kod, vsechno se dela ve stavu DoSleep
907:
908:Int0HandlerIgnore:
909:
910:	; osetreni ostatnich preruseni, pokud by nastala
911:
912:	reti	           
913:
914:;****************************************************
915:
916:				;EEPROM Inhalt
917:	.eseg
918:	.org	0
919:	.db	0		; bajt [0] je prazdny
920:
921:eeprom_Start:
922:				; "CQ DE" jako test pameti
923:	.db	0b10011001	;-.-.
924:	.db	0b00101001	;_--.
925:	.db	0b10001001	;-_-.
926:	.db	0b01000100	;._._
927:    .db 0b11000000  ;|___
928:
929: