aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports/SAMA/SAMA5D2x/hal_lld.h
blob: c1b1e14d56997621f40a7498a51160ef358e52fa (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
/*
    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"

/*===========================================================================*/
/* 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   Defines if the code is running in the secure side of the ARM Trust
 *          Zone. It must be @p TRUE whenever the code is compiled for the
 *          secure side.
 */
#if !defined(SAMA_HAL_IS_SECURE) || defined(__DOXYGEN__)
#define SAMA_HAL_IS_SECURE                  TRUE
#endif

/**
 * @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_PCK                            (SAMA_SLOW_CLK / SAMA_MCK_PRES_VALUE)
#elif (SAMA_MCK_SEL == SAMA_MCK_MAIN_CLK)
#define SAMA_PCK                            (SAMA_MAIN_CLK / SAMA_MCK_PRES_VALUE)
#elif (SAMA_MCK_SEL == SAMA_MCK_PLLA_CLK)
#if SAMA_PLLADIV2_EN
#define SAMA_PCK                            (SAMA_PLLACLKOUT / SAMA_MCK_PRES_VALUE / 2)
#else
#define SAMA_PCK                            (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_MCK                            (SAMA_PCK / SAMA_MCK_MDIV_VALUE)

/* Checks on Processor Clock crystal range. */
#if (SAMA_PCK > SAMA_PCK_MAX) || (SAMA_PCK < SAMA_PCK_MIN)
#error "Processor clock frequency out of range."
#endif

/* Checks on Master Clock crystal range. */
#if (SAMA_MCK > SAMA_MCK_MAX) || (SAMA_MCK < SAMA_MCK_MIN)
#error "Master clock frequency out of range."
#endif

/**
 * @brief   Matrix H64H32 clock ratio.
 */
#if ((SAMA_H64MX_H32MX_RATIO == 2) || defined(__DOXYGEN__))
#define SAMA_H64MX_H32MX_DIV  PMC_MCKR_H32MXDIV_H32MXDIV2
#elif (SAMA_H64MX_H32MX_RATIO == 1)
#define SAMA_H64MX_H32MX_DIV  PMC_MCKR_H32MXDIV_H32MXDIV1
#if (SAMA_MCK > 83000000)
#error "Invalid H32MXCLK. MCK > 83MHz wants SAMA_H64MX_H32MX_RATIO == 2"
#endif
#else
#error "H64MX H32MX clock ratio out of range."
#endif

/**
 * @brief   UARTx clock.
 */
#define SAMA_UART0CLK                       (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_UART1CLK                       (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_UART2CLK                       (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_UART3CLK                       (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_UART4CLK                       (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)

/**
 * @brief   FLEXCOMx clock.
 */
#define SAMA_FLEXCOM0CLK                    (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_FLEXCOM1CLK                    (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_FLEXCOM2CLK                    (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_FLEXCOM3CLK                    (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_FLEXCOM4CLK                    (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)

/**
 * @brief   TCx clock.
 */
#define SAMA_TC0CLK                         (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
#define SAMA_TC1CLK                         (SAMA_MCK / SAMA_H64MX_H32MX_RATIO)
/*===========================================================================*/
/* Driver data structures and types.                                         */
/*===========================================================================*/

/*===========================================================================*/
/* Driver macros.                                                            */
/*===========================================================================*/

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

/* Various helpers.*/
#include "sama_pmc.h"
#include "aic.h"
#include "sama_matrix.h"
#include "sama_xdmac.h" 
#include "sama_cache.h"
#include "hal_tc_lld.h"

#ifdef __cplusplus
extern "C" {
#endif
  void hal_lld_init(void);
  void sama_clock_init(void);
#ifdef __cplusplus
}
#endif

#endif /* _HAL_LLD_H_ */

/** @} */