-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdmaspi.c
152 lines (111 loc) · 5.17 KB
/
dmaspi.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "periph.h"
#include "video.h"
//========================================
void DMA_Init(){
uint32_t tmpreg =0;
uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
uint32_t DMA1_Channel3_IRQn = 13;
// Enable DMA1 clock. Bit0 in RCC->AHBENR register
RCC->AHBENR |= (1 << 0); // Bit0 = 1
/* First Disable DMA1_Channel3: reset EN flag (Bit0) in DMA1->CCR3 */
DMA1->CCR3 &= ~((uint16_t)0x0001) ; // Bit0 = 0 => DMA C3 disabled
/* Reset DMA1_Channel3 control register */
DMA1->CCR3 = 0;
/* Reset DMA1_Channel3 remaining bytes register */
DMA1->CNDTR3 = 0;
/* Reset DMA1_Channel3 peripheral address register */
DMA1->CPAR3 = 0;
/* Reset DMA1_Channel3 memory address register */
DMA1->CMAR3 = 0;
/* Reset interrupt pending bits for DMA1 Channel3 (Bits11:8) */
DMA1->IFCR |= (uint32_t)(0x00000F00); // DMA1_Channel3_IT_Mask
/*--------------------------- DMA1_Channel3 CCR Configuration -----------------*/
/* Get the DMA1_Channel3 CCR value */
tmpreg = DMA1->CCR3;
/* Clear MEM2MEM, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
tmpreg &= (uint32_t)0xFFFF800F; // CCR_CLEAR_Mask
/* Configure DMA1_Channel3: data transfer, data size, priority level and mode */
/*
tmpreg |= DMA_DIR_PeripheralDST | DMA_Mode_Normal |
DMA_PeripheralInc_Disable | DMA_MemoryInc_Enable |
DMA_PeripheralDataSize_Byte | DMA_MemoryDataSize_Byte |
DMA_Priority_Medium | DMA_M2M_Disable;
*/
tmpreg |= ((uint32_t)(0x00000010 | 0x00000000 |0x00000000 | 0x00000080 |0x00000000 | 0x00000000 |
0x00001000 | 0x00000000));
/* Write to DMA1_Channel3 CCR */
DMA1->CCR3 = tmpreg;
// DMA1_Channel3 CPAR Configuration : destination peripheral address
DMA1->CPAR3 = (uint32_t)&SPI1->DR;
// Transfer "count" bytes, decrements after each transfer
DMA1->CNDTR3 = VTOTAL; // 52 BYTES
// source: Memory (or periheral) adress
DMA1->CMAR3 = (uint32_t)&fb; //
//========= Config interrupts priority=1, subprio=0 ===============
/*
// Compute the Corresponding IRQ Priority
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = (uint32_t) (1 << tmppre);
tmppriority |= (0 & tmpsub);
tmppriority = tmppriority << 0x04;
NVIC->IP[DMA1_Channel3_IRQn] = tmppriority;
*/
// Enable DMA1 Channel3 interrupt in NVIC
NVIC->ISER[DMA1_Channel3_IRQn >> 5] = (uint32_t) (0x01 << (DMA1_Channel3_IRQn & 0x1F));
// set DMA1 channel3 Transfer complete interrupt TCIE flag (Bit1)
DMA1->CCR3 |= 0x00000002; // Bit1 = 1 => Transfer complete interrupt enabled
DMA1->CCR3 |= 1<<0; // enable DMA1 channel3
}
//=================================================
void SPI_Init(){
uint16_t tmpreg = 0;
unsigned int ra;
//enable portA and SPI CLOCKs
ra = RCC->APB2ENR; // Read APB2 peripheral clock enable register
ra |= 1<<2 | 1<< 12 ; // set bit2 (PORTA) and bit12 (SPI)
RCC->APB2ENR = ra; // write back to APB2 peripheral clock enable register
//configure PA7 to MOSI and PA5 to SCK: CNF= 10 ==> alternate function output push-pull, MODE= 11 ==> 50MHz
ra = PORTA->CRL;
ra &= ~(0x0F<<28); // clear bits(31:28) --> PA8 mode and CNF
ra |= 0x0B << 28; // bits(31:28) = 1011 --> MODE= 11, CNF= 10
ra &= ~(0x0F<<20); // clear bits(23:20) --> PA5 mode and CNF
ra |= 0x0B << 20; // bits(23:20) = 1011 --> MODE= 11, CNF= 10
PORTA->CRL = ra;
/*---------------------------- SPIx CR1 Configuration ------------------------*/
/* Get the SPIx CR1 value */
tmpreg = SPI1->CR1;
/* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
tmpreg &= 0x3040; // CR1_CLEAR_Mask
/* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
master/salve mode, CPOL and CPHA */
/* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
/* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
/* Set LSBFirst bit according to SPI_FirstBit value */
/* Set BR bits according to SPI_BaudRatePrescaler value */
/* Set CPOL bit according to SPI_CPOL value */
/* Set CPHA bit according to SPI_CPHA value */
/*
tmpreg |= (uint16_t)(SPI_Direction | SPI_Mode | SPI_DataSize | SPI_CPOL | SPI_CPHA | SPI_NSS | SPI_BaudRatePrescaler | SPI_FirstBit);
*/
// SPI_BaudRatePrescaler = 0x0008 ==> SPI CLK = 72MHz/4= 18MHz
tmpreg |= (uint16_t)(0x0000 | 0x0104 | 0x0000 | 0x0000 | 0x0000 | 0x0300 | 0x0008 | 0x0000);
/* Write to SPI1 CR1 */
SPI1->CR1 = tmpreg;
// Enable DMA request whenever the Transmit buffer is empty (TXE flag in SPI status register SPI->SR is set).
SPI1->CR2 |= 1<<1; // set bit1
/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
SPI1->I2SCFGR &= 0xF7FF; //SPI_Mode_Select (clear bit11)
/*---------------------------- SPIx CRCPOLY Configuration --------------------*/
/* Write to SPIx CRCPOLY */
//SPI1->CRCPR = 7; // SPI_CRCPolynomial, default = 7
//---------------------
/* Enable SPI1 */
SPI1->CR1 |= 0x0040; // CR1_SPE_Set
}
//====================================
void SPIDMA_Init(){
DMA_Init();
SPI_Init();
}