Welcome to mirror list, hosted at ThFree Co, Russian Federation.

rcc.h « l0 « stm32 « libopencm3 « include - github.com/thirdpin/libopencm3.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 591944258144d8825b3d4a4a3f121a91faa1dcb4 (plain)
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
/** @defgroup rcc_defines RCC Defines
 *
 * @ingroup STM32L0xx_defines
 *
 * @brief <b>Defined Constants and Types for the STM32L0xx Reset and Clock
 * Control</b>
 *
 * @version 1.0.0
 *
 * @author @htmlonly &copy; @endhtmlonly 2014
 * Karl Palsson <karlp@tweak.net.au>
 *
 * @date 17 November 2014
 *
 * LGPL License Terms @ref lgpl_license
 *  */

/*
 * This file is part of the libopencm3 project.
 *
 * Copyright (C) 2014 Karl Palsson <karlp@tweak.net.au>
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/**@{*/

#ifndef LIBOPENCM3_RCC_H
#define LIBOPENCM3_RCC_H

#include <stdbool.h>
#include <stdint.h>
#include <libopencm3/stm32/pwr.h>

/* --- RCC registers ------------------------------------------------------- */

#define RCC_CR					MMIO32(RCC_BASE + 0x00)
#define RCC_ICSCR				MMIO32(RCC_BASE + 0x04)
#define RCC_CRRCR				MMIO32(RCC_BASE + 0x08)
#define RCC_CFGR				MMIO32(RCC_BASE + 0x0c)
#define RCC_CIER				MMIO32(RCC_BASE + 0x10)
#define RCC_CIFR				MMIO32(RCC_BASE + 0x14)
#define RCC_CICR				MMIO32(RCC_BASE + 0x18)
#define RCC_IOPRSTR				MMIO32(RCC_BASE + 0x1c)
#define RCC_AHBRSTR				MMIO32(RCC_BASE + 0x20)
#define RCC_APB2RSTR				MMIO32(RCC_BASE + 0x24)
#define RCC_APB1RSTR				MMIO32(RCC_BASE + 0x28)
#define RCC_IOPENR				MMIO32(RCC_BASE + 0x2c)
#define RCC_AHBENR				MMIO32(RCC_BASE + 0x30)
#define RCC_APB2ENR				MMIO32(RCC_BASE + 0x34)
#define RCC_APB1ENR				MMIO32(RCC_BASE + 0x38)
#define RCC_IOPSMEN				MMIO32(RCC_BASE + 0x3c)
#define RCC_AHBSMENR				MMIO32(RCC_BASE + 0x40)
#define RCC_APB2SMENR				MMIO32(RCC_BASE + 0x44)
#define RCC_APB1SMENR				MMIO32(RCC_BASE + 0x48)
#define RCC_CCIPR				MMIO32(RCC_BASE + 0x4c)
#define RCC_CSR					MMIO32(RCC_BASE + 0x50)

/* --- RCC_CR values ------------------------------------------------------- */

#define RCC_CR_PLLRDY				(1 << 25)
#define RCC_CR_PLLON				(1 << 24)
#define RCC_CR_RTCPRE_SHIFT			20
#define RCC_CR_RTCPRE_MASK			0x3
#define RCC_CR_RTCPRE_DIV2			0
#define RCC_CR_RTCPRE_DIV4			1
#define RCC_CR_RTCPRE_DIV8			2
#define RCC_CR_RTCPRE_DIV16			3
#define RCC_CR_CSSHSEON                         (1 << 19)
#define RCC_CR_HSEBYP				(1 << 18)
#define RCC_CR_HSERDY				(1 << 17)
#define RCC_CR_HSEON				(1 << 16)
#define RCC_CR_MSIRDY				(1 << 9)
#define RCC_CR_MSION				(1 << 8)
#define RCC_CR_HSI16DIVF			(1 << 4)
#define RCC_CR_HSI16DIVEN			(1 << 3)
#define RCC_CR_HSI16RDY				(1 << 2)
#define RCC_CR_HSI16KERON			(1 << 1)
#define RCC_CR_HSI16ON				(1 << 0)


/* --- RCC_ICSCR values ---------------------------------------------------- */

#define RCC_ICSCR_MSITRIM_SHIFT		24
#define RCC_ICSCR_MSITRIM_MASK		0xff
#define RCC_ICSCR_MSICAL_SHIFT		16
#define RCC_ICSCR_MSICAL_MASK		0xff

#define RCC_ICSCR_MSIRANGE_SHIFT	13
#define RCC_ICSCR_MSIRANGE_MASK		0x7
#define RCC_ICSCR_MSIRANGE_65KHZ	0x0
#define RCC_ICSCR_MSIRANGE_131KHZ	0x1
#define RCC_ICSCR_MSIRANGE_262KHZ	0x2
#define RCC_ICSCR_MSIRANGE_524KHZ	0x3
#define RCC_ICSCR_MSIRANGE_1MHZ		0x4
#define RCC_ICSCR_MSIRANGE_2MHZ		0x5
#define RCC_ICSCR_MSIRANGE_4MHZ		0x6

