1 /* 2 * Copyright (c) 2023 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * Template code (macros) for the most typical/repetitive 9 * code of the HW models 10 * 11 * The _si versions are for peripheral which can only have one instance 12 */ 13 #ifndef _NRF_HW_MODEL_NHW_TEMPLATES_H 14 #define _NRF_HW_MODEL_NHW_TEMPLATES_H 15 16 #include "NHW_config.h" 17 18 /* 19 * TASKS register write side-effects 20 * (just calls thru to the task) 21 */ 22 #define NHW_SIDEEFFECTS_TASKS_si(peri, task) \ 23 void nhw_##peri##_regw_sideeffects_TASKS_##task(void) { \ 24 if ( NRF_##peri##_regs.TASKS_##task ) { \ 25 NRF_##peri##_regs.TASKS_##task = 0; \ 26 nhw_##peri##_TASK_##task(); \ 27 } \ 28 } 29 30 #define NHW_SIDEEFFECTS_TASKS(peri, peri_regs, task) \ 31 void nhw_##peri##_regw_sideeffects_TASKS_##task(unsigned int inst) { \ 32 if ( peri_regs TASKS_##task ) { \ 33 peri_regs TASKS_##task = 0; \ 34 nhw_##peri##_TASK_##task(inst); \ 35 } \ 36 } 37 38 /* 39 * SUBSCRIBE register write side-effects 40 */ 41 #define NHW_SIDEEFFECTS_SUBSCRIBE_si(peri, task) \ 42 void nhw_##peri##_regw_sideeffects_SUBSCRIBE_##task(unsigned int inst) { \ 43 static struct nhw_subsc_mem task##_subscribed[NHW_##peri##_TOTAL_INST]; \ 44 nhw_dppi_common_subscribe_sideeffect(nhw_##peri##_dppi_map[inst], \ 45 NRF_##peri##_regs.SUBSCRIBE_##task, \ 46 &task##_subscribed[inst], \ 47 (dppi_callback_t)nhw_##peri##_TASK_##task, \ 48 DPPI_CB_NO_PARAM); \ 49 } 50 51 /* 52 * Any EVENT register write side-effect 53 */ 54 #define NHW_SIDEEFFECTS_EVENTS(peri) \ 55 void nhw_##peri##_regw_sideeffects_EVENTS_all(unsigned int inst) { \ 56 nhw_##peri##_eval_interrupt(inst); \ 57 } 58 59 60 #if (NHW_HAS_PPI) 61 #define _NHW_XPPI_EVENT(peri, peri_regs, inst, event) \ 62 nrf_ppi_event(peri##_EVENTS_##event) 63 #elif (NHW_HAS_DPPI) 64 #define _NHW_XPPI_EVENT(peri, peri_regs, inst, event) \ 65 nhw_dppi_event_signal_if(nhw_##peri##_dppi_map[inst], \ 66 peri_regs PUBLISH_##event) 67 #endif /* (NHW_HAS_PPI) / (NHW_HAS_DPPI)*/ 68 69 70 #define _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) \ 71 { \ 72 peri_regs EVENTS_##event = 1; \ 73 nhw_##peri##_eval_interrupt(inst); \ 74 _NHW_XPPI_EVENT(peri, peri_regs, inst, event); \ 75 } 76 77 /* 78 * Signal an event: 79 * * Set the corresponding event register 80 * * Cause level interrupts to be reevaluated 81 * * Send the event either to the PPI or DPPI (if enabled) 82 * 83 * NOTE: Cannot be used for events with shortcuts 84 * NOTE: Cannot be used for multi-instance peripherals connected to the PPI 85 */ 86 #define NHW_SIGNAL_EVENT(peri, peri_regs, event) \ 87 void nhw_##peri##_signal_EVENTS_##event(unsigned int inst) \ 88 _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) 89 90 /* 91 * Signal an event. Like NHW_SIGNAL_EVENT() 92 * but when the event has shortcuts. 93 * 94 * NOTE: Cannot be used for multi-instance peripherals connected to the PPI 95 */ 96 #define NHW_SIGNAL_EVENT_ns(peri, peri_regs, event) \ 97 void nhw_##peri##_signal_EVENTS_##event##_noshort(unsigned int inst) \ 98 _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) 99 100 #define NHW_SIGNAL_EVENT_si(peri, event) \ 101 NHW_SIGNAL_EVENT(peri, NRF_##peri##_regs. , event) 102 103 #define NHW_SIGNAL_EVENT_ns_si(peri, event) \ 104 NHW_SIGNAL_EVENT_ns(peri, NRF_##peri##_regs. , event) 105 106 #define NHW_SIDEEFFECTS_INTSET_si(peri, peri_regs, inten)\ 107 void nhw_##peri##_regw_sideeffects_INTENSET(void) { \ 108 if ( peri_regs INTENSET ){ /* LCOV_EXCL_BR_LINE */\ 109 inten |= peri_regs INTENSET; \ 110 peri_regs INTENSET = inten; \ 111 nhw_##peri##_eval_interrupt(0); \ 112 } \ 113 } 114 115 #define NHW_SIDEEFFECTS_INTCLR_si(peri, peri_regs, inten) \ 116 void nhw_##peri##_regw_sideeffects_INTENCLR(void) { \ 117 if ( peri_regs INTENCLR ){/* LCOV_EXCL_BR_LINE */ \ 118 inten &= ~(peri_regs INTENCLR); \ 119 peri_regs INTENSET = inten; \ 120 peri_regs INTENCLR = 0; \ 121 nhw_##peri## _eval_interrupt(0); \ 122 } \ 123 } 124 125 #define NHW_SIDEEFFECTS_INTSET(peri, peri_regs, inten) \ 126 void nhw_##peri##_regw_sideeffects_INTENSET(uint inst) { \ 127 if ( peri_regs INTENSET ){ /* LCOV_EXCL_BR_LINE */\ 128 inten |= peri_regs INTENSET; \ 129 peri_regs INTENSET = inten; \ 130 nhw_##peri##_eval_interrupt(inst); \ 131 } \ 132 } 133 134 #define NHW_SIDEEFFECTS_INTEN(peri, peri_regs, inten) \ 135 void nhw_##peri##_regw_sideeffects_INTEN(uint inst) { \ 136 peri_regs INTENSET = inten; \ 137 nhw_##peri##_eval_interrupt(inst); \ 138 } 139 140 #define NHW_SIDEEFFECTS_INTCLR(peri, peri_regs, inten) \ 141 void nhw_##peri##_regw_sideeffects_INTENCLR(uint inst) { \ 142 if ( peri_regs INTENCLR ){/* LCOV_EXCL_BR_LINE */ \ 143 inten &= ~(peri_regs INTENCLR); \ 144 peri_regs INTENSET = inten; \ 145 peri_regs INTENCLR = 0; \ 146 nhw_##peri## _eval_interrupt(inst); \ 147 } \ 148 } 149 150 #define NHW_CHECK_INTERRUPT(peri, peri_regs, event, inten) \ 151 if (peri_regs EVENTS_##event && (inten & peri##_INTENSET_##event##_Msk)){ \ 152 new_int_line = true; \ 153 } 154 155 #define NHW_CHECK_INTERRUPT_si(peri, event, inten) \ 156 if (NRF_##peri##_regs.EVENTS_##event && (inten & peri##_INTENSET_##event##_Msk)){ \ 157 new_int_line = true; \ 158 } 159 160 #define NHW_SHORT_si(peri, event, task) \ 161 if (NRF_##peri##_regs.SHORTS & peri##_SHORTS_##event##_##task##_Msk) { \ 162 nhw_##peri##_TASK_##task(); \ 163 } 164 165 #define NHW_SHORT(peri, inst, peri_regs, event, task) \ 166 if (peri_regs SHORTS & peri##_SHORTS_##event##_##task##_Msk) { \ 167 nhw_##peri##_TASK_##task(inst); \ 168 } 169 170 #endif /* _NRF_HW_MODEL_NHW_TEMPLATES_H */ 171