root / branches / encoders / code / lib / src / libdragonfly / spi.c @ 1345
History | View | Annotate | Download (1.85 KB)
1 | 749 | bneuman | /**
|
---|---|---|---|
2 | * @file spi.c
|
||
3 | * @brief Basic SPI module to handle encoders
|
||
4 | * @author Colony Project, CMU Robotics Club
|
||
5 | * @bug Not tested
|
||
6 | * Need to move spi.h include into dragonfly_lib.h when stable
|
||
7 | **/
|
||
8 | 546 | kwoo | |
9 | #include <avr/interrupt.h> |
||
10 | 749 | bneuman | #include <dragonfly_lib.h> |
11 | 546 | kwoo | #include "spi.h" |
12 | |||
13 | 752 | bneuman | |
14 | 749 | bneuman | static volatile char spi_bytes; /* number of bytes to read */ |
15 | static spi_fun_recv_t spi_recv_func; /* byte handler */ |
||
16 | static spi_fun_recv_complete_t spi_recv_complete_func; /*transmission completion handler */ |
||
17 | 546 | kwoo | |
18 | 749 | bneuman | void spi_init (spi_fun_recv_t recv_func, spi_fun_recv_complete_t recv_complete_func)
|
19 | { |
||
20 | /* Enable Interrupt, Enable SPI Module, MSB First, Master Mode, Clock div = 64 */
|
||
21 | 844 | justin | SPCR = _BV(SPE) | _BV(SPIE) /*| _BV(DORD)*/ | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
|
22 | 749 | bneuman | SPSR = _BV(SPI2X); |
23 | 546 | kwoo | |
24 | /* Set SCLK, SS, MOSI as outputs. MISO as input */
|
||
25 | 752 | bneuman | DDRB |= MOSI | SCLK | SS; |
26 | 749 | bneuman | DDRB &= ~MISO; |
27 | 546 | kwoo | |
28 | 749 | bneuman | /* Keep SS high until transmit */
|
29 | PORTB |= SS; |
||
30 | 546 | kwoo | |
31 | 749 | bneuman | /* set function to be executed when we receive a byte */
|
32 | spi_recv_func = recv_func; |
||
33 | 844 | justin | spi_recv_complete_func = recv_complete_func; |
34 | 749 | bneuman | spi_bytes = 0;
|
35 | 1345 | chihsiuh | //usb_puts("\tspi.c Debug: SPI INITIALIZED\n");
|
36 | 546 | kwoo | } |
37 | |||
38 | 749 | bneuman | /* Transfer a given byte to slave and receive a byte */
|
39 | void spi_transfer(char bytes) |
||
40 | 546 | kwoo | { |
41 | 749 | bneuman | spi_bytes = bytes; |
42 | PORTB &= ~SS; /* Set SS low to initiate transmission */
|
||
43 | SPDR = 0xff; /* Initiate data transmision */ |
||
44 | 546 | kwoo | } |
45 | |||
46 | 749 | bneuman | ISR(SIG_SPI) |
47 | { |
||
48 | //usb_puts("Interrupt");
|
||
49 | /* only handle intterupt when we are expecting data */
|
||
50 | if(spi_bytes > 0){ |
||
51 | /* process byte */
|
||
52 | 844 | justin | spi_recv_func(SPDR); |
53 | 749 | bneuman | /* if we've read all the bytes, set SS high to end transmission,
|
54 | * otherwise get the next byte */
|
||
55 | if(--spi_bytes == 0){ |
||
56 | //usb_puts("Read all bytes\r\n");
|
||
57 | 844 | justin | PORTB |= SS; |
58 | if(spi_recv_complete_func)
|
||
59 | spi_recv_complete_func(); |
||
60 | 749 | bneuman | }else {
|
61 | //usb_puts("There are this many bytes left: "); usb_puti(spi_bytes);usb_puts("\r\n");
|
||
62 | 844 | justin | SPDR = 0xff;
|
63 | } |
||
64 | 546 | kwoo | } |
65 | } |