Project

General

Profile

Revision 316

Added by Ben Poole over 16 years ago

SPI update, still not functional

View differences:

spi.c
1
/*
2
 * SPI MODULE
3
 *
4
 * ...work in progress
1
/* @file spi.c
2
 * @brief
3
 * SPI module
4
 * @bug broken
5 5
 */
6 6

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

  
12

  
7 13
/*
8
PINS: 
9 14
SS = PB0
10 15
SCK = PB1
11 16
MOSI = PB2
12 17
MISO = PB3
13 18
*/
19
/* Controls clock freq. see Table 72 of specs*/
14 20

  
15
/* Controls clock freq. see Table 72 */
16 21
#define DOUBLE_SCK 1
17 22
#define SPR0_BIT 1
23
#define SPR1_BIT 0
18 24
#define LSB 1
19 25
#define MSB 0
20 26

  
21 27

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

  
33

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

  
39
	cli();
29 40
	RING_BUFFER_CLEAR(spi_send_buff);
30 41
	RING_BUFFER_CLEAR(spi_rec_buff);
42

  
43
	spi_recv_function = recv_func;
44
	spi_send_function = send_func;
45

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

  
50
	SPSR = (DOUBLE_SCK<<SPI2X); 
31 51
	
32
	/* Set MOSI and SCK as output -- also SS for now...*/
33
	DDR_SPI = (1<<PB2)|(1<<PB1)|(1<<PB0);
52
	spi_status = SPI_VOID;
53

  
54
	if(mode == MASTER) 
55
	    DDRB = (1<<PB2)|(1<<PB1)|(1<<PB0);
56
		
57
	else{
58
	    DDRB = (1<<PB3);
59
		}
60
		
34 61
	
35
	SPCR = (1<<SPIE)|(1<<SPE)|(LSB<<DORD)|(1<<MSTR)|
36
		   (SPR1_BIT<<SPR1)|(SPR0_BIT<<SPR0);
37
	
38
	SPSR = (1<<SPIF)|(DOUBLE_SCK<<SPI2X); 
62
	sei();
63
	usb_puts("spi_init: end\n");
39 64
}
40 65

  
41
void 
66
int
42 67
spi_send(char *data, size_t bytes)
43 68
{
44
	if(bytes == 0) return -1; /* ...needed?*/
45
	
46
	cli();
47
	for(i = 1; i < bytes; i++) {
48
		if(RING_BUFFER_FULL(spi_send_buff)) {
49
			sei();
50
			return -1;
69
    
70
	usb_puts("spi_send: start\n");
71
	int i;
72
    if(bytes == 0) return -1; /* ...needed?*/
73
    cli();
74
    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]);
51 80
    }
52
    RING_BUFFER_ADD(spi_send_buff, data[i]);
53
  }
54
  sei();
55
  spi_status |= SPI_SENDING;
56
  SPDR = *data;
81
    sei();
82
    spi_status = SPI_SENDING;
83
    SPDR = *data;
84
	usb_puts("spi_send: end\n");
85
	//sei();
57 86
}
58 87

  
59
char
60
spi_receive(void)
61
{
62
	spi_status = SENDING;
88
ISR(SIG_SPI) {
89
    usb_puts("ISR: start\n");
90
	char c = SPDR;
63 91

  
64
	return SPDR;
65
}
66
	
67 92

  
68
ISR(SIG_SPI) {
69
	char c;
70
	
93
	usb_putc('['); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n");
71 94
	switch(spi_status){
72
		case SENDING:
95
		case SPI_SENDING:
73 96
			if(!RING_BUFFER_EMPTY(spi_send_buff)) {
74 97
				RING_BUFFER_REMOVE(spi_send_buff, c);
98
				usb_puts("SPDR=["); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n");
75 99
				SPDR = c;
100
				c = SPDR;
101
				usb_puts("c=["); usb_puti(c);usb_putc(',');usb_puti(spi_status);usb_puts("]\n");
102
				
76 103
			} else {
77
				/* notify of sent? */
78
				spi_status = VOID;
104
				spi_status = SPI_VOID;
79 105
			}
80 106
			break;
81
		case RECEIVING:
82
			spi_send_func(SPDR);
107
		case SPI_VOID:
108
			spi_recv_function(c);
83 109
			break;
84
				
85
				
86
			
87
			
88
			
110
	}
111
		SPSR ^= (1 << SPIF);
112
	usb_puts("ISR: end\n");
89 113
}		

Also available in: Unified diff