Created
April 19, 2012 22:24
-
-
Save erenon/2424618 to your computer and use it in GitHub Desktop.
Crossover
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;*************************************************************** | |
;* Feladat: Forgalmi jelzolampa fenyerzekelo ejszakai uzemmoddal | |
;* Rövid leírás: | |
; | |
;* Szerzők: Thaler Benedek EDDO10 | |
;* Mérőcsoport: CDU65 | |
; | |
;*************************************************************** | |
;* "AVR ExperimentBoard" port assignment information: | |
;*************************************************************** | |
;* | |
;* LED0(P):PortC.0 LED4(P):PortC.4 | |
;* LED1(P):PortC.1 LED5(P):PortC.5 | |
;* LED2(S):PortC.2 LED6(S):PortC.6 | |
;* LED3(Z):PortC.3 LED7(Z):PortC.7 INT:PortE.4 | |
;* | |
;* SW0:PortG.0 SW1:PortG.1 SW2:PortG.4 SW3:PortG.3 | |
;* | |
;* BT0:PortE.5 BT1:PortE.6 BT2:PortE.7 BT3:PortB.7 | |
;* | |
;*************************************************************** | |
;* | |
;* AIN:PortF.0 NTK:PortF.1 OPTO:PortF.2 POT:PortF.3 | |
;* | |
;*************************************************************** | |
;* | |
;* LCD1(VSS) = GND LCD9(DB2): - | |
;* LCD2(VDD) = VCC LCD10(DB3): - | |
;* LCD3(VO ) = GND LCD11(DB4): PortA.4 | |
;* LCD4(RS ) = PortA.0 LCD12(DB5): PortA.5 | |
;* LCD5(R/W) = GND LCD13(DB6): PortA.6 | |
;* LCD6(E ) = PortA.1 LCD14(DB7): PortA.7 | |
;* LCD7(DB0) = - LCD15(BLA): VCC | |
;* LCD8(DB1) = - LCD16(BLK): PortB.5 (1=Backlight ON) | |
;* | |
;*************************************************************** | |
.include "m128def.inc" ; Definition file for ATmega128 | |
;* Program Constants | |
.equ const =$00 ; Generic Constant Structure example | |
;* Program Variables Definitions | |
.def temp = r16 ; Temporary Register example | |
;*************************************************************** | |
;* Reset & Interrupt Vectors | |
.cseg | |
.org $0000 ; Define start of Code segment | |
jmp RESET ; Reset Handler, jmp is 2 word instruction | |
jmp DUMMY_IT ; Ext. INT0 Handler | |
jmp DUMMY_IT ; Ext. INT1 Handler | |
jmp DUMMY_IT ; Ext. INT2 Handler | |
jmp DUMMY_IT ; Ext. INT3 Handler | |
jmp DUMMY_IT ; Ext. INT4 Handler (INT gomb) | |
jmp DUMMY_IT ; Ext. INT5 Handler | |
jmp DUMMY_IT ; Ext. INT6 Handler | |
jmp DUMMY_IT ; Ext. INT7 Handler | |
jmp DUMMY_IT ; Timer2 Compare Match Handler | |
jmp DUMMY_IT ; Timer2 Overflow Handler | |
jmp DUMMY_IT ; Timer1 Capture Event Handler | |
jmp DUMMY_IT ; Timer1 Compare Match A Handler | |
jmp DUMMY_IT ; Timer1 Compare Match B Handler | |
jmp DUMMY_IT ; Timer1 Overflow Handler | |
jmp TIMER_IT ; Timer0 Compare Match Handler | |
jmp DUMMY_IT ; Timer0 Overflow Handler | |
jmp DUMMY_IT ; SPI Transfer Complete Handler | |
jmp DUMMY_IT ; USART0 RX Complete Handler | |
jmp DUMMY_IT ; USART0 Data Register Empty Hanlder | |
jmp DUMMY_IT ; USART0 TX Complete Handler | |
jmp ADC_IT ; ADC Conversion Complete Handler | |
jmp DUMMY_IT ; EEPROM Ready Hanlder | |
jmp DUMMY_IT ; Analog Comparator Handler | |
jmp DUMMY_IT ; Timer1 Compare Match C Handler | |
jmp DUMMY_IT ; Timer3 Capture Event Handler | |
jmp DUMMY_IT ; Timer3 Compare Match A Handler | |
jmp DUMMY_IT ; Timer3 Compare Match B Handler | |
jmp DUMMY_IT ; Timer3 Compare Match C Handler | |
jmp DUMMY_IT ; Timer3 Overflow Handler | |
jmp DUMMY_IT ; USART1 RX Complete Handler | |
jmp DUMMY_IT ; USART1 Data Register Empty Hanlder | |
jmp DUMMY_IT ; USART1 TX Complete Handler | |
jmp DUMMY_IT ; Two-wire Serial Interface Handler | |
jmp DUMMY_IT ; Store Program Memory Ready Handler | |
.org $0046 | |
;**************************************************************** | |
;* DUMMY_IT interrupt handler -- CPU hangup with LED pattern | |
;* (This way unhandled interrupts will be noticed) | |
;< többi IT kezelő a fájl végére! > | |
DUMMY_IT: | |
ldi r16, 0xFF ; LED pattern: *- | |
out DDRC, r16 ; -* | |
ldi r16, 0xA5 ; *- | |
out PORTC, r16 ; -* | |
DUMMY_LOOP: | |
rjmp DUMMY_LOOP ; endless loop | |
;< többi IT kezelő a fájl végére! > | |
;*************************************************************** | |
;* MAIN program, Initialisation part | |
.org $004B; | |
RESET: | |
;* Stack Pointer init, | |
; Set stack pointer to top of RAM | |
ldi temp, LOW(RAMEND) ; RAMEND = "max address in RAM" | |
out SPL, temp ; RAMEND value in "m128def.inc" | |
ldi temp, HIGH(RAMEND) | |
out SPH, temp | |
M_INIT: | |
;< ki- és bemenetek inicializálása stb > | |
; init LEDs as output | |
ldi temp, 0xFF ; every led is output | |
out DDRC, temp | |
; led status register -- state of the leds | |
.equ ST_BLANK = 0b00000000 ; all off | |
.equ ST_YY = 0b00100010 ; two yellows | |
.equ ST_RR = 0b11001100 ; two reds | |
.equ ST_YRR = 0b11101100 ; A: yellow and red, B: red | |
.equ ST_GR = 0b00011100 ; A: green, B: red | |
.equ ST_YR = 0b00101100 ; A: yellow, B: red | |
.equ ST_RYR = 0b11001110 ; A: red, B: yellow and red | |
.equ ST_RG = 0b11000001 ; A: red, B: green | |
.equ ST_RY = 0b11000010 ; A: red, B: yellow | |
.def ledStatus = r17 | |
ldi ledStatus, ST_BLANK ; initial state: all leds are off | |
; init ADC - photo resistor | |
ldi temp, 0b01100011 ; ADMUX: 5V ref, left aligned, photo | |
; 01...... ; REFS = 01 (ref voltage: 5V VCC) | |
; ..1..... ; ADLAR = 1 (left aligned) | |
; ...00010 ; ADMUX = 00011 (photo resistor) | |
out ADMUX, temp | |
ldi temp, 0b11101111 ; ADCSRA: cont. running, IT, 128 prescale | |
; 1....... ; ADEN = 1 (enable A/D) | |
; .1...... ; ADSC = 1 (start conversion) | |
; ..1..... ; ADFR = 1 (free running) | |
; ...0.... ; ADIF (don't clear the IT flag) | |
; ....1... ; ADIE = 1 (enable IT) | |
; .....111 ; ADPS = 111 (128 prescale) | |
out ADCSRA, temp | |
.equ ADC_DAYLIGHT_LIMIT = 0b01111111 | |
; end ADC | |
; init TIMER0 | |
ldi temp, 107 ; value to compare (0?107 = 108) | |
out OCR0, temp | |
ldi temp, 0b00001111 ; TCCR0: CTC mode, 1024 prescale | |
; 0.00.... ; FOC=0 COM=00 (block output) | |
; .0..1... ; WGM=10 (CTC mode) | |
; .....111 ; CS0=111 (CLK/1024) | |
out TCCR0, temp | |
ldi temp, 0b00000010 ; TIMSK: enable Output Compare Match IT | |
; ......1. ; OCIE0=1: interrupt if TCNT0 == OCR0 | |
; .......0 ; TOIE0=0 (no IT on overflow) | |
out TIMSK, temp | |
; end TIMER0 | |
; init Timer signals | |
; Timer Status variables | |
; lower parts | |
.equ TSL_ONE_SEC = 0b01100100 ; wait 100 * 10 milliseconds | |
.equ TSL_TWO_SEC = 0b11001000 ; wait 200 * 10 milliseconds | |
.equ TSL_THIRTY_SEC = 0b10111000; wait 3000 * 10 miliseconds, uses upper part | |
; upper parts | |
.equ TSU_ONE_SEC = 0b00000001 | |
.equ TSU_TWO_SEC = 0b00000001 | |
.equ TSU_THIRTY_SEC = 0b00001100 | |
.def tick = r18 ; tick: TIMER_IT uses this to signal logical timeout | |
.def remainingTimerITCountUp = r19 ; count of the remaining TIMER_IT to the next tick [Upper part] | |
.def remainingTimerITCountLow = r20 ; count of the remaining TIMER_IT to the next tick [Lower part] | |
ldi tick, 0 ; no tick initially | |
ldi remainingTimerITCountUp, TSU_ONE_SEC ; wait one second in the initial state [Upper part] | |
ldi remainingTimerITCountLow, TSL_ONE_SEC ; wait one second in the initial state [Lower part] | |
; end Timer signals | |
sei ; enable global IT | |
;*************************************************************** | |
;* MAIN program, Endless loop part | |
M_LOOP: | |
out PORTC, ledStatus ; show status on leds | |
tst tick ; is there any tick? | |
breq M_LOOP | |
ldi tick, 0 ; clear tick | |
; if we got here, there was a tick | |
; advance status | |
cpi ledStatus, ST_BLANK | |
breq M_CASE_BLANK | |
cpi ledStatus, ST_YY | |
breq M_CASE_yy | |
cpi ledStatus, ST_RR | |
breq M_CASE_RR | |
cpi ledStatus, ST_YRR | |
breq M_CASE_YRR | |
cpi ledStatus, ST_GR | |
breq M_CASE_GR | |
cpi ledStatus, ST_YR | |
breq M_CASE_YR | |
cpi ledStatus, ST_RYR | |
breq M_CASE_RYR | |
cpi ledStatus, ST_RG | |
breq M_CASE_RG | |
cpi ledStatus, ST_RY | |
breq M_CASE_RY | |
; shouldn't get here | |
jmp DUMMY_IT | |
M_CASE_BLANK: | |
call SET_ST_YY | |
jmp M_CASE_END | |
M_CASE_YY: | |
call SET_ST_BLANK | |
jmp M_CASE_END | |
M_CASE_RR: | |
call SET_ST_YRR | |
jmp M_CASE_END | |
M_CASE_YRR: | |
call SET_ST_GR | |
jmp M_CASE_END | |
M_CASE_GR: | |
call SET_ST_YR | |
jmp M_CASE_END | |
M_CASE_YR: | |
call SET_ST_RYR | |
jmp M_CASE_END | |
M_CASE_RYR: | |
call SET_ST_RG | |
jmp M_CASE_END | |
M_CASE_RG: | |
call SET_ST_RY | |
jmp M_CASE_END | |
M_CASE_RY: | |
call SET_ST_YRR | |
jmp M_CASE_END | |
M_CASE_END: | |
jmp M_LOOP ; Endless Loop | |
;*************************************************************** | |
;* Subroutines, Interrupt routines | |
ADC_IT: | |
; save state | |
push temp | |
in temp, SREG | |
push temp | |
in temp, ADCH ; load converted value | |
; check for daylight | |
cpi temp, ADC_DAYLIGHT_LIMIT ; subtrac daylight limit from current | |
brge ADC_DAYLIGHT ; branch if greater or equal | |
; TODO | |
; enable ADC interrupt | |
ADC_DARKNESS: ; change to darkness if prev. status is not darkness | |
cpi ledStatus, ST_BLANK ; is status blank? | |
breq ADC_END | |
cpi ledStatus, ST_YY ; is status two yellows? | |
breq ADC_END | |
; if we are still here, the previous status is daylight | |
; let's change it to darkness | |
call SET_ST_BLANK | |
jmp ADC_END | |
ADC_DAYLIGHT: ; change to daylight if prev. status is darkness | |
cpi ledStatus, ST_BLANK ; is status blank? | |
breq ADC_CHANGE_TO_DAYLIGHT | |
cpi ledStatus, ST_YY ; is status two yellow? | |
breq ADC_CHANGE_TO_DAYLIGHT | |
; if we are still here, the previous status is daylight as well | |
; we have nothing to do here | |
jmp ADC_END | |
ADC_CHANGE_TO_DAYLIGHT: | |
; if we are get here, we should change to daylight | |
call SET_ST_RR | |
ADC_END: | |
; restore state | |
pop temp | |
out SREG, temp | |
pop temp | |
reti | |
TIMER_IT: | |
; save state | |
push temp | |
in temp, SREG | |
push temp | |
dec remainingTimerITCountLow ; decrement remaining IT count, lower part | |
brne TIMER_IT_END ; jump if there are remaining IT count in the lower part | |
; if we get here, we should decrement the upper part | |
ldi remainingTimerITCountLow, 0xFF ; rearm lower part | |
dec remainingTimerITCountUp ; decrement remaining IT count, upper part | |
brne TIMER_IT_END ; jump if there are remaining IT count in the upper part | |
; if we get here, it's a tick | |
ldi tick, 1 ; signal to the M_LOOP | |
; don't rearm remainingTimerITCount here | |
; the status change will do it | |
TIMER_IT_END: | |
; restore state | |
pop temp | |
out SREG, temp | |
pop temp | |
reti | |
; TODO doublecheck timing | |
SET_ST_BLANK: | |
ldi ledStatus, ST_BLANK | |
ldi remainingTimerITCountUp, TSU_ONE_SEC | |
ldi remainingTimerITCountLow, TSL_ONE_SEC | |
ret | |
SET_ST_YY: | |
ldi ledStatus, ST_YY | |
ldi remainingTimerITCountUp, TSU_ONE_SEC | |
ldi remainingTimerITCountLow, TSL_ONE_SEC | |
ret | |
SET_ST_RR: | |
ldi ledStatus, ST_RR | |
ldi remainingTimerITCountUp, TSU_TWO_SEC | |
ldi remainingTimerITCountLow, TSL_TWO_SEC | |
ret | |
SET_ST_YRR: | |
ldi ledStatus, ST_YRR | |
ldi remainingTimerITCountUp, TSU_ONE_SEC | |
ldi remainingTimerITCountLow, TSL_ONE_SEC | |
SET_ST_GR: | |
ldi ledStatus, ST_GR | |
ldi remainingTimerITCountUp, TSU_THIRTY_SEC | |
ldi remainingTimerITCountLow, TSL_THIRTY_SEC | |
SET_ST_YR: | |
ldi ledStatus, ST_YR | |
ldi remainingTimerITCountUp, TSU_TWO_SEC | |
ldi remainingTimerITCountLow, TSL_TWO_SEC | |
SET_ST_RYR: | |
ldi ledStatus, ST_RYR | |
ldi remainingTimerITCountUp, TSU_ONE_SEC | |
ldi remainingTimerITCountLow, TSL_ONE_SEC | |
SET_ST_RG: | |
ldi ledStatus, ST_RG | |
ldi remainingTimerITCountUp, TSU_THIRTY_SEC | |
ldi remainingTimerITCountLow, TSL_THIRTY_SEC | |
SET_ST_RY: | |
ldi ledStatus, ST_RY | |
ldi remainingTimerITCountUp, TSU_TWO_SEC | |
ldi remainingTimerITCountLow, TSL_TWO_SEC |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment