Project

General

Profile

Revision 572

Added by Ben Poole about 16 years ago

more broken code

View differences:

branches/encoders/code/projects/libdragonfly/spi.c
5 5
 */
6 6

  
7 7
#include <avr/interrupt.h>
8
#include <avr/str_defs.h>
8 9
#include "ring_buffer.h"
9 10
#include "spi.h"
10 11
#include <dragonfly_lib.h>
......
35 36
void spi_init(char mode, spi_fun_recv_t recv_func) {
36 37
    usb_puts("spi_init: start\n");
37 38

  
38
	spi_mode = mode;
39
    spi_mode = mode;
40
    RING_BUFFER_CLEAR(spi_send_buff);
41
    RING_BUFFER_CLEAR(spi_rec_buff);
42
    spi_recv_function = recv_func;
43
    char tmp;
39 44

  
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 45
    /* Enables the SPI module
47 46
     * Enable Interrupt, Enable SPI Module, LSB First, Master Mode, Clock div = 64
48 47
     */
49
    SPCR = 0x00;
50 48
    if (spi_mode == MASTER) {
51
    	SPCR = _BV(SPIE) | _BV(SPE) | _BV(DORD) | _BV(MSTR)| _BV(SPR1) | _BV(SPR0);
49
	if(bit_is_clear(DDRB,0))
50
	    PORTB |= _BV(0);//activate SS pull-up
51
	DDRB |= _BV(1) | _BV(2);
52
	PORTB |= _BV(3); //enable MISO pull up
53
    	SPCR = _BV(SPE) | _BV(MSTR)| _BV(SPR1) | _BV(SPR0);
52 54
    } else {
53
    	SPCR = _BV(SPIE) | _BV(SPE) | _BV(DORD) | ~_BV(MSTR)| _BV(SPR1) | _BV(SPR0);
55
	DDRB |= _BV(3);
56
	PORTB |= _BV(2);
57
    	SPCR = _BV(SPE) | _BV(SPR1) | _BV(SPR0);
54 58
    }
55
            
56
    SPSR = 0x00;
57
	SPSR = _BV(SPI2X); 
58
	
59
	spi_status = SPI_IDLE;
60 59

  
61
    /* Set SCLK, SS, MOSI as outputs. MISO as input */
62
	if(spi_mode == MASTER) {
63
	    DDRB |= MOSI | SCLK | SS;
64
	    DDRB &= ~MISO;
65
		PORTB |= SS;	//Keep SS High until transmit
66
	/* Set SCLK, SS, MOSI as inputs. MISO as output */
67
	} else {
68
	    DDRB &= ~MOSI & ~SCLK & ~SS;
69
	    DDRB |= MISO;
70
    }
71
	
72
	//sei();
73
	//usb_puts("spi_init: end\n");
60
    spi_status = SPI_RECV;//always print out received data
61
    SPSR = _BV(SPI2X); 
62

  
63
    //clear flags
64
    tmp = SPSR;
65
    tmp = SPDR;
66
    
67
   
68
    usb_puts("spi_init: end\n");
74 69
}
75 70

  
76 71
int spi_send(char *data, int bytes) {
72
    int i;
73
    if(spi_status & SPI_SEND)
74
	return 1;
77 75

  
78
	int i;
79

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

  
99
/*
117 100
void spi_read(int bytes) {
118 101
    
119 102
    cli();
......
137 120
	
138 121
    SPDR = '0';
139 122

  
140
}
123
}*/
141 124

  
142
void spi_read_one(void)
143
{
144
	PORTB &= ~SS;
145
	SPDR = 'x';
146
}
147 125

  
126
//finished sending a byte
148 127
ISR(SIG_SPI) {
149
	char c;
150 128

  
151
	//You always receive something. You need to handle it before you overwrite it.
152
    spi_recv_function(SPDR);	
129
   char c = SPDR;
130
   //if we're receiving, pass the received character to recv func
131
   if(spi_status & SPI_RECV)
132
       spi_recv_function(SPDR);	
133
   if(!RING_BUFFER_EMPTY(spi_send_buff)) {
134
       RING_BUFFER_REMOVE(spi_send_buff, c);
135
       SPDR = c;
136
   } else if (spi_mode == MASTER && spi_status & SPI_SEND) {
137
       SPCR &= ~_BV(SPIE);
138
   } else if (spi_mode == SLAVE) {
153 139

  
154
    //The clock is running so dequeue another byte to send	
155
	if(!RING_BUFFER_EMPTY(spi_send_buff)) {//cheap way to test if SPI_SEND
156
		RING_BUFFER_REMOVE(spi_send_buff, c);
157
		SPDR = c;
158
	//If we're the master and we're done sending, end the transmission
159
	} else if (spi_mode == MASTER) {
160
	    PORTB |= SS;
161
	} else if (spi_mode == SLAVE) {
162
	    SPDR = '0';
163
	}
140
   }
164 141
	
165

  
166
    
167
	/*
168
	if(spi_status & SPI_SEND) {
169
		spi_status ^= SPI_SEND;
170
		
171
        if (spi_mode == MASTER) {
172
    		PORTB |= SS;
173
        }
174
    } else if (spi_status & SPI_RECV) {
175
           
176
    }
177
    */
178
    //End the transmission if we are not sending or recieving anymore
179
	//} else if(spi_mode == MASTER) {
180
	//   PORTB |= SS;
181
	//}
182
	
183
	//Call the recv function whenver we recieve a byte
184
	//if(spi_status == SPI_RECV){
185
		//spi_recv_function(SPDR);
186
		//if(spi_mode == MASTER)
187
			//PORTB |= SS;
188
	//}
189 142
}		
190 143

  

Also available in: Unified diff