terom@3: .nolist terom@3: .include "m168def.inc" ; Same family as 328P terom@3: .list terom@3: terom@32: terom@3: ;; Interrupt Vector terom@3: .org 0x00 terom@3: rjmp init terom@3: terom@18: .org OC1Aaddr terom@30: ; Timer/Counter1 Compare Output A terom@18: rjmp Timer_OC1A terom@18: terom@30: .org OC0Aaddr terom@30: ; Timer/Counter0 Compare Output A terom@30: rjmp Timer_OC0A terom@30: terom@3: .org SPIaddr terom@3: rjmp SPI_Interrupt terom@3: terom@8: .org ADCCaddr terom@8: rjmp ADC_Interrupt terom@8: terom@23: .org 0x40 terom@23: terom@23: ;; Syntax terom@23: .include "macros.inc" terom@23: terom@3: ;; SPI terom@17: .include "spi.inc" terom@3: terom@3: ;; LCD terom@17: .include "led7seg.inc" terom@3: terom@28: ;; DIPs terom@28: .include "dip.inc" terom@28: terom@8: ;; ADC terom@32: terom@32: ; ADC Interrupt handler terom@32: On_ADC: terom@32: ; DEBUG terom@32: sbi PIND, PORTD7 terom@32: terom@32: ; Check timer, from r16 terom@32: rcall ADC_Read8 terom@32: terom@32: ldi r17, 64 terom@32: mul r16, r17 terom@32: mov XL, r0 terom@32: mov XH, r1 terom@32: terom@32: rjmp Timer_Update terom@32: terom@32: .set ADC_Handler = On_ADC terom@32: terom@17: .include "adc.inc" terom@8: terom@18: ;; Timer terom@30: .set TIMER0_CB_A = SPI_Update terom@30: terom@18: .include "timer.inc" terom@18: terom@17: ;; Utils terom@17: .include "delay.inc" terom@25: .include "div.inc" terom@7: terom@25: Sleep_ADC: terom@25: ; delay terom@32: rcall ADC_Read8 terom@32: ; rcall DIP_Read8 terom@25: terom@25: ; Sleep for 64 * var timer cycles terom@25: ldi r17, 64 terom@25: mul r16, r17 terom@25: mov XL, r0 terom@25: mov XH, r1 terom@25: terom@25: rjmp Timer_Sleep terom@25: terom@28: ;; Show value terom@28: Main_ShowValue: terom@25: ; load value to r16 terom@30: ; rcall DIP_Read8 terom@32: rcall ADC_Read8 terom@32: ; rcall Timer0_Read8 terom@25: terom@25: ; display from r16 terom@25: rcall LED7_ShowHex terom@25: terom@30: ; wait terom@30: rcall Sleep_ADC terom@30: terom@30: ; ldi XL, 0 terom@30: ; ldi XH, 16 terom@30: ; rcall Timer_Sleep terom@30: terom@30: ; rcall ADC_Read8 terom@30: ; mov r20, r16 terom@30: ; rcall VarDelay terom@25: terom@25: ; continue terom@28: rjmp Main_ShowValue terom@25: terom@25: ;; Count down from F terom@6: ; Returns once we've hit zero terom@6: Main_Countdown: terom@16: ; init from F terom@17: ldi r24, LED7_F terom@6: terom@15: _count_loop: terom@6: ; display terom@6: mov r16, r24 terom@25: mov r16, r24 terom@17: rcall LED7_Show terom@6: terom@6: ; exit if zero terom@6: tst r24 terom@15: breq _count_end terom@6: terom@6: ; count down terom@6: dec r24 terom@6: terom@6: ; wait... terom@25: rcall Sleep_ADC terom@6: terom@6: ; next terom@15: rjmp _count_loop terom@15: terom@15: _count_end: terom@15: ; done terom@15: ret terom@6: terom@25: ;; Count up from 00 -> 255 terom@25: ; Returns once done terom@25: Main_CountUp: terom@25: ; init from 0 terom@25: ldi r24, 0 terom@25: terom@25: _countup_loop: terom@25: ; display terom@25: mov r16, r24 terom@25: rcall LED7_ShowDec terom@25: terom@25: ; wait... terom@25: rcall Sleep_ADC terom@25: terom@25: ; exit if zero terom@25: cpi r24, 255 terom@25: breq _countup_end terom@25: terom@25: ; count up terom@25: inc r24 terom@25: terom@25: ; continue terom@25: rjmp _countup_loop terom@25: terom@25: _countup_end: terom@25: ; done terom@25: ret terom@25: terom@6: ;; Blink between dot and empty terom@6: Main_Blink: terom@6: _blink_loop: terom@6: ; dot terom@17: ldi r16, LED7_DOT terom@25: ldi r17, LED7_EMPTY terom@17: rcall LED7_Show terom@6: terom@6: ; wait... terom@25: rcall Sleep_ADC terom@6: terom@6: ; empty terom@17: ldi r16, LED7_EMPTY terom@25: ldi r17, LED7_DOT terom@17: rcall LED7_Show terom@6: terom@25: ; wait... terom@25: rcall Sleep_ADC terom@6: terom@6: ; loop terom@6: rjmp _blink_loop terom@6: terom@6: ;; Chase segments terom@6: Main_Spin: terom@6: _spin_init: terom@6: ; init from top terom@6: ldi r24, 0b00000001 terom@6: terom@6: _spin_next: terom@6: ; display terom@6: mov r16, r24 terom@23: mov r17, r24 terom@23: com r17 terom@32: andi r17, 0b00111111 terom@17: rcall LED7_ShowRaw terom@6: terom@18: ; delay terom@25: rcall Sleep_ADC terom@25: terom@6: ; next segment terom@6: lsl r24 terom@6: terom@6: ; go back to A if we hit G terom@6: sbrc r24, 6 terom@6: rjmp _spin_init terom@6: terom@6: rjmp _spin_next terom@4: terom@4: Main: terom@3: init: terom@3: ; Stack terom@3: ldi r16, high(RAMEND) terom@3: ldi r17, low(RAMEND) terom@3: out SPH, r16 terom@3: out SPL, r17 terom@3: terom@3: ; Enable interrupts terom@3: sei terom@3: terom@8: ; ADC (slowest to start up) terom@23: rcall ADC_Init terom@18: terom@18: ; Timer terom@18: rcall Timer_Init terom@8: terom@3: ; SPI terom@3: rcall SPI_Init terom@3: terom@8: ; LCD (requires interrupts, blocks) terom@17: rcall LED7_Init terom@6: terom@30: ; DEBUG terom@30: sbi DDRD, PORTD7 terom@30: cbi PORTD, PORTD7 terom@30: terom@6: ; Run terom@32: rcall Main_Countup terom@32: ; rcall Main_Countdown terom@30: ; rcall Main_ShowValue terom@32: ; rcall Main_Spin terom@32: rcall Main_Blink terom@4: terom@4: end: terom@4: rjmp end terom@4: