use timer for 1s delay
authorTero Marttila <terom@fixme.fi>
Sat, 08 May 2010 17:27:27 +0300
changeset 18 79b25e81721f
parent 17 a7c668003a19
child 19 1e00790c5029
use timer for 1s delay
.hgignore
Makefile
adc.inc
console.s
led7seg.inc
led7seg.s
macros.inc
spi.inc
timer.inc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Sat May 08 17:27:27 2010 +0300
@@ -0,0 +1,7 @@
+syntax: regexp
+
+
+\.(swo|swp)$
+\.(hex|s.cof|s.eep.hex|s.obj)$
+
+^docs/
--- a/Makefile	Sat May 08 16:00:18 2010 +0300
+++ b/Makefile	Sat May 08 17:27:27 2010 +0300
@@ -11,7 +11,7 @@
 
 PROG = led7seg
 
-led7seg.hex: spi.inc led7seg.inc adc.inc delay.inc
+led7seg.hex: spi.inc led7seg.inc adc.inc timer.inc delay.inc
 
 all: $(PROG).hex
 
--- a/adc.inc	Sat May 08 16:00:18 2010 +0300
+++ b/adc.inc	Sat May 08 17:27:27 2010 +0300
@@ -1,3 +1,7 @@
+;;
+;; Basic ADC operation
+;;
+
 .equ ADC_DDR    = DDRC
 .equ ADC_PORT   = PORTC
 .equ ADC_PIN    = PORTC0
--- a/console.s	Sat May 08 16:00:18 2010 +0300
+++ b/console.s	Sat May 08 17:27:27 2010 +0300
@@ -2,22 +2,7 @@
 .include "m168def.inc"      ; Same family as 328P
 .list
 
-.macro poke
-		.message	"No parameters"
-.endm
-
-.macro poke_i_8_i
-		ldi			@1, @2
-		sts			@0, @1
-.endm
-
-.macro poke_i_16_i
-		ldi			@1, low(@3)
-		sts			@0+0, @1
-		
-		ldi			@2, high(@3)
-		sts			@0+1, @2
-.endm
+.include "macros.inc"
 
 ;; Load a 16-bit *word* address into the given register a a byte address
 .macro loadp_16_i
--- a/led7seg.inc	Sat May 08 16:00:18 2010 +0300
+++ b/led7seg.inc	Sat May 08 17:27:27 2010 +0300
@@ -1,8 +1,14 @@
+;;
+;; Driving 7-segment LED displays over SPI
+;;
+
+; Output Enable control
 .equ LED7_DDR    = DDRB
 .equ LED7_PORT   = PORTB
 .equ LED7_OE     = PORTB1                ; Output Enable (Low)
 
-; Output font for 7-segment display
+; Font for 7-segment display
+; Includes decimal digits 0-9, hexadecimal digits A-F, and some special chars
 LED7_Font:
 .db     0b00111111, 0b00000110      ; 0, 1
 .db     0b01011011, 0b01001111      ; 2, 3
--- a/led7seg.s	Sat May 08 16:00:18 2010 +0300
+++ b/led7seg.s	Sat May 08 17:27:27 2010 +0300
@@ -6,6 +6,10 @@
 .org 0x00
         rjmp        init
 
+.org OC1Aaddr
+		; Timer/Counter1 Overflow
+		rjmp		Timer_OC1A
+
 .org SPIaddr
         rjmp        SPI_Interrupt
 
@@ -21,6 +25,9 @@
 ;; ADC
 .include "adc.inc"
 
+;; Timer
+.include "timer.inc"
+
 ;; Utils
 .include "delay.inc"
 
@@ -82,18 +89,8 @@
         mov         r16, r24
         rcall       LED7_ShowRaw
 
-        ; delay from ADC
-        ;rcall       ADC_Read8
-        ;mov         r20, r16
-
-        ; delay from input
-        mov         r20, r10
-        
-        ; constant
-        ;ldi         r20, 20
-
-        ; short delay
-        rcall       VarDelay
+        ; delay
+        rcall       Timer_Sleep_1s
 
         ; next segment
         lsl         r24
