1 | #include <stdint.h>
|
2 | #include "stm32f1xx.h"
|
3 |
|
4 | #define HSE_VALUE 8000000U
|
5 | #define SYSCLK_FREQ_72MHz 72000000U
|
6 |
|
7 | // ---------------- GPIOx_CRx MODE+CNF-Bits kombiniert --------------------
|
8 |
|
9 | #define noPin 4 // floating input, reset state
|
10 | #define ANALOG 0 /* analog input */
|
11 | #define OUT_10 1 /* out, 10 MHz */
|
12 | #define OUT_2 2 /* out, 2 MHz */
|
13 | #define OUT_50 3 /* out, 50 MHz */
|
14 | #define IN 4 /* digital input */
|
15 | #define OUT_10_OD 5 /* out, 10 MHz, open drain */
|
16 | #define OUT_2_OD 6 /* out, 2 MHz, open drain */
|
17 | #define OUT_50_OD 7 /* out, 50 MHz, open drain */
|
18 | #define IN_PUPD 8 /* digital input, pull up/down depending on GPIOx_ODR */
|
19 | #define ALTF_10 9 /* alternate function, 10 MHz */
|
20 | #define ALTF_2 10 /* alternate function, 2 MHz */
|
21 | #define ALTF_50 11 /* alternate function, 50 MHz */
|
22 | #define ALTF_10_OD 13 /* alternate function, 10 MHz, open drain */
|
23 | #define ALTF_2_OD 14 /* alternate function, 2 MHz, open drain */
|
24 | #define ALTF_50_OD 15 /* alternate function, 50 MHz, open drain */
|
25 |
|
26 | // ---------------- Port A --------------------
|
27 | #define wf_PA0 OUT_2_OD
|
28 | #define wf_PA1 OUT_2_OD
|
29 | #define wf_PA2 OUT_2_OD
|
30 | #define wf_PA3 OUT_2_OD
|
31 | #define wf_PA4 OUT_10
|
32 | #define wf_PA5 ALTF_50
|
33 | #define wf_PA6 OUT_10
|
34 | #define wf_PA7 ALTF_50
|
35 | #define wf_PA8 noPin
|
36 | #define wf_PA9 noPin
|
37 | #define wf_PA10 noPin
|
38 | #define wf_PA11 ALTF_50
|
39 | #define wf_PA12 ALTF_50
|
40 | #define wf_PA13 IN
|
41 | #define wf_PA14 IN
|
42 | #define wf_PA15 IN_PUPD
|
43 |
|
44 | // ---------------- Port B --------------------
|
45 | #define wf_PB0 noPin
|
46 | #define wf_PB1 noPin
|
47 | #define wf_PB2 IN
|
48 | #define wf_PB3 IN_PUPD
|
49 | #define wf_PB4 OUT_2_OD
|
50 | #define wf_PB5 OUT_2_OD
|
51 | #define wf_PB6 OUT_2_OD
|
52 | #define wf_PB7 OUT_2_OD
|
53 | #define wf_PB8 ALTF_50_OD
|
54 | #define wf_PB9 ALTF_50_OD
|
55 | #define wf_PB10 OUT_2
|
56 | #define wf_PB11 OUT_2
|
57 | #define wf_PB12 OUT_2
|
58 | #define wf_PB13 ALTF_50
|
59 | #define wf_PB14 OUT_2
|
60 | #define wf_PB15 ALTF_50
|
61 |
|
62 | // ---------------- Port C --------------------
|
63 | #define wf_PC0 noPin
|
64 | #define wf_PC1 noPin
|
65 | #define wf_PC2 noPin
|
66 | #define wf_PC3 noPin
|
67 | #define wf_PC4 noPin
|
68 | #define wf_PC5 noPin
|
69 | #define wf_PC6 noPin
|
70 | #define wf_PC7 noPin
|
71 | #define wf_PC8 noPin
|
72 | #define wf_PC9 noPin
|
73 | #define wf_PC10 noPin
|
74 | #define wf_PC11 noPin
|
75 | #define wf_PC12 noPin
|
76 | #define wf_PC13 OUT_2
|
77 | #define wf_PC14 IN
|
78 | #define wf_PC15 IN
|
79 |
|
80 | // ---------------- Port D --------------------
|
81 | #define wf_PD0 IN
|
82 | #define wf_PD1 IN
|
83 | #define wf_PD2 noPin
|
84 | #define wf_PD3 noPin
|
85 | #define wf_PD4 noPin
|
86 | #define wf_PD5 noPin
|
87 | #define wf_PD6 noPin
|
88 | #define wf_PD7 noPin
|
89 | #define wf_PD8 noPin
|
90 | #define wf_PD9 noPin
|
91 | #define wf_PD10 noPin
|
92 | #define wf_PD11 noPin
|
93 | #define wf_PD12 noPin
|
94 | #define wf_PD13 noPin
|
95 | #define wf_PD14 noPin
|
96 | #define wf_PD15 noPin
|
97 |
|
98 | // -------------------- combine to CRx values
|
99 | #define wf_GPIOA_CRL (wf_PA0 | (wf_PA1<<4) | (wf_PA2<<8) | (wf_PA3<<12) | (wf_PA4<<16) | (wf_PA5<<20) | (wf_PA6<<24) | ((unsigned)wf_PA7)<<28)
|
100 | #define wf_GPIOA_CRH (wf_PA8 | (wf_PA9<<4) | (wf_PA10<<8) | (wf_PA11<<12) | (wf_PA12<<16) | (wf_PA13<<20) | (wf_PA14<<24) | ((unsigned)wf_PA15)<<28)
|
101 |
|
102 | #define wf_GPIOB_CRL (wf_PB0 | (wf_PB1<<4) | (wf_PB2<<8) | (wf_PB3<<12) | (wf_PB4<<16) | (wf_PB5<<20) | (wf_PB6<<24) | ((unsigned)wf_PB7)<<28)
|
103 | #define wf_GPIOB_CRH (wf_PB8 | (wf_PB9<<4) | (wf_PB10<<8) | (wf_PB11<<12) | (wf_PB12<<16) | (wf_PB13<<20) | (wf_PB14<<24) | ((unsigned)wf_PB15)<<28)
|
104 |
|
105 | #define wf_GPIOC_CRL (wf_PC0 | (wf_PC1<<4) | (wf_PC2<<8) | (wf_PC3<<12) | (wf_PC4<<16) | (wf_PC5<<20) | (wf_PC6<<24) | ((unsigned)wf_PC7)<<28)
|
106 | #define wf_GPIOC_CRH (wf_PC8 | (wf_PC9<<4) | (wf_PC10<<8) | (wf_PC11<<12) | (wf_PC12<<16) | (wf_PC13<<20) | (wf_PC14<<24) | ((unsigned)wf_PC15)<<28)
|
107 |
|
108 | #define wf_GPIOD_CRL (wf_PD0 | (wf_PD1<<4) | (wf_PD2<<8) | (wf_PD3<<12) | (wf_PD4<<16) | (wf_PD5<<20) | (wf_PD6<<24) | ((unsigned)wf_PD7)<<28)
|
109 | #define wf_GPIOD_CRH (wf_PD8 | (wf_PD9<<4) | (wf_PD10<<8) | (wf_PD11<<12) | (wf_PD12<<16) | (wf_PD13<<20) | (wf_PD14<<24) | ((unsigned)wf_PD15)<<28)
|
110 |
|
111 | // -------------------- peripherial clock enable registers
|
112 | #define wf_APB1ENR ( RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN | RCC_APB1ENR_USBEN )
|
113 | #define wf_APB2ENR ( RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_SPI1EN )
|
114 |
|
115 | // -------------------- AHB clock enabler register
|
116 | #define wf_AHBENR ( RCC_AHBENR_SRAMEN | RCC_AHBENR_FLITFEN )
|
117 |
|
118 | // -------------------- alternate function remap register
|
119 | #define wf_AFIO_MAPR ( AFIO_MAPR_I2C1_REMAP )
|
120 |
|
121 | /* ---------- systick ----------- */
|
122 | volatile uint32_t ticks = 0;
|
123 |
|
124 | void SysTick_Handler (void)
|
125 | {
|
126 | ticks++;
|
127 | }
|
128 |
|
129 | void systick_init (void)
|
130 | {
|
131 | ticks = 0;
|
132 |
|
133 | SysTick->LOAD = (SYSCLK_FREQ_72MHz / 1000)-1;
|
134 | SysTick->VAL = 0;
|
135 | SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
136 | SysTick_CTRL_TICKINT_Msk |
|
137 | SysTick_CTRL_ENABLE_Msk;
|
138 | }
|
139 |
|
140 | void delay_ms (uint32_t ms)
|
141 | {
|
142 | const uint32_t start = ticks;
|
143 | while(ticks - start < ms)
|
144 | __WFI();
|
145 | }
|
146 |
|
147 | /* ---------- sysconfig ---------- */
|
148 | void sysconfig (void)
|
149 | {
|
150 | long L;
|
151 |
|
152 | RCC->CIR = 0;
|
153 | RCC->APB1RSTR = 0;
|
154 | RCC->APB2RSTR = 0;
|
155 | FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2;
|
156 |
|
157 | RCC->CFGR = RCC_CFGR_MCO_HSI;
|
158 |
|
159 | RCC->AHBENR = wf_AHBENR;
|
160 | RCC->APB1ENR = wf_APB1ENR;
|
161 | RCC->APB2ENR = wf_APB2ENR;
|
162 |
|
163 | GPIOA->BSRR = (1U << 4);
|
164 |
|
165 | GPIOA->CRL = wf_GPIOA_CRL;
|
166 | GPIOA->CRH = wf_GPIOA_CRH;
|
167 | GPIOB->CRL = wf_GPIOB_CRL;
|
168 | GPIOB->CRH = wf_GPIOB_CRH;
|
169 | GPIOC->CRL = wf_GPIOC_CRL;
|
170 | GPIOC->CRH = wf_GPIOC_CRH;
|
171 |
|
172 | AFIO->MAPR = wf_AFIO_MAPR;
|
173 |
|
174 | RCC->CR = (16 << RCC_CR_HSICAL_Pos) | RCC_CR_HSION;
|
175 | while ( ! (RCC->CR & RCC_CR_HSIRDY) );
|
176 |
|
177 | RCC->CR |= RCC_CR_HSEON;
|
178 | L = 10000;
|
179 | while (--L) {
|
180 | if (RCC->CR & RCC_CR_HSERDY)
|
181 | break;
|
182 | }
|
183 |
|
184 | if (L) {
|
185 | FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_2;
|
186 | RCC->CFGR = RCC_CFGR_MCO_PLLCLK_DIV2 | (0*RCC_CFGR_USBPRE) |
|
187 | RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLSRC |
|
188 | RCC_CFGR_ADCPRE_DIV8 |
|
189 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV2;
|
190 |
|
191 | RCC->CR |= RCC_CR_PLLON;
|
192 |
|
193 | while ((RCC->CR & RCC_CR_PLLRDY) == 0);
|
194 | RCC->CFGR = ( RCC->CFGR & ~RCC_CFGR_SW_Msk ) | RCC_CFGR_SW_PLL;
|
195 | while( (RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL );
|
196 | }
|
197 |
|
198 | if ( (RCC->BDCR & RCC_BDCR_LSERDY) == 0) {
|
199 | PWR->CR |= (1 << 8);
|
200 | RCC->BDCR = RCC_BDCR_BDRST | RCC_BDCR_RTCEN | RCC_BDCR_LSEON;
|
201 | RCC->BDCR = RCC_BDCR_RTCSEL_LSE | RCC_BDCR_RTCEN | RCC_BDCR_LSEON;
|
202 | }
|
203 | }
|
204 |
|
205 | /* ---------- main ---------- */
|
206 |
|
207 | int main(void)
|
208 | {
|
209 | systick_init();
|
210 |
|
211 | // initialisiere SPI1
|
212 | SPI1->CR2 = 0x00;
|
213 | SPI1->CR1 = SPI_CR1_CPHA
|
214 | | SPI_CR1_CPOL
|
215 | | (0x07 << SPI_CR1_BR_Pos)
|
216 | | SPI_CR1_SSM
|
217 | | SPI_CR1_SPE
|
218 | | SPI_CR1_SSI
|
219 | | SPI_CR1_MSTR;
|
220 |
|
221 | // auf SPI1 senden
|
222 | for(;;) {
|
223 | // Test ob was kommt -> Signal da auf PA6 ist da!
|
224 | GPIOA->BSRR = (1u<<6);
|
225 | delay_ms(1);
|
226 | GPIOA->BRR = (1u<<6);
|
227 | delay_ms(10);
|
228 |
|
229 | while ( ! (SPI1->SR & SPI_SR_TXE) ); // wait until TXE = 1
|
230 | SPI1->DR = 0x33;
|
231 | while ( ! (SPI1->SR & SPI_SR_TXE) ); // wait until TXE = 1
|
232 | while ( (SPI1->SR & SPI_SR_BSY) ); // wait until BSY = 0
|
233 | }
|
234 | }
|