/*****************************************************************************
* Copyright (c) 2005 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/

#ifndef NAMACRO_H
#define NAMACRO_H

#include <limits.h>
#include "assert.h"   /* needed for NA_ASSERT */

#ifdef __ghs__
    #include <stddef.h> /* for offsetof */
#endif


#ifdef __cplusplus
extern "C"
{
#endif





/*ad*
 * Use this macro to suppress warnings about unused parameters.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   p   Parameter that is not used by the function that calls this macro
*ad*/
#define NA_UNUSED_PARAM(p)    ((void)(p))



/*ad*
 * This macro determines the number of elements in an array.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   array   array for which to determine the number of elements of
*ad*/
#define asizeof(array)      (sizeof array/sizeof array[0])


/*ad*
 * This macro is used to suppress compiler warnings about qualifiers on function parameters. 
 * Typically, NA_REMOVE_QUALIFIER is used when calling free() with a pointer that has the "volatile" 
 * qualifier.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x   Parameter that needs to have qualifiers (volatile) removed for the function call
*ad*/
#define NA_REMOVE_QUALIFIER(x)      ((void *) x)

/*ad*
 * This address causes a data abort if code reads or writes to it. Set dead pointers 
 * to this address.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
*ad*/
#define NA_BAD_POINTER              ((void *) 0xffffffff)


/*ad*
 * Sets the bits in the argument bits in the word x.  The parameter
 * x is bitwise-ORed with the parameter bits, and the result is
 * placed in x.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to modify by setting bits
 * @param   bits    Bit value to bitwise-OR into x
*ad*/
#define NA_SET(x,bits)              ((void) ((x) |= (bits)))

/*ad*
 * Clears a set of bits in a value.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Value to modify
 * @param   bits    Bits set in this word will be cleared in X
*ad*/
#define NA_CLEAR(x,bits)            ((void) ((x) &= ~(bits)))

/*ad*
 * Mask bits in a bit value.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Value to modify by masking bits.
 * @param   bits    Bits to mask with in x.  Bits not set in bits are cleared in x.
*ad*/
#define NA_MASK(x, bits)            ((void) ((x) &= (bits)))

/*ad*
 * Converts a bit number into a bit value; for example, NA_BIT_NUM(4)= 16.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Bit position to convert into a value
*ad*/
#define NA_BIT_NUM(x)               (NA_ASSERT((((int)x) >= 0) && ((x) < 32)), ((unsigned long)(1 << (x))))

/*ad*
 * Returns a word with all bits set from the bit number to bit 0.  NA_BIT_DOWN(4) = 31.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   bit       Bit position to convert into 2^(x+1) - 1
*ad*/
#define NA_BIT_DOWN(bit)            (((bit) == 31) ? ULONG_MAX : (NA_BIT_NUM((bit) + 1) - 1))

/*ad*
 * Returns a word with all bits set within the indicated range.  NA_BIT_RANGE(4,1) = 30.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   start   High bit of bit range
 * @param   end     Low bit of bit range
*ad*/
#define NA_BIT_RANGE(start, end)    (NA_ASSERT((start) >= (end)), (NA_BIT_DOWN(start) ^ (((end) == 0) ? 0 : NA_BIT_DOWN(end - 1))))

/*ad*
 * Sets the indicated bit.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to set bit in
 * @param   bit     Bit position to set in x
*ad*/
#define NA_SET_BIT_NUM(x,bit)       ((void) ((x) |= NA_BIT_NUM(bit)))

/*ad*
 * Clears the indicated bit.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to clear bit in
 * @param   bit     Bit position to clear in x
*ad*/
#define NA_CLR_BIT_NUM(x,bit)       ((void) ((x) &= ~NA_BIT_NUM(bit)))

/*ad*
 * Returns the value of the indicated bit.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to read
 * @param   bit     Bit position in x for which to get value
*ad*/
#define NA_GET_BIT_NUM(x,bit)       ((NA_BIT_NUM(bit) & (x)) >> (bit))

/*ad*
 * Sets a bit to a specific value.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to set bit in
 * @param   bit     Bit position in x to set
 * @param   value   Value to set bit to
*ad*/
#define NA_PUT_BIT_NUM(x,bit,value) ((void) (NA_ASSERT((value == 0) || (value == 1)), ((x) = (((x) & ~NA_BIT_NUM(bit)) | (unsigned long) ((value) << (bit))))))

/*ad*
 * Sets a range of bits in a word to all 1's.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to set bits in
 * @param   start   Position of high bit in range to set
 * @param   end     Position of low bit in range to set
*ad*/
#define NA_SET_BIT_RANGE(x,start,end)       ((void) ((x) |= NA_BIT_RANGE((start),(end))))

/*ad*
 * Clears a range of bits in a word.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to clear bits in
 * @param   start   Position of high bit in range to clear
 * @param   end     Position of low bit in range to clear
*ad*/
#define NA_CLR_BIT_RANGE(x,start,end)       ((void) ((x) &= ~NA_BIT_RANGE((start),(end))))

/*ad*
 * Gets the value of a range of bits in a word.  Shifts the value down
 * so the lsb of the range is at position 0.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to read
 * @param   start   Position of high bit in range to read
 * @param   end     Position of low bit in range to read
*ad*/
#define NA_GET_BIT_RANGE(x,start,end)       (((x) & NA_BIT_RANGE((start),(end))) >> (end))

/*ad*
 * Sets a range of bits in a word to a specific value.  The value must be passed
 * with the first bit in the range at position 0.  It will be shifted before it is
 * or'd in.
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   x       Word to modify
 * @param   start   Position of high bit in range to modify
 * @param   end     Position of low bit in range to modify
 * @param   value   Value to shift into x
*ad*/
#define NA_PUT_BIT_RANGE(x,start,end,value) ((void) (NA_ASSERT(((value) & ~NA_BIT_RANGE((start) - (end), 0)) == 0), \
                ((x) = (((x) & ~(NA_BIT_RANGE((start),(end)))) | (unsigned long)((value) << (end))))))

