--- /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
+