spi.inc
author Tero Marttila <terom@fixme.fi>
Sat, 08 May 2010 16:00:18 +0300
changeset 17 a7c668003a19
child 18 79b25e81721f
permissions -rw-r--r--
split led7seg.s into .inc modules, and update Makefile to use .s -> .hex, and above .inc's for led7seg
;; 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