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
|
/*
ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file SAMA5D2x/hal_lld.h
* @brief SAMA5D2x HAL subsystem low level driver header.
* @pre This module requires the following macros to be defined in the
* @p board.h file:
* - SAMA_MOSCXTCLK.
* - SAMA_OSCXTCLK
* .
* One of the following macros must also be defined:
* - SAMA5D21, SAMA5D22, SAMA5D23, SAMA5D24, SAMA5D25, SAMA5D26,
* SAMA5D27, SAMA5D28.
*
* @addtogroup HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "sama_registry.h"
/* If the device type is not externally defined, for example from the Makefile,
then a file named board.h is included. This file must contain a device
definition compatible with the vendor include file.*/
#if !defined (SAMA5D21) && !defined (SAMA5D22) && !defined (SAMA5D23) && \
!defined (SAMA5D24) && !defined (SAMA5D25) && !defined (SAMA5D26) && \
!defined (SAMA5D27) && !defined (SAMA5D28)
#include "board.h"
#endif
/* Including the device CMSIS header. Note, we are not using the definitions
from this header because we need this file to be usable also from
assembler source files. We verify that the info matches instead.*/
#include "sama5d2x.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name Platform identification macros
* @{
*/
#if defined(SAMA5D21) || defined(__DOXYGEN__)
#define PLATFORM_NAME "500Mhz processor with TrustZone, 16-bit DDR, BGA196"
#elif defined(SAMA5D22)
#define PLATFORM_NAME "500Mhz processor with TrustZone, 16-bit DDR, CAN, BGA196"
#elif defined(SAMA5D23)
#define PLATFORM_NAME "500Mhz processor with TrustZone, 16-bit DDR, CAN, Enhanced Security, BGA196"
#elif defined(SAMA5D24)
#define PLATFORM_NAME "A500Mhz processor with TrustZone, 16/32-bit DDR, USB HSIC, BGA256"
#elif defined(SAMA5D25)
#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, BGA289"
#elif defined(SAMA5D26)
#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, CAN, BGA289"
#elif defined(SAMA5D27)
#define PLATFORM_NAME "500Mhz processor with TrustZone, 16/32-bit DDR, CAN, Enhanced Security, BGA289"
#else
#error "SAMA5D2x device unsupported or not specified"
#endif
/** @} */
/**
* @name Absolute Maximum Ratings
* @{
*/
/**
* @brief Maximum processor clock frequency.
*/
#define SAMA_PCK_MAX 500000000
/**
* @brief Minimum processor clock frequency.
*/
#define SAMA_PCK_MIN 250000000
/**
* @brief Maximum master clock frequency.
*/
#define SAMA_MCK_MAX 166000000
/**
* @brief Minimum master clock frequency.
*/
#define SAMA_MCK_MIN 125000000
/**
* @brief Maximum Main Crystal Oscillator clock frequency.
*/
#define SAMA_MOSCXTCLK_MAX 24000000
/**
* @brief Minimum Main Crystal Oscillator clock frequency.
*/
#define SAMA_MOSCXTCLK_MIN 8000000
/**
* @brief Maximum PLLs input clock frequency.
*/
#define SAMA_PLLIN_MAX 24000000
/**
* @brief Minimum PLLs input clock frequency.
*/
#define SAMA_PLLIN_MIN 800000
/**
* @brief Maximum PLL output clock frequency.
*/
#define SAMA_PLLOUT_MAX 1200000000
/**
* @brief Minimum PLL output clock frequency.
*/
#define SAMA_PLLOUT_MIN 600000000
/** @} */
/**
* @name Internal clock sources
* @{
*/
#define SAMA_MOSCRCCLK 12000000 /**< RC Main oscillator clock. */
#define SAMA_OSCRCCLK 32000 /**< RC Slow oscillator clock. */
/** @} */
/**
* @name SCK_CR register bits definitions
* @{
*/
#define SAMA_OSC_OSCRC (0 << 3) /**< Slow Clock source MOSCRC. */
#define SAMA_OSC_OSCXT (1 << 3) /**< Slow Clock source MOSCXT. */
/** @} */
/**
* @name PCM_MOR register bits definitions
* @{
*/
#define SAMA_MOSC_MOSCRC (0 << 24) /**< Main Clock source MOSCRC. */
#define SAMA_MOSC_MOSCXT (1 << 24) /**< Main Clock source MOSCXT. */
/** @} */
/**
* @name PCM_MCR register bits definitions
* @{
*/
#define SAMA_MCK_SLOW_CLK (0 << 0) /**< MCK source is Slow Clock. */
#define SAMA_MCK_MAIN_CLK (1 << 0) /**< MCK source is Main Clock. */
#define SAMA_MCK_PLLA_CLK (2 << 0) /**< MCK source is PLLA Clock. */
#define SAMA_MCK_UPLL_CLK (3 << 0) /**< MCK source is UPLL Clock. */
#define SAMA_MCK_PRE_DIV1 (0 << 4) /**< MCK not prescaled. */
#define SAMA_MCK_PRE_DIV2 (1 << 4) /**< MCK prescaled by 2. */
#define SAMA_MCK_PRE_DIV4 (2 << 4) /**< MCK prescaled by 4. */
#define SAMA_MCK_PRE_DIV8 (3 << 4) /**< MCK prescaled by 8. */
#define SAMA_MCK_PRE_DIV16 (4 << 4) /**< MCK prescaled by 16. */
#define SAMA_MCK_PRE_DIV32 (5 << 4) /**< MCK prescaled by 32. */
#define SAMA_MCK_PRE_DIV64 (6 << 4) /**< MCK prescaled by 64. */
#define SAMA_MCK_MDIV_DIV1 (0 << 8) /**< MCK is not divided. */
#define SAMA_MCK_MDIV_DIV2 (1 << 8) /**< MCK is divided by 2. */
#define SAMA_MCK_MDIV_DIV3 (3 << 8) /**< MCK is divided by 3. */
#define SAMA_MCK_MDIV_DIV4 (2 << 8) /**< MCK is divided by 4. */
#define SAMA_MCK_PLLADIV2 (1 << 12) /**< PLLA is divided by 2. */
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief Disables the PMC initialization in the HAL.
*/
#if !defined(SAMA_NO_INIT) || defined(__DOXYGEN__)
#define SAMA_NO_INIT FALSE
#endif
/**
* @brief Enables or disables the MOSCRC clock source.
*/
#if !defined(SAMA_MOSCRC_ENABLED) || defined(__DOXYGEN__)
#define SAMA_MOSCRC_ENABLED TRUE
#endif
/**
* @brief Enables or disables the MOSCXT clock source.
*/
#if !defined(SAMA_MOSCXT_ENABLED) || defined(__DOXYGEN__)
#define SAMA_MOSCXT_ENABLED FALSE
#endif
/**
* @brief Main clock source selection.
*/
#if !defined(SAMA_MOSC_SEL) || defined(__DOXYGEN__)
#define SAMA_MOSC_SEL SAMA_MOSC_MOSCRC
#endif
/**
* @brief Slow clock source selection.
*/
#if !defined(SAMA_OSC_SEL) || defined(__DOXYGEN__)
#define SAMA_OSC_SEL SAMA_OSC_OSCRC
#endif
/**
* @brief Master clock source selection.
*/
#if !defined(SAMA_MCK_SEL) || defined(__DOXYGEN__)
#define SAMA_MCK_SEL SAMA_MCK_PLLA_CLK
#endif
/**
* @brief Master clock prescaler.
*/
#if !defined(SAMA_MCK_PRES_VALUE) || defined(__DOXYGEN__)
#define SAMA_MCK_PRES_VALUE 1
#endif
/**
* @brief Master clock divider.
*/
#if !defined(SAMA_MCK_MDIV_VALUE) || defined(__DOXYGEN__)
#define SAMA_MCK_MDIV_VALUE 3
#endif
/**
* @brief PLLA clock multiplier.
*/
#if !defined(SAMA_PLLA_MUL_VALUE) || defined(__DOXYGEN__)
#define SAMA_PLLA_MUL_VALUE 83
#endif
/**
* @brief PLLADIV2 clock divider.
*/
#if !defined(SAMA_PLLADIV2_EN) || defined(__DOXYGEN__)
#define SAMA_PLLADIV2_EN TRUE
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*
* Configuration-related checks.
*/
#if !defined(SAMA5D2x_MCUCONF)
#error "Using a wrong mcuconf.h file, SAMA5D2x_MCUCONF not defined"
#endif
/**
* @brief Slow clock value.
*/
/* Main oscillator is fed by internal RC. */
#if (SAMA_OSC_SEL == SAMA_OSC_OSCRC) || defined(__DOXYGEN__)
#define SAMA_SLOW_CLK SAMA_OSCRCCLK
#elif (SAMA_OSC_SEL == SAMA_OSC_OSCXT)
#define SAMA_SLOW_CLK SAMA_OSCXTCLK
#else
#error "Wrong SAMA_OSC_SEL value."
#endif
/**
* @brief MAIN clock value.
*/
/* Main oscillator is fed by internal RC. */
#if (SAMA_MOSC_SEL == SAMA_MOSC_MOSCRC) || defined(__DOXYGEN__)
#if !SAMA_MOSCRC_ENABLED
#error "Internal RC oscillator disabled (required by SAMA_MOSC_SEL)."
#endif
#define SAMA_MAIN_CLK SAMA_MOSCRCCLK
/* Main oscillator is fed by external XTAL. */
#elif (SAMA_MOSC_SEL == SAMA_MOSC_MOSCXT)
#if !SAMA_MOSCXT_ENABLED
#error "External crystal oscillator disabled (required by SAMA_MOSC_SEL)."
#endif
#define SAMA_MAIN_CLK SAMA_MOSCXTCLK
/* Checks on external crystal range. */
#if (SAMA_MOSCXTCLK > SAMA_MOSCXTCLK_MAX) || \
(SAMA_MOSCXTCLK < SAMA_MOSCXTCLK_MIN)
#error "External crystal oscillator out of range."
#endif
/* Unallowed condition. */
#else
#error "Wrong SAMA_MOSC_SEL value."
#endif /* SAMA_MOSCXTCLK */
#if (SAMA_MCK_SEL == SAMA_MCK_PLLA_CLK) || defined(__DOXYGEN__)
#define SAMA_ACTIVATE_PLLA TRUE
#else
#define SAMA_ACTIVATE_PLLA FALSE
#endif
/**
* @brief PLLAMUL field.
*/
#if ((SAMA_PLLA_MUL_VALUE >= 1) && (SAMA_PLLA_MUL_VALUE <= 127)) || \
defined(__DOXYGEN__)
#define SAMA_PLLA_MUL ((SAMA_PLLA_MUL_VALUE + 1) << 18)
#else
#error "invalid SAMA_PLLA_MUL_VALUE value specified"
#endif
/**
* @brief PLLA input clock frequency.
* @todo Consider to add DIVA to this. On SAMA5D27 DIVA is a nonsense since
* it could be only 1 or 0 whereas 0 means PLLA disabled. This could
* be useful for other chip belonging to this family
*/
#define SAMA_PLLACLKIN SAMA_MAIN_CLK
/* PLLA input frequency range check.*/
#if (SAMA_PLLACLKIN < SAMA_PLLIN_MIN) || (SAMA_PLLACLKIN > SAMA_PLLIN_MAX)
#error "SAMA_PLLACLKIN out of range"
#endif
/**
* @brief PLLA output clock frequency.
*/
#define SAMA_PLLACLKOUT (SAMA_MAIN_CLK * SAMA_PLLA_MUL_VALUE)
/* PLLA output frequency range check.*/
#if (SAMA_PLLACLKOUT < SAMA_PLLOUT_MIN) || (SAMA_PLLACLKOUT > SAMA_PLLOUT_MAX)
#error "SAMA_PLLACLKOUT out of range"
#endif
/**
* @brief PLLADIV2 divider value.
*/
#if SAMA_PLLADIV2_EN || defined(__DOXYGEN__)
#define SAMA_PLLADIV2 SAMA_MCK_PLLADIV2
#else
#define SAMA_PLLADIV 0
#endif
/**
* @brief Master Clock prescaler.
*/
#if (SAMA_MCK_PRES_VALUE == 1) || defined(__DOXYGEN__)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV1
#elif (SAMA_MCK_PRES_VALUE == 2)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV2
#elif (SAMA_MCK_PRES_VALUE == 4)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV4
#elif (SAMA_MCK_PRES_VALUE == 8)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV8
#elif (SAMA_MCK_PRES_VALUE == 16)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV16
#elif (SAMA_MCK_PRES_VALUE == 32)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV32
#elif (SAMA_MCK_PRES_VALUE == 64)
#define SAMA_MCK_PRES SAMA_MCK_PRE_DIV64
#else
#error "Wrong SAMA_MCK_PRES_VALUE."
#endif
/**
* @brief Master Clock divider.
*/
#if (SAMA_MCK_MDIV_VALUE == 1) || defined(__DOXYGEN__)
#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV1
#elif (SAMA_MCK_MDIV_VALUE == 2)
#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV2
#elif (SAMA_MCK_MDIV_VALUE == 3)
#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV3
#elif (SAMA_MCK_MDIV_VALUE == 4)
#define SAMA_MCK_MDIV SAMA_MCK_MDIV_DIV4
#else
#error "Wrong SAMA_MCK_MDIV_VALUE."
#endif
/* Check on MDIV and PLLADIV2 value. */
#if (SAMA_MCK_MDIV == SAMA_MCK_MDIV_DIV3) && !SAMA_PLLADIV2_EN
#error "PLLADIV2 must be always enabled when Main Clock Divider is 3"
#endif
/**
* @brief Processor Clock frequency.
*/
#if (SAMA_MCK_SEL == SAMA_MCK_SLOW_CLK) || defined(__DOXYGEN__)
#define SAMA_PCKOUT (SAMA_SLOW_CLK / SAMA_MCK_PRES_VALUE)
#elif (SAMA_MCK_SEL == SAMA_MCK_MAIN_CLK)
#define SAMA_PCKOUT (SAMA_MAIN_CLK / SAMA_MCK_PRES_VALUE)
#elif (SAMA_MCK_SEL == SAMA_MCK_PLLA_CLK)
#if SAMA_PLLADIV2_EN
#define SAMA_PCKOUT (SAMA_PLLACLKOUT / SAMA_MCK_PRES_VALUE / 2)
#else
#define SAMA_PCKOUT (SAMA_PLLACLKOUT / SAMA_MCK_PRES_VALUE)
#endif
#elif (SAMA_MCK_SEL == SAMA_MCK_UPLL_CLK)
#error "UPLL still unsupported"
#else
#error "Wrong SAMA_MCK_SEL."
#endif
/**
* @brief Master Clock frequency.
*/
#define SAMA_MCKOUT (SAMA_PCKOUT / SAMA_MCK_MDIV_VALUE)
/* Checks on Processor Clock crystal range. */
#if (SAMA_PCKOUT > SAMA_PCK_MAX) || (SAMA_PCKOUT < SAMA_PCK_MIN)
#error "Processor clock frequency out of range."
#endif
/* Checks on Master Clock crystal range. */
#if (SAMA_MCKOUT > SAMA_MCK_MAX) || (SAMA_MCKOUT < SAMA_MCK_MIN)
#error "Master clock frequency out of range."
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void sama_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */
|