/*
 *	The usual macros: asizeof/offsetof
 */

#if !defined(offsetof) && !defined(__ghs__) && !defined(__CC_ARM)
#define	offsetof(structure, field) ((WORD32)(&(((structure *)0)->field)))
#endif

#ifndef OFFSETOF
/*ad*
 * Determine offset of a field inside a structure
 *
 * @since 6.0
 * @category SystemSWServices:general_purpose
 * @external
 *
 * @param   structure   name of structure
 * @param   field       name of field
 *
 * @return         minimum of a and b
*ad*/
#define	OFFSETOF(structure, field) ((WORD32)(&(((structure *)0)->field)))
#endif


/*ad*
 * This section sets up some defines used for logical variables.
 *
 * @external
 * @category SystemSWServices:general_purpose
 * @since 1.0
 * @name BIT "Bit Definitions"
 *
 * @param BIT_0       0x00000001
 * @param BIT_1       0x00000002
 * @param BIT_2       0x00000004
 * @param BIT_3       0x00000008
 * @param BIT_4       0x00000010
 * @param BIT_5       0x00000020
 * @param BIT_6       0x00000040
 * @param BIT_7       0x00000080
 * @param BIT_8       0x00000100
 * @param BIT_9       0x00000200
 * @param BIT_10      0x00000400
 * @param BIT_11      0x00000800
 * @param BIT_12      0x00001000
 * @param BIT_13      0x00002000
 * @param BIT_14      0x00004000
 * @param BIT_15      0x00008000
 * @param BIT_16      0x00010000
 * @param BIT_17      0x00020000
 * @param BIT_18      0x00040000
 * @param BIT_19      0x00080000
 * @param BIT_20      0x00100000
 * @param BIT_21      0x00200000
 * @param BIT_22      0x00400000
 * @param BIT_23      0x00800000
 * @param BIT_24      0x01000000
 * @param BIT_25      0x02000000
 * @param BIT_26      0x04000000
 * @param BIT_27      0x08000000
 * @param BIT_28      0x10000000
 * @param BIT_29      0x20000000
 * @param BIT_30      0x40000000
 * @param BIT_31      0x80000000
*ad*/
#define BIT_0       0x00000001
#define BIT_1       0x00000002
#define BIT_2       0x00000004
#define BIT_3       0x00000008
#define BIT_4       0x00000010
#define BIT_5       0x00000020
#define BIT_6       0x00000040
#define BIT_7       0x00000080
#define BIT_8       0x00000100
#define BIT_9       0x00000200
#define BIT_10      0x00000400
#define BIT_11      0x00000800
#define BIT_12      0x00001000
#define BIT_13      0x00002000
#define BIT_14      0x00004000
#define BIT_15      0x00008000
#define BIT_16      0x00010000
#define BIT_17      0x00020000
#define BIT_18      0x00040000
#define BIT_19      0x00080000
#define BIT_20      0x00100000
#define BIT_21      0x00200000
#define BIT_22      0x00400000
#define BIT_23      0x00800000
#define BIT_24      0x01000000
#define BIT_25      0x02000000
#define BIT_26      0x04000000
#define BIT_27      0x08000000
#define BIT_28      0x10000000
#define BIT_29      0x20000000
#define BIT_30      0x40000000
#define BIT_31      0x80000000




#ifdef __cplusplus
}
#endif

#endif

