equal
deleted
inserted
replaced
|
1 ;; vim: filetype=avr |
|
2 |
|
3 ;; SPI |
|
4 .equ SPI_DDR = DDRB |
|
5 .equ SPI_PORT = PORTB |
|
6 .equ SPI_SCK = PORTB5 |
|
7 .equ SPI_MISO = PORTB4 |
|
8 .equ SPI_MOSI = PORTB3 |
|
9 .equ SPI_SS = PORTB2 |
|
10 |
|
11 .equ SPI_FLAGS = GPIOR0 |
|
12 .equ SPI_BUSY = 0 |
|
13 |
|
14 ;; Initialize SPI subsystem for master operation |
|
15 SPI_Init: |
|
16 ; Set modes |
|
17 sbi SPI_DDR, SPI_SCK ; Out |
|
18 sbi SPI_DDR, SPI_MOSI ; Out |
|
19 sbi SPI_DDR, SPI_SS ; Out |
|
20 |
|
21 ; Drive SS high (off) |
|
22 sbi SPI_PORT, SPI_SS |
|
23 |
|
24 ; Set control mode |
|
25 ; Enable interrupt |
|
26 ; Enable SPI |
|
27 ; MSB first |
|
28 ; Master mode |
|
29 ; Polarity/phase: Mode 0 (sample on rising edge) |
|
30 ; Clock rate 1/16 |
|
31 ldi r16, (1 << SPIE) | (1 << SPE) | (0 << DORD) | (1 << MSTR) | (0 << CPOL) | (0 << CPHA) | (0b01 << SPR0) |
|
32 out SPCR, r16 |
|
33 |
|
34 ; Flags |
|
35 clr r0 |
|
36 out SPI_FLAGS, r0 |
|
37 |
|
38 ; Done |
|
39 ret |
|
40 |
|
41 ;; Send byte |
|
42 ;; Input: r16 |
|
43 ;; XXX: should not be busy... |
|
44 SPI_SendRecv: |
|
45 ; Flag |
|
46 sbi SPI_FLAGS, SPI_BUSY |
|
47 |
|
48 ; Enable slave (low) |
|
49 cbi SPI_PORT, SPI_SS |
|
50 |
|
51 ; Write byte (starts SCK) |
|
52 out SPDR, r16 |
|
53 |
|
54 ; Wait for interrupt |
|
55 ; Done |
|
56 ret |
|
57 |
|
58 ;; Wait for byte to be sent |
|
59 SPI_Wait: |
|
60 sbic SPI_FLAGS, SPI_BUSY ; Test for busy flag |
|
61 rjmp SPI_Wait ; loop |
|
62 |
|
63 ; Done |
|
64 ret |
|
65 |
|
66 ;; Service SPI interrupt |
|
67 SPI_Interrupt: |
|
68 ; Store SREG |
|
69 in r16, SREG |
|
70 |
|
71 ; Drive SS high (off) |
|
72 sbi SPI_PORT, SPI_SS |
|
73 |
|
74 ; Read |
|
75 in r10, SPDR |
|
76 |
|
77 ; Flag |
|
78 cbi SPI_FLAGS, SPI_BUSY |
|
79 |
|
80 ; Done |
|
81 out SREG, r16 |
|
82 reti |
|
83 |
|
84 |