#define __SFR_OFFSET 0 #include #include // #define watchdog_enable #define interrupt_enable .global remocon ; .global c3024_init ; .global rcin ; .global sonar ; .global pwm ; .global fpwm ; .global erx_etx_open; .global erx_etx_close .global erx_char; .global etx_char; .global etx_ready; .global erx_ready; .global srx_stx_open; .global srx_srx_close .global srx_char; .global stx_char; .global stx_ready; .global srx_ready; .global led0_on; .global led1_on; .global led0_off; .global led1_off; ;------------------------------------------------------------------- ; This is the function to read the Robonova Remote control ; It is taken from the C3024 Code. Here for IM code FB REMOCON ; the function tales no input unlike the C3024 version, since we only ever used (1) ; return value is in r24 and is value if received or 0 if not ; Clobbers r18, r19, r20, r21, r22, r23, r24, r25 which is OK remocon: lds r24, DDRF ; Bit F 7 is the input andi r24, 0x7F sts DDRF, r24 ldi 24, 0x00 REMCON1B: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r25, 0x00 REMCON1C: dec r25 ; wait for a low signal nop nop nop nop sbis PINF, 0x07 rjmp REMCON1D brne REMCON1C dec r24 brne REMCON1B rjmp REMCON1E ; never went low REMCON1D: rcall REMCON1F ; check valid preamble brlo REMCON1E ; exit if bad (carry set) rcall REMCON1V brlo REMCON1E ; exit if bad cpi r24, 0x00 brne REMCON1E rcall REMCON1V brlo REMCON1E cpi r24, 0x80 brne REMCON1E rcall REMCON1V brlo REMCON1E cpi r24, 0x00 brne REMCON1E rcall REMCON1V brlo REMCON1E cpi r24, 0x80 brne REMCON1E rcall REMCON1R brlo REMCON1E lsr r19 mov r24, r19 inc r24 #ifdef interrupt_enable sei #endif /* interrupt_enable */ ret REMCON1E: ldi r24, 0x00 ; never went low return 0 #ifdef interrupt_enable sei #endif /* interrupt_enable */ ret REMCON1F: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x00 ; did go low REMCON1G: ldi r25, 0x1B ; wait for high again REMCON1H: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINF, 0x07 rjmp REMCON1Q ; high again to soon dec r25 brne REMCON1H inc r24 cpi r24, 0x46 brlo REMCON1G ldi r24, 0x00 ; wait for high REMCON1I: ldi r25, 0x64 REMCON1J: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINF, 0x07 rjmp REMCON1K ; ok dec r25 brne REMCON1J inc r24 cpi r24, 0x40 brsh REMCON1Q ; didn't go high in time rjmp REMCON1I REMCON1K: ldi r24, 0x00 ; went high ok in time window REMCON1L: ldi r25, 0x0C REMCON1M: wdr sbis PINF, 0x07 ; wait for low rjmp REMCON1Q ; too soon dec r25 brne REMCON1M inc r24 cpi r24, 0x46 brlo REMCON1L ldi r24, 0x00 REMCON1N: ldi r25, 0x0C REMCON1O: wdr sbis PINF, 0x07 ; wait for low again rjmp REMCON1P ; ok dec r25 brne REMCON1N inc r24 cpi r24, 0x28 brsh REMCON1Q ; too late rjmp REMCON1O REMCON1P: clc ; good exit ret REMCON1Q: sec ; error exit ret REMCON1R: ldi r20, 0x08 ldi r19, 0x00 ldi r21, 0x00 ldi r22, 0x00 REMCON1S: rcall REMCON1V brlo REMCON1U cpi r20, 0x01 breq REMCON1T tst r24 breq REMCON1T com r22 REMCON1T: rol r24 rol r19 rol r21 dec r20 brne REMCON1S mov r21, r19 andi r21, 0x01 andi r22, 0x01 cp r21, r22 brne REMCON1U clc ret REMCON1U: sec ret REMCON1V: ldi r24, 0x00 ; wait for high REMCON1W: ldi r25, 0x0C REMCON1X: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINF, 0x07 rjmp REMCON1Y ; ok dec r25 brne REMCON1X inc r24 cpi r24, 0x80 brsh REMCON1AD ; waited to long rjmp REMCON1W REMCON1Y: mov r18, r24 ; save r24 ldi r24, 0x00 REMCON1Z: ldi r25, 0x0C REMCON1AA: wdr sbis PINF, 0x07 ; wait fo low rjmp REMCON1AB ; ok dec r25 brne REMCON1AA inc r24 cpi r24, 0x80 brsh REMCON1AD ; too long rjmp REMCON1Z REMCON1AB: ldi r25, 0x00 cp r18, r24 brsh REMCON1AC ldi r25, 0x80 REMCON1AC: mov r24, r25 clc ret REMCON1AD: sec ret ;----------------------------------------------------------------------- ;This function sets all C3024 ports to input c3024_init: ldi r18, 0x00 sts 0x0061, r18 ; DDRF = 0 ldi r18, 0x00 out DDRA, r18 out DDRB, r18 out DDRC, r18 out DDRD, r18 out 0x02, r18 ; DDRG = 0 sts 0x0064, r18 ret ;---------------------------------------------------------------------- ; Global function sonar ; r24 = sonar number, returns r25:r24 = distance sonar: #ifdef interrupt_enable cli #endif /* interrupt_enable */ cpi r24, 0x00 breq SONAR0 cpi r24, 0x01 breq SONAR1 cpi r24, 0x02 breq SONAR2 cpi r24, 0x03 breq SONAR3 cpi r24, 0x04 breq SONAR4 cpi r24, 0x05 breq SONAR5 cpi r24, 0x06 breq SONAR6 cpi r24, 0x07 breq SONAR7 cpi r24, 0x08 breq SONAR8 cpi r24, 0x09 breq SONAR9 cpi r24, 0x0A breq SONARA cpi r24, 0x0B breq SONARB rjmp SONARY SONAR0: rjmp SONAR0A SONAR1: rjmp SONAR1A SONAR2: rjmp SONAR2A SONAR3: rjmp SONAR3A SONAR4: rjmp SONAR4A SONAR5: rjmp SONAR5A SONAR6: rjmp SONAR6A SONAR7: rjmp SONAR7A SONAR8: rjmp SONAR8A SONAR9: rjmp SONAR9A SONARA: rjmp SONARAA SONARB: rjmp SONARBA SONAR0A: sbi DDRA, 0 ; port A bit 0 out cbi DDRA, 1 ; port A bit 1 in sbi PORTA, 0 ; set bit 0 ldi r24, 0x1B ; delay SONAR0B: dec r24 brne SONAR0B cbi PORTA, 0 ; clear bit 0 ldi r24, 0xC8 SONAR0C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINA, 1 ; wait for bit to set rjmp SONAR0D nop nop nop nop dec r24 brne SONAR0C rjmp SONARY ; not set exit SONAR0D: cli ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR0E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR0F: dec r24 brne SONAR0F sbis PINA, 1 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR0E tst XL brne SONAR0E rjmp SONARY ; too long SONAR1A: sbi DDRA, 2 ; port A bit 2 out cbi DDRA, 3 ; port A bit 3 in sbi PORTA, 2 ; set bit 2 ldi r24, 0x1B ; delay SONAR1B: dec r24 brne SONAR1B cbi PORTA, 2 ; clear bit 2 ldi r24, 0xC8 SONAR1C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINA, 3 ; wait for bit to set rjmp SONAR1D nop nop nop nop dec r24 brne SONAR1C rjmp SONARY ; not set exit SONAR1D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR1E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR1F: dec r24 brne SONAR1F sbis PINA, 3 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR1E tst XL brne SONAR1E rjmp SONARY ; too long SONAR2A: sbi DDRA, 4 ; port A bit 4 out cbi DDRA, 5 ; port A bit 5 in sbi PORTA, 4 ; set bit 4 ldi r24, 0x1B ; delay SONAR2B: dec r24 brne SONAR2B cbi PORTA, 4 ; clear bit 4 ldi r24, 0xC8 SONAR2C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINA, 5 ; wait for bit to set rjmp SONAR2D nop nop nop nop dec r24 brne SONAR2C rjmp SONARY ; not set exit SONAR2D: cli ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR2E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR2F: dec r24 brne SONAR2F sbis PINA, 5 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR2E tst XL brne SONAR2E rjmp SONARY ; too long SONAR3A: sbi DDRA, 6 ; port A bit 6 out cbi DDRA, 7 ; port A bit 7 in sbi PORTA, 6 ; set bit 6 ldi r24, 0x1B ; delay SONAR3B: dec r24 brne SONAR3B cbi PORTA, 0 ; clear bit 6 ldi r24, 0xC8 SONAR3C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINA, 7 ; wait for bit to set rjmp SONAR3D nop nop nop nop dec r24 brne SONAR3C rjmp SONARY ; not set exit SONAR3D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR3E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR3F: dec r24 brne SONAR3F sbis PINA, 7 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR3E tst XL brne SONAR3E rjmp SONARY ; too long SONAR4A: sbi DDRB, 0 ; port B bit 0 out cbi DDRB, 1 ; port B bit 1 in sbi PORTB, 0 ; set bit 0 ldi r24, 0x1B ; delay SONAR4B: dec r24 brne SONAR4B cbi PORTB, 0 ; clear bit 0 ldi r24, 0xC8 SONAR4C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINB, 1 ; wait for bit to set rjmp SONAR4D nop nop nop nop dec r24 brne SONAR4C rjmp SONARY ; not set exit SONAR4D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR4E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR4F: dec r24 brne SONAR4F sbis PINB, 1 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR4E tst XL brne SONAR4E rjmp SONARY ; too long SONAR5A: sbi DDRB, 2 ; port B bit 2 out cbi DDRB, 3 ; port B bit 3 in sbi PORTB, 2 ; set bit 2 ldi r24, 0x1B ; delay SONAR5B: dec r24 brne SONAR5B cbi PORTB, 2 ; clear bit 2 ldi r24, 0xC8 SONAR5C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINB, 3 ; wait for bit to set rjmp SONAR5D nop nop nop nop dec r24 brne SONAR5C rjmp SONARY ; not set exit SONAR5D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR5E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR5F: dec r24 brne SONAR5F sbis PINB, 3 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR5E tst XL brne SONAR5E rjmp SONARY ; too long SONAR6A: sbi DDRB, 4 ; port B bit 4 out cbi DDRB, 5 ; port B bit 5 in sbi PORTB, 4 ; set bit 4 ldi r24, 0x1B ; delay SONAR6B: dec r24 brne SONAR6B cbi PORTB, 4 ; clear bit 4 ldi r24, 0xC8 SONAR6C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINB, 5 ; wait for bit to set rjmp SONAR6D nop nop nop nop dec r24 brne SONAR6C rjmp SONARY ; not set exit SONAR6D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR6E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR6F: dec r24 brne SONAR6F sbis PINB, 5 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR6E tst XL brne SONAR6E rjmp SONARY ; too long SONAR7A: sbi DDRB, 6 ; port B bit 6 out cbi DDRB, 7 ; port B bit 7 in sbi PORTB, 6 ; set bit 6 ldi r24, 0x1B ; delay SONAR7B: dec r24 brne SONAR7B cbi PORTB, 0 ; clear bit 6 ldi r24, 0xC8 SONAR7C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINB, 7 ; wait for bit to set rjmp SONAR7D nop nop nop nop dec r24 brne SONAR7C rjmp SONARY ; not set exit SONAR7D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR7E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR7F: dec r24 brne SONAR7F sbis PINB, 7 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR7E tst XL brne SONAR7E rjmp SONARY ; too long SONAR8A: sbi DDRC, 0 ; port C bit 0 out cbi DDRC, 1 ; port C bit 1 in sbi PORTC, 0 ; set bit 0 ldi r24, 0x1B ; delay SONAR8B: dec r24 brne SONAR8B cbi PORTC, 0 ; clear bit 0 ldi r24, 0xC8 SONAR8C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINC, 1 ; wait for bit to set rjmp SONAR8D nop nop nop nop dec r24 brne SONAR8C rjmp SONARY ; not set exit SONAR8D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR8E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR8F: dec r24 brne SONAR8F sbis PINC, 1 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR8E tst XL brne SONAR8E rjmp SONARY ; too long SONAR9A: sbi DDRC, 2 ; port C bit 2 out cbi DDRA, 3 ; port C bit 3 in sbi PORTC, 2 ; set bit 2 ldi r24, 0x1B ; delay SONAR9B: dec r24 brne SONAR9B cbi PORTC, 2 ; clear bit 2 ldi r24, 0xC8 SONAR9C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINC, 3 ; wait for bit to set rjmp SONAR9D nop nop nop nop dec r24 brne SONAR9C rjmp SONARY ; not set exit SONAR9D: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONAR9E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONAR9F: dec r24 brne SONAR9F sbis PINC, 3 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR9E tst XL brne SONAR9E rjmp SONARY ; too long SONARAA: sbi DDRC, 4 ; port C bit 4 out cbi DDRC, 5 ; port C bit 5 in sbi PORTC, 4 ; set bit 4 ldi r24, 0x1B ; delay SONARAB: dec r24 brne SONARAB cbi PORTC, 4 ; clear bit 4 ldi r24, 0xC8 SONARAC: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINC, 5 ; wait for bit to set rjmp SONARAD nop nop nop nop dec r24 brne SONARAC rjmp SONARY ; not set exit SONARAD: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONARAE: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONARAF: dec r24 brne SONARAF sbis PINC, 5 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONAR9E tst XL brne SONARAE rjmp SONARY ; too long SONARBA: sbi DDRC, 6 ; port C bit 6 out cbi DDRC, 7 ; port C bit 7 in sbi PORTC, 6 ; set bit 6 ldi r24, 0x1B ; delay SONARBB: dec r24 brne SONARBB cbi PORTC, 0 ; clear bit 6 ldi r24, 0xC8 SONARBC: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic PINC, 7 ; wait for bit to set rjmp SONARBD nop nop nop nop dec r24 brne SONARBC rjmp SONARY ; not set exit SONARBD: #ifdef interrupt_enable cli #endif /* interrupt_enable */ ldi XH, 0x00 ; zero counter ldi XL, 0x00 SONARBE: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ ldi r24, 0x0C SONARBF: dec r24 brne SONARBF sbis PINC, 7 ; wait for clear rjmp SONARX adiw XL, 0x01 cpi XH, 0x32 brne SONARBE tst XL brne SONARBE rjmp SONARY ; too long SONARX: mov r25, YH mov r24, YL rjmp SONARZ SONARY: ldi r25, 0x00 ; zero result ldi r24, 0x00 SONARZ: #ifdef interrupt_enable sei #endif /* interrupt_enable */ ret ;------------------------------------------------------- ;----------------------------------------------------- ; Here for RCIN rcin: mov r18, r24 call CLRDDRF ; clear bit in DDRF from r18 input ldi r17, 0x05 out 0x25, r17 ; TCCR2 = 5 tclk / 1024 = ldi r17, 0x00 out 0x24, r17 ; TCNT2 = 0 in r17, 0x36 andi r17, 0x40 out 0x36, r17 ; timer 2 clear overflow if set ldi r17, 0x02 out 0x2E, r17 ; TCCR1B = 2 set up timer 1 for use to measure pulse tck /8 #ifdef interrupt_enable cli #endif /* interrupt_enable */ cpi r24, 0x00 breq RCIN0A cpi r24, 0x01 breq RCIN1A cpi r24, 0x02 breq RCIN2A cpi r24, 0x03 breq RCIN3A cpi r24, 0x04 breq RCIN4A cpi r24, 0x05 breq RCIN5A cpi r24, 0x06 breq RCIN6A cpi r24, 0x07 breq RCIN7A rjmp RCINY RCIN0A: rjmp RCIN0B RCIN1A: rjmp RCIN1B RCIN2A: rjmp RCIN2B RCIN3A: rjmp RCIN3B RCIN4A: rjmp RCIN4B RCIN5A: rjmp RCIN5B RCIN6A: rjmp RCIN6B RCIN7A: rjmp RCIN7B RCIN0B: sbis 0x00, 0 ;is bit 0 in port F set ? rjmp RCIN0D ; jump if low #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 ; wait for 20mSec out 0x24, r19 in r19, 0x36 ; clear overflow if set andi r19, 0x40 out 0x36, r19 RCIN0C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 ; get T2 overflow sbrs r19, 6 rjmp RCIN0C ; loop if not set #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN0D: ldi r19, 0x50 ; timer 10 mSec out 0x24, r19 in r19, 0x36 ; clear overflow if set andi r19, 0x40 out 0x36, r19 RCIN0E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 0 ; is bit 0 in port F clear ? rjmp RCIN0F in r19, 0x36 ; get overflow sbrs r19, 6 rjmp RCIN0E rjmp RCINY ; null return RCIN0F: ldi r19, 0xEB ; here when high after low out 0x24, r19 ; timer 32.5mSec in r19, 0x36 ; clear T2 overflow if set andi r19, 0x40 out 0x36, r19 clr r19 ; clear Timer 1 out 0x2D, r19 out 0x2C, r19 RCIN0G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 0 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN0G rjmp RCINY ; waited too long null return RCIN1B: sbis 0x00, 1 ; port 1 rjmp RCIN1D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN1C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 sbrs r19, 6 rjmp RCIN1C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN1D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN1E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 1 rjmp RCIN1F in r19, 0x36 sbrs r19, 6 rjmp RCIN1E rjmp RCINY RCIN1F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN1G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 1 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN1G rjmp RCINY RCIN2B: sbis 0x00, 2 ; bit 2 rjmp RCIN2D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN2C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 sbrs r19, 6 rjmp RCIN2C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN2D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN2E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 2 rjmp RCIN2F in r19, 0x36 sbrs r19, 6 rjmp RCIN2E rjmp RCINY RCIN2F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN2G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 2 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN2G rjmp RCINY ; RCIN3B: sbis 0x00, 3 ; bit 3 rjmp RCIN3D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN3C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 sbrs r19, 6 rjmp RCIN3C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN3D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN3E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 3 rjmp RCIN3F in r19, 0x36 sbrs r19, 6 rjmp RCIN3E rjmp RCINY RCIN3F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN3G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 3 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN3G rjmp RCINY RCIN4B: sbis 0x00, 4 ; bit 4 rjmp RCIN4D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN4C: in r19, 0x36 sbrs r19, 6 rjmp RCIN4C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN4D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN4E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 4 rjmp RCIN4F in r19, 0x36 sbrs r19, 6 rjmp RCIN4E rjmp RCINY RCIN4F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN4G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 4 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN4G rjmp RCINY RCIN5B: sbis 0x00, 5 ; bit 5 rjmp RCIN5D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN5C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 sbrs r19, 6 rjmp RCIN5C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN5D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN5E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 5 rjmp RCIN5F in r19, 0x36 sbrs r19, 6 rjmp RCIN5E rjmp RCINY RCIN5F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN5G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 5 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN5G rjmp RCINY RCIN6B: sbis 0x00, 6 ; bit 6 rjmp RCIN6D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN6C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 sbrs r19, 6 rjmp RCIN6C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN6D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN6E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 6 rjmp RCIN6F in r19, 0x36 sbrs r19, 6 rjmp RCIN6E rjmp RCINY RCIN6F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN6G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 6 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN6G rjmp RCINY RCIN7B: sbis 0x00, 7 ; bit 7 rjmp RCIN7D #ifdef interrupt_enable sei #endif /* interrupt_enable */ ldi r19, 0x96 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN7C: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ in r19, 0x36 sbrs r19, 6 rjmp RCIN7C #ifdef interrupt_enable cli #endif /* interrupt_enable */ RCIN7D: ldi r19, 0x50 out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 RCIN7E: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbic 0x00, 7 rjmp RCIN7F in r19, 0x36 sbrs r19, 6 rjmp RCIN7E rjmp RCINY RCIN7F: ldi r19, 0xEB out 0x24, r19 in r19, 0x36 andi r19, 0x40 out 0x36, r19 clr r19 out 0x2D, r19 out 0x2C, r19 RCIN7G: #ifdef watchdog_enable wdr #endif /* watchdog_enable*/ sbis 0x00, 7 rjmp RCINU in r19, 0x36 sbrs r19, 6 rjmp RCIN7G rjmp RCINY RCINU: in r24, 0x2C ; here at end of pulse in r25, 0x2D ; read the timers ror r25 ; divide by 4 ror r24 ror r25 ror r24 andi r25, 0x3F ; clear top 2 bits cpi r25, 0x00 ; if top byte = 0 then clear bottom too brne RCINV ldi r24, 0x00 RCINV: cpi r25, 0x02 ; if top > 2 brlo RCINW ldi r24, 0xB4 ; bottom = 180 RCINW: cpi r24, 0xB4 ; if bottom > B4 brlo RCINX ldi r18, 0xB4 ; bottom = b4 RCINX: clr r25 ldi r18, 0x0A ; add 10 add r24, r18 rjmp RCINZ RCINY: clr r24 ; null return clr r25 RCINZ: #ifdef interrupt_enable sei #endif /* interrupt_enable */ ret CLRDDRF: lds r19, 0x0061 ; Clear bits in DDRF based on r18 cpi r18, 0x00 breq CLRDDRF0 cpi r18, 0x01 breq CLRDDRF1 cpi r18, 0x02 breq CLRDDRF2 cpi r18, 0x03 breq CLRDDRF3 cpi 18, 0x04 breq CLRDDRF4 cpi r18, 0x05 breq CLRDDRF5 cpi r18, 0x06 breq CLRDDRF6 cpi r18, 0x07 breq CLRDDRF7 CLRDDRF0: andi r19, 0xFE rjmp CLRDDRFA CLRDDRF1: andi r19, 0xFD rjmp CLRDDRFA CLRDDRF2: andi r19, 0xFB rjmp CLRDDRFA CLRDDRF3: andi r19, 0xF7 rjmp CLRDDRFA CLRDDRF4: andi r19, 0xEF rjmp CLRDDRFA CLRDDRF5: andi r19, 0xDF rjmp CLRDDRFA CLRDDRF6: andi r19, 0xBF rjmp CLRDDRFA CLRDDRF7: andi r19, 0x7F CLRDDRFA: sts 0x0061, r19 ret ;-------------------------------------------------------------------- ; global function pwm ; r24 = port, r22 = duty ( 0 = off) pwm: cpi r24, 0x00 ; PWM0 ? breq PWM0 cpi r24, 0x01 ; PWM1 ? breq PWM1 cpi r24, 0x02 ; PWM2 ? breq PWM2 ret PWM0: sbi 0x02, 3 ; set data direction lds r19, 0x008B ; get TCR3 bits tst r22 breq PWM0A ori r19, 0x81 ; set bits 0 and 7 rjmp PWM0B PWM0A: andi r19, 0x3F ; clear bits 6 and 7 PWM0B: sts 0x008B, r19 ; store ldi r19, 0x0B sts 0x008A, r19 ldi r19, 0x00 sts 0x0087, r19 ; sts 0x0086, r22 ; set compare value ret PWM1: sbi 0x02, 4 ; set data direction lds r19, 0x008B ; get TCR3 bits; tst r22 breq PWM1A ori r19, 0x21 ; set bits 0 and 5 rjmp PWM1B PWM1A: andi r19, 0xCF ; clear bits 4 and 5 PWM1B: sts 0x008B, r19 ; store ldi r19, 0x0B sts 0x008A, r19 ldi r19, 0x00 sts 0x0085, r19 sts 0x0084, r22 ; set compare value ret PWM2: sbi 0x02, 5 ; set data direction lds r19, 0x008B ; get TCR3 bits tst r22 breq PWM2A ori r19, 0x09 ; set bits 0 and 3 rjmp PWM2B PWM2A: andi r19, 0xF3 ; clear bits 2 and 3 PWM2B: sts 0x008B, r19 ; store ldi r19, 0x0B sts 0x008A, r19 ldi r19, 0x00 sts 0x0083, r19 sts 0x0082, r22 ret ; ;----------------------------------------------------------------- ; global function fpwm same as pwm, but change frequency too ; r24 = port, r22 = frequency, r20 = duty rate fpwm: cpi r22, 0x01 breq FPWMA cpi r22, 0x02 breq FPWMA cpi r22, 0x03 breq FPWMA cpi r22, 0x04 breq FPWMA cpi r22, 0x05 breq FPWMA ldi r22, 0x03 ; freq not 1 to 5 then default 3 FPWMA : cpi r24, 0x00 breq FPWM0 cpi r24, 0x01 breq FPWM1 cpi r24, 0x02 breq FPWM2 ret FPWM0: sbi 0x02, 3 ; set bit 3 in Data direction lds r19, 0x008B ; get TCR3 bits tst r20 breq FPWM0A ori r19, 0x81 ; set bits 7 and 0 rjmp FPWM0B FPWM0A: andi r19, 0x3F ; clear bits 6 and 7 FPWM0B: sts 0x008B, r19 ldi r19, 0x08 or r19, r22 ; or freq sts 0x008A, r19 ldi r19, 0x00 sts 0x0087, r19 sts 0x0086, r20 ret FPWM1: sbi 0x02, 4 ; set bit 4 in data direction lds r19, 0x008B ; get TCR3 bits tst r20 breq FPWM1A ori r19, 0x21 ; set bits 5 and 0 rjmp FPWM1B FPWM1A: andi r19, 0xCF ; clear bits 4 and 5 FPWM1B: sts 0x008B, r19 ldi r19, 0x08 or r19, r22 ; or freq sts 0x008A, r19 ldi r19, 0x00 sts 0x0085, r19 sts 0x0084, r20 ret FPWM2: sbi 0x02, 5 ; set bit 5 in data direction lds r19, 0x008B ; get TCR3 bits tst r20 breq FPWM2A ori r19, 0x09 ; set bits 0 and 3 rjmp FPWM2B FPWM2A: andi r19, 0xF3 ; clear bits 2 and 3 FPWM2B: sts 0x008B, r19 ldi r19, 0x08 or r19, r22 ; or freq sts 0x008A, r19 ldi r19, 0x00 sts 0x0083, r19 sts 0x0082, r20 ret ;------------------------------------------------------------------------- ; global function srx_stx_open ; r4 = baud rate srx_stx_open: sts 0x099, r24 ; set baud rate ldi r16, 0x00 ; high baud rate = 0 sts 0x0098, r16 lds r16, 0x9A ori r16, 0x18 ; TX and RX enable sts 0x9A, r16 ; in r16, DDRD ; set data direction andi r16, 0xFB ; ori r16, 0x08 ; out DDRD, r16 ; nop ; lds r16, 0x9C ; read char ret ; ;------------------------------------------------------------------------- ; global function srx_stx_close srx_stx_close: lds r16, 0x9A andi r16, 0xE7 ;TX and RX disable sts 0x9A, r16 in r16, DDRD ; set data direction andi r16, 0xF3 out DDRD, r16 nop ret ;------------------------------------------------------------------------- ; global function stx_char stx_char: wdr lds r18, 0x9B sbrs r18, 5 ; wait for txempty rjmp stx_char sts 0x9C, r24 ; send char ret ;------------------------------------------------------------------------- ; global function srx_char srx_char: lds r24, 0x9C ; read char ret ;------------------------------------------------------------------------- ; global function srx_ready srx_ready: ser r24 lds r18, 0x9B sbrc r18, 7 clr r24 ret ;------------------------------------------------------------------------- ; global function stx_ready stx_ready: ser r24 lds r18, 0x9B sbrc r18, 5 clr r24 ret ;------------------------------------------------------------------------- ; global function erx_etx_open ; r4 = baud rate erx_etx_open: out 0x09, r24 ; set baud rate ldi r16, 0x00 ; high baud rate = 0 sts 0x0090, r16 in r16, 0x0A ori r16, 0x18 ; TX and RX enable out 0x0A, r16 ; in r16, 0x02 ; set data direction andi r16, 0xFE ; ori r16, 0x02 ; out 0x02, r16 ; nop ; in r16, 0x0C ; read char ret ; ;------------------------------------------------------------------------- ; global function erx_etx_close erx_etx_close: in r16, 0x0A andi r16, 0xE7 ;TX and RX disable out 0x0A, r16 in r16, 0x02 ; set data direction andi r16, 0xFC out 0x02, r16 nop ret ;------------------------------------------------------------------------- ; global function etx_char etx_char: wdr sbis 0x0B, 5 ; wait for txempty rjmp stx_char out 0x0C, r24 ; send char ret ;------------------------------------------------------------------------- ; global function erx_char erx_char: in r16, 0x0C ; read char ret ;------------------------------------------------------------------------- ; global function erx_ready erx_ready: ser r24 sbic 0x0B, 7 clr r24 ret ;------------------------------------------------------------------------- ; global function etx_ready etx_ready: ser r24 sbic 0x0B, 5 clr r24 ret ;------------------------------------------------------------------------- ; global function led0_on led0_on: lds r16,PORTG andi r16,0xF7 ; reset bit 3 sts PORTG,r16 lds r16,DDRG ori r16,0x08 ; set bit 3 sts DDRG,r16 ret ;------------------------------------------------------------------------- ; global function led1_on led1_on: lds r16,PORTG andi r16,0xEF ; reset bit 4 sts PORTG,r16 lds r16,DDRG ori r16,0x10 ; set bit 4 sts DDRG,r16 ret ;------------------------------------------------------------------------- ; global function led0_off led0_off: lds r16,PORTG ori r16,0x08 ; set bit 3 sts PORTG,r16 lds r16,DDRG ori r16,0x08 ; set bit 3 sts DDRG,r16 ret ;------------------------------------------------------------------------- ; global function led1_off led1_off: lds r16,PORTG ori r16,0x10 ; set bit 4 sts PORTG,r16 lds r16,DDRG ori r16,0x10 ; set bit 4 sts DDRG,r16 ret