1 /*
2 * Copyright (c) 2021-2024, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== hal_cc23x0rx.c ========
34 */
35
36 #include <ti/drivers/Power.h>
37
38 #include <ti/drivers/Temperature.h>
39
40 #include <ti/devices/DeviceFamily.h>
41 #include DeviceFamily_constructPath(inc/hw_types.h)
42 #include DeviceFamily_constructPath(inc/hw_memmap.h)
43 #include DeviceFamily_constructPath(inc/hw_systim.h)
44 #include DeviceFamily_constructPath(inc/hw_ints.h)
45 #include DeviceFamily_constructPath(inc/hw_evtsvt.h)
46 #include DeviceFamily_constructPath(inc/hw_clkctl.h)
47 #include DeviceFamily_constructPath(inc/hw_ckmd.h)
48
49 #include DeviceFamily_constructPath(inc/hw_lrfdmdm.h)
50 #include DeviceFamily_constructPath(inc/hw_lrfddbell.h)
51
52 #include DeviceFamily_constructPath(driverlib/lrfd.h)
53
54 #include <ti/log/Log.h>
55
56 #include <ti/drivers/rcl/hal/hal.h>
57
58 #ifndef SOCFPGA
59 /* FPGA doesn't support Standby */
60 static int hal_power_post_notify_fxn(unsigned int eventType, uintptr_t eventArg, uintptr_t clientArg);
61 Power_NotifyObj powerAwakeStandbyObj;
62 Power_NotifyObj powerEnterStandbyObj;
63
64 static void (*rclPowerNotify)(RCL_PowerEvent) = NULL;
65 #endif
66 static void hal_cancel_lrfd_systim0(void);
67
68 #define RCL_DEFAULT_HFTRACKCTL_RATIO CKMD_HFTRACKCTL_RATIO_REF48M
69
70 static HwiP_Struct schedHwi;
71 void (*halSchedFsmCb)(void) = NULL;
72
RF_schedHwi(uintptr_t a)73 static void RF_schedHwi(uintptr_t a)
74 {
75 (void) a;
76 if (halSchedFsmCb != NULL)
77 {
78 halSchedFsmCb();
79 }
80 }
81
82 static HwiP_Struct dispatchHwi;
83 void (*halDispatchFsmCb)(void) = NULL;
RF_dispatchHwi(uintptr_t a)84 static void RF_dispatchHwi(uintptr_t a)
85 {
86 (void) a;
87 if (halDispatchFsmCb != NULL)
88 {
89 halDispatchFsmCb();
90 }
91 }
92
93 static HwiP_Struct commandHwi;
94 void (*halCommandFsmCb)(void) = NULL;
RF_commandHwi(uintptr_t a)95 static void RF_commandHwi(uintptr_t a)
96 {
97 (void) a;
98 if (halCommandFsmCb != NULL)
99 {
100 halCommandFsmCb();
101 }
102 }
103
hal_get_command_ifg_reg(void)104 uint32_t hal_get_command_ifg_reg(void)
105 {
106 uint32_t dbellIrq;
107 /* Using masked interrupt */
108 dbellIrq = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_MIS0);
109 /* Remove SYSTIM 0 and 1 interrupts, as they should be handled by hal_check_clear_timer_compare() */
110 dbellIrq &= ~(LRFDDBELL_MIS0_SYSTIM0_M | LRFDDBELL_MIS0_SYSTIM1_M);
111 /* Clear interrupts (unmasked only) */
112 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = dbellIrq;
113
114 return dbellIrq;
115 }
116
hal_get_dispatch_ifg_reg(void)117 uint32_t hal_get_dispatch_ifg_reg(void)
118 {
119 uint32_t dbellIrq;
120 /* Using masked interrupt */
121 dbellIrq = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_MIS1);
122 /* Clear interrupts (unmasked only) */
123 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR1) = dbellIrq;
124
125 return dbellIrq;
126 }
127
128 /*
129 * Initialize RCL interrupt handlers
130 */
hal_init_fsm(void (* dispatchFsmCb)(void),void (* schedFsmCb)(void),void (* commandFsmCb)(void))131 void hal_init_fsm(void (*dispatchFsmCb)(void), void (*schedFsmCb)(void),
132 void (*commandFsmCb)(void))
133 {
134 HwiP_Params hp;
135 HwiP_Params_init(&hp);
136 #ifdef DeviceFamily_CC27XX
137 hp.priority = INT_PRI_LEVEL4;
138 #else
139 hp.priority = INT_PRI_LEVEL2;
140 #endif
141 HwiP_construct(&schedHwi, INT_CPUIRQ4, RF_schedHwi, &hp);
142 #ifdef DeviceFamily_CC27XX
143 hp.priority = INT_PRI_LEVEL2;
144 #else
145 hp.priority = INT_PRI_LEVEL1;
146 #endif
147 HwiP_construct(&dispatchHwi, INT_LRFD_IRQ1, RF_dispatchHwi, &hp);
148 #ifdef DeviceFamily_CC27XX
149 hp.priority = INT_PRI_LEVEL1;
150 #else
151 hp.priority = INT_PRI_LEVEL0;
152 #endif
153 HwiP_construct(&commandHwi, INT_LRFD_IRQ0, RF_commandHwi, &hp);
154
155 halDispatchFsmCb = dispatchFsmCb;
156 halSchedFsmCb = schedFsmCb;
157 halCommandFsmCb = commandFsmCb;
158 /* TODO: See RCL-345 */
159
160 HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ4SEL) = 0xE; /* LRFDIRQ2 */
161 }
162
163
hal_trigger_command_fsm(void)164 void hal_trigger_command_fsm(void)
165 {
166 /* Software trig command FSM */
167 HwiP_post(INT_LRFD_IRQ0);
168 }
169
hal_trigger_dispatch_fsm(void)170 void hal_trigger_dispatch_fsm(void)
171 {
172 /* Software trig dispatch IRQ */
173 HwiP_post(INT_LRFD_IRQ1);
174 }
175
hal_trigger_scheduler_fsm(void)176 void hal_trigger_scheduler_fsm(void)
177 {
178 /* Software schedule IRQ */
179 HwiP_post(INT_CPUIRQ4);
180 }
181
hal_get_current_time(void)182 uint32_t hal_get_current_time(void)
183 {
184 return HWREG(SYSTIM_BASE + SYSTIM_O_TIME250N);
185 }
186
187 enum {
188 SYSTIM_CH2_SETUP = 1, /* Early start, to kick off setup */
189 SYSTIM_CH2_START = 2, /* Start event to radio */
190 SYSTIM_CH2_STOP = 3, /* Hard stop time */
191 } channel2usage = SYSTIM_CH2_SETUP;
192
hal_enable_setup_time_irq(void)193 void hal_enable_setup_time_irq(void)
194 {
195 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) | LRFDDBELL_IMASK0_SYSTIM0_M;
196 }
197
hal_setup_setup_time(uint32_t time)198 void hal_setup_setup_time(uint32_t time)
199 {
200 channel2usage = SYSTIM_CH2_SETUP;
201 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = LRFDDBELL_ICLR0_SYSTIM0_M;
202 HWREG(SYSTIM_BASE + SYSTIM_O_CH2CC) = time;
203 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) | LRFDDBELL_IMASK0_SYSTIM0_M;
204 #ifndef SOCFPGA
205 /* The power driver uses SYSTIM_0_IMASK to restore the timeouts (including CH2).
206 Therefore, we need to set this register in case the system goes into standby. */
207 HWREG(SYSTIM_BASE + SYSTIM_O_IMSET) = SYSTIM_IMSET_EV2_SET;
208 #endif
209 }
210
hal_setup_start_time(uint32_t time)211 void hal_setup_start_time(uint32_t time)
212 {
213 channel2usage = SYSTIM_CH2_START;
214 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = LRFDDBELL_ICLR0_SYSTIM0_M;
215 HWREG(SYSTIM_BASE + SYSTIM_O_CH2CC) = time;
216 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) | LRFDDBELL_IMASK0_SYSTIM0_M;
217 }
218
hal_setup_hard_stop_time(uint32_t time)219 void hal_setup_hard_stop_time(uint32_t time)
220 {
221 channel2usage = SYSTIM_CH2_STOP;
222 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = LRFDDBELL_ICLR0_SYSTIM0_M;
223 HWREG(SYSTIM_BASE + SYSTIM_O_CH2CC) = time;
224 /* Interrupt is not always needed, as event will be handled by PBE */
225 }
226
hal_enable_hard_stop_time_irq(void)227 void hal_enable_hard_stop_time_irq(void)
228 {
229 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) | LRFDDBELL_IMASK0_SYSTIM0_M;
230 }
231
hal_disable_hard_stop_time_irq(void)232 void hal_disable_hard_stop_time_irq(void)
233 {
234 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) & ~LRFDDBELL_IMASK0_SYSTIM0_M;
235 }
236
hal_setup_graceful_stop_time(uint32_t time)237 void hal_setup_graceful_stop_time(uint32_t time)
238 {
239 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = LRFDDBELL_ICLR0_SYSTIM1_M;
240 HWREG(SYSTIM_BASE + SYSTIM_O_CH3CC) = time;
241 /* Interrupt is not always needed, as event will be handled by PBE */
242 }
243
hal_enable_graceful_stop_time_irq(void)244 void hal_enable_graceful_stop_time_irq(void)
245 {
246 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) | LRFDDBELL_IMASK0_SYSTIM1_M;
247 }
248
hal_cancel_lrfd_systim0(void)249 static void hal_cancel_lrfd_systim0(void)
250 {
251 HWREG(SYSTIM_BASE + SYSTIM_O_CH2CC) = 0;
252 HWREG(SYSTIM_BASE + SYSTIM_O_CH2CFG) = SYSTIM_CH2CFG_MODE_CAPT;
253 HWREG(SYSTIM_BASE + SYSTIM_O_CH2CFG) = SYSTIM_CH2CFG_MODE_DIS;
254 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) & (~LRFDDBELL_IMASK0_SYSTIM0_M);
255 #ifndef SOCFPGA
256 /* The power driver uses SYSTIM_0_IMASK to restore the timeouts (including CH2).
257 Therefore, we need to clear the CH2 IMASK field in addition. */
258 HWREG(SYSTIM_BASE + SYSTIM_O_IMCLR) = SYSTIM_IMCLR_EV2_CLR;
259 #endif
260 }
261
hal_cancel_setup_time(void)262 void hal_cancel_setup_time(void)
263 {
264 hal_cancel_lrfd_systim0();
265 }
266
hal_cancel_start_time(void)267 void hal_cancel_start_time(void)
268 {
269 hal_cancel_lrfd_systim0();
270 }
271
hal_cancel_hard_stop_time(void)272 void hal_cancel_hard_stop_time(void)
273 {
274 hal_cancel_lrfd_systim0();
275 }
276
hal_cancel_graceful_stop_time(void)277 void hal_cancel_graceful_stop_time(void)
278 {
279 HWREG(SYSTIM_BASE + SYSTIM_O_CH3CC) = 0;
280 HWREG(SYSTIM_BASE + SYSTIM_O_CH3CFG) = SYSTIM_CH3CFG_MODE_CAPT;
281 HWREG(SYSTIM_BASE + SYSTIM_O_CH3CFG) = SYSTIM_CH3CFG_MODE_DIS;
282 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) & ~LRFDDBELL_IMASK0_SYSTIM1_M;
283 }
284
hal_enable_clk_buffer(void)285 void hal_enable_clk_buffer(void)
286 {
287 #ifndef SOCFPGA
288 /* FPGA doesn't support standby */
289 HWREG( CKMD_BASE + CKMD_O_HFXTCTL ) |= CKMD_HFXTCTL_HPBUFEN;
290 #endif
291 }
292
hal_setup_sync_found_cap(void)293 void hal_setup_sync_found_cap(void)
294 {
295 /* SRAT sync found repeat capture config */
296 /* Route event_ibus(21) (mdm) to DBELL input (capt_sources[0]) */
297 HWREG_WRITE_LRF(LRFDMDM_BASE + LRFDMDM_O_SYSTIMEVTMUX0) = (21 << LRFDMDM_SYSTIMEVTMUX0_SEL0_S);
298 /* Route through DBELL */
299 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_SYSTIMOEV) = (LRFDDBELL_SYSTIMOEV_SRC2_MCESYSTIM0);
300 /* SYSTIM channel 4 uses srat_ievent(0) as repeated capture trigger */
301 HWREG(SYSTIM_BASE + SYSTIM_O_CH4CFG) |= SYSTIM_CH4CFG_INP_RISE | SYSTIM_CH4CFG_MODE_CAPT | SYSTIM_CH4CFG_REARM_EN;
302 }
303
hal_check_clear_timer_compare(void)304 HalTimerEvent hal_check_clear_timer_compare(void)
305 {
306 HalTimerEvent event = HAL_TIMER_EVT_NONE;
307
308 uint32_t mis0 = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_MIS0);
309
310 /* Start or hard-stop takes priority, meaning hard-stop takes priority over graceful. */
311 if (mis0 & LRFDDBELL_MIS0_SYSTIM0_M)
312 {
313 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) & (~LRFDDBELL_IMASK0_SYSTIM0_M);
314 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = LRFDDBELL_ICLR0_SYSTIM0_M;
315 #ifndef SOCFPGA
316 /* The power driver uses SYSTIM_0_IMASK to restore the timeouts (including CH2).
317 Therefore, we need to clear the CH2 IMASK field in addition. */
318 HWREG(SYSTIM_BASE + SYSTIM_O_IMCLR) = SYSTIM_IMCLR_EV2_CLR;
319 #endif
320 switch (channel2usage)
321 {
322 case SYSTIM_CH2_SETUP:
323 event = HAL_TIMER_EVT_SETUP;
324 break;
325 case SYSTIM_CH2_START:
326 event = HAL_TIMER_EVT_START;
327 break;
328 case SYSTIM_CH2_STOP:
329 event = HAL_TIMER_EVT_HARD_STOP;
330 break;
331 default:
332 break;
333 }
334 }
335 else if (mis0 & LRFDDBELL_MIS0_SYSTIM1_M)
336 {
337 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) & (~LRFDDBELL_IMASK0_SYSTIM1_M);
338 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = LRFDDBELL_ICLR0_SYSTIM1_M;
339 event = HAL_TIMER_EVT_GRACEFUL_STOP;
340 }
341 return event;
342 }
343
hal_init_dispatch_radio_interrupts(uint32_t mask)344 void hal_init_dispatch_radio_interrupts(uint32_t mask)
345 {
346 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR1) = ~0;
347 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK1) = mask;
348 }
349
hal_enable_command_radio_interrupt(uint32_t mask)350 void hal_enable_command_radio_interrupt(uint32_t mask)
351 {
352 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) =
353 HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) | mask;
354 }
355
hal_clear_command_radio_interrupt(uint32_t mask)356 void hal_clear_command_radio_interrupt(uint32_t mask)
357 {
358 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = mask;
359 }
360
hal_disable_command_radio_interrupt(uint32_t mask)361 void hal_disable_command_radio_interrupt(uint32_t mask)
362 {
363 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) =
364 HWREG_READ_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) & ~mask;
365 }
366
hal_disable_all_command_radio_interrupts(void)367 void hal_disable_all_command_radio_interrupts(void)
368 {
369 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK0) = 0;
370 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR0) = ~0;
371 }
372
hal_disable_all_dispatch_radio_interrupts(void)373 void hal_disable_all_dispatch_radio_interrupts(void)
374 {
375 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_IMASK1) = 0;
376 HWREG_WRITE_LRF(LRFDDBELL_BASE + LRFDDBELL_O_ICLR1) = ~0;
377 }
378
hal_set_rcl_clock_enable(uint16_t mask)379 void hal_set_rcl_clock_enable(uint16_t mask)
380 {
381 uintptr_t key = HwiP_disable();
382 LRFDSetClockDependency(mask, LRFD_CLK_DEP_RCL);
383 HwiP_restore(key);
384 }
385
hal_clear_rcl_clock_enable(uint16_t mask)386 void hal_clear_rcl_clock_enable(uint16_t mask)
387 {
388 uintptr_t key = HwiP_disable();
389 LRFDReleaseClockDependency(mask, LRFD_CLK_DEP_RCL);
390 HwiP_restore(key);
391 }
392
393 #ifndef SOCFPGA
hal_power_post_notify_fxn(unsigned int eventType,uintptr_t eventArg,uintptr_t clientArg)394 static int hal_power_post_notify_fxn(unsigned int eventType, uintptr_t eventArg, uintptr_t clientArg)
395 {
396 (void) eventArg;
397 (void) clientArg;
398
399 if (rclPowerNotify != NULL)
400 {
401 if (eventType == PowerLPF3_AWAKE_STANDBY)
402 {
403 rclPowerNotify(RCL_POWER_STANDBY_AWAKE);
404 }
405 else if (eventType == PowerLPF3_ENTERING_STANDBY)
406 {
407 rclPowerNotify(RCL_POWER_STANDBY_ENTER);
408 }
409 }
410 return (Power_NOTIFYDONE);
411 }
412 #endif
413
hal_power_set_constraint(void)414 void hal_power_set_constraint(void)
415 {
416 #ifndef SOCFPGA
417 /* FPGA doesn't support standby */
418 Power_setConstraint(PowerLPF3_DISALLOW_STANDBY);
419 Log_printf(RclCore, Log_INFO, "Power constraints set");
420 #endif
421 }
422
hal_power_release_constraint(void)423 void hal_power_release_constraint(void)
424 {
425 #ifndef SOCFPGA
426 /* FPGA doesn't support standby */
427 Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
428 Log_printf(RclCore, Log_INFO, "Power constraints released");
429 #endif
430 }
431
hal_power_open(void (* f)(RCL_PowerEvent))432 void hal_power_open(void (*f)(RCL_PowerEvent))
433 {
434 #ifndef SOCFPGA
435 rclPowerNotify = f;
436
437 /* Register power notification functions */
438 Power_registerNotify(&powerEnterStandbyObj, PowerLPF3_ENTERING_STANDBY, hal_power_post_notify_fxn, (uintptr_t)NULL);
439 Power_registerNotify(&powerAwakeStandbyObj, PowerLPF3_AWAKE_STANDBY, hal_power_post_notify_fxn, (uintptr_t)NULL);
440 #endif
441 }
442
hal_power_close(void)443 void hal_power_close(void)
444 {
445 #ifndef SOCFPGA
446 /* Unregister power notification objects */
447 Power_unregisterNotify(&powerEnterStandbyObj);
448 Power_unregisterNotify(&powerAwakeStandbyObj);
449 #endif
450 }
451
hal_temperature_init(void)452 void hal_temperature_init(void)
453 {
454 Temperature_init();
455 }
456
457 /* Make function weak to allow tests to override reported temperature */
hal_get_temperature(void)458 __attribute__((weak)) int16_t hal_get_temperature(void)
459 {
460 return Temperature_getTemperature();
461 }
462
hal_get_hfxt_ratio(void)463 uint32_t hal_get_hfxt_ratio(void)
464 {
465 return (HWREG(CKMD_BASE + CKMD_O_HFTRACKCTL) & CKMD_HFTRACKCTL_RATIO_M) >> CKMD_HFTRACKCTL_RATIO_S;
466 }
467
hal_get_hfxt_ratio_default(void)468 uint32_t hal_get_hfxt_ratio_default(void)
469 {
470 #ifdef DeviceFamily_CC27XX
471 return 0x00200000U;
472 #else
473 return RCL_DEFAULT_HFTRACKCTL_RATIO;
474 #endif
475 }
476