Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / projects / libdragonfly / spi.c @ 731

History | View | Annotate | Download (1.41 KB)

1
/**
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

    
9
#include <avr/interrupt.h>
10
#include <dragonfly_lib.h>
11
#include "spi.h"
12

    
13
static volatile char spi_bytes; /* number of bytes to read */
14
static spi_fun_recv_t spi_recv_func; /* byte handler */
15

    
16
void spi_init (spi_fun_recv_t recv_func)
17
{
18
    /*  Enable Interrupt, Enable SPI Module, MSB First, Master Mode, Clock div = 64 */
19
    SPCR = _BV(SPE) | _BV(SPIE) | _BV(DORD) | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
20
    SPSR = _BV(SPI2X); 
21

    
22
    /* Set SCLK, SS, MOSI as outputs. MISO as input */
23
    DDRB = MOSI | SCLK | SS;
24
    DDRB &= ~MISO;
25
    
26
    /* Keep SS high until transmit */
27
    PORTB |= SS;
28

    
29
    /* set function to be executed when we receive a byte */
30
    spi_recv_func = recv_func;
31
    spi_bytes = 0;
32
}
33

    
34
/* Transfer a given byte to slave and receive a byte */
35
void spi_transfer(char bytes)
36
{
37
    spi_bytes = bytes;
38
    PORTB &= ~SS; /* Set SS low to initiate transmission */
39
    SPDR = 0xff; /* Initiate data transmision */
40
}
41

    
42
ISR(SIG_SPI) 
43
{
44
    /* only handle intterupt when we are expecting data */
45
    if(spi_bytes > 0){
46
        /* process byte */
47
        spi_recv_func(SPDR);
48
        /* if we've read all the bytes, set SS high to end transmission,
49
         * otherwise get the next byte  */
50
        if(--spi_bytes == 0)
51
            PORTB |= SS;
52
        else 
53
            SPDR = 0xff;
54
    }
55
}