cpu_conf.h
8.69 KB
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
/*
* Copyright (C) 2015 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @defgroup cpu_k60 Freescale Kinetis K60
* @ingroup cpu
* @brief CPU specific implementations for the Freescale Kinetis K60
* @{
*
* @file
* @brief Implementation specific CPU configuration options
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef CPU_CONF_H_
#define CPU_CONF_H_
#include "cpu_conf_common.h"
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#if defined(CPU_MODEL_K60DN512VLL10) || defined(CPU_MODEL_K60DN256VLL10)
/* Rev. 2.x silicon */
#define K60_CPU_REV 2
#include "MK60D10.h"
/** The expected CPUID value, can be used to implement a check that we are
* running on the right hardware */
#define K60_EXPECTED_CPUID 0x410fc241u
/* K60 rev 2.x replaced the RNG module in 1.x by the RNGA PRNG module */
#define KINETIS_RNGA (RNG)
#elif defined(CPU_MODEL_K60DN512ZVLL10) || defined(CPU_MODEL_K60DN256ZVLL10)
/* Rev. 1.x silicon */
#define K60_CPU_REV 1
#include "MK60DZ10.h"
/** The expected CPUID value, can be used to implement a check that we are
* running on the right hardware */
#define K60_EXPECTED_CPUID 0x410fc240u
/* K60 rev 1.x has the cryptographically strong RNGB module */
#define KINETIS_RNGB (RNG)
#else
#error Unknown CPU model. Update Makefile.include in the board directory.
#endif
/* Compatibility definitions between the two different Freescale headers */
#include "MK60-comp.h"
/**
* @brief ARM Cortex-M specific CPU configuration
* @{
*/
#define CPU_DEFAULT_IRQ_PRIO (1U)
#define CPU_IRQ_NUMOF (104U)
#define CPU_FLASH_BASE (0x00000000)
/** @} */
/**
* @name GPIO pin mux function numbers
*/
/** @{ */
#define PIN_MUX_FUNCTION_ANALOG 0
#define PIN_MUX_FUNCTION_GPIO 1
/** @} */
/**
* @name GPIO interrupt flank settings
*/
/** @{ */
#define PIN_INTERRUPT_RISING 0b1001
#define PIN_INTERRUPT_FALLING 0b1010
#define PIN_INTERRUPT_EDGE 0b1011
/** @} */
/** @name PORT module clock gates */
/** @{ */
#define PORTA_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT))
#define PORTB_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT))
#define PORTC_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT))
#define PORTD_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT))
#define PORTE_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT))
/** @} */
/**
* @name UART driver settings
*/
/** @{ */
/** UART typedef from CPU header. */
#define KINETIS_UART UART_Type
/** @} */
/**
* @name Clock settings for the LPTMR0 timer
* @{
*/
#define LPTIMER_DEV (LPTMR0) /**< LPTIMER hardware module */
#define LPTIMER_CLKEN() (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 1) /**< Enable LPTMR0 clock gate */
#define LPTIMER_CLKDIS() (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 0) /**< Disable LPTMR0 clock gate */
#define LPTIMER_CLKSRC_MCGIRCLK 0 /**< internal reference clock (4MHz) */
#define LPTIMER_CLKSRC_LPO 1 /**< PMC 1kHz output */
#define LPTIMER_CLKSRC_ERCLK32K 2 /**< RTC clock 32768Hz */
#define LPTIMER_CLKSRC_OSCERCLK 3 /**< system oscillator output, clock from RF-Part */
#ifndef LPTIMER_CLKSRC
#define LPTIMER_CLKSRC LPTIMER_CLKSRC_ERCLK32K /**< default clock source */
#endif
#if (LPTIMER_CLKSRC == LPTIMER_CLKSRC_MCGIRCLK)
#define LPTIMER_CLK_PRESCALE 1
#define LPTIMER_SPEED 1000000
#elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_OSCERCLK)
#define LPTIMER_CLK_PRESCALE 1
#define LPTIMER_SPEED 1000000
#elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_ERCLK32K)
#define LPTIMER_CLK_PRESCALE 0
#define LPTIMER_SPEED 32768
#else
#define LPTIMER_CLK_PRESCALE 0
#define LPTIMER_SPEED 1000
#endif
/** IRQ priority for hwtimer interrupts */
#define LPTIMER_IRQ_PRIO 1
/** IRQ channel for hwtimer interrupts */
#define LPTIMER_IRQ_CHAN LPTMR0_IRQn
#if K60_CPU_REV == 1
/*
* The CNR register latching in LPTMR0 was added in silicon rev 2.x. With
* rev 1.x we do not need to do anything in order to read the current timer counter
* value
*/
#define LPTIMER_CNR_NEEDS_LATCHING 0
#elif K60_CPU_REV == 2
#define LPTIMER_CNR_NEEDS_LATCHING 1
#endif
/** @} */
/**
* @name Power mode hardware details
*/
/** @{ */
#if K60_CPU_REV == 1
#define KINETIS_PMCTRL MC->PMCTRL
#define KINETIS_PMCTRL_SET_MODE(x) (KINETIS_PMCTRL = MC_PMCTRL_LPLLSM(x) | MC_PMCTRL_LPWUI_MASK)
/* Clear LLS protection, clear VLPS, VLPW, VLPR protection */
/* Note: This register can only be written once after each reset, so we must
* enable all power modes that we wish to use. */
#define KINETIS_UNLOCK_PMPROT() (MC->PMPROT |= MC_PMPROT_ALLS_MASK | MC_PMPROT_AVLP_MASK)
#elif K60_CPU_REV == 2
#define KINETIS_PMCTRL SMC->PMCTRL
#define KINETIS_PMCTRL_SET_MODE(x) (KINETIS_PMCTRL = SMC_PMCTRL_STOPM(x) | SMC_PMCTRL_LPWUI_MASK)
#define KINETIS_PMPROT_UNLOCK() (SMC->PMPROT |= SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK)
#else
#error Unknown K60 CPU revision!
#endif
/**
* @name STOP mode bitfield values
* @{
*/
/** @brief Normal STOP */
#define KINETIS_POWER_MODE_NORMAL (0b000)
/** @brief VLPS STOP */
#define KINETIS_POWER_MODE_VLPS (0b010)
/** @brief LLS STOP */
#define KINETIS_POWER_MODE_LLS (0b011)
/** @} */
/**
* @brief Wake up source number for the LPTMR0
*
* In order to let the hwtimer wake the CPU from low power modes, we need to
* enable this wake up source.
*/
#define KINETIS_LLWU_WAKEUP_MODULE_LPTMR 0
/**
* @brief IRQn name to enable LLWU IRQ in NVIC
*/
#define KINETIS_LLWU_IRQ LLW_IRQn
/**
* @brief Enable clock gate on LLWU module.
*/
#define LLWU_UNLOCK() (BITBAND_REG32(SIM->SCGC4, SIM_SCGC4_LLWU_SHIFT) = 1)
/**
* @brief Internal modules whose interrupts are mapped to LLWU wake up sources.
*
* Other modules CAN NOT be used to wake the CPU from LLS or VLLSx power modes.
*/
typedef enum llwu_wakeup_module {
KINETIS_LPM_WAKEUP_MODULE_LPTMR = 0,
KINETIS_LPM_WAKEUP_MODULE_CMP0 = 1,
KINETIS_LPM_WAKEUP_MODULE_CMP1 = 2,
KINETIS_LPM_WAKEUP_MODULE_CMP2 = 3,
KINETIS_LPM_WAKEUP_MODULE_TSI = 4,
KINETIS_LPM_WAKEUP_MODULE_RTC_ALARM = 5,
KINETIS_LPM_WAKEUP_MODULE_RESERVED = 6,
KINETIS_LPM_WAKEUP_MODULE_RTC_SECONDS = 7,
KINETIS_LPM_WAKEUP_MODULE_END,
} llwu_wakeup_module_t;
/**
* @brief enum that maps physical pins to wakeup pin numbers in LLWU module
*
* Other pins CAN NOT be used to wake the CPU from LLS or VLLSx power modes.
*/
typedef enum llwu_wakeup_pin {
KINETIS_LPM_WAKEUP_PIN_PTE1 = 0,
KINETIS_LPM_WAKEUP_PIN_PTE2 = 1,
KINETIS_LPM_WAKEUP_PIN_PTE4 = 2,
KINETIS_LPM_WAKEUP_PIN_PTA4 = 3,
KINETIS_LPM_WAKEUP_PIN_PTA13 = 4,
KINETIS_LPM_WAKEUP_PIN_PTB0 = 5,
KINETIS_LPM_WAKEUP_PIN_PTC1 = 6,
KINETIS_LPM_WAKEUP_PIN_PTC3 = 7,
KINETIS_LPM_WAKEUP_PIN_PTC4 = 8,
KINETIS_LPM_WAKEUP_PIN_PTC5 = 9,
KINETIS_LPM_WAKEUP_PIN_PTC6 = 10,
KINETIS_LPM_WAKEUP_PIN_PTC11 = 11,
KINETIS_LPM_WAKEUP_PIN_PTD0 = 12,
KINETIS_LPM_WAKEUP_PIN_PTD2 = 13,
KINETIS_LPM_WAKEUP_PIN_PTD4 = 14,
KINETIS_LPM_WAKEUP_PIN_PTD6 = 15,
KINETIS_LPM_WAKEUP_PIN_END
} llwu_wakeup_pin_t;
/** @} */
/**
* @name Bit band macros
* @{
*/
/* Generic bitband conversion routine */
/** @brief Convert bit-band region address and bit number to bit-band alias address
*
* @param[in] addr base address in non-bit-banded memory
* @param[in] bit bit number within the word
*
* @return Address of the bit within the bit-band memory region
*/
#define BITBAND_ADDR(addr, bit) ((((uint32_t) (addr)) & 0xF0000000u) + 0x2000000 + ((((uint32_t) (addr)) & 0xFFFFF) << 5) + ((bit) << 2))
/**
* @brief Bitband 32 bit access to variable stored in SRAM_U
*
* @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
* @note var must be declared 'volatile'
*/
#define BITBAND_VAR32(var, bit) (*((uint32_t volatile*) BITBAND_ADDR(&(var), (bit))))
/**
* @brief Bitband 16 bit access to variable stored in SRAM_U
*
* @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
* @note var must be declared 'volatile'
*/
#define BITBAND_VAR16(var, bit) (*((uint16_t volatile*) BITBAND_ADDR(&(var), (bit))))
/**
* @brief Bitband 8 bit access to variable stored in SRAM_U
*
* @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
* @note var must be declared 'volatile'
*/
#define BITBAND_VAR8(var, bit) (*((uint8_t volatile*) BITBAND_ADDR(&(var), (bit))))
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* CPU_CONF_H_ */
/** @} */