split led7seg.s into .inc modules, and update Makefile to use .s -> .hex, and above .inc's for led7seg
authorTero Marttila <terom@fixme.fi>
Sat, 08 May 2010 16:00:18 +0300
changeset 17 a7c668003a19
parent 16 11d6167a67cb
child 18 79b25e81721f
split led7seg.s into .inc modules, and update Makefile to use .s -> .hex, and above .inc's for led7seg
Makefile
adc.inc
delay.inc
led7seg.inc
led7seg.s
spi.inc
--- a/Makefile	Sat May 08 15:13:45 2010 +0300
+++ b/Makefile	Sat May 08 16:00:18 2010 +0300
@@ -4,20 +4,23 @@
 AD_PART = m328p
 AD_PROG = arduino
 AD_BAUD = 57600
-AD_PORT = /dev/ttyUSB1
+AD_PORT = /dev/ttyUSB0
 
 AD = avrdude
 ADFLAGS = -p $(AD_PART) -c $(AD_PROG) -b $(AD_BAUD) -P $(AD_PORT)
 
-PROG = console
-
-all: $(PROG).s.hex
+PROG = led7seg
 
-%.s.hex: %.s
+led7seg.hex: spi.inc led7seg.inc adc.inc delay.inc
+
+all: $(PROG).hex
+
+%.hex: %.s
 	$(AS) $(ASFLAGS) $<
+	mv $<.hex $@
 
-upload: $(PROG).s.hex
-	$(AD) $(ADFLAGS) -U flash:w:$(PROG).s.hex
+upload: $(PROG).hex
+	$(AD) $(ADFLAGS) -U flash:w:$<
 
 SERIAL_BAUD = 9600
 SERIAL_FLOW = n
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adc.inc	Sat May 08 16:00:18 2010 +0300
@@ -0,0 +1,55 @@
+.equ ADC_DDR    = DDRC
+.equ ADC_PORT   = PORTC
+.equ ADC_PIN    = PORTC0
+        
+;; Initialize the ADC for starting conversions
+ADC_Init:
+    ; Setup ADMUX
+        ; Use AVcc as ref
+        ; Left-adjust result (for 8-bit access)
+        ; Select ADC0
+        ldi         r16, (0b01 << REFS0) | (1 << ADLAR) | (0b000 << MUX0)
+        sts         ADMUX, r16
+    
+    ; Setup ADCSRB
+        ; Free-running mode
+        ldi         r16, (0b000 << ADTS0)
+        sts         ADCSRB, r16
+
+    ; Setup ADCSRA
+        ; Enable
+        ; Start right away...
+        ; Auto-trigger
+        ; Enable Interrupt
+        ; Scale 1/128
+        ldi         r16, (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (1 << ADIE) | (0b111 << ADPS0)
+        sts         ADCSRA, r16
+
+    ; Disable digital circuit for pin
+        ldi         r16, (1 << ADC_PIN)
+        sts         DIDR0, r16
+
+    ; Debug LED
+        sbi         DDRD, PORTD7
+        sbi         PORTD, PORTD7
+
+    ; Done
+        ret
+
+ADC_Interrupt:
+    ; Off
+        cbi         PORTD, PORTD7
+    
+    ; Done
+        reti    
+
+;; Read the current 8-bit ADC sample 
+; Returns value in r16
+ADC_Read8:
+    ; Copy
+        lds         r16, ADCH
+
+    ; Done
+        ret
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/delay.inc	Sat May 08 16:00:18 2010 +0300
@@ -0,0 +1,36 @@
+;;
+;; Busy-loop delays
+;;
+
+;; Delay for approx. one second
+Delay_1s:
+        ; ~16M cycles
+        ldi         r20, 82
+        rjmp        delay_init
+
+;; Delay for a variable amount of time, adjusted by r20
+; Input: r20 controls number of delay loops
+VarDelay:
+        tst         r20
+        breq        delay_out
+
+delay_init:
+        ldi         r21, 255
+
+delay_loop:
+        ; 254 * (1 + 2) + 1 * (1 + 1) = 764 cycles / loop
+        dec         r22             
+        brne        delay_loop
+
+        ; 254 * 764 + 764 = 194820 cycles / loop
+        dec         r21             ;  1 * r20 * r21
+        brne        delay_loop      ;  2 * r20 * r21
+        
+        ; r20 * 194820 + r20 * 3 = 194823 cycles / loop (r20)
+        dec         r20             ;  1 * r20 
+        brne        delay_loop      ;  2 * r20
+
+delay_out:
+        ret
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/led7seg.inc	Sat May 08 16:00:18 2010 +0300
@@ -0,0 +1,96 @@
+.equ LED7_DDR    = DDRB
+.equ LED7_PORT   = PORTB
+.equ LED7_OE     = PORTB1                ; Output Enable (Low)
+
+; Output font for 7-segment display
+LED7_Font:
+.db     0b00111111, 0b00000110      ; 0, 1
+.db     0b01011011, 0b01001111      ; 2, 3
+.db     0b01100110, 0b01101101      ; 4, 5
+.db     0b01111101, 0b00000111      ; 6, 7
+.db     0b01111111, 0b01100111      ; 8, 9
+.db     0b01110111, 0b01111100      ; A, b
+.db     0b00111001, 0b01011110      ; C, d
+.db     0b01111001, 0b01110001      ; E, f
+.db     0b10000000, 0b00000000      ; ., 
+
+;.db     0b00111111,     ; 0
+;        0b00000110,     ; 1
+;        0b01011011,     ; 2
+;        0b01001111,     ; 3
+;        0b01100110,     ; 4
+;        0b01101101,     ; 5
+;        0b01111101,     ; 6
+;        0b00000111,     ; 7
+;        0b01111111,     ; 8
+;        0b01100111,     ; 9
+;        0b10000000,     ; .
+;        0b01000000      ; 
+
+.equ LED7_0      = 0
+.equ LED7_1      = 1
+.equ LED7_2      = 2
+.equ LED7_3      = 3
+.equ LED7_4      = 4
+.equ LED7_5      = 5
+.equ LED7_6      = 6
+.equ LED7_7      = 7
+.equ LED7_8      = 8
+.equ LED7_9      = 9
+.equ LED7_A      = 10
+.equ LED7_B      = 11
+.equ LED7_C      = 12
+.equ LED7_D      = 13
+.equ LED7_E      = 14
+.equ LED7_F      = 15
+.equ LED7_DOT    = 16
+.equ LED7_EMPTY  = 17
+
+;; Initialize LCD to empty, and enable
+LED7_Init:
+    ; Setup ENable port
+        sbi         LED7_PORT, LED7_OE    ; Disabled (Low)
+        sbi         LED7_DDR, LED7_OE     ; Out
+
+        ; empty
+        ldi         r16, 0b11111111
+
+    ; Output
+        rcall       SPI_SendRecv
+        rcall       SPI_Wait
+
+    ; Enable
+        cbi         LED7_PORT, LED7_OE
+
+    ; Done
+        ret
+
+;; Display a single digit on the display
+;;  Input: r16
+LED7_Show:
+        clr         r0, 0
+
+    ; Prep address
+        ; base addr for font table
+        ldi         ZH, high(2*LED7_Font)
+        ldi         ZL, low(2*LED7_Font)
+        
+        ; offset
+        add         ZL, r16
+        adc         ZH, r0
+
+    ; Load char
+        lpm         r16, Z
+    
+    ;; Continue
+
+;; Display a raw segment mask
+;;  Input: r16
+LED7_ShowRaw:
+    ; Invert
+        ; com         r16
+
+    ; Display
+        rjmp        SPI_SendRecv
+
+
--- a/led7seg.s	Sat May 08 15:13:45 2010 +0300
+++ b/led7seg.s	Sat May 08 16:00:18 2010 +0300
@@ -13,272 +13,27 @@
         rjmp        ADC_Interrupt
 
 ;; SPI
-.equ SPI_DDR    = DDRB
-.equ SPI_PORT   = PORTB
-.equ SPI_SCK    = PORTB5
-.equ SPI_MISO   = PORTB4
-.equ SPI_MOSI   = PORTB3
-.equ SPI_SS     = PORTB2
-
-.equ SPI_FLAGS  = GPIOR0
-.equ SPI_BUSY   = 0
-
-;; Initialize SPI subsystem for master operation
-SPI_Init:
-    ; Set modes
-        sbi         SPI_DDR, SPI_SCK        ; Out
-        sbi         SPI_DDR, SPI_MOSI       ; Out
-        sbi         SPI_DDR, SPI_SS         ; Out
-
-    ; Drive SS high (off)
-        sbi         SPI_PORT, SPI_SS
-
-    ; Set control mode
-        ; Enable interrupt
-        ; Enable SPI
-        ; MSB first
-        ; Master mode
-        ; Polarity/phase: Mode 0 (sample on rising edge)
-        ; Clock rate 1/16
-        ldi         r16, (1 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (0b01 << SPR0)
-        out         SPCR, r16
-    
-    ; Flags
-        clr         r0
-        out         SPI_FLAGS, r0
-    
-    ; Done
-        ret
-
-;; Send byte
-;;  Input: r16
-;;  XXX: should not be busy...
-SPI_SendRecv:
-    ; Flag
-        sbi         SPI_FLAGS, SPI_BUSY
-
-    ; Enable slave (low)
-        cbi         SPI_PORT, SPI_SS
-    
-    ; Write byte (starts SCK)
-        out         SPDR, r16
-    
-    ; Wait for interrupt
-    ; Done
-        ret
-
-;; Wait for byte to be sent
-SPI_Wait:
-wait_idle:
-        sbic        SPI_FLAGS, SPI_BUSY     ; Test for busy flag
-        rjmp        wait_idle               ; loop
-        
-    ; Done
-        ret
-
-;; Service SPI interrupt
-SPI_Interrupt:
-    ; Store SREG
-        in          r16, SREG
-
-    ; Drive SS high (off)
-        sbi         SPI_PORT, SPI_SS
-
-    ; Read
-        in         r10, SPDR
-
-    ; Flag
-        cbi         SPI_FLAGS, SPI_BUSY
-
-    ; Done
-        out         SREG, r16
-        reti
+.include "spi.inc"
 
 ;; LCD
-.equ LCD_DDR    = DDRB
-.equ LCD_PORT   = PORTB
-.equ LCD_OE     = PORTB1                ; Output Enable (Low)
-
-; Output font for 7-segment display
-LCD_Font:
-.db     0b00111111, 0b00000110      ; 0, 1
-.db     0b01011011, 0b01001111      ; 2, 3
-.db     0b01100110, 0b01101101      ; 4, 5
-.db     0b01111101, 0b00000111      ; 6, 7
-.db     0b01111111, 0b01100111      ; 8, 9
-.db     0b01110111, 0b01111100      ; A, b
-.db     0b00111001, 0b01011110      ; C, d
-.db     0b01111001, 0b01110001      ; E, f
-.db     0b10000000, 0b00000000      ; ., 
-
-;.db     0b00111111,     ; 0
-;        0b00000110,     ; 1
-;        0b01011011,     ; 2
-;        0b01001111,     ; 3
-;        0b01100110,     ; 4
-;        0b01101101,     ; 5
-;        0b01111101,     ; 6
-;        0b00000111,     ; 7
-;        0b01111111,     ; 8
-;        0b01100111,     ; 9
-;        0b10000000,     ; .
-;        0b01000000      ; 
-
-.equ LCD_0      = 0
-.equ LCD_1      = 1
-.equ LCD_2      = 2
-.equ LCD_3      = 3
-.equ LCD_4      = 4
-.equ LCD_5      = 5
-.equ LCD_6      = 6
-.equ LCD_7      = 7
-.equ LCD_8      = 8
-.equ LCD_9      = 9
-.equ LCD_A      = 10
-.equ LCD_B      = 11
-.equ LCD_C      = 12
-.equ LCD_D      = 13
-.equ LCD_E      = 14
-.equ LCD_F      = 15
-.equ LCD_DOT    = 16
-.equ LCD_EMPTY  = 17
-
-;; Initialize LCD to empty, and enable
-LCD_Init:
-    ; Setup ENable port
-        sbi         LCD_PORT, LCD_OE    ; Disabled (Low)
-        sbi         LCD_DDR, LCD_OE     ; Out
-
-        ; empty
-        ldi         r16, 0b11111111
-
-    ; Output
-        rcall       SPI_SendRecv
-        rcall       SPI_Wait
-
-    ; Enable
-        cbi         LCD_PORT, LCD_OE
-
-    ; Done
-        ret
-
-;; Display a single digit on the display
-;;  Input: r16
-LCD_Show:
-        clr         r0, 0
-
-    ; Prep address
-        ; base addr for font table
-        ldi         ZH, high(2*LCD_Font)
-        ldi         ZL, low(2*LCD_Font)
-        
-        ; offset
-        add         ZL, r16
-        adc         ZH, r0
-
-    ; Load char
-        lpm         r16, Z
-    
-    ;; Continue
-
-;; Display a raw segment mask
-;;  Input: r16
-LCD_ShowRaw:
-    ; Invert
-        ; com         r16
-
-    ; Display
-        rjmp        SPI_SendRecv
+.include "led7seg.inc"
 
 ;; ADC
-.equ ADC_DDR    = DDRC
-.equ ADC_PORT   = PORTC
-.equ ADC_PIN    = PORTC0
-        
-;; Initialize the ADC for starting conversions
-ADC_Init:
-    ; Setup ADMUX
-        ; Use AVcc as ref
-        ; Left-adjust result (for 8-bit access)
-        ; Select ADC0
-        ldi         r16, (0b01 << REFS0) | (1 << ADLAR) | (0b000 << MUX0)
-        sts         ADMUX, r16
-    
-    ; Setup ADCSRB
-        ; Free-running mode
-        ldi         r16, (0b000 << ADTS0)
-        sts         ADCSRB, r16
-
-    ; Setup ADCSRA
-        ; Enable
-        ; Start right away...
-        ; Auto-trigger
-        ; Enable Interrupt
-        ; Scale 1/128
-        ldi         r16, (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | (1 << ADIE) | (0b111 << ADPS0)
-        sts         ADCSRA, r16
-
-    ; Disable digital circuit for pin
-        ldi         r16, (1 << ADC_PIN)
-        sts         DIDR0, r16
-
-    ; Debug LED
-        sbi         DDRD, PORTD7
-        sbi         PORTD, PORTD7
-
-    ; Done
-        ret
+.include "adc.inc"
 
-ADC_Interrupt:
-    ; Off
-        cbi         PORTD, PORTD7
-    
-    ; Done
-        reti    
-
-;; Read the current 8-bit ADC sample 
-; Returns value in r16
-ADC_Read8:
-    ; Copy
-        lds         r16, ADCH
-
-    ; Done
-        ret
-
-;; Delay for approx. one second
-Delay_1s:
-        ; 40 * 64k = 2.6M loops
-        ldi         r20, 40
-
-;; Delay for r20 * 64k cycles
-VarDelay:
-        ldi         r21, 255
-
-;; Delay for r20 * r21 * 255 cycles
-ShortDelay:
-        ldi         r22, 255
-
-delay:
-        dec         r22
-        brne        delay
-        dec         r21
-        brne        delay
-        dec         r20
-        brne        delay
-
-        ret
-
+;; Utils
+.include "delay.inc"
 
 ;; Count down from 9
 ; Returns once we've hit zero
 Main_Countdown:
         ; init from F
-        ldi         r24, LCD_F
+        ldi         r24, LED7_F
 
 _count_loop:
         ; display
         mov         r16, r24
-        rcall       LCD_Show
+        rcall       LED7_Show
 
         ; exit if zero
         tst         r24
@@ -301,15 +56,15 @@
 Main_Blink:
 _blink_loop:
         ; dot
-        ldi         r16, LCD_DOT
-        rcall       LCD_Show
+        ldi         r16, LED7_DOT
+        rcall       LED7_Show
 
         ; wait...
         rcall       Delay_1s
         
         ; empty
-        ldi         r16, LCD_EMPTY
-        rcall       LCD_Show
+        ldi         r16, LED7_EMPTY
+        rcall       LED7_Show
         
         rcall       Delay_1s
         
@@ -325,9 +80,9 @@
 _spin_next:
         ; display
         mov         r16, r24
-        rcall       LCD_ShowRaw
+        rcall       LED7_ShowRaw
 
-        ; variable delay -> r16
+        ; delay from ADC
         ;rcall       ADC_Read8
         ;mov         r20, r16
 
@@ -337,9 +92,8 @@
         ; constant
         ;ldi         r20, 20
 
-        ; short delay, from ADC
-        ldi         r21, 255
-        rcall       ShortDelay
+        ; short delay
+        rcall       VarDelay
 
         ; next segment
         lsl         r24
@@ -368,15 +122,15 @@
         rcall       SPI_Init
     
     ; LCD (requires interrupts, blocks)
-        rcall       LCD_Init    
+        rcall       LED7_Init    
     
     ; Run
         ; spin!
-        ;rcall       Main_Spin
+        rcall       Main_Spin
         
         ; count!
-        rcall       Main_Countdown
-        rcall       Main_Blink
+        ; rcall       Main_Countdown
+        ; rcall       Main_Blink
 
 end:
         rjmp        end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spi.inc	Sat May 08 16:00:18 2010 +0300
@@ -0,0 +1,84 @@
+;; vim: filetype=avr
+
+;; SPI
+.equ SPI_DDR    = DDRB
+.equ SPI_PORT   = PORTB
+.equ SPI_SCK    = PORTB5
+.equ SPI_MISO   = PORTB4
+.equ SPI_MOSI   = PORTB3
+.equ SPI_SS     = PORTB2
+
+.equ SPI_FLAGS  = GPIOR0
+.equ SPI_BUSY   = 0
+
+;; Initialize SPI subsystem for master operation
+SPI_Init:
+    ; Set modes
+        sbi         SPI_DDR, SPI_SCK        ; Out
+        sbi         SPI_DDR, SPI_MOSI       ; Out
+        sbi         SPI_DDR, SPI_SS         ; Out
+
+    ; Drive SS high (off)
+        sbi         SPI_PORT, SPI_SS
+
+    ; Set control mode
+        ; Enable interrupt
+        ; Enable SPI
+        ; MSB first
+        ; Master mode
+        ; Polarity/phase: Mode 0 (sample on rising edge)
+        ; Clock rate 1/16
+        ldi         r16, (1 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (0b01 << SPR0)
+        out         SPCR, r16
+    
+    ; Flags
+        clr         r0
+        out         SPI_FLAGS, r0
+    
+    ; Done
+        ret
+
+;; Send byte
+;;  Input: r16
+;;  XXX: should not be busy...
+SPI_SendRecv:
+    ; Flag
+        sbi         SPI_FLAGS, SPI_BUSY
+
+    ; Enable slave (low)
+        cbi         SPI_PORT, SPI_SS
+    
+    ; Write byte (starts SCK)
+        out         SPDR, r16
+    
+    ; Wait for interrupt
+    ; Done
+        ret
+
+;; Wait for byte to be sent
+SPI_Wait:
+        sbic        SPI_FLAGS, SPI_BUSY     ; Test for busy flag
+        rjmp        SPI_Wait                ; loop
+        
+    ; Done
+        ret
+
+;; Service SPI interrupt
+SPI_Interrupt:
+    ; Store SREG
+        in          r16, SREG
+
+    ; Drive SS high (off)
+        sbi         SPI_PORT, SPI_SS
+
+    ; Read
+        in         r10, SPDR
+
+    ; Flag
+        cbi         SPI_FLAGS, SPI_BUSY
+
+    ; Done
+        out         SREG, r16
+        reti
+
+