Revision 546
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.
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