#define RCC_ICSCR_HSI16TRIM_SHIFT	8
#define RCC_ICSCR_HSI16TRIM_MASK	0x1f
#define RCC_ICSCR_HSI16CAL_SHIFT	0
#define RCC_ICSCR_HSI16CAL_MASK		0xff

/* --- RCC_CRRCR register */

#define RCC_CRRCR_HSI48CAL_SHIFT	8
#define RCC_CRRCR_HSI48CAL_MASK		0xff
#define RCC_CRRCR_HSI48RDY		(1<<1)
#define RCC_CRRCR_HSI48ON		(1<<0)

/* --- RCC_CFGR values ----------------------------------------------------- */

/* MCOPRE */
#define RCC_CFGR_MCOPRE_DIV1	    0
#define RCC_CFGR_MCOPRE_DIV2	    1
#define RCC_CFGR_MCOPRE_DIV4	    2
#define RCC_CFGR_MCOPRE_DIV8	    3
#define RCC_CFGR_MCOPRE_DIV16	    4

/* MCO: Microcontroller clock output */
#define RCC_CFGR_MCO_NOCLK			0x0
#define RCC_CFGR_MCO_SYSCLK			0x1
#define RCC_CFGR_MCO_HSI16			0x2
#define RCC_CFGR_MCO_MSI			0x3
#define RCC_CFGR_MCO_HSE			0x4
#define RCC_CFGR_MCO_PLL			0x5
#define RCC_CFGR_MCO_LSI			0x6
#define RCC_CFGR_MCO_LSE			0x7
#define RCC_CFGR_MCO_HSI48			0x8
#define RCC_CFGR_MCO_SHIFT			24
#define RCC_CFGR_MCO_MASK			0xf

/** @defgroup rcc_cfgr_pdf PLLDIV PLL division factor
 @{*/
#define RCC_CFGR_PLLDIV_DIV2	0x1
#define RCC_CFGR_PLLDIV_DIV3	0x2
#define RCC_CFGR_PLLDIV_DIV4	0x3
/**@}*/
#define RCC_CFGR_PLLDIV_SHIFT	22
#define RCC_CFGR_PLLDIV_MASK	0x3

/** @defgroup rcc_cfgr_pmf PLLMUL PLL multiplication factor
 @{*/
#define RCC_CFGR_PLLMUL_MUL3		0x0
#define RCC_CFGR_PLLMUL_MUL4		0x1
#define RCC_CFGR_PLLMUL_MUL6		0x2
#define RCC_CFGR_PLLMUL_MUL8		0x3
#define RCC_CFGR_PLLMUL_MUL12		0x4
#define RCC_CFGR_PLLMUL_MUL16		0x5
#define RCC_CFGR_PLLMUL_MUL24		0x6
#define RCC_CFGR_PLLMUL_MUL32		0x7
#define RCC_CFGR_PLLMUL_MUL48		0x8
/**@}*/
#define RCC_CFGR_PLLMUL_SHIFT		18
#define RCC_CFGR_PLLMUL_MASK		0xf

/* PLLSRC: PLL entry clock source */
#define RCC_CFGR_PLLSRC_HSI16_CLK	0x0
#define RCC_CFGR_PLLSRC_HSE_CLK		0x1

/* Wakeup from stop clock selection */
#define RCC_CFGR_STOPWUCK_MSI		(0<<15)
#define RCC_CFGR_STOPWUCK_HSI16		(1<<15)

/* PPRE2: APB high-speed prescaler (APB2) */
/** @defgroup rcc_cfgr_apb2pre RCC_CFGR APB2 prescale Factors
@{*/
#define RCC_CFGR_PPRE2_NODIV		0x0
#define RCC_CFGR_PPRE2_DIV2		0x4
#define RCC_CFGR_PPRE2_DIV4		0x5
#define RCC_CFGR_PPRE2_DIV8		0x6
#define RCC_CFGR_PPRE2_DIV16		0x7
/**@}*/
#define RCC_CFGR_PPRE2_MASK		0x7
#define RCC_CFGR_PPRE2_SHIFT		11

/* PPRE1: APB low-speed prescaler (APB1) */
/** @defgroup rcc_cfgr_apb1pre RCC_CFGR APB1 prescale Factors
@{*/
#define RCC_CFGR_PPRE1_NODIV		0x0
#define RCC_CFGR_PPRE1_DIV2		0x4
#define RCC_CFGR_PPRE1_DIV4		0x5
#define RCC_CFGR_PPRE1_DIV8		0x6
#define RCC_CFGR_PPRE1_DIV16		0x7
/**@}*/
#define RCC_CFGR_PPRE1_MASK		0x7
#define RCC_CFGR_PPRE1_SHIFT		8

/* HPRE: AHB prescaler */
/** @defgroup rcc_cfgr_ahbpre RCC_CFGR AHB prescale Factors
@{*/
#define RCC_CFGR_HPRE_NODIV		0x0
#define RCC_CFGR_HPRE_DIV2		0x8
#define RCC_CFGR_HPRE_DIV4		0x9
#define RCC_CFGR_HPRE_DIV8		0xa
#define RCC_CFGR_HPRE_DIV16		0xb
#define RCC_CFGR_HPRE_DIV64		0xc
#define RCC_CFGR_HPRE_DIV128		0xd
#define RCC_CFGR_HPRE_DIV256		0xe
#define RCC_CFGR_HPRE_DIV512		0xf
/**@}*/
#define RCC_CFGR_HPRE_MASK		0xf
#define RCC_CFGR_HPRE_SHIFT		4

/* SWS: System clock switch status */
#define RCC_CFGR_SWS_MSI			0x0
#define RCC_CFGR_SWS_HSI16			0x1
#define RCC_CFGR_SWS_HSE			0x2
#define RCC_CFGR_SWS_PLL			0x3
#define RCC_CFGR_SWS_MASK			0x3
#define RCC_CFGR_SWS_SHIFT			2

/* SW: System clock switch */
#define RCC_CFGR_SW_MSI				0x0
#define RCC_CFGR_SW_HSI16			0x1
#define RCC_CFGR_SW_HSE				0x2
#define RCC_CFGR_SW_PLL				0x3
#define RCC_CFGR_SW_MASK			0x3
#define RCC_CFGR_SW_SHIFT			0

/* --- RCC_CIER - Clock interrupt enable register */

#define RCC_CIER_CSSLSE				(1 << 7)
/* OSC ready interrupt enable bits */
#define RCC_CIER_HSI48RDYIE			(1 << 6)
#define RCC_CIER_MSIRDYIE			(1 << 5)
#define RCC_CIER_PLLRDYIE			(1 << 4)
#define RCC_CIER_HSERDYIE			(1 << 3)
#define RCC_CIER_HSI16RDYIE			(1 << 2)
#define RCC_CIER_LSERDYIE			(1 << 1)
#define RCC_CIER_LSIRDYIE			(1 << 0)

/* --- RCC_CIFR - Clock interrupt flag register */

#define RCC_CIFR_CSSHSEF			(1 << 8)
#define RCC_CIFR_CSSLSEF			(1 << 7)
#define RCC_CIFR_HSI48RDYF			(1 << 6)
#define RCC_CIFR_MSIRDYF			(1 << 5)
#define RCC_CIFR_PLLRDYF			(1 << 4)
#define RCC_CIFR_HSERDYF			(1 << 3)
#define RCC_CIFR_HSI16RDYF			(1 << 2)
#define RCC_CIFR_LSERDYF			(1 << 1)
#define RCC_CIFR_LSIRDYF			(1 << 0)

/* --- RCC_CICR - Clock interrupt clear register */

#define RCC_CICR_CSSHSEC			(1 << 8)
#define RCC_CICR_CSSLSEC			(1 << 7)
#define RCC_CICR_HSI48RDYC			(1 << 6)
#define RCC_CICR_MSIRDYC			(1 << 5)
#define RCC_CICR_PLLRDYC			(1 << 4)
#define RCC_CICR_HSERDYC			(1 << 3)
#define RCC_CICR_HSI16RDYC			(1 << 2)
#define RCC_CICR_LSERDYC			(1 << 1)
#define RCC_CICR_LSIRDYC			(1 << 0)

/* --- RCC_IOPRSTR - GPIO Reset Register */

#define RCC_IOPPRSTR_IOPHRST			(1<<7)
#define RCC_IOPPRSTR_IOPERST			(1<<4)
#define RCC_IOPPRSTR_IOPDRST			(1<<3)
#define RCC_IOPPRSTR_IOPCRST			(1<<2)
#define RCC_IOPPRSTR_IOPBRST			(1<<1)
#define RCC_IOPPRSTR_IOPARST			(1<<0)

/** @defgroup rcc_ahbrstr_rst RCC_AHBRSTR reset values
@{*/
#define RCC_AHBRSTR_CRYPRST			(1 << 24)
#define RCC_AHBRSTR_RNGRST			(1 << 20)
#define RCC_AHBRSTR_TSCRST			(1 << 16)
#define RCC_AHBRSTR_CRCRST			(1 << 12)
#define RCC_AHBRSTR_MIFRST			(1 << 8)
#define RCC_AHBRSTR_DMARST			(1 << 0)
/**@}*/

/** @defgroup rcc_apb2rstr_rst RCC_APB2RSTR reset values
@{*/
#define RCC_APB2RSTR_DBGRST			(1 << 22)
#define RCC_APB2RSTR_USART1RST			(1 << 14)
#define RCC_APB2RSTR_SPI1RST			(1 << 12)
#define RCC_APB2RSTR_ADC1RST			(1 << 9)
#define RCC_APB2RSTR_TIM22RST			(1 << 5)
#define RCC_APB2RSTR_TIM21RST			(1 << 2)
#define RCC_APB2RSTR_SYSCFGRST			(1 << 0)
/**@}*/

/** @defgroup rcc_apb1rstr_rst RCC_APB1RSTR reset values
@{*/
#define RCC_APB1RSTR_LPTIM1RST			(1 << 31)
#define RCC_APB1RSTR_I2C3RST			(1 << 30)
#define RCC_APB1RSTR_DACRST			(1 << 29)
#define RCC_APB1RSTR_PWRRST			(1 << 28)
#define RCC_APB1RSTR_CRSRST			(1 << 27)
#define RCC_APB1RSTR_USBRST			(1 << 23)
#define RCC_APB1RSTR_I2C2RST			(1 << 22)
#define RCC_APB1RSTR_I2C1RST			(1 << 21)
#define RCC_APB1RSTR_USART5RST			(1 << 20)
#define RCC_APB1RSTR_USART4RST			(1 << 19)
#define RCC_APB1RSTR_LPUART1RST			(1 << 18)
#define RCC_APB1RSTR_USART2RST			(1 << 17)
#define RCC_APB1RSTR_SPI2RST			(1 << 14)
#define RCC_APB1RSTR_WWDGRST			(1 << 11)
#define RCC_APB1RSTR_LCDRST			(1 << 9)
#define RCC_APB1RSTR_TIM7RST			(1 << 5)
#define RCC_APB1RSTR_TIM6RST			(1 << 4)
#define RCC_APB1RSTR_TIM3RST			(1 << 1)
#define RCC_APB1RSTR_TIM2RST			(1 << 0)
/**@}*/

/* --- RCC_IOPENR - GPIO clock enable register */

#define RCC_IOPENR_IOPHEN			(1<<7)
#define RCC_IOPENR_IOPEEN			(1<<4)
#define RCC_IOPENR_IOPDEN			(1<<3)
#define RCC_IOPENR_IOPCEN			(1<<2)
#define RCC_IOPENR_IOPBEN			(1<<1)
#define RCC_IOPENR_IOPAEN			(1<<0)

/** @defgroup rcc_ahbenr_en RCC_APHBENR enable values
@{*/
#define RCC_AHBENR_CRYPEN			(1 << 24)
#define RCC_AHBENR_RNGEN			(1 << 20)
#define RCC_AHBENR_TSCEN			(1 << 16)
#define RCC_AHBENR_CRCEN			(1 << 12)
#define RCC_AHBENR_MIFEN			(1 << 8)
#define RCC_AHBENR_DMAEN			(1 << 0)
/**@}*/

/** @defgroup rcc_apb2enr_en RCC_APPB2ENR enable values
@{*/
#define RCC_APB2ENR_DBGEN			(1 << 22)
#define RCC_APB2ENR_USART1EN			(1 << 14)
#define RCC_APB2ENR_SPI1EN			(1 << 12)
#define RCC_APB2ENR_ADC1EN			(1 << 9)
#define RCC_APB2ENR_MIFEN			(1 << 7)
#define RCC_APB2ENR_TIM22EN			(1 << 5)
#define RCC_APB2ENR_TIM21EN			(1 << 2)
#define RCC_APB2ENR_SYSCFGEN			(1 << 0)
/**@}*/

/** @defgroup rcc_apb1enr_en RCC_APB1ENR enable values
@{*/
#define RCC_APB1ENR_LPTIM1EN			(1 << 31)
#define RCC_APB1ENR_DACEN			(1 << 29)
#define RCC_APB1ENR_PWREN			(1 << 28)
#define RCC_APB1ENR_CRSEN			(1 << 27)
#define RCC_APB1ENR_USBEN			(1 << 23)
#define RCC_APB1ENR_I2C2EN			(1 << 22)
#define RCC_APB1ENR_I2C1EN			(1 << 21)
#define RCC_APB1ENR_USART5EN			(1 << 20)
#define RCC_APB1ENR_USART4EN			(1 << 19)
#define RCC_APB1ENR_LPUART1EN			(1 << 18)
#define RCC_APB1ENR_USART2EN			(1 << 17)
#define RCC_APB1ENR_SPI2EN			(1 << 14)
#define RCC_APB1ENR_WWDGEN			(1 << 11)
#define RCC_APB1ENR_LCDEN			(1 << 9)
#define RCC_APB1ENR_TIM7EN			(1 << 5)
#define RCC_APB1ENR_TIM6EN			(1 << 4)
#define RCC_APB1ENR_TIM3EN			(1 << 1)
#define RCC_APB1ENR_TIM2EN			(1 << 0)
/**@}*/

/* --- RCC_IOPSMENR - GPIO Clock enable in sleep mode */

#define RCC_IOPSMENR_IOPHSMEN			(1<<7)
#define RCC_IOPSMENR_IOPESMEN			(1<<4)
#define RCC_IOPSMENR_IOPDSMEN			(1<<3)
#define RCC_IOPSMENR_IOPCSMEN			(1<<2)
#define RCC_IOPSMENR_IOPBSMEN			(1<<1)
#define RCC_IOPSMENR_IOPASMEN			(1<<0)

/* --- RCC_AHBSMENR - AHB periph clock in sleep mode */

#define RCC_AHBSMENR_CRYPSMEN			(1 << 24)
#define RCC_AHBSMENR_RNGSMEN			(1 << 20)
#define RCC_AHBSMENR_TSCSMEN			(1 << 16)
#define RCC_AHBSMENR_CRCSMEN			(1 << 12)
#define RCC_AHBSMENR_MIFSMEN			(1 << 8)
#define RCC_AHBSMENR_DMASMEN			(1 << 0)

/* --- RCC_APB2SMENR - APB2 periph clock in sleep mode */

#define RCC_APB2SMENR_DBGSMEN			(1 << 22)
#define RCC_APB2SMENR_USART1SMEN		(1 << 14)
#define RCC_APB2SMENR_SPI1SMEN			(1 << 12)
#define RCC_APB2SMENR_ADC1SMEN			(1 << 9)
#define RCC_APB2SMENR_MIFSMEN			(1 << 7)
#define RCC_APB2SMENR_TIM22SMEN			(1 << 5)
#define RCC_APB2SMENR_TIM21SMEN			(1 << 2)
#define RCC_APB2SMENR_SYSCFGSMEN		(1 << 0)

/* --- RCC_APB1SMENR - APB1 periph clock in sleep mode */

#define RCC_APB1SMENR_LPTIM1SMEN	(1 << 31)
#define RCC_APB1SMENR_I2C3SMEN		(1 << 30)
#define RCC_APB1SMENR_DACSMEN		(1 << 29)
#define RCC_APB1SMENR_PWRSMEN		(1 << 28)
#define RCC_APB1SMENR_CRSSMEN		(1 << 27)
#define RCC_APB1SMENR_USBSMEN		(1 << 23)
#define RCC_APB1SMENR_I2C2SMEN		(1 << 22)
#define RCC_APB1SMENR_I2C1SMEN		(1 << 21)
#define RCC_APB1SMENR_USART5SMEN	(1 << 20)
#define RCC_APB1SMENR_USART4SMEN	(1 << 19)
#define RCC_APB1SMENR_LPUART1SMEN	(1 << 18)
#define RCC_APB1SMENR_USART2SMEN	(1 << 17)
#define RCC_APB1SMENR_SPI2SMEN		(1 << 14)
#define RCC_APB1SMENR_WWDGSMEN		(1 << 11)
#define RCC_APB1SMENR_LCDSMEN		(1 << 9)
#define RCC_APB1SMENR_TIM7SMEN		(1 << 5)
#define RCC_APB1SMENR_TIM6SMEN		(1 << 4)
#define RCC_APB1SMENR_TIM3SMEN		(1 << 1)
#define RCC_APB1SMENR_TIM2SMEN		(1 << 0)

/* --- RCC_CCIPR - Clock config register */

#define RCC_CCIPR_HSI48SEL		(1<<26)

#define RCC_CCIPR_LPTIM1SEL_APB		0
#define RCC_CCIPR_LPTIM1SEL_LSI		1
#define RCC_CCIPR_LPTIM1SEL_HSI16	2
#define RCC_CCIPR_LPTIM1SEL_LSE		3
#define RCC_CCIPR_LPTIM1SEL_SHIFT	18
#define RCC_CCIPR_LPTIM1SEL_MASK	0x3

#define RCC_CCIPR_I2C3SEL_APB		0
#define RCC_CCIPR_I2C3SEL_SYS		1
#define RCC_CCIPR_I2C3SEL_HSI16		2
#define RCC_CCIPR_I2C3SEL_SHIFT		16
#define RCC_CCIPR_I2C3SEL_MASK		0x3

#define RCC_CCIPR_I2C1SEL_APB		0
#define RCC_CCIPR_I2C1SEL_SYS		1
#define RCC_CCIPR_I2C1SEL_HSI16		2
#define RCC_CCIPR_I2C1SEL_SHIFT		12
#define RCC_CCIPR_I2C1SEL_MASK		0x3

#define RCC_CCIPR_LPUART1SEL_APB	0
#define RCC_CCIPR_LPUART1SEL_SYS	1
#define RCC_CCIPR_LPUART1SEL_HSI16	2
#define RCC_CCIPR_LPUART1SEL_LSE	3
#define RCC_CCIPR_LPUART1SEL_SHIFT	10
#define RCC_CCIPR_LPUART1SEL_MASK	0x3

#define RCC_CCIPR_USART2SEL_APB		0
#define RCC_CCIPR_USART2SEL_SYS		1
#define RCC_CCIPR_USART2SEL_HSI16	2
#define RCC_CCIPR_USART2SEL_LSE		3
#define RCC_CCIPR_USART2SEL_SHIFT	2
#define RCC_CCIPR_USART2SEL_MASK	0x3

#define RCC_CCIPR_USART1SEL_APB		0
#define RCC_CCIPR_USART1SEL_SYS		1
#define RCC_CCIPR_USART1SEL_HSI16	2
#define RCC_CCIPR_USART1SEL_LSE		3
#define RCC_CCIPR_USART1SEL_SHIFT	0
#define RCC_CCIPR_USART1SEL_MASK	0x3

/* --- RCC_CSRT - Control/Status register */

#define RCC_CSR_LPWRRSTF			(1 << 31)
#define RCC_CSR_WWDGRSTF			(1 << 30)
#define RCC_CSR_IWDGRSTF			(1 << 29)
#define RCC_CSR_SFTRSTF				(1 << 28)
#define RCC_CSR_PORRSTF				(1 << 27)
#define RCC_CSR_PINRSTF				(1 << 26)
#define RCC_CSR_OBLRSTF				(1 << 25)
#define RCC_CSR_FWRSTF				(1 << 24)
#define RCC_CSR_RMVF				(1 << 23)
#define RCC_CSR_RESET_FLAGS	(RCC_CSR_LPWRRSTF | RCC_CSR_WWDGRSTF |\
		RCC_CSR_IWDGRSTF | RCC_CSR_SFTRSTF | RCC_CSR_PORRSTF |\
		RCC_CSR_PINRSTF | RCC_CSR_OBLRSTF | RCC_CSR_FWRSTF)
#define RCC_CSR_RTCRST				(1 << 19)
#define RCC_CSR_RTCEN				(1 << 18)
#define RCC_CSR_RTCSEL_SHIFT			(16)
#define RCC_CSR_RTCSEL_MASK			(0x3)
#define RCC_CSR_RTCSEL_NONE			(0x0)
#define RCC_CSR_RTCSEL_LSE			(0x1)
#define RCC_CSR_RTCSEL_LSI			(0x2)
#define RCC_CSR_RTCSEL_HSE			(0x3)
#define RCC_CSR_CSSLSED				(1 << 14)
#define RCC_CSR_CSSLSEON			(1 << 13)
#define RCC_CSR_LSEDRV_SHIFT			11
#define RCC_CSR_LSEDRV_MASK			0x3
#define RCC_CSR_LSEDRV_LOWEST			0
#define RCC_CSR_LSEDRV_MLOW			1
#define RCC_CSR_LSEDRV_MHIGH			2
#define RCC_CSR_LSEDRV_HIGHEST			3
#define RCC_CSR_LSEBYP				(1 << 10)
#define RCC_CSR_LSERDY				(1 << 9)
#define RCC_CSR_LSEON				(1 << 8)
#define RCC_CSR_LSIRDY				(1 << 1)
#define RCC_CSR_LSION				(1 << 0)

struct rcc_clock_scale {
	uint8_t pll_mul;
	uint16_t pll_div;
	uint8_t pll_source;
	uint8_t flash_waitstates;
	enum pwr_vos_scale voltage_scale;
	uint8_t hpre;
	uint8_t ppre1;
	uint8_t ppre2;
	// FIXME enum pwr_vos_scale voltage_scale;
	uint32_t ahb_frequency;
	uint32_t apb1_frequency;
	uint32_t apb2_frequency;
	uint8_t msi_range;
};

/* --- Variable definitions ------------------------------------------------ */
extern uint32_t rcc_ahb_frequency;
extern uint32_t rcc_apb1_frequency;
extern uint32_t rcc_apb2_frequency;

/* --- Function prototypes ------------------------------------------------- */

enum rcc_osc {
	RCC_PLL, RCC_HSE, RCC_HSI48, RCC_HSI16, RCC_MSI, RCC_LSE, RCC_LSI
};


#define _REG_BIT(base, bit)		(((base) << 5) + (bit))

enum rcc_periph_clken {
	/* GPIO peripherals  */
	RCC_GPIOA = _REG_BIT(0x2c, 0),
	RCC_GPIOB = _REG_BIT(0x2c, 1),
	RCC_GPIOC = _REG_BIT(0x2c, 2),
	RCC_GPIOD = _REG_BIT(0x2c, 3),
	RCC_GPIOE = _REG_BIT(0x2c, 4),
	RCC_GPIOH = _REG_BIT(0x2c, 7),

	/* AHB peripherals */
	RCC_DMA = _REG_BIT(0x30, 0),
	RCC_MIF = _REG_BIT(0x30, 8),
	RCC_CRC = _REG_BIT(0x30, 12),
	RCC_TSC = _REG_BIT(0x30, 16),
	RCC_RNG = _REG_BIT(0x30, 20),
	RCC_CRYPT = _REG_BIT(0x30, 24),

	/* APB2 peripherals */
	RCC_SYSCFG = _REG_BIT(0x34, 0),
	RCC_TIM21 = _REG_BIT(0x34, 2),
	RCC_TIM22 = _REG_BIT(0x34, 5),
	RCC_FW = _REG_BIT(0x34, 7),
	RCC_ADC1 = _REG_BIT(0x34, 9),
	RCC_SPI1 = _REG_BIT(0x34, 12),
	RCC_USART1 = _REG_BIT(0x34, 14),
	RCC_DBG = _REG_BIT(0x34, 22),

	/* APB1 peripherals */
	RCC_TIM2 = _REG_BIT(0x38, 0),
	RCC_TIM3 = _REG_BIT(0x38, 1),
	RCC_TIM6 = _REG_BIT(0x38, 4),
	RCC_TIM7 = _REG_BIT(0x38, 5),
	RCC_LCD = _REG_BIT(0x38, 9),
	RCC_WWDG = _REG_BIT(0x38, 11),
	RCC_SPI2 = _REG_BIT(0x38, 14),
	RCC_USART2 = _REG_BIT(0x38, 17),
	RCC_LPUART1 = _REG_BIT(0x38, 18),
	RCC_USART4 = _REG_BIT(0x38, 19),
	RCC_USART5 = _REG_BIT(0x38, 20),
	RCC_I2C1 = _REG_BIT(0x38, 21),
	RCC_I2C2 = _REG_BIT(0x38, 22),
	RCC_USB = _REG_BIT(0x38, 23),
	RCC_CRS = _REG_BIT(0x38, 27),
	RCC_PWR = _REG_BIT(0x38, 28),
	RCC_DAC = _REG_BIT(0x38, 29),
	RCC_I2C3 = _REG_BIT(0x38, 30),
	RCC_LPTIM1 = _REG_BIT(0x38, 31),

	/* GPIO peripherals in sleep mode */
	SCC_GPIOA = _REG_BIT(0x3c, 0),
	SCC_GPIOB = _REG_BIT(0x3c, 1),
	SCC_GPIOC = _REG_BIT(0x3c, 2),
	SCC_GPIOD = _REG_BIT(0x3c, 3),
	SCC_GPIOE = _REG_BIT(0x3c, 4),
	SCC_GPIOH = _REG_BIT(0x3c, 7),

	/* AHB peripherals in sleep mode */
	SCC_DMA = _REG_BIT(0x40, 0),
	SCC_MIF = _REG_BIT(0x40, 8),
	SCC_SRAM = _REG_BIT(0x40, 12),
	SCC_CRC = _REG_BIT(0x40, 12),
	SCC_TSC = _REG_BIT(0x40, 16),
	SCC_RNG = _REG_BIT(0x40, 20),
	SCC_CRYPT = _REG_BIT(0x40, 24),

	/* APB2 peripherals in sleep mode */
	SCC_SYSCFG = _REG_BIT(0x44, 0),
	SCC_TIM21 = _REG_BIT(0x44, 2),
	SCC_TIM22 = _REG_BIT(0x44, 5),
	SCC_ADC1 = _REG_BIT(0x44, 9),
	SCC_SPI1 = _REG_BIT(0x44, 12),
	SCC_USART1 = _REG_BIT(0x44, 14),
	SCC_DBG = _REG_BIT(0x44, 22),

	/* APB1 peripherals in sleep mode */
	SCC_TIM2 = _REG_BIT(0x48, 0),
	SCC_TIM3 = _REG_BIT(0x48, 1),
	SCC_TIM6 = _REG_BIT(0x48, 4),
	SCC_TIM7 = _REG_BIT(0x48, 5),
	SCC_LCD = _REG_BIT(0x48, 9),
	SCC_WWDG = _REG_BIT(0x48, 11),
	SCC_SPI2 = _REG_BIT(0x48, 14),
	SCC_USART2 = _REG_BIT(0x48, 17),
	SCC_LPUART1 = _REG_BIT(0x48, 18),
	SCC_USART4 = _REG_BIT(0x48, 19),
	SCC_USART5 = _REG_BIT(0x48, 20),
	SCC_I2C1 = _REG_BIT(0x48, 21),
	SCC_I2C2 = _REG_BIT(0x48, 22),
	SCC_USB = _REG_BIT(0x48, 23),
	SCC_CRS = _REG_BIT(0x48, 27),
	SCC_PWR = _REG_BIT(0x48, 28),
	SCC_DAC = _REG_BIT(0x48, 29),
	SCC_I2C3 = _REG_BIT(0x48, 30),
	SCC_LPTIM1 = _REG_BIT(0x48, 31),
};

enum rcc_periph_rst {
	/* GPIO peripherals */
	RST_GPIOA = _REG_BIT(0x1c, 0),
	RST_GPIOB = _REG_BIT(0x1c, 1),
	RST_GPIOC = _REG_BIT(0x1c, 2),
	RST_GPIOD = _REG_BIT(0x1c, 3),
	RST_GPIOE = _REG_BIT(0x1c, 4),
	RST_GPIOH = _REG_BIT(0x1c, 7),

	/* AHB peripherals  */
	RST_DMA = _REG_BIT(0x20, 0),
	RST_MIF = _REG_BIT(0x20, 8),
	RST_CRC = _REG_BIT(0x20, 12),
	RST_TSC = _REG_BIT(0x20, 16),
	RST_RNG = _REG_BIT(0x20, 20),
	RST_CRYPT = _REG_BIT(0x20, 24),

	/* APB2 peripherals */
	RST_SYSCFG = _REG_BIT(0x24, 0),
	RST_TIM21 = _REG_BIT(0x24, 2),
	RST_TIM22 = _REG_BIT(0x24, 5),
	RST_ADC1 = _REG_BIT(0x24, 9),
	RST_SPI1 = _REG_BIT(0x24, 12),
	RST_USART1 = _REG_BIT(0x24, 14),
	RST_DBG = _REG_BIT(0x24, 22),

	/* APB1 peripherals*/
	RST_TIM2 = _REG_BIT(0x28, 0),
	RST_TIM3 = _REG_BIT(0x28, 1),
	RST_TIM6 = _REG_BIT(0x28, 4),
	RST_TIM7 = _REG_BIT(0x28, 5),
	RST_LCD = _REG_BIT(0x28, 9),
	RST_WWDG = _REG_BIT(0x28, 11),
	RST_SPI2 = _REG_BIT(0x28, 14),
	RST_USART2 = _REG_BIT(0x28, 17),
	RST_LPUART1 = _REG_BIT(0x28, 18),
	RST_USART4 = _REG_BIT(0x28, 19),
	RST_USART5 = _REG_BIT(0x28, 20),
	RST_I2C1 = _REG_BIT(0x28, 21),
	RST_I2C2 = _REG_BIT(0x28, 22),
	RST_USB = _REG_BIT(0x28, 23),
	RST_CRS = _REG_BIT(0x28, 27),
	RST_PWR = _REG_BIT(0x28, 28),
	RST_DAC = _REG_BIT(0x28, 29),
	RST_I2C3 = _REG_BIT(0x28, 30),
	RST_LPTIM1 = _REG_BIT(0x28, 31),
};
#include <libopencm3/stm32/common/rcc_common_all.h>

BEGIN_DECLS

void rcc_osc_on(enum rcc_osc osc);
void rcc_osc_off(enum rcc_osc osc);
void rcc_osc_ready_int_clear(enum rcc_osc osc);
void rcc_osc_ready_int_enable(enum rcc_osc osc);
void rcc_osc_ready_int_disable(enum rcc_osc osc);
int rcc_osc_ready_int_flag(enum rcc_osc osc);
void rcc_set_hsi48_source_rc48(void);
void rcc_set_hsi48_source_pll(void);
void rcc_set_sysclk_source(enum rcc_osc osc);
void rcc_set_pll_multiplier(uint32_t factor);
void rcc_set_pll_divider(uint32_t factor);
void rcc_set_pll_source(uint32_t pllsrc);
void rcc_set_ppre2(uint32_t ppre2);
void rcc_set_ppre1(uint32_t ppre1);
void rcc_set_hpre(uint32_t hpre);
void rcc_clock_setup_pll(const struct rcc_clock_scale *clock);

void rcc_set_msi_range(uint32_t msi_range);

void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t sel);

void rcc_set_lptim1_sel(uint32_t lptim1_sel);
void rcc_set_lpuart1_sel(uint32_t lpupart1_sel);
void rcc_set_usart1_sel(uint32_t usart1_sel);
void rcc_set_usart2_sel(uint32_t usart2_sel);

END_DECLS

/**@}*/

#endif