1 /******************************************************************************
2 *  Filename:       rf_mailbox.h
3 *
4 *  Description:    Definitions for interface between system and radio CPU
5 *
6 *  Copyright (c) 2015 - 2020, Texas Instruments Incorporated
7 *  All rights reserved.
8 *
9 *  Redistribution and use in source and binary forms, with or without
10 *  modification, are permitted provided that the following conditions are met:
11 *
12 *  1) Redistributions of source code must retain the above copyright notice,
13 *     this list of conditions and the following disclaimer.
14 *
15 *  2) Redistributions in binary form must reproduce the above copyright notice,
16 *     this list of conditions and the following disclaimer in the documentation
17 *     and/or other materials provided with the distribution.
18 *
19 *  3) Neither the name of the ORGANIZATION nor the names of its contributors may
20 *     be used to endorse or promote products derived from this software without
21 *     specific prior written permission.
22 *
23 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 *  POSSIBILITY OF SUCH DAMAGE.
34 *
35 ******************************************************************************/
36 
37 #ifndef _MAILBOX_H
38 #define _MAILBOX_H
39 
40 #include <stdint.h>
41 #include <string.h>
42 
43 
44 /// \name RF mode values
45 /// Defines used to indicate mode of operation to radio core.
46 ///@{
47 #define RF_MODE_AUTO             0x00
48 #define RF_MODE_BLE              0x00
49 #define RF_MODE_IEEE_15_4        0x00
50 #define RF_MODE_PROPRIETARY_2_4  0x00
51 #define RF_MODE_PROPRIETARY      RF_MODE_PROPRIETARY_2_4
52 #define RF_MODE_MULTIPLE         0x00
53 ///@}
54 
55 
56 /// Type definition for RAT
57 typedef uint32_t ratmr_t;
58 
59 
60 
61 /// Type definition for a data queue
62 typedef struct {
63    uint8_t *pCurrEntry;   ///< Pointer to the data queue entry to be used, NULL for an empty queue
64    uint8_t *pLastEntry;   ///< Pointer to the last entry in the queue, NULL for a circular queue
65 } dataQueue_t;
66 
67 
68 
69 /// \name CPE interrupt definitions
70 /// Interrupt masks for the CPE interrupt in RDBELL.
71 ///@{
72 #define IRQN_COMMAND_DONE           0           ///< Radio operation command finished
73 #define IRQN_LAST_COMMAND_DONE      1           ///< Last radio operation command in a chain finished
74 #define IRQN_FG_COMMAND_DONE        2           ///< FG level Radio operation command finished
75 #define IRQN_LAST_FG_COMMAND_DONE   3           ///< Last FG level radio operation command in a chain finished
76 #define IRQN_TX_DONE                4           ///< Packet transmitted
77 #define IRQN_TX_ACK                 5           ///< ACK packet transmitted
78 #define IRQN_TX_CTRL                6           ///< Control packet transmitted
79 #define IRQN_TX_CTRL_ACK            7           ///< Acknowledgement received on a transmitted control packet
80 #define IRQN_TX_CTRL_ACK_ACK        8           ///< Acknowledgement received on a transmitted control packet, and acknowledgement transmitted for that packet
81 #define IRQN_TX_RETRANS             9           ///< Packet retransmitted
82 #define IRQN_TX_ENTRY_DONE          10          ///< Tx queue data entry state changed to Finished
83 #define IRQN_TX_BUFFER_CHANGED      11          ///< A buffer change is complete
84 #define IRQN_COMMAND_STARTED        12          ///< A radio operation command has gone into active state
85 #define IRQN_FG_COMMAND_STARTED     13          ///< FG level radio operation command has gone into active state
86 #define IRQN_PA_CHANGED             14          ///< PA is changed
87 #define IRQN_RX_OK                  16          ///< Packet received with CRC OK, payload, and not to be ignored
88 #define IRQN_RX_NOK                 17          ///< Packet received with CRC error
89 #define IRQN_RX_IGNORED             18          ///< Packet received with CRC OK, but to be ignored
90 #define IRQN_RX_EMPTY               19          ///< Packet received with CRC OK, not to be ignored, no payload
91 #define IRQN_RX_CTRL                20          ///< Control packet received with CRC OK, not to be ignored
92 #define IRQN_RX_CTRL_ACK            21          ///< Control packet received with CRC OK, not to be ignored, then ACK sent
93 #define IRQN_RX_BUF_FULL            22          ///< Packet received that did not fit in the Rx queue
94 #define IRQN_RX_ENTRY_DONE          23          ///< Rx queue data entry changing state to Finished
95 #define IRQN_RX_DATA_WRITTEN        24          ///< Data written to partial read Rx buffer
96 #define IRQN_RX_N_DATA_WRITTEN      25          ///< Specified number of bytes written to partial read Rx buffer
97 #define IRQN_RX_ABORTED             26          ///< Packet reception stopped before packet was done
98 #define IRQN_RX_COLLISION_DETECTED  27          ///< A collision was indicated during packet reception
99 #define IRQN_SYNTH_NO_LOCK          28          ///< The synth has gone out of lock after calibration
100 #define IRQN_MODULES_UNLOCKED       29          ///< As part of the boot process, the CM0 has opened access to RF core modules and memories
101 #define IRQN_BOOT_DONE              30          ///< The RF core CPU boot is finished
102 
103 #define IRQN_INTERNAL_ERROR         31          ///< Internal error observed
104 
105 #define IRQ_COMMAND_DONE            (1U << IRQN_COMMAND_DONE)
106 #define IRQ_LAST_COMMAND_DONE       (1U << IRQN_LAST_COMMAND_DONE)
107 #define IRQ_FG_COMMAND_DONE         (1U << IRQN_FG_COMMAND_DONE)
108 #define IRQ_LAST_FG_COMMAND_DONE    (1U << IRQN_LAST_FG_COMMAND_DONE)
109 
110 #define IRQ_TX_DONE                 (1U << IRQN_TX_DONE)
111 #define IRQ_TX_ACK                  (1U << IRQN_TX_ACK)
112 #define IRQ_TX_CTRL                 (1U << IRQN_TX_CTRL)
113 #define IRQ_TX_CTRL_ACK             (1U << IRQN_TX_CTRL_ACK)
114 #define IRQ_TX_CTRL_ACK_ACK         (1U << IRQN_TX_CTRL_ACK_ACK)
115 #define IRQ_TX_RETRANS              (1U << IRQN_TX_RETRANS)
116 
117 #define IRQ_TX_ENTRY_DONE           (1U << IRQN_TX_ENTRY_DONE)
118 #define IRQ_TX_BUFFER_CHANGED       (1U << IRQN_TX_BUFFER_CHANGED)
119 
120 #define IRQ_COMMAND_STARTED         (1U << IRQN_COMMAND_STARTED)
121 #define IRQ_FG_COMMAND_STARTED      (1U << IRQN_FG_COMMAND_STARTED)
122 #define IRQ_PA_CHANGED              (1U << IRQN_PA_CHANGED)
123 
124 #define IRQ_RX_OK                   (1U << IRQN_RX_OK)
125 #define IRQ_RX_NOK                  (1U << IRQN_RX_NOK)
126 #define IRQ_RX_IGNORED              (1U << IRQN_RX_IGNORED)
127 #define IRQ_RX_EMPTY                (1U << IRQN_RX_EMPTY)
128 #define IRQ_RX_CTRL                 (1U << IRQN_RX_CTRL)
129 #define IRQ_RX_CTRL_ACK             (1U << IRQN_RX_CTRL_ACK)
130 #define IRQ_RX_BUF_FULL             (1U << IRQN_RX_BUF_FULL)
131 #define IRQ_RX_ENTRY_DONE           (1U << IRQN_RX_ENTRY_DONE)
132 #define IRQ_RX_DATA_WRITTEN         (1U << IRQN_RX_DATA_WRITTEN)
133 #define IRQ_RX_N_DATA_WRITTEN       (1U << IRQN_RX_N_DATA_WRITTEN)
134 #define IRQ_RX_ABORTED              (1U << IRQN_RX_ABORTED)
135 #define IRQ_RX_COLLISION_DETECTED   (1U << IRQN_RX_COLLISION_DETECTED)
136 #define IRQ_SYNTH_NO_LOCK           (1U << IRQN_SYNTH_NO_LOCK)
137 #define IRQ_MODULES_UNLOCKED        (1U << IRQN_MODULES_UNLOCKED)
138 #define IRQ_BOOT_DONE               (1U << IRQN_BOOT_DONE)
139 #define IRQ_INTERNAL_ERROR          (1U << IRQN_INTERNAL_ERROR)
140 ///@}
141 
142 
143 
144 /// \name CMDSTA values
145 /// Values returned in result byte of CMDSTA
146 ///@{
147 #define CMDSTA_Pending 0x00              ///< The command has not yet been parsed
148 #define CMDSTA_Done 0x01                 ///< Command successfully parsed
149 
150 #define CMDSTA_IllegalPointer 0x81       ///< The pointer signaled in CMDR is not valid
151 #define CMDSTA_UnknownCommand 0x82       ///< The command number in the command structure is unknown
152 #define CMDSTA_UnknownDirCommand 0x83    ///< The command number for a direct command is unknown, or the
153                                          ///< command is not a direct command
154 #define CMDSTA_ContextError 0x85         ///< An immediate or direct command was issued in a context
155                                          ///< where it is not supported
156 #define CMDSTA_SchedulingError 0x86      ///< A radio operation command was attempted to be scheduled
157                                          ///< while another operation was already running in the RF core
158 #define CMDSTA_ParError 0x87             ///< There were errors in the command parameters that are parsed
159                                          ///< on submission.
160 #define CMDSTA_QueueError 0x88           ///< An operation on a data entry queue was attempted that was
161                                          ///< not supported by the queue in its current state
162 #define CMDSTA_QueueBusy 0x89            ///< An operation on a data entry was attempted while that entry
163                                          ///< was busy
164 ///@}
165 
166 
167 
168 /// \name Macros for sending direct commands
169 ///@{
170 /// Direct command with no parameter
171 #define CMDR_DIR_CMD(cmdId) (((cmdId) << 16) | 1)
172 
173 /// Direct command with 1-byte parameter
174 #define CMDR_DIR_CMD_1BYTE(cmdId, par) (((cmdId) << 16) | ((par) << 8) | 1)
175 
176 /// Direct command with 2-byte parameter
177 #define CMDR_DIR_CMD_2BYTE(cmdId, par) (((cmdId) << 16) | ((par) & 0xFFFC) | 1)
178 
179 ///@}
180 
181 
182 
183 /// \name Definitions for trigger types
184 ///@{
185 #define TRIG_NOW 0            ///< Triggers immediately
186 #define TRIG_NEVER 1          ///< Never trigs
187 #define TRIG_ABSTIME 2        ///< Trigs at an absolute time
188 #define TRIG_REL_SUBMIT 3     ///< Trigs at a time relative to the command was submitted
189 #define TRIG_REL_START 4      ///< Trigs at a time relative to the command started
190 #define TRIG_REL_PREVSTART 5  ///< Trigs at a time relative to the previous command in the chain started
191 #define TRIG_REL_FIRSTSTART 6 ///< Trigs at a time relative to the first command in the chain started
192 #define TRIG_REL_PREVEND 7    ///< Trigs at a time relative to the previous command in the chain ended
193 #define TRIG_REL_EVT1 8       ///< Trigs at a time relative to the context defined "Event 1"
194 #define TRIG_REL_EVT2 9       ///< Trigs at a time relative to the context defined "Event 2"
195 #define TRIG_EXTERNAL 10      ///< Trigs at an external event to the radio timer
196 #define TRIG_PAST_BM 0x80     ///< Bitmask for setting pastTrig bit in order to trig immediately if
197                               ///< trigger happened in the past
198 ///@}
199 
200 
201 /// \name Definitions for conditional execution
202 ///@{
203 #define COND_ALWAYS 0         ///< Always run next command (except in case of Abort)
204 #define COND_NEVER 1          ///< Never run next command
205 #define COND_STOP_ON_FALSE 2  ///< Run next command if this command returned True, stop if it returned
206                               ///< False
207 #define COND_STOP_ON_TRUE 3   ///< Stop if this command returned True, run next command if it returned
208                               ///< False
209 #define COND_SKIP_ON_FALSE 4  ///< Run next command if this command returned True, skip a number of
210                               ///< commands if it returned False
211 #define COND_SKIP_ON_TRUE 5   ///< Skip a number of commands if this command returned True, run next
212                               ///< command if it returned False
213 ///@}
214 
215 
216 
217 /// \name Radio operation status
218 ///@{
219 /// \name Operation not finished
220 ///@{
221 #define IDLE             0x0000   ///< Operation not started
222 #define PENDING          0x0001   ///< Start of command is pending
223 #define ACTIVE           0x0002   ///< Running
224 #define SKIPPED          0x0003   ///< Operation skipped due to condition in another command
225 ///@}
226 /// \name Operation finished normally
227 ///@{
228 #define DONE_OK          0x0400   ///< Operation ended normally
229 #define DONE_COUNTDOWN   0x0401   ///< Counter reached zero
230 #define DONE_RXERR       0x0402   ///< Operation ended with CRC error
231 #define DONE_TIMEOUT     0x0403   ///< Operation ended with timeout
232 #define DONE_STOPPED     0x0404   ///< Operation stopped after CMD_STOP command
233 #define DONE_ABORT       0x0405   ///< Operation aborted by CMD_ABORT command
234 #define DONE_FAILED      0x0406   ///< Scheduled immediate command failed
235 ///@}
236 /// \name Operation finished with error
237 ///@{
238 #define ERROR_PAST_START 0x0800   ///< The start trigger occurred in the past
239 #define ERROR_START_TRIG 0x0801   ///< Illegal start trigger parameter
240 #define ERROR_CONDITION  0x0802   ///< Illegal condition for next operation
241 #define ERROR_PAR        0x0803   ///< Error in a command specific parameter
242 #define ERROR_POINTER    0x0804   ///< Invalid pointer to next operation
243 #define ERROR_CMDID      0x0805   ///< Next operation has a command ID that is undefined or not a radio
244                                   ///< operation command
245 #define ERROR_WRONG_BG   0x0806   ///< FG level command not compatible with running BG level command
246 #define ERROR_NO_SETUP   0x0807   ///< Operation using Rx or Tx attempted without CMD_RADIO_SETUP
247 #define ERROR_NO_FS      0x0808   ///< Operation using Rx or Tx attempted without frequency synth configured
248 #define ERROR_SYNTH_PROG 0x0809   ///< Synthesizer calibration failed
249 #define ERROR_TXUNF      0x080A   ///< Tx underflow observed
250 #define ERROR_RXOVF      0x080B   ///< Rx overflow observed
251 #define ERROR_NO_RX      0x080C   ///< Attempted to access data from Rx when no such data was yet received
252 #define ERROR_PENDING    0x080D   ///< Command submitted in the future with another command at different level pending
253 ///@}
254 ///@}
255 
256 
257 /// \name Data entry types
258 ///@{
259 #define DATA_ENTRY_TYPE_GEN 0     ///< General type: Tx entry or single element Rx entry
260 #define DATA_ENTRY_TYPE_MULTI 1   ///< Multi-element Rx entry type
261 #define DATA_ENTRY_TYPE_PTR 2     ///< Pointer entry type
262 #define DATA_ENTRY_TYPE_PARTIAL 3 ///< Partial read entry type
263 ///@
264 
265 
266 /// \name Data entry statuses
267 ///@{
268 #define DATA_ENTRY_PENDING 0      ///< Entry not yet used
269 #define DATA_ENTRY_ACTIVE 1       ///< Entry in use by radio CPU
270 #define DATA_ENTRY_BUSY 2         ///< Entry being updated
271 #define DATA_ENTRY_FINISHED 3     ///< Radio CPU is finished accessing the entry
272 #define DATA_ENTRY_UNFINISHED 4   ///< Radio CPU is finished accessing the entry, but packet could not be finished
273 ///@}
274 
275 
276 /// \name Macros for RF register override
277 ///@{
278 /// Macro for ADI half-size value-mask combination
279 #define ADI_VAL_MASK(addr, mask, value) \
280 (((addr) & 1) ? (((mask) & 0x0F) | (((value) & 0x0F) << 4)) : \
281  ((((mask) & 0x0F) << 4) | ((value) & 0x0F)))
282 /// 32-bit write of 16-bit value
283 #define HW_REG_OVERRIDE(addr, val) ((((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(val) << 16))
284 /// ADI register, full-size write
285 #define ADI_REG_OVERRIDE(adiNo, addr, val) (2 | ((uint32_t)(val) << 16) | \
286 (((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31))
287 /// 2 ADI registers, full-size write
288 #define ADI_2REG_OVERRIDE(adiNo, addr, val, addr2, val2) \
289 (2 | ((uint32_t)(val2) << 2) | (((addr2) & 0x3F) << 10) | ((uint32_t)(val) << 16) | \
290 (((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31))
291 /// ADI register, half-size read-modify-write
292 #define ADI_HALFREG_OVERRIDE(adiNo, addr, mask, val) (2 | (ADI_VAL_MASK(addr, mask, val) << 16) | \
293 (((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31))
294 /// 2 ADI registers, half-size read-modify-write
295 #define ADI_2HALFREG_OVERRIDE(adiNo, addr, mask, val, addr2, mask2, val2) \
296 (2 | (ADI_VAL_MASK(addr2, mask2, val2) << 2) | (((addr2) & 0x3F) << 10) | \
297 (ADI_VAL_MASK(addr, mask, val) << 16) | (((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31))
298 
299 /// 16-bit SW register as defined in radio_par_def.txt
300 #define SW_REG_OVERRIDE(cmd, field, val) (3 | ((_POSITION_##cmd##_##field) << 4) | ((uint32_t)(val) << 16))
301 /// SW register as defined in radio_par_def.txt with added index (for use with registers > 16 bits).
302 #define SW_REG_IND_OVERRIDE(cmd, field, offset, val) (3 | \
303 (((_POSITION_##cmd##_##field) + ((offset) << 1)) << 4) | ((uint32_t)(val) << 16))
304 /// 8-bit SW register as defined in radio_par_def.txt
305 #define SW_REG_BYTE_OVERRIDE(cmd, field, val) (0x8003 | ((_POSITION_##cmd##_##field) << 4) | \
306 (((uint32_t)(val) & 0xFF) << 16))
307 /// Two 8-bit SW registers as defined in radio_par_def.txt; the one given by field and the next byte.
308 #define SW_REG_2BYTE_OVERRIDE(cmd, field, val0, val1) (3 | (((_POSITION_##cmd##_##field) & 0xFFFE) << 4) | \
309                                                        (((uint32_t)(val0) << 16) & 0x00FF0000) | ((uint32_t)(val1) << 24))
310 #define SW_REG_MASK_OVERRIDE(cmd, field, offset, mask, val) (0x8003 | \
311 ((_POSITION_##cmd##_##field + (offset)) << 4) | (((uint32_t)(val) & 0xFF) << 16) | (((uint32_t)(mask) & 0xFF) << 24))
312 
313 #define HW16_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(length) << 16))
314 #define HW32_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | \
315 ((uint32_t)(length) << 16) | (1U << 30))
316 #define HW16_MASK_ARRAY_OVERRIDE(addr, length) (0x20000001 | (((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(length) << 16))
317 #define HW32_MASK_ARRAY_OVERRIDE(addr, length) (0x60000001 | (((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(length) << 16))
318 #define HW16_MASK_VAL(mask, val) ((mask) << 16 | (val))
319 #define ADI_ARRAY_OVERRIDE(adiNo, addr, bHalfSize, length) (1 | ((((addr) & 0x3F) << 2)) | \
320 ((!!(bHalfSize)) << 8) | ((!!(adiNo)) << 9) | ((uint32_t)(length) << 16) | (2U << 30))
321 #define SW_ARRAY_OVERRIDE(cmd, firstfield, length) (1 | (((_POSITION_##cmd##_##firstfield)) << 2) | \
322 ((uint32_t)(length) << 16) | (3U << 30))
323 #define MCE_RFE_OVERRIDE(mceCfg, mceRomBank, mceMode, rfeCfg, rfeRomBank, rfeMode) \
324    (7 | ((mceCfg & 2) << 3) | ((rfeCfg & 2) << 4) |\
325     ((mceCfg & 1) << 6) | (((mceRomBank) & 0x0F) << 7) | \
326     ((rfeCfg & 1) << 11) | (((rfeRomBank) & 0x0F) << 12) | \
327     (((mceMode) & 0x00FF) << 16) | (((rfeMode) & 0x00FF) << 24))
328 #define HPOSC_OVERRIDE(freqOffset) (0x000B | ((freqOffset) << 16))
329 #define TX20_POWER_OVERRIDE(tx20Power) (0x002B | (((uint32_t) tx20Power) << 10))
330 #define TX_STD_POWER_OVERRIDE(txPower) (0x022B | (((uint32_t) txPower) << 10))
331 #define MCE_RFE_SPLIT_OVERRIDE(mceRxCfg, mceTxCfg, rfeRxCfg, rfeTxCfg) \
332     (0x003B | ((mceRxCfg) << 12) | ((mceTxCfg) << 17) | ((rfeRxCfg) << 22) | ((rfeTxCfg) << 27))
333 #define CENTER_FREQ_OVERRIDE(centerFreq, flags) (0x004B | ((flags & 0x03) << 18) | \
334    ((centerFreq) << 20))
335 #define MOD_TYPE_OVERRIDE(modType, deviation, stepSz, flags) (0x005B | ((flags & 0x01) << 15) | \
336    ((modType) << 16) | ((deviation) << 19) |((stepSz) << 30) )
337 #define NEW_OVERRIDE_SEGMENT(address) (((((uintptr_t)(address)) & 0x03FFFFFC) << 6) | 0x000F | \
338    (((((uintptr_t)(address) >> 24) == 0x20) ? 0x01 : \
339      (((uintptr_t)(address) >> 24) == 0x21) ? 0x02 : \
340      (((uintptr_t)(address) >> 24) == 0xA0) ? 0x03 : \
341      (((uintptr_t)(address) >> 24) == 0x00) ? 0x04 : \
342      (((uintptr_t)(address) >> 24) == 0x10) ? 0x05 : \
343      (((uintptr_t)(address) >> 24) == 0x11) ? 0x06 : \
344      (((uintptr_t)(address) >> 24) == 0x40) ? 0x07 : \
345      (((uintptr_t)(address) >> 24) == 0x50) ? 0x08 : \
346      0x09) << 4)) // Use illegal value for illegal address range
347 /// End of string for override register
348 #define END_OVERRIDE 0xFFFFFFFF
349 
350 
351 /// ADI address-value pair
352 #define ADI_ADDR_VAL(addr, value) ((((addr) & 0x7F) << 8) | ((value) & 0xFF))
353 #define ADI_ADDR_VAL_MASK(addr, mask, value) ((((addr) & 0x7F) << 8) | ADI_VAL_MASK(addr, mask, value))
354 
355 /// Low half-word
356 #define LOWORD(value) ((value) & 0xFFFF)
357 /// High half-word
358 #define HIWORD(value) ((value) >> 16)
359 ///@}
360 
361 
362 #endif
363