/*! * \file hal_defs.h * * \brief The header of hal_defs.c * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * * _ __ _ ________ _ * | |/ /(_)___ / ____/ /_ (_)___ * | // / __ \/ / / __ \/ / __ \ * / |/ / / / / /___/ / / / / /_/ / * /_/|_/_/_/ /_/\____/_/ /_/_/ .___/ * /_/ * (C) 2022-2025 XinChip * * \endcode * * \author ( XinChip ) Alex-J * * \author ( XinChip ) */ #ifndef HAL_DEFS_H #define HAL_DEFS_H #include "xc6xxx.h" /* ------------------------------------------------------------------------------------------------ * Macros * ------------------------------------------------------------------------------------------------ */ #ifndef BV #define BV(n) (1 << (n)) #endif #ifndef BF #define BF(x,b,s) (((x) & (b)) >> (s)) #endif #ifndef MIN #define MIN(n,m) (((n) < (m)) ? (n) : (m)) #endif #ifndef MAX #define MAX(n,m) (((n) < (m)) ? (m) : (n)) #endif #ifndef ABS #define ABS(n) (((n) < 0) ? -(n) : (n)) #endif /* takes a byte out of a uint32 : var - uint32, ByteNum - byte to take out (0 - 3) */ #define BREAK_UINT32( var, ByteNum ) \ (uint8)((uint32)(((var) >>((ByteNum) * 8)) & 0x00FF)) #define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \ ((uint32)((uint32)((Byte0) & 0x00FF) \ + ((uint32)((Byte1) & 0x00FF) << 8) \ + ((uint32)((Byte2) & 0x00FF) << 16) \ + ((uint32)((Byte3) & 0x00FF) << 24))) #define BUILD_UINT16(loByte, hiByte) \ ((uint16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8))) #define HI_UINT16(a) (((a) >> 8) & 0xFF) #define LO_UINT16(a) ((a) & 0xFF) #define BUILD_UINT8(hiByte, loByte) \ ((uint8)(((loByte) & 0x0F) + (((hiByte) & 0x0F) << 4))) #define HI_UINT8(a) (((a) >> 4) & 0x0F) #define LO_UINT8(a) ((a) & 0x0F) // Write the 32bit value of 'val' in little endian format to the buffer pointed // to by pBuf, and increment pBuf by 4 #define UINT32_TO_BUF_LITTLE_ENDIAN(pBuf,val) \ do { \ *(pBuf)++ = ((((uint32)(val)) >> 0) & 0xFF); \ *(pBuf)++ = ((((uint32)(val)) >> 8) & 0xFF); \ *(pBuf)++ = ((((uint32)(val)) >> 16) & 0xFF); \ *(pBuf)++ = ((((uint32)(val)) >> 24) & 0xFF); \ } while (0) // Return the 32bit little-endian formatted value pointed to by pBuf, and increment pBuf by 4 #define BUF_TO_UINT32_LITTLE_ENDIAN(pBuf) (((pBuf) += 4), BUILD_UINT32((pBuf)[-4], (pBuf)[-3], (pBuf)[-2], (pBuf)[-1])) #ifndef CHECK_BIT #define CHECK_BIT(DISCS, IDX) ((DISCS) & (1<<(IDX))) #endif #ifndef GET_BIT #define GET_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] & BV((IDX) % 8)) ? TRUE : FALSE) #endif #ifndef SET_BIT #define SET_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] |= BV((IDX) % 8))) #endif #ifndef CLR_BIT #define CLR_BIT(DISCS, IDX) (((DISCS)[((IDX) / 8)] &= (BV((IDX) % 8) ^ 0xFF))) #endif /* * This macro is for use by other macros to form a fully valid C statement. * Without this, the if/else conditionals could show unexpected behavior. * * For example, use... * #define SET_REGS() st( ioreg1 = 0; ioreg2 = 0; ) * instead of ... * #define SET_REGS() { ioreg1 = 0; ioreg2 = 0; } * or * #define SET_REGS() ioreg1 = 0; ioreg2 = 0; * The last macro would not behave as expected in the if/else construct. * The second to last macro will cause a compiler error in certain uses * of if/else construct * * It is not necessary, or recommended, to use this macro where there is * already a valid C statement. For example, the following is redundant... * #define CALL_FUNC() st( func(); ) * This should simply be... * #define CALL_FUNC() func() * * (The while condition below evaluates false without generating a * constant-controlling-loop type of warning on most compilers.) */ #define st(x) do { x } while (__LINE__ == -1) /************************************************************************************************** */ #endif