Statistics
| Revision:

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
}