@@ -117,6 +114,9 @@
 
     ; ADC (slowest to start up)
         ; rcall       ADC_Init
+    
+    ; Timer
+        rcall       Timer_Init
 
     ; SPI
         rcall       SPI_Init
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/macros.inc	Sat May 08 17:27:27 2010 +0300
@@ -0,0 +1,22 @@
+; XXX: stupid thing won't parse, and it's right from the README example...
+; .ifndef _MACROS_INC_
+; .define _MACROS_INC_
+
+.macro poke
+		.message	"No parameters"
+.endm
+
+.macro poke_i_8_i
+		ldi			@1, @2
+		sts			@0, @1
+.endm
+
+.macro poke_i_16_i
+		ldi			@1, low(@3)
+		sts			@0+0, @1
+		
+		ldi			@2, high(@3)
+		sts			@0+1, @2
+.endm
+
+; .endif
--- a/spi.inc	Sat May 08 16:00:18 2010 +0300
+++ b/spi.inc	Sat May 08 17:27:27 2010 +0300
@@ -1,6 +1,8 @@
 ;; vim: filetype=avr
+;;
+;; SPI interface control and use
+;;
 
-;; SPI
 .equ SPI_DDR    = DDRB
 .equ SPI_PORT   = PORTB
 .equ SPI_SCK    = PORTB5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/timer.inc	Sat May 08 17:27:27 2010 +0300
@@ -0,0 +1,93 @@
+;; vim: filetype=avr
+;;
+;; Timer unit control and use
+;;
+
+.include "macros.inc"
+
+; Waveform Generation Mode (nibble low/high)
+.set TIMER_WGML = 0b00
+.set TIMER_WGMH = 0b01
+
+; Clock Source
+.set TIMER_CS = 0b101
+
+.equ TIMER_FLAGS  = GPIOR0
+.equ TIMER_BUSY   = 1
+
+Timer_Init:
+		; OC1A/B disconnected from output
+		; No PWM mode
+		poke		[TCCR1A, r16, (0b00 << COM1A0) | (0b00 << COM1B0) | (TIMER_WGML << WGM10)]
+
+		; Clear
+		poke		[TCCR1B, r16, 0]
+		poke		[TCCR1C, r16, 0]
+
+		; Enable timer overflow interrupt
+		poke		[TIMSK1, r16, (1 << OCIE1A)]
+		
+		ret
+
+Timer_Start:
+	; Initialize timer
+		poke		[TCNT1H, r16, high(0)]
+		poke		[TCNT1L, r16, low(0)]
+
+	; Set flag
+		sbi			TIMER_FLAGS, TIMER_BUSY
+
+		; WGM
+		; Clock Source
+		poke		[TCCR1B, r16, (TIMER_WGMH << WGM12) | (TIMER_CS << CS10)]
+
+		ret
+
+Timer_Stop:
+		; WGM
+		; Clock off
+		poke		[TCCR1B, r16, (TIMER_WGMH << WGM12) | (0b00 << CS10)]
+		
+	; Clear flag
+		cbi			TIMER_FLAGS, TIMER_BUSY
+
+		ret
+
+;; Timer Compare 1A interrupt handler
+Timer_OC1A:
+		in			r0, SREG
+	
+	; Stop timer
+		rcall		Timer_Stop
+
+		out			SREG, r0
+		reti
+
+;; Count to X
+Timer_Sleep:
+	; Set TOP
+		sts			OCR1AH, XH
+		sts			OCR1AL, XL
+
+	; Start timer
+		rcall		Timer_Start
+
+	; Wait for timer to complete
+_timer_sleep:
+		;sleep
+
+		sbic		TIMER_FLAGS, TIMER_BUSY
+		rjmp		_timer_sleep
+		
+	; Done
+		ret
+
+;; Prime the timer and sleep for 1s
+Timer_Sleep_1s:
+	; Initialize counter to 16k cycles
+		ldi			XH, high(16 * 1024)
+		ldi			XL, low(16 * 1024)
+
+	; Start timer
+		rjmp		Timer_Sleep
+