-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspi.c
99 lines (74 loc) · 2 KB
/
spi.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <avr/io.h>
#include <avr/interrupt.h>
#include "spi.h"
#include "buffer.h"
#define SPI_MOSI PB5
#define SPI_SCK PB7
#define SPI_SS PB4
#define SPI_DDR DDRB
#define SPI_PORT PORTB
static uint8_t _txBuffer[SPI_BUFFER_SIZE];
static uint8_t _rxBuffer[SPI_BUFFER_SIZE];
CIRC_BUFFER(spiTxBuffer, _txBuffer, SPI_BUFFER_SIZE);
CIRC_BUFFER(spiRxBuffer, _rxBuffer, SPI_BUFFER_SIZE);
volatile bool SPI_ACTIVE = FALSE;
volatile uint32_t reqNumBytes = 0U;
PUBLIC bool initSPI(uint8_t mode, uint8_t clock) {
// Set MOSI and SCK output
SPI_DDR |= _BV(SPI_MOSI) | _BV(SPI_SCK);
SPI_PORT |= _BV(SPI_MOSI) | _BV(SPI_SCK);
// SS
SPI_DDR |= _BV(SPI_SS);
SPI_PORT |= _BV(SPI_SS);
// Enable interrupt, enbale spi, set master, mode and clock divider
SPCR = _BV(SPIE) | _BV(SPE) | _BV(MSTR) | (mode << CPHA) | (clock << SPR0);
return TRUE;
}
PRIVATE bool triggerSendSPI(void) {
if (!SPI_ACTIVE) {
SPI_ACTIVE = TRUE;
if (!isEmptyBuffer(&spiTxBuffer)) {
uint8_t byte;
if (getByteBuffer(&spiTxBuffer, &byte)) {
SPDR = byte;
return TRUE;
}
}
}
return FALSE;
}
PUBLIC bool sendSpiReceive(uint32_t numBytes) {
reqNumBytes = numBytes;
if (!SPI_ACTIVE) {
SPI_ACTIVE = TRUE;
SPDR = 0x00;
}
return TRUE;
}
PUBLIC bool sendSpiByte(uint8_t byte) {
if (writeByteBuffer(&spiTxBuffer, byte)) {
return triggerSendSPI();
}
return FALSE;
}
PUBLIC bool getSpiByte(uint8_t *byte) {
return getByteBuffer(&spiRxBuffer, byte);
}
ISR(SPI_STC_vect) {
// Receive data
if (!isFullBuffer(&spiRxBuffer)) {
writeByteBuffer(&spiRxBuffer, SPDR);
}
// Send data
if (!isEmptyBuffer(&spiTxBuffer)) {
uint8_t byte;
getByteBuffer(&spiTxBuffer, &byte);
SPDR = byte;
} else if (reqNumBytes > 0U) {
reqNumBytes--;
SPDR = 0x00; // Fill with 0
} else {
// Done
SPI_ACTIVE = FALSE;
}
}