Project

General

Profile

Revision 619

Added by Ben Poole about 16 years ago

encoders might work now

View differences:

branches/encoders/code/projects/libdragonfly/spi.c
23 23
#define SPR1_BIT 0
24 24
#define LSB 1
25 25
#define MSB 0
26
#define FIRST_BYTE 1
27
#define SECOND_BYTE 2
26 28

  
27

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

  
33

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

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

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

  
43 43
    /* Enables the SPI module
44 44
     * Enable Interrupt, Enable SPI Module, LSB First, Master Mode, Clock div = 64
45 45
     */
46
    if (spi_mode == MASTER) {
47
	if(!(DDRB&_BV(0)))
48
	    PORTB |= _BV(0);//activate SS pull-up
49
	DDRB |= _BV(1) | _BV(2);
50
	PORTB |= _BV(3); //enable MISO pull up
51
    	SPCR = _BV(SPE) | _BV(MSTR)| _BV(SPR1) | _BV(SPR0);
52
    } else {
53
	DDRB |= _BV(3);
54
	PORTB |= _BV(2);
55
    	SPCR = _BV(SPE) | _BV(SPR1) | _BV(SPR0);
56
    }
46
	SPCR = _BV(SPE) | _BV(SPIE)|_BV(DORD) | _BV(MSTR)| _BV(SPR1) | _BV(SPR0);
47
	SPSR = _BV(SPI2X); 
48
	
49
	spi_status = SPI_VOID;
57 50

  
58
    spi_status = SPI_RECV;//always print out received data
59
    SPSR = _BV(SPI2X); 
51
    /* 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
60 55

  
61
    //clear flags
62
    tmp = SPSR;
63
    tmp = SPDR;
64
    
65
   
66
    usb_puts("spi_init: end\n");
56
	//sei();
57
	usb_puts("spi_init: end\n");
67 58
}
68 59

  
69
int spi_send(char *data, int bytes) {
70
    int i;
71

  
72
    //FIXME: dont need to block, add to queue
73
    if(spi_status & SPI_SEND)
74
	return 1;
75

  
76
    //Prevent race condition on the buffer
77
    cli();
78
    for(i = 1; i < bytes; i++) {
79
        // Fail if the buffer is full
80
	    if(RING_BUFFER_FULL(spi_send_buff)) {
81
	        sei();
82
	        return 1;
83
	    }
84
	    RING_BUFFER_ADD(spi_send_buff, data[i]);
85
    }
86
    sei();
87
    
88
    //we are sending data/have data to send
89
    spi_status |= SPI_SEND;
60
void spi_transfer(char c){
90 61
	
91
    //if master, start transmission
92
    if (spi_mode == MASTER ){
93
	SPCR |= _BV(SPIE);
94
	SPDR = *data;
95
    }
96
	
97
    return 0;
62
	spi_mode = FIRST_BYTE;
63
	PORTB &= ~SS;
64
	SPDR = c;
98 65
}
99 66

  
100
void spi_read(int bytes) {
101

  
102
    //send bytes not constant
103
    spi_send("AAAAAA",6);
104

  
105
}
106

  
107

  
108
//finished sending a byte
109 67
ISR(SIG_SPI) {
68
  //  usb_puts("ISR: start\n\r");
69
	//char c=SPDR;
70
	//PORTB |= SS;
71
	if(spi_mode == FIRST_BYTE){
72
		i = (uint16_t)SPDR << 8;
73
		spi_recv_function(SPDR);
74
		spi_mode = SECOND_BYTE;
75
		SPDR = 'c';
76
	} else if (spi_mode == SECOND_BYTE){
77
		i = (uint16_t)SPDR << 8;
78
		spi_mode = 4;
79
		PORTB |= SS;
80
	}
110 81

  
111
   char c = SPDR;
112
   //if we're receiving, pass the received character to recv func
113
   if(spi_status & SPI_RECV)
114
       spi_recv_function(SPDR);	
115
   if(!RING_BUFFER_EMPTY(spi_send_buff)) {
116
       RING_BUFFER_REMOVE(spi_send_buff, c);
117
       SPDR = c;
118
   } else if (spi_mode == MASTER && spi_status & SPI_SEND) {
119
       SPCR &= ~_BV(SPIE);
120
   } else if (spi_mode == SLAVE) {
121

  
122
   }
123
	
82
	//usb_puts("ISR: end\n");
124 83
}		
125

  
branches/encoders/code/projects/libdragonfly/spi.h
7 7
#define MSB 0
8 8
#define MASTER 1
9 9
#define SLAVE 0
10
#define SPI_SENDING 1
11
#define SPI_VOID 0
12
#define SPI_MASTER_RECV 2
10 13

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

  
16

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

  
23
//#define size_t int
20
#define size_t int
24 21
typedef void (*spi_fun_recv_t)(char);
25 22
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);
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);
28 28

  
29 29
#endif

Also available in: Unified diff