Project

General

Profile

Revision 546

Added by Kevin Woo over 13 years ago

Modified spi.c/h. Sends 1 packet before failing. Funny light blinking
thing happens when sending, no idea where that came from. It looks like
the orbs are used as transmit lights but there's no code for that as far
as I know.

View differences:

branches/encoders/code/lib/include/libdragonfly/spi.h
1
#ifndef __SPI_H__
2
#define __SPI_H__
3

  
4
#define DOUBLE_SCK 1
5
#define SPR0_BIT 1
6
#define LSB 1
7
#define MSB 0
8
#define MASTER 1
9
#define SLAVE 0
10

  
11
#define SPI_IDLE 0x00
12
#define SPI_SEND 0x01
13
#define SPI_RECV 0x02
14
#define SPI_BOTH 0x03
15

  
16

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

  
23
//#define size_t int
24
typedef void (*spi_fun_recv_t)(char);
25
typedef void (*spi_fun_send_t)(char);
26
void spi_init(char mode, spi_fun_recv_t recv_func);
27
int spi_send(char *data, int bytes);
28
void spi_master_recv_on(void);
29
void spi_master_recv_off(void);
30
void spi_read_one(void);
31
void spi_read(int bytes);
32

  
33
#endif
branches/encoders/code/lib/include/libdragonfly/dragonfly_lib.h
65 65
#include <bom.h>
66 66
#include <move.h>
67 67
#include <reset.h>
68
//#include "spi.h"
68 69
#include <math.h>
69 70

  
70 71
#endif
branches/encoders/code/lib/src/libdragonfly/encoders.c
1

  
2
//Dummy file for now.
branches/encoders/code/lib/src/libdragonfly/spi.c
1
/* @file spi.c
2
 * @brief
3
 * SPI module
4
 * @bug broken
5
 */
6

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

  
12

  
13
/*
14
SS = PB0
15
SCK = PB1
16
MOSI = PB2
17
MISO = PB3
18
*/
19
/* Controls clock freq. see Table 72 of specs*/
20

  
21
#define DOUBLE_SCK 1
22
#define SPR0_BIT 1
23
#define SPR1_BIT 0
24
#define LSB 1
25
#define MSB 0
26

  
27

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

  
34

  
35
void spi_init(char mode, spi_fun_recv_t recv_func) {
36
    usb_puts("spi_init: start\n");
37

  
38
	spi_mode = mode;
39

  
40
	RING_BUFFER_CLEAR(spi_send_buff);
41
	RING_BUFFER_CLEAR(spi_rec_buff);
42

  
43
	spi_recv_function = recv_func;
44
	//spi_send_function = send_func;
45

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

  
56
    /* Set SCLK, SS, MOSI as outputs. MISO as input */
57
	if(mode == MASTER) {
58
	    DDRB |= MOSI | SCLK | SS;
59
	    DDRB &= ~MISO;
60
		PORTB |= SS;	//Keep SS High until transmit
61
	/* Set SCLK, SS, MOSI as inputs. MISO as output */
62
	} else {
63
	    DDRB &= ~MOSI & ~SCLK & ~SS;
64
	    DDRB |= MISO;
65
    }
66
	
67
	//sei();
68
	usb_puts("spi_init: end\n");
69
}
70

  
71
int spi_send(char *data, int bytes) {
72

  
73
	int i;
74

  
75
    if(bytes == 0) 
76
        return -1; /* ...needed?*/
77
    
78
    //Prevent race condition on the buffer
79
    cli();
80
    for(i = 1; i < bytes; i++) {
81
        // Fail if the buffer is full
82
	    if(RING_BUFFER_FULL(spi_send_buff)) {
83
	        sei();
84
	        return -1;
85
	    }
86
	
87
	    RING_BUFFER_ADD(spi_send_buff, data[i]);
88
    }
89
    
90
    sei();
91
    
92
    spi_status |= SPI_SEND;
93
	
94
	if (spi_mode == MASTER ){
95
		PORTB &= ~SS;	//Select slave
96
	}
97
	
98
    SPDR = *data;
99
    
100
	if(spi_mode)
101
		usb_puts("MASTER");
102
	else
103
		usb_puts("SLAVE");
104
		
105
	usb_puts(": sending [");usb_putc(*data);usb_puts("]\n\r");
106
	
107
	//sei();
108
	
109
	return 1;
110
}
111

  
112
void spi_read(int bytes) {
113
    
114
    cli();
115
    for(int i = 1; i < bytes; i++) {
116
        // Fail if the buffer is full
117
	    if(RING_BUFFER_FULL(spi_send_buff)) {
118
	        sei();
119
	        return;
120
	    }
121
	
122
	    RING_BUFFER_ADD(spi_send_buff, '\n');
123
    }
124
    
125
    sei();
126

  
127
    spi_status |= SPI_RECV;
128
	
129
	if (spi_mode == MASTER ){
130
		PORTB &= ~SS;	//Select slave
131
	}
132
	
133
    SPDR = '\n';
134

  
135
}
136

  
137
void spi_read_one(void)
138
{
139
	PORTB &= ~SS;
140
	SPDR = 'x';
141
}
142

  
143
ISR(SIG_SPI) {
144
	char c;
145

  
146
    //The clock is running so dequeue another byte to send	
147
	if(!RING_BUFFER_EMPTY(spi_send_buff)) {//cheap way to test if SPI_SEND
148
		RING_BUFFER_REMOVE(spi_send_buff, c);
149
		SPDR = c;
150
	
151
	//If we're the master and we're done sending, end the transmission
152
	} else if (spi_mode == MASTER) {
153
	    PORTB |= SS;
154
	}
155
	
156
	//You always receive something. You need to handle it.
157
    spi_recv_function(SPDR);	
158
    
159
	/*
160
	if(spi_status & SPI_SEND) {
161
		spi_status ^= SPI_SEND;
162
		
163
        if (spi_mode == MASTER) {
164
    		PORTB |= SS;
165
        }
166
    } else if (spi_status & SPI_RECV) {
167
           
168
    }
169
    */
170
    //End the transmission if we are not sending or recieving anymore
171
	//} else if(spi_mode == MASTER) {
172
	//   PORTB |= SS;
173
	//}
174
	
175
	//Call the recv function whenver we recieve a byte
176
	//if(spi_status == SPI_RECV){
177
		//spi_recv_function(SPDR);
178
		//if(spi_mode == MASTER)
179
			//PORTB |= SS;
180
	//}
181
}		
182

  
branches/encoders/code/projects/template/main.c
6 6
extern char spi_status;
7 7

  
8 8
void recv_func(char c) {
9
    if (c != '\n');
9 10
	if(MODE)
10 11
		usb_puts("MASTER");
11 12
	else
12 13
		usb_puts("SLAVE");
14
	
13 15
	usb_puts(": received [");usb_putc(c);usb_puts("]\n\r");
14 16
	return;
15 17
}
......
24 26
	while(1) {
25 27
		if(TEST){
26 28
			if(MODE){
27
				spi_read_one();
29
				spi_read(6);
28 30
				delay_ms(1000);
29 31
			} else {
30
				if(!(spi_status &SPI_SEND))
31
				spi_send("SLAVE",6);
32
				//if(!(spi_status & SPI_SEND))
33
				spi_send("SLAVE ",6);
34
				//delay_ms(800);
32 35
			}
33 36
		} else {
34 37
			if (MODE) {
branches/encoders/code/projects/template/Makefile
14 14
# USE_WIRELESS = 1
15 15

  
16 16
# com1 = serial port. Use lpt1 to connect to parallel port.
17
AVRDUDE_PORT = com3
17
AVRDUDE_PORT = /dev/ttyUSB0
18 18
#
19
#
20 19
###################################
21 20

  
22 21
# Hey Emacs, this is a -*- makefile -*-
branches/encoders/code/projects/libdragonfly/spi.c
51 51
    SPSR = 0x00;
52 52
	SPSR = _BV(SPI2X); 
53 53
	
54
	spi_status = SPI_RECV;
54
	spi_status = SPI_IDLE;
55 55

  
56 56
    /* Set SCLK, SS, MOSI as outputs. MISO as input */
57 57
	if(mode == MASTER) {
......
68 68
	usb_puts("spi_init: end\n");
69 69
}
70 70

  
71
int spi_send(char *data, size_t bytes) {
71
int spi_send(char *data, int bytes) {
72 72

  
73 73
	int i;
74 74

  
......
112 112
void spi_read(int bytes) {
113 113
    
114 114
    cli();
115
    for(i = 1; i < bytes; i++) {
115
    for(int i = 1; i < bytes; i++) {
116 116
        // Fail if the buffer is full
117 117
	    if(RING_BUFFER_FULL(spi_send_buff)) {
118 118
	        sei();
119
	        return -1;
119
	        return;
120 120
	    }
121 121
	
122
	    RING_BUFFER_ADD(spi_send_buff, '\0');
122
	    RING_BUFFER_ADD(spi_send_buff, '\n');
123 123
    }
124 124
    
125 125
    sei();
......
130 130
		PORTB &= ~SS;	//Select slave
131 131
	}
132 132
	
133
    SPDR = *data;
133
    SPDR = '\n';
134 134

  
135 135
}
136 136

  
......
142 142

  
143 143
ISR(SIG_SPI) {
144 144
	char c;
145
	
145

  
146
    //The clock is running so dequeue another byte to send	
146 147
	if(!RING_BUFFER_EMPTY(spi_send_buff)) {//cheap way to test if SPI_SEND
147 148
		RING_BUFFER_REMOVE(spi_send_buff, c);
148 149
		SPDR = c;
149
		
150
		if(spi_mode)
151
			usb_puts("MASTER");
152
		else
153
			usb_puts("SLAVE");
154
			
155
		usb_puts(": sending [");usb_putc(c);usb_puts("]\n\r");
156 150
	
157
	//If we were sending and we are done end the transmission
158
	} else if(spi_status == SPI_SEND) {
159
		spi_status ^= SPI_SEND;
160
		PORTB |= SS; //Sleep slave
161

  
162
    //End the transmission if we are not sending or recieving anymore
163
	} else if(spi_mode == MASTER) {
151
	//If we're the master and we're done sending, end the transmission
152
	} else if (spi_mode == MASTER) {
164 153
	    PORTB |= SS;
165 154
	}
166 155
	
156
	//You always receive something. You need to handle it.
157
    spi_recv_function(SPDR);	
158
    
159
	/*
160
	if(spi_status & SPI_SEND) {
161
		spi_status ^= SPI_SEND;
162
		
163
        if (spi_mode == MASTER) {
164
    		PORTB |= SS;
165
        }
166
    } else if (spi_status & SPI_RECV) {
167
           
168
    }
169
    */
170
    //End the transmission if we are not sending or recieving anymore
171
	//} else if(spi_mode == MASTER) {
172
	//   PORTB |= SS;
173
	//}
174
	
167 175
	//Call the recv function whenver we recieve a byte
168
	if(spi_status == SPI_RECV){
169
		spi_recv_function(SPDR);
176
	//if(spi_status == SPI_RECV){
177
		//spi_recv_function(SPDR);
170 178
		//if(spi_mode == MASTER)
171 179
			//PORTB |= SS;
172
	}
180
	//}
173 181
}		
174 182

  
branches/encoders/code/projects/libdragonfly/spi.h
8 8
#define MASTER 1
9 9
#define SLAVE 0
10 10

  
11
#define SPI_IDLE _BV(0)
12
#define SPI_SEND _BV(1)
13
#define SPI_RECV _BV(2)
14
#define SPI_BOTH _BV(3)
11
#define SPI_IDLE 0x00
12
#define SPI_SEND 0x01
13
#define SPI_RECV 0x02
14
#define SPI_BOTH 0x03
15 15

  
16 16

  
17 17
/* Pin Defines */
......
20 20
#define SS _BV(PB0)
21 21
#define SCLK _BV(PB1)
22 22

  
23
#define size_t int
23
//#define size_t int
24 24
typedef void (*spi_fun_recv_t)(char);
25 25
typedef void (*spi_fun_send_t)(char);
26 26
void spi_init(char mode, spi_fun_recv_t recv_func);
27
int spi_send(char *data, size_t bytes);
27
int spi_send(char *data, int bytes);
28 28
void spi_master_recv_on(void);
29 29
void spi_master_recv_off(void);
30 30
void spi_read_one(void);
31
void spi_read(int bytes);
31 32

  
32 33
#endif

Also available in: Unified diff