Skip to content

Instantly share code, notes, and snippets.

@erenon
Created April 19, 2012 22:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erenon/2424618 to your computer and use it in GitHub Desktop.
Save erenon/2424618 to your computer and use it in GitHub Desktop.
Crossover
;***************************************************************
;* 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