synchronous SPI, two-digit led7
authorTero Marttila <terom@fixme.fi>
Sat, 08 May 2010 20:09:08 +0300
changeset 23 a6afc0eb347f
parent 22 fd72c63b8db8
child 24 8100038e3d58
synchronous SPI, two-digit led7
led7seg.inc
led7seg.s
spi.inc
--- a/led7seg.inc	Sat May 08 20:08:33 2010 +0300
+++ b/led7seg.inc	Sat May 08 20:09:08 2010 +0300
@@ -20,83 +20,100 @@
 .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
 
-.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
+; output buffer
+.set LED7_COUNT = 2
+
+.dseg
+led7_buffer:    .byte LED7_COUNT
+
+.cseg
 
 ;; 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
+    
+    ; Initialize buffer
         ldi         r16, 0b11111111
+        sts         led7_buffer + 0, r16
+        sts         led7_buffer + 1, r16
 
     ; Output
-        rcall       SPI_SendRecv
-        rcall       SPI_Wait
+        ldi         r16, LED7_COUNT
+        ldi         XL, low(led7_buffer + LED7_COUNT)
+        ldi         XH, high(led7_buffer + LED7_COUNT)
+        rcall       SPI_SendBuf
 
-    ; Enable
+    ; Enable output once the initial display has been shifted out
         cbi         LED7_PORT, LED7_OE
 
     ; Done
         ret
 
-;; Display a single digit on the display
-;;  Input: r16
-LED7_Show:
+LED7_LoadChar:
         clr         r0, 0
 
     ; Prep address
         ; base addr for font table
-        ldi         ZH, high(2*LED7_Font)
-        ldi         ZL, low(2*LED7_Font)
+        ldi         ZH, high(2 * LED7_Font)
+        ldi         ZL, low(2 * LED7_Font)
         
         ; offset
-        add         ZL, r16
+        add         ZL, r8
         adc         ZH, r0
 
     ; Load char
-        lpm         r16, Z
-    
+        lpm         r8, Z
+
+    ; Done
+        ret
+ 
+;; Display a single digit on the display
+;;  Input: r16, r17
+LED7_Show:
+        mov         r8, r16
+        rcall       LED7_LoadChar
+        mov         r16, r8
+
+        mov         r8, r16
+        rcall       LED7_LoadChar
+        mov         r16, r8
+        
     ;; Continue
 
 ;; Display a raw segment mask
-;;  Input: r16
+;;  Input: r16, r17
 LED7_ShowRaw:
-    ; Invert
-        ; com         r16
+    ; Set buffer
+        sts         led7_buffer + 0, r16
+        sts         led7_buffer + 1, r17
+
+    ; Output
+        ldi         r16, LED7_COUNT
+        ldi         XL, low(led7_buffer + LED7_COUNT)
+        ldi         XH, high(led7_buffer + LED7_COUNT)
 
     ; Display
-        rjmp        SPI_SendRecv
+        rjmp        SPI_SendBuf
 
 
--- a/led7seg.s	Sat May 08 20:08:33 2010 +0300
+++ b/led7seg.s	Sat May 08 20:09:08 2010 +0300
@@ -16,6 +16,11 @@
 .org ADCCaddr
         rjmp        ADC_Interrupt
 
+.org 0x40
+
+;; Syntax
+.include "macros.inc"
+
 ;; SPI
 .include "spi.inc"
 
@@ -87,10 +92,14 @@
 _spin_next:
         ; display
         mov         r16, r24
+        mov         r17, r24
+        com         r17
         rcall       LED7_ShowRaw
 
         ; delay
-        mov         r16, r10
+        rcall       ADC_Read8 
+        ;mov         r16, r10
+
         ldi         r17, 64
         mul         r16, r17
         mov         XL, r0
@@ -109,6 +118,10 @@
 
 Main:
 init:
+	; DEBUG
+		sbi			DDRD, PORTD7
+		sbi			PORTD, PORTD7
+
     ; Stack
         ldi         r16, high(RAMEND)
         ldi         r17, low(RAMEND)
@@ -119,7 +132,7 @@
         sei
 
     ; ADC (slowest to start up)
-        ; rcall       ADC_Init
+        rcall       ADC_Init
     
     ; Timer
         rcall       Timer_Init
--- a/spi.inc	Sat May 08 20:08:33 2010 +0300
+++ b/spi.inc	Sat May 08 20:09:08 2010 +0300
@@ -24,13 +24,13 @@
         sbi         SPI_PORT, SPI_SS
 
     ; Set control mode
-        ; Enable interrupt
+        ; XXX: 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)
+        ldi         r16, (0 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (0b01 << SPR0)
         out         SPCR, r16
     
     ; Flags
@@ -40,9 +40,10 @@
     ; Done
         ret
 
-;; Send byte
+;; Send/recv one byte
 ;;  Input: r16
-;;  XXX: should not be busy...
+;;  Output: r10
+;;  Note: should not be busy...
 SPI_SendRecv:
     ; Flag
         sbi         SPI_FLAGS, SPI_BUSY
@@ -53,34 +54,59 @@
     ; Write byte (starts SCK)
         out         SPDR, r16
     
-    ; Wait for interrupt
+    ; Wait for byte to be sent
+spi_sr_wait:
+        in          r1, SPSR
+        sbrs        r1, SPIF
+        rjmp        spi_sr_wait
+
+    ; Read
+        in         r10, SPDR
+    
+    ; Drive SS high (end of packet)
+        sbi         SPI_PORT, SPI_SS
+
     ; Done
         ret
 
-;; Wait for byte to be sent
-SPI_Wait:
-        sbic        SPI_FLAGS, SPI_BUSY     ; Test for busy flag
-        rjmp        SPI_Wait                ; loop
-        
+;; Send buffer bytes
+;;  Input: post-buffer byte in X, buffer length in r16
+;;  Output: r10
+;;  Note: should not be busy...
+SPI_SendBuf:
+    ; Flag
+        sbi         SPI_FLAGS, SPI_BUSY
+
+    ; Enable slave (low)
+        cbi         SPI_PORT, SPI_SS
+
+    ; Write byte from X (starts SCK)
+spi_srb_next:
+        ld          r1, -X
+        out         SPDR, r1
+
+    ; Wait for byte to be sent
+spi_srb_wait:        
+        in          r1, SPSR
+        sbrs        r1, SPIF
+        rjmp        spi_srb_wait
+
+    ; Read
+        in          r10, SPDR
+ 
+    ; Done?
+        dec         r16
+        brne        spi_srb_next
+    
+    ; Drive SS high (end of packet)
+        sbi         SPI_PORT, SPI_SS
+
     ; 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
+    ; XXX: disabled
         reti