Project

General

Profile

Revision 350

Added by Kevin Woo almost 13 years ago

Changed formatting so that it isn't as messy. Probably won't compile.
Still probably doesn't work.

View differences:

branches/encoders/code/projects/libdragonfly/spi.c
25 25
#define MSB 0
26 26

  
27 27

  
28
RING_BUFFER_NEW(spi_buffer, 64, char, spi_send_buff, spi_rec_buff);
28
RING_BUFFER_NEW(spi_buffer, 16, char, spi_send_buff, spi_rec_buff);
29 29
volatile char spi_status;
30 30
static spi_fun_recv_t  spi_recv_function;
31 31
static spi_fun_send_t  spi_send_function;
32 32

  
33 33

  
34
int
35
spi_init(char mode,spi_fun_send_t send_func, spi_fun_recv_t recv_func)
36
{
34
int spi_init(char mode, spi_fun_send_t send_func, spi_fun_recv_t recv_func) {
37 35
    usb_puts("spi_init: start\n");
38 36

  
39
	cli();
37
	//cli();
40 38
	RING_BUFFER_CLEAR(spi_send_buff);
41 39
	RING_BUFFER_CLEAR(spi_rec_buff);
42 40

  
43 41
	spi_recv_function = recv_func;
44 42
	spi_send_function = send_func;
45 43

  
46
	SPCR = (1<<SPIE)|
47
	(1<<SPE)|(LSB<<DORD)|(mode<<MSTR)|
48
	       (SPR1_BIT<<SPR1)|(SPR0_BIT<<SPR0);
49

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

  
54
	if(mode == MASTER) 
55
	    DDRB = (1<<PB2)|(1<<PB1)|(1<<PB0);
56
		
57
	else{
58
	    DDRB = (1<<PB3);
59
		}
60
		
54
    /* Set SCLK, SS, MOSI as outputs. MISO as input */
55
	if(mode == MASTER) {
56
	    DDRB |= MOSI | SCLK | SS;
57
	    DDRB &= ~MISO;
58
	/* Set SCLK, SS, MOSI as inputs. MISO as output */
59
	} else {
60
	    DDRB &= ~MOSI & ~SCLK & ~SS;
61
	    DDRB |= MISO;
62
    }
61 63
	
62
	sei();
64
	//sei();
63 65
	usb_puts("spi_init: end\n");
64 66
}
65 67

  
66
int
67
spi_send(char *data, size_t bytes)
68
{
68
int spi_send(char *data, size_t bytes) {
69

  
70
	int i;
71
	    
72
	usb_puts("spi_send: start\n");
73

  
74
    if(bytes == 0) 
75
        return -1; /* ...needed?*/
69 76
    
70
	usb_puts("spi_send: start\n");
71
	int i;
72
    if(bytes == 0) return -1; /* ...needed?*/
77
    //Prevent race condition on the buffer
73 78
    cli();
74 79
    for(i = 1; i < bytes; i++) {
75
	if(RING_BUFFER_FULL(spi_send_buff)) {
76
	    sei();
77
	    return -1;
78
	}
79
	RING_BUFFER_ADD(spi_send_buff, data[i]);
80
        // Fail if the buffer is full
81
	    if(RING_BUFFER_FULL(spi_send_buff)) {
82
	        sei();
83
	        return -1;
84
	    }
85
	
86
	    RING_BUFFER_ADD(spi_send_buff, data[i]);
80 87
    }
88
    
81 89
    sei();
90
    
82 91
    spi_status = SPI_SENDING;
83 92
    SPDR = *data;
93
	
84 94
	usb_puts("spi_send: end\n");
85 95
	//sei();
86 96
}
87 97

  
88 98
ISR(SIG_SPI) {
89
    usb_puts("ISR: start\n");
99
    usb_puts("ISR: start\n\r");
90 100
	char c = SPDR;
91 101

  
92

  
93
	usb_putc('['); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n");
102
	usb_putc('['); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n\r");
94 103
	switch(spi_status){
95 104
		case SPI_SENDING:
96 105
			if(!RING_BUFFER_EMPTY(spi_send_buff)) {
97 106
				RING_BUFFER_REMOVE(spi_send_buff, c);
98
				usb_puts("SPDR=["); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n");
107
				usb_puts("SPDR=["); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n\r");
99 108
				SPDR = c;
100 109
				c = SPDR;
101 110
				usb_puts("c=["); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n");
branches/encoders/code/projects/libdragonfly/spi.h
7 7
#define SPI_SENDING 1
8 8
#define SPI_VOID 0
9 9

  
10
/* Pin Defines */
11
#define MOSI _BV(PB2)
12
#define MISO _BV(PB3)
13
#define SS _BV(PB0)
14
#define SCLK _BV(PB1)
15

  
10 16
#define size_t int
11 17
typedef void (*spi_fun_recv_t)(char);
12 18
typedef void (*spi_fun_send_t)(char);

Also available in: Unified diff