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 * version of NHW_SIDEEFFECTS_TASKS() where the task is in a struct 40 */ 41 #define NHW_SIDEEFFECTS_TASKS_ST(peri, peri_regs, task, taskst) \ 42 void nhw_##peri##_regw_sideeffects_TASKS_##task(unsigned int inst) { \ 43 if ( peri_regs TASKS_##taskst ) { \ 44 peri_regs TASKS_##taskst = 0; \ 45 nhw_##peri##_TASK_##task(inst); \ 46 } \ 47 } 48 49 /* 50 * SUBSCRIBE register write side-effects 51 */ 52 #define NHW_SIDEEFFECTS_SUBSCRIBE_si(peri, task) \ 53 void nhw_##peri##_regw_sideeffects_SUBSCRIBE_##task(unsigned int inst) { \ 54 static struct nhw_subsc_mem task##_subscribed[NHW_##peri##_TOTAL_INST]; \ 55 nhw_dppi_common_subscribe_sideeffect(nhw_##peri##_dppi_map[inst], \ 56 NRF_##peri##_regs.SUBSCRIBE_##task, \ 57 &task##_subscribed[inst], \ 58 (dppi_callback_t)nhw_##peri##_TASK_##task, \ 59 DPPI_CB_NO_PARAM); \ 60 } 61 62 /* 63 * Any EVENT register write side-effect 64 */ 65 #define NHW_SIDEEFFECTS_EVENTS(peri) \ 66 void nhw_##peri##_regw_sideeffects_EVENTS_all(unsigned int inst) { \ 67 nhw_##peri##_eval_interrupt(inst); \ 68 } 69 70 71 #if (NHW_HAS_PPI) 72 #define _NHW_XPPI_EVENT(peri, peri_regs, inst, event) \ 73 nrf_ppi_event(peri##_EVENTS_##event) 74 #elif (NHW_HAS_DPPI) 75 #define _NHW_XPPI_EVENT(peri, peri_regs, inst, event) \ 76 nhw_dppi_event_signal_if(nhw_##peri##_dppi_map[inst], \ 77 peri_regs PUBLISH_##event) 78 #endif /* (NHW_HAS_PPI) / (NHW_HAS_DPPI)*/ 79 80 81 #define _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) \ 82 { \ 83 peri_regs EVENTS_##event = 1; \ 84 nhw_##peri##_eval_interrupt(inst); \ 85 _NHW_XPPI_EVENT(peri, peri_regs, inst, event); \ 86 } 87 88 /* 89 * Signal an event: 90 * * Set the corresponding event register 91 * * Cause level interrupts to be reevaluated 92 * * Send the event either to the PPI or DPPI (if enabled) 93 * 94 * NOTE: Cannot be used for events with shortcuts 95 * NOTE: Cannot be used for multi-instance peripherals connected to the PPI 96 */ 97 #define NHW_SIGNAL_EVENT(peri, peri_regs, event) \ 98 void nhw_##peri##_signal_EVENTS_##event(unsigned int inst) \ 99 _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) 100 101 /* 102 * Signal an event. Like NHW_SIGNAL_EVENT() 103 * but when the event has shortcuts. 104 * 105 * NOTE: Cannot be used for multi-instance peripherals connected to the PPI 106 */ 107 #define NHW_SIGNAL_EVENT_ns(peri, peri_regs, event) \ 108 void nhw_##peri##_signal_EVENTS_##event##_noshort(unsigned int inst) \ 109 _NHW_SIGNAL_EVENT_body(peri, peri_regs, event) 110 111 #define NHW_SIGNAL_EVENT_si(peri, event) \ 112 NHW_SIGNAL_EVENT(peri, NRF_##peri##_regs. , event) 113 114 #define NHW_SIGNAL_EVENT_ns_si(peri, event) \ 115 NHW_SIGNAL_EVENT_ns(peri, NRF_##peri##_regs. , event) 116 117 #define NHW_SIDEEFFECTS_INTSET_si(peri, peri_regs, inten)\ 118 void nhw_##peri##_regw_sideeffects_INTENSET(void) { \ 119 if ( peri_regs INTENSET ){ /* LCOV_EXCL_BR_LINE */\ 120 inten |= peri_regs INTENSET; \ 121 peri_regs INTENSET = inten; \ 122 nhw_##peri##_eval_interrupt(0); \ 123 } \ 124 } 125 126 #define NHW_SIDEEFFECTS_INTCLR_si(peri, peri_regs, inten) \ 127 void nhw_##peri##_regw_sideeffects_INTENCLR(void) { \ 128 if ( peri_regs INTENCLR ){/* LCOV_EXCL_BR_LINE */ \ 129 inten &= ~(peri_regs INTENCLR); \ 130 peri_regs INTENSET = inten; \ 131 peri_regs INTENCLR = 0; \ 132 nhw_##peri## _eval_interrupt(0); \ 133 } \ 134 } 135 136 #define NHW_SIDEEFFECTS_INTSET(peri, peri_regs, inten) \ 137 void nhw_##peri##_regw_sideeffects_INTENSET(uint inst) { \ 138 if ( peri_regs INTENSET ){ /* LCOV_EXCL_BR_LINE */\ 139 inten |= peri_regs INTENSET; \ 140 peri_regs INTENSET = inten; \ 141 nhw_##peri##_eval_interrupt(inst); \ 142 } \ 143 } 144 145 #define NHW_SIDEEFFECTS_INTEN(peri, peri_regs, inten) \ 146 void nhw_##peri##_regw_sideeffects_INTEN(uint inst) { \ 147 peri_regs INTENSET = inten; \ 148 nhw_##peri##_eval_interrupt(inst); \ 149 } 150 151 #define NHW_SIDEEFFECTS_INTCLR(peri, peri_regs, inten) \ 152 void nhw_##peri##_regw_sideeffects_INTENCLR(uint inst) { \ 153 if ( peri_regs INTENCLR ){/* LCOV_EXCL_BR_LINE */ \ 154 inten &= ~(peri_regs INTENCLR); \ 155 peri_regs INTENSET = inten; \ 156 peri_regs INTENCLR = 0; \ 157 nhw_##peri## _eval_interrupt(inst); \ 158 } \ 159 } 160 161 #define NHW_CHECK_INTERRUPT(peri, peri_regs, event, inten) \ 162 if (peri_regs EVENTS_##event && (inten & peri##_INTENSET_##event##_Msk)){ \ 163 new_int_line = true; \ 164 } 165 166 /* 167 * version of NHW_CHECK_INTERRUPT() where the event is in a struct 168 */ 169 #define NHW_CHECK_INTERRUPT_ST(peri, peri_regs, event, intevnt, inten) \ 170 if (peri_regs EVENTS_##event && (inten & peri##_INTENSET_##intevnt##_Msk)){ \ 171 new_int_line = true; \ 172 } 173 174 #define NHW_CHECK_INTERRUPT_si(peri, event, inten) \ 175 if (NRF_##peri##_regs.EVENTS_##event && (inten & peri##_INTENSET_##event##_Msk)){ \ 176 new_int_line = true; \ 177 } 178 179 #define NHW_SHORT_si(peri, event, task) \ 180 if (NRF_##peri##_regs.SHORTS & peri##_SHORTS_##event##_##task##_Msk) { \ 181 nhw_##peri##_TASK_##task(); \ 182 } 183 184 #define NHW_SHORT(peri, inst, peri_regs, event, task) \ 185 if (peri_regs SHORTS & peri##_SHORTS_##event##_##task##_Msk) { \ 186 nhw_##peri##_TASK_##task(inst); \ 187 } 188 189 /* 190 * version of NHW_SHORT() where the task is in a struct 191 */ 192 #define NHW_SHORT_ST(peri, inst, peri_regs, event, task, task_st) \ 193 if (peri_regs SHORTS & peri##_SHORTS_##event##_##task_st##_Msk) { \ 194 nhw_##peri##_TASK_##task(inst); \ 195 } 196 197 #endif /* _NRF_HW_MODEL_NHW_TEMPLATES_H */ 198