Project

General

Profile

Statistics
| Revision:

root / branches / encoders / code / projects / libdragonfly / spi.c @ 252

History | View | Annotate | Download (1.28 KB)

1
/*
2
 * SPI MODULE
3
 *
4
 * ...work in progress
5
 */
6

    
7
/*
8
PINS: 
9
SS = PB0
10
SCK = PB1
11
MOSI = PB2
12
MISO = PB3
13
*/
14

    
15
/* Controls clock freq. see Table 72 */
16
#define DOUBLE_SCK 1
17
#define SPR0_BIT 1
18
#define LSB 1
19
#define MSB 0
20

    
21

    
22
RING_BUFFER_NEW(spi_buffer, 64, char, spi_send_buff, spi_rec_buff);
23
char spi_status;
24

    
25
int
26
spi_init() 
27
{
28

    
29
        RING_BUFFER_CLEAR(spi_send_buff);
30
        RING_BUFFER_CLEAR(spi_rec_buff);
31
        
32
        /* Set MOSI and SCK as output -- also SS for now...*/
33
        DDR_SPI = (1<<PB2)|(1<<PB1)|(1<<PB0);
34
        
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); 
39
}
40

    
41
void 
42
spi_send(char *data, size_t bytes)
43
{
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;
51
    }
52
    RING_BUFFER_ADD(spi_send_buff, data[i]);
53
  }
54
  sei();
55
  spi_status |= SPI_SENDING;
56
  SPDR = *data;
57
}
58

    
59
char
60
spi_receive(void)
61
{
62
        spi_status = SENDING;
63

    
64
        return SPDR;
65
}
66
        
67

    
68
ISR(SIG_SPI) {
69
        char c;
70
        
71
        switch(spi_status){
72
                case SENDING:
73
                        if(!RING_BUFFER_EMPTY(spi_send_buff)) {
74
                                RING_BUFFER_REMOVE(spi_send_buff, c);
75
                                SPDR = c;
76
                        } else {
77
                                /* notify of sent? */
78
                                spi_status = VOID;
79
                        }
80
                        break;
81
                case RECEIVING:
82
                        spi_send_func(SPDR);
83
                        break;
84
                                
85
                                
86
                        
87
                        
88
                        
89
}