Project

General

Profile

Statistics
| Revision:

root / branches / wireless / code / projects / libdragonfly / spi.c @ 1493

History | View | Annotate | Download (2.38 KB)

1 868 justin
/**
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 1462 dsschult
10
#include "dragonfly_defs.h"
11 868 justin
#include "spi.h"
12
13 1461 bneuman
unsigned char spi_initd=0;
14 868 justin
15
static volatile char spi_bytes; /* number of bytes to read */
16
static spi_fun_recv_t spi_recv_func; /* byte handler */
17
static spi_fun_recv_complete_t spi_recv_complete_func; /*transmission completion handler */
18
19
/**
20
* @brief Initialize SPI hardware for communication.
21
*
22
* @param recv_func The function to be called for each byte of data received.
23
* @param recv_complete_func  The function to be called at the end of a complete transmission.
24 1461 bneuman
*
25
* @return 0 if init succesfull, an error code otherwise
26 868 justin
*/
27 1461 bneuman
int spi_init (spi_fun_recv_t recv_func, spi_fun_recv_complete_t recv_complete_func)
28 868 justin
{
29 1461 bneuman
    if(spi_initd) {
30
      return ERROR_INIT_ALREADY_INITD;
31
    }
32
33 868 justin
    /*  Enable Interrupt, Enable SPI Module, MSB First, Master Mode, Clock div = 64 */
34
    SPCR = _BV(SPE) | _BV(SPIE) /*| _BV(DORD)*/ | _BV(MSTR) | _BV(SPR1) | _BV(SPR0);
35
    SPSR = _BV(SPI2X);
36
37
    /* Set SCLK, SS, MOSI as outputs. MISO as input */
38
    DDRB |= MOSI | SCLK | SS;
39
    DDRB &= ~MISO;
40
41
    /* Keep SS high until transmit */
42
    PORTB |= SS;
43
44
    /* set function to be executed when we receive a byte */
45
    spi_recv_func = recv_func;
46
    spi_recv_complete_func = recv_complete_func;
47
    spi_bytes = 0;
48
    //usb_puts("\tspi.c Debug: SPI INITIALIZED\n");
49 1461 bneuman
50
    spi_initd=1;
51
    return 0;
52 868 justin
}
53
54
/**
55
* @brief Transfer a given byte to slave and receive a byte
56
*
57
* @param bytes The number of bytes to be transferred.
58
**/
59 1461 bneuman
int spi_transfer(char bytes)
60 868 justin
{
61 1461 bneuman
    if(!spi_initd)
62
      return ERROR_LIBRARY_NOT_INITD;
63
64 868 justin
    spi_bytes = bytes;
65
    PORTB &= ~SS; /* Set SS low to initiate transmission */
66
    SPDR = 0xff; /* Initiate data transmision */
67 1461 bneuman
68
    return 0;
69 868 justin
}
70
71
ISR(SIG_SPI)
72
{
73
        //usb_puts("Interrupt");
74
    /* only handle intterupt when we are expecting data */
75
    if(spi_bytes > 0){
76
        /* process byte */
77
        spi_recv_func(SPDR);
78
        /* if we've read all the bytes, set SS high to end transmission,
79
         * otherwise get the next byte  */
80
        if(--spi_bytes == 0){
81
                //usb_puts("Read all bytes\r\n");
82
                PORTB |= SS;
83
                if(spi_recv_complete_func)
84
                        spi_recv_complete_func();
85
        }else {
86
                //usb_puts("There are this many bytes left: "); usb_puti(spi_bytes);usb_puts("\r\n");
87
                SPDR = 0xff;
88
        }
89
    }
90
}