diff -r 11d6167a67cb -r a7c668003a19 led7seg.s --- 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