-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathspi.c
106 lines (86 loc) · 2.33 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
100
101
102
103
104
105
106
#include "stm32f10x.h"
#include "spi.h"
extern void SPI_Initialize(void){
RCC -> APB2ENR |= RCC_APB2ENR_SPI1EN |
RCC_APB2ENR_AFIOEN |
RCC_APB2ENR_IOPAEN;
GPIOA -> CRL |= GPIO_CRL_MODE4 |
GPIO_CRL_MODE5 |
GPIO_CRL_MODE7;
GPIOA -> CRL &= ~(GPIO_CRL_CNF4_0 |
GPIO_CRL_CNF5_0 |
GPIO_CRL_CNF7_0);
GPIOA -> CRL |= GPIO_CRL_CNF5_1 |
GPIO_CRL_CNF7_1;
SPI1 -> CR1 |= SPI_CR1_BR_0 |
SPI_CR1_SSI |
SPI_CR1_SSM |
SPI_CR1_MSTR;
SPI_EN_bb = 1ul;
}
extern void SPI_Initialize_DMA(void){
RCC -> APB2ENR |= RCC_APB2ENR_SPI1EN |
RCC_APB2ENR_AFIOEN |
RCC_APB2ENR_IOPAEN;
GPIOA -> CRL |= GPIO_CRL_MODE4 |
GPIO_CRL_MODE5 |
GPIO_CRL_MODE7;
GPIOA -> CRL &= ~(GPIO_CRL_CNF4_0 |
GPIO_CRL_CNF5_0 |
GPIO_CRL_CNF7_0);
GPIOA -> CRL |= GPIO_CRL_CNF5_1 |
GPIO_CRL_CNF7_1;
SPI1 -> CR1 |= SPI_CR1_BR_0 |
SPI_CR1_SSI |
SPI_CR1_SSM |
SPI_CR1_MSTR;
SPI1 -> CR2 |= SPI_CR2_TXDMAEN;
// set up DMA1 channel 3 for data transfer
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
// disable channel completely
DMA1_Channel3->CCR = 0;
// SPI address
DMA1_Channel3->CPAR = (uint32_t)&SPI1->DR;
// other params
DMA1_Channel3->CCR = DMA_CCR3_DIR | // memory->SPI
DMA_CCR3_MINC | // memory increment
DMA_CCR3_PL_1 | // priority high
DMA_CCR3_TCIE; // transfer complete irq
NVIC_EnableIRQ(DMA1_Channel3_IRQn);
NVIC_SetPriority(DMA1_Channel3_IRQn,14);
SPI_EN_bb = 1ul;
}
extern int SPI1_Transmit(uint8_t *buf, uint16_t buf_len){
SPI1_CS_bb = 0ul;
do{
while(!SPI_TXE_bb);
SPI1 -> DR = *buf++;
} while(--buf_len);
while(SPI_BSY_bb);
SPI1_CS_bb = 1ul;
return 0;
}
extern int SPI1_Transmit_DMA(uint8_t *buf, uint16_t buf_len){
DMA1_Channel3->CMAR = (uint32_t)buf;
DMA1_Channel3->CNDTR = buf_len;
SPI1_CS_bb = 0ul;
DMA1_Channel3->CCR |= DMA_CCR3_EN;
return 0;
}
extern int SPI1_Receive(uint8_t *buf, uint16_t buf_len){
uint16_t i = buf_len - 1;
SPI1_CS_bb = 0ul;
while (i--){
while(!SPI_RXNE_bb);
*buf++ = SPI1 -> DR;
}
while(SPI_BSY_bb);
SPI1_CS_bb = 1ul;
return 0;
}
void DMA1_Channel3_IRQHandler(void){
DMA1->IFCR|=DMA_IFCR_CTCIF3;
DMA1_Channel3->CCR &= ~DMA_CCR3_EN;
while(SPI_BSY_bb);
SPI1_CS_bb = 1ul;
}