spi.inc
author Tero Marttila <terom@fixme.fi>
Sat, 08 May 2010 20:59:22 +0300
changeset 25 33496b1a964f
parent 24 8100038e3d58
child 26 db2ec641c955
permissions -rw-r--r--
show (hexa)decimal values on display from ADC or DIP
;; vim: filetype=avr
;;
;; SPI interface control and use
;;

.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
        ; XXX: Enable interrupt
        ; Enable SPI
        ; MSB first
        ; Master mode
        ; Polarity/phase: Mode 0 (sample on rising edge)
        ; Clock rate 1/16
        ldi         r16, (0 << 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/recv one byte
;;  Input: r16
;;  Output: r10
;;  Note: 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 byte to be sent
spi_sr_wait:
        in          r1, SPSR
        sbrs        r1, SPIF
        rjmp        spi_sr_wait

    ; Read
        mov         r10, r11
        in          r11, SPDR
    
    ; Drive SS high (end of packet)
        sbi         SPI_PORT, SPI_SS

    ; Done
        ret

;; 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
        mov         r10, r11
        in          r11, 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:
    ; XXX: disabled
        reti