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