summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/mcux-sdk/drivers/cdog/fsl_cdog.c
blob: 9b985e1cbd220bb89ddf5efb7e61b1bf4b76c0e3 (plain) (blame)
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
/*
 * Copyright 2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_cdog.h"

/*******************************************************************************
 * Definitions
 *******************************************************************************/

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.cdog"
#endif

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/

/*!
 * brief Sets the default configuration of CDOG
 *
 * This function initialize CDOG config structure to default values.
 *
 * param conf CDOG configuration structure
 */
void CDOG_GetDefaultConfig(cdog_config_t *conf)
{
    /* Default configuration after reset */
    conf->lock       = (uint8_t)kCDOG_LockCtrl_Unlock;    /* Lock control */
    conf->timeout    = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Timeout control */
    conf->miscompare = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Miscompare control */
    conf->sequence   = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Sequence control */
    conf->state      = (uint8_t)kCDOG_FaultCtrl_NoAction; /* State control */
    conf->address    = (uint8_t)kCDOG_FaultCtrl_NoAction; /* Address control */
    conf->irq_pause  = (uint8_t)kCDOG_IrqPauseCtrl_Run;   /* IRQ pause control */
    conf->debug_halt = (uint8_t)kCDOG_DebugHaltCtrl_Run;  /* Debug halt control */
    return;
}

/*!
 * brief Sets secure counter and instruction timer values
 *
 * This function sets value in RELOAD and START registers for instruction timer.
 *
 * param base CDOG peripheral base address
 * param reload reload value
 * param start start value
 */
void CDOG_Start(CDOG_Type *base, uint32_t reload, uint32_t start)
{
    base->RELOAD = reload;
    base->START  = start;
}

/*!
 * brief Stops secure counter and instruction timer
 *
 * This function stops instruction timer and secure counter.
 * This also change state of CDOG to IDLE.
 *
 * param base CDOG peripheral base address
 * param stop expected value which will be compared with value of secure counter
 */
void CDOG_Stop(CDOG_Type *base, uint32_t stop)
{
    base->STOP = stop;
}

/*!
 * brief Sets secure counter and instruction timer values
 *
 * This function sets value in STOP, RELOAD and START registers
 * for instruction timer and secure counter.
 *
 * param base CDOG peripheral base address
 * param stop expected value which will be compared with value of secure counter
 * param reload reload value for instruction timer
 * param start start value for secure timer
 */
void CDOG_Set(CDOG_Type *base, uint32_t stop, uint32_t reload, uint32_t start)
{
    base->STOP   = stop;
    base->RELOAD = reload;
    base->START  = start;
}

/*!
 * brief Add value to secure counter
 *
 * This function add specified value to secure counter.
 *
 * param base CDOG peripheral base address.
 * param add Value to be added.
 */
void CDOG_Add(CDOG_Type *base, uint32_t add)
{
    base->ADD = (secure_counter_t)add;
}

/*!
 * brief Add 1 to secure counter
 *
 * This function add 1 to secure counter.
 *
 * param base CDOG peripheral base address.
 * param add Value to be added.
 */
void CDOG_Add1(CDOG_Type *base)
{
    base->ADD1 = (secure_counter_t)0x1U;
}

/*!
 * brief Add 16 to secure counter
 *
 * This function add 16 to secure counter.
 *
 * param base CDOG peripheral base address.
 * param add Value to be added.
 */
void CDOG_Add16(CDOG_Type *base)
{
    base->ADD16 = (secure_counter_t)0x1U;
}

/*!
 * brief Add 256 to secure counter
 *
 * This function add 256 to secure counter.
 *
 * param base CDOG peripheral base address.
 * param add Value to be added.
 */
void CDOG_Add256(CDOG_Type *base)
{
    base->ADD256 = (secure_counter_t)0x1U;
}

/*!
 * brief Substract value to secure counter
 *
 * This function substract specified value to secure counter.
 *
 * param base CDOG peripheral base address.
 * param sub Value to be substracted.
 */
void CDOG_Sub(CDOG_Type *base, uint32_t sub)
{
    base->SUB = (secure_counter_t)sub;
}

/*!
 * brief Substract 1 from secure counter
 *
 * This function substract specified 1 from secure counter.
 *
 * param base CDOG peripheral base address.
 */
void CDOG_Sub1(CDOG_Type *base)
{
    base->SUB1 = (secure_counter_t)0x1U;
}

/*!
 * brief Substract 16 from secure counter
 *
 * This function substract specified 16 from secure counter.
 *
 * param base CDOG peripheral base address.
 */
void CDOG_Sub16(CDOG_Type *base)
{
    base->SUB16 = (secure_counter_t)0x1U;
}

/*!
 * brief Substract 256 from secure counter
 *
 * This function substract specified 256 from secure counter.
 *
 * param base CDOG peripheral base address.
 */
void CDOG_Sub256(CDOG_Type *base)
{
    base->SUB256 = (secure_counter_t)0x1U;
}

/*!
 * brief Checks secure counter.
 *
 * This function compares stop value with secure counter value
 * by writting to RELOAD refister.
 *
 * param base CDOG peripheral base address
 * param check expected (stop) value.
 */
void CDOG_Check(CDOG_Type *base, uint32_t check)
{
    base->RESTART = check;
}

/*!
 * brief Set the CDOG persistent word.
 *
 * param base CDOG peripheral base address.
 * param value The value to be written.
 */
void CDOG_WritePersistent(CDOG_Type *base, uint32_t value)
{
    base->PERSISTENT = value;
}

/*!
 * brief Get the CDOG persistent word.
 *
 * param base CDOG peripheral base address.
 * return The persistent word.
 */
uint32_t CDOG_ReadPersistent(CDOG_Type *base)
{
    return base->PERSISTENT;
}

/*!
 * brief Initialize CDOG
 *
 * This function initializes CDOG block and setting.
 *
 * param base CDOG peripheral base address
 * param conf CDOG configuration structure
 * return Status of the init operation
 */
status_t CDOG_Init(CDOG_Type *base, cdog_config_t *conf)
{
    /* Ungate clock to CDOG engine and reset it */
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#ifdef CDOG_CLOCKS
    CLOCK_EnableClock(kCLOCK_Cdog);
#endif /* CDOG_CLOCKS */
#endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

#if !(defined(FSL_FEATURE_CDOG_HAS_NO_RESET) && FSL_FEATURE_CDOG_HAS_NO_RESET)
    RESET_PeripheralReset(kCDOG_RST_SHIFT_RSTn);
#endif /* !FSL_FEATURE_CDOG_HAS_NO_RESET */

    if (base->CONTROL == 0x0U)
    {
        /* CDOG is not in IDLE mode, which may be cause after SW reset. */
        /* Writing to CONTROL register will trigger fault. */
        return kStatus_Fail;
    }

    /* Clear pending errors, otherwise the device will reset */
    /* itself immediately after enable Code Watchdog */
    if ((uint32_t)kCDOG_LockCtrl_Lock ==
        ((base->CONTROL & CDOG_CONTROL_LOCK_CTRL_MASK) >> CDOG_CONTROL_LOCK_CTRL_SHIFT))

    {
        CDOG->FLAGS = CDOG_FLAGS_TO_FLAG(1U) | CDOG_FLAGS_MISCOM_FLAG(1U) | CDOG_FLAGS_SEQ_FLAG(1U) |
                      CDOG_FLAGS_CNT_FLAG(1U) | CDOG_FLAGS_STATE_FLAG(1U) | CDOG_FLAGS_ADDR_FLAG(1U) |
                      CDOG_FLAGS_POR_FLAG(1U);
    }
    else
    {
        CDOG->FLAGS = CDOG_FLAGS_TO_FLAG(0U) | CDOG_FLAGS_MISCOM_FLAG(0U) | CDOG_FLAGS_SEQ_FLAG(0U) |
                      CDOG_FLAGS_CNT_FLAG(0U) | CDOG_FLAGS_STATE_FLAG(0U) | CDOG_FLAGS_ADDR_FLAG(0U) |
                      CDOG_FLAGS_POR_FLAG(0U);
    }

    base->CONTROL =
        CDOG_CONTROL_TIMEOUT_CTRL(conf->timeout) |       /* Action if the timeout event is triggered  */
        CDOG_CONTROL_MISCOMPARE_CTRL(conf->miscompare) | /* Action if the miscompare error event is triggered  */
        CDOG_CONTROL_SEQUENCE_CTRL(conf->sequence) |     /* Action if the sequence error event is triggered  */
        CDOG_CONTROL_STATE_CTRL(conf->state) |           /* Action if the state error event is triggered  */
        CDOG_CONTROL_ADDRESS_CTRL(conf->address) |       /* Action if the address error event is triggered */
        CDOG_CONTROL_IRQ_PAUSE(conf->irq_pause) |        /* Pause running during interrupts setup */
        CDOG_CONTROL_DEBUG_HALT_CTRL(
            conf->debug_halt) |             /* Halt CDOG timer during debug so we have chance to debug code */
        CDOG_CONTROL_LOCK_CTRL(conf->lock); /* Lock control register */

    NVIC_EnableIRQ(CDOG_IRQn);

    return kStatus_Success;
}

/*!
 * brief Deinitialize CDOG
 *
 * This function stops CDOG secure counter.
 *
 * param base CDOG peripheral base address
 */
void CDOG_Deinit(CDOG_Type *base)
{
    NVIC_DisableIRQ(CDOG_IRQn);

#if !(defined(FSL_FEATURE_CDOG_HAS_NO_RESET) && FSL_FEATURE_CDOG_HAS_NO_RESET)
    RESET_SetPeripheralReset(kCDOG_RST_SHIFT_RSTn);
#endif /* !FSL_FEATURE_CDOG_HAS_NO_RESET */

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
#ifdef CDOG_CLOCKS
    CLOCK_DisableClock(kCLOCK_Cdog);
#endif /* CDOG_CLOCKS */
#endif /* !FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}