Project

General

Profile

Revision 731

Added by Ben Poole about 16 years ago

code commented and cleaned up. should work but untested.

View differences:

branches/encoders/code/projects/libdragonfly/spi.c
1
/* @file spi.c
2
 * @brief
3
 * SPI module
4
 * @bug broken
5
 */
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
 **/
6 8

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

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

  
13
/*
14
SS = PB0
15
SCK = PB1
16
MOSI = PB2
17
MISO = PB3
18
*/
19
/* Controls clock freq. see Table 72 of specs*/
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); 
20 21

  
21
#define DOUBLE_SCK 1
22
#define SPR0_BIT 1
23
#define SPR1_BIT 0
24
#define LSB 1
25
#define MSB 0
26
#define FIRST_BYTE 1
27
#define SECOND_BYTE 2
28

  
29
RING_BUFFER_NEW(spi_buffer, 16, char, spi_send_buff, spi_rec_buff);
30
volatile char spi_status;
31
volatile char spi_mode;
32
static spi_fun_recv_t  spi_recv_function;
33
//static spi_fun_send_t  spi_send_function;
34
static volatile uint16_t i;
35

  
36
void spi_init(spi_fun_recv_t recv_func) {
37
    usb_puts("spi_init: start\n");
38

  
39

  
40
	spi_recv_function = recv_func;
41
	//spi_send_function = send_func;
42

  
43
    /* Enables the SPI module
44
     * Enable Interrupt, Enable SPI Module, LSB First, Master Mode, Clock div = 64
45
     */
46
	SPCR = _BV(SPE) | _BV(SPIE)|_BV(DORD) | _BV(MSTR)| _BV(SPR1) | _BV(SPR0);
47
	SPSR = _BV(SPI2X); 
48
	
49
	spi_status = SPI_VOID;
50

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

  
56
	//sei();
57
	usb_puts("spi_init: end\n");
29
    /* set function to be executed when we receive a byte */
30
    spi_recv_func = recv_func;
31
    spi_bytes = 0;
58 32
}
59 33

  
60
void spi_transfer(char c){
61
	
62
	spi_mode = FIRST_BYTE;
63
	PORTB &= ~SS;
64
	SPDR = c;
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 */
65 40
}
66 41

  
67
ISR(SIG_SPI) {
68
    //usb_puts("ISR: start\n\r");
69
	//char c=SPDR;
70
	//PORTB |= SS;
71
	usb_puts("spi_mode is: "); usb_puti(spi_mode);usb_puts("\r\n");
72
	if(spi_mode < 4){
73
		i=0;
74
		i = (uint16_t)SPDR;
75
		spi_recv_function(SPDR);
76
		SPDR = 0xff;
77
		spi_mode++;
78
		//usb_puts("done\n\r");
79
	} else {
80
		spi_recv_function(SPDR);
81
		//usb_puts("second byte\r\n");
82
		i |= (uint16_t)SPDR << 8;
83
		spi_mode = 1;
84
		PORTB |= SS;
85
		usb_puts("\r\n");
86
	}
87

  
88
	//usb_puts("ISR: end\n");
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
    }
89 55
}		
branches/encoders/code/projects/libdragonfly/spi.h
1
/**
2
 * @file spi.h
3
 * @brief Definitions for SPI
4
 * @author Colony Project, CMU Robotics Club
5
 **/
6

  
1 7
#ifndef __SPI_H__
2 8
#define __SPI_H__
3 9

  
4 10
#define DOUBLE_SCK 1
5 11
#define SPR0_BIT 1
6
#define LSB 1
7
#define MSB 0
12

  
8 13
#define MASTER 1
9 14
#define SLAVE 0
10
#define SPI_SENDING 1
11
#define SPI_VOID 0
12
#define SPI_MASTER_RECV 2
13 15

  
14
/* Pin Defines */
15 16
#define MOSI _BV(PB2)
16 17
#define MISO _BV(PB3)
17
#define SS _BV(PB0)
18
#define SS   _BV(PB0)
18 19
#define SCLK _BV(PB1)
19 20

  
20
#define size_t int
21
typedef void (*spi_fun_recv_t)(unsigned char);
22
typedef void (*spi_fun_send_t)(unsigned char);
23
void spi_init(spi_fun_recv_t recv_func);
24
int spi_send(char *data, size_t bytes);
25
void spi_master_recv_on(void);
26
void spi_master_recv_off(void);
27
void spi_transfer(char c);
21
typedef void (*spi_fun_recv_t)(char);
28 22

  
23
void spi_init (spi_fun_recv_t);
24
void spi_transfer (char);
25

  
29 26
#endif

Also available in: Unified diff