📄 hal.h
字号:
// Example usage:
// INT_PRIORITY(RFERR_RF_DMA, 3);
#define INT_PRIORITY(group, pri) \
do { \
if (pri == 0) { IP0 &= ~group; IP1 &= ~group; } \
if (pri == 1) { IP0 |= group; IP1 &= ~group; } \
if (pri == 2) { IP0 &= ~group; IP1 |= group; } \
if (pri == 3) { IP0 |= group; IP1 |= group; } \
} while (0)
// Where pri is one of:
// 0 = Level 0 (lowest priority)
// 1 = Level 1
// 2 = Level 2
// 3 = Level 3 (highest priority)
// Where group is one of
#define RFERR_RF_DMA 0x01 // Group IP0
#define ADC_P2INT_T1 0x02 // Group IP1
#define URX0_UTX0_T2 0x04 // Group IP2
#define URX1_UTX1_T3 0x08 // Group IP3
#define ENC_P1INT_T4 0x10 // Group IP4
#define ST_WDT_P0INT 0x20 // Group IP5
// Macro used together with the INUM_* constants
// to read the interrupt flags.
// Example usage:
// if (INT_GETFLAG(INUM_URX0))
// ...
// while (!INT_GETFLAG(INUM_URX0));
#define INT_GETFLAG(inum) ( \
(inum==INUM_RFERR) ? RFERRIF : \
(inum==INUM_ADC) ? ADCIF : \
(inum==INUM_URX0) ? URX0IF : \
(inum==INUM_URX1) ? URX1IF : \
(inum==INUM_ENC) ? ENCIF_0 : \
(inum==INUM_ST) ? STIF : \
(inum==INUM_P2INT) ? P2IF : \
(inum==INUM_UTX0) ? UTX0IF : \
(inum==INUM_DMA) ? DMAIF : \
(inum==INUM_T1) ? T1IF : \
(inum==INUM_T2) ? T2IF : \
(inum==INUM_T3) ? T3IF : \
(inum==INUM_T4) ? T4IF : \
(inum==INUM_P0INT) ? P0IF : \
(inum==INUM_UTX1) ? UTX1IF : \
(inum==INUM_P1INT) ? P1IF : \
(inum==INUM_RF) ? S1CON &= ~0x03 : \
(inum==INUM_WDT) ? WDTIF : \
0 \
)
// Macro used to set or clear certain interrupt flags.
// Example usage:
// INT_SETFLAG(INUM_URX0, INT_SET;
// INT_SETFLAG(INUM_T3, INT_CLR);
#define INT_SETFLAG(inum, f) \
do { \
if (inum==INUM_RFERR) { RFERRIF= f; } \
else if (inum==INUM_ADC) { ADCIF = f; } \
else if (inum==INUM_URX0) { URX0IF = f; } \
else if (inum==INUM_URX1) { URX1IF = f; } \
else if (inum==INUM_ENC) { ENCIF_1 = ENCIF_0 = f; } \
else if (inum==INUM_ST) { STIF = f; } \
else if (inum==INUM_P2INT) { P2IF = f; } \
else if (inum==INUM_UTX0) { UTX0IF= f; } \
else if (inum==INUM_DMA) { DMAIF = f; } \
else if (inum==INUM_T1) { T1IF = f; } \
else if (inum==INUM_T2) { T2IF = f; } \
else if (inum==INUM_T3) { T3IF = f; } \
else if (inum==INUM_T4) { T4IF = f; } \
else if (inum==INUM_P0INT) { P0IF = f; } \
else if (inum==INUM_UTX1) { UTX1IF= f; } \
else if (inum==INUM_P1INT) { P1IF = f; } \
else if (inum==INUM_RF) { (f) ? (S1CON |= 0x03) : (S1CON &= ~0x03); } \
else if (inum==INUM_WDT) { WDTIF = f; } \
} while (0)
/******************************************************************************
************************** DMA structures / macros *************************
******************************************************************************/
// The macros and structs in this section simplify setup and usage of DMA.
//******************************************************************************
#define DMA_CHANNEL_0 0x01
#define DMA_CHANNEL_1 0x02
#define DMA_CHANNEL_2 0x04
#define DMA_CHANNEL_3 0x08
#define DMA_CHANNEL_4 0x10
#define VLEN_USE_LEN 0x00 // Use LEN for transfer count
#define VLEN_FIXED 0x00 // Use LEN for transfer count
#define VLEN_1_P_VALOFFIRST 0x01 // Transfer the first byte + the number of bytes indicated by the first byte
#define VLEN_VALOFFIRST 0x02 // Transfer the number of bytes indicated by the first byte (starting with the first byte)
#define VLEN_1_P_VALOFFIRST_P_1 0x03 // Transfer the first byte + the number of bytes indicated by the first byte + 1 more byte
#define VLEN_1_P_VALOFFIRST_P_2 0x04 // Transfer the first byte + the number of bytes indicated by the first byte + 2 more bytes
#define WORDSIZE_BYTE 0x00 // Transfer a byte at a time
#define WORDSIZE_WORD 0x01 // Transfer a 16-bit word at a time
#define TMODE_SINGLE 0x00 // Transfer a single byte/word after each DMA trigger
#define TMODE_BLOCK 0x01 // Transfer block of data (length len) after each DMA trigger
#define TMODE_SINGLE_REPEATED 0x02 // Transfer single byte/word (after len transfers, rearm DMA)
#define TMODE_BLOCK_REPEATED 0x03 // Transfer block of data (after len transfers, rearm DMA)
#define DMATRIG_NONE 0 // No trigger, setting DMAREQ.DMAREQx bit starts transfer
#define DMATRIG_PREV 1 // DMA channel is triggered by completion of previous channel
#define DMATRIG_T1_CH0 2 // Timer 1, compare, channel 0
#define DMATRIG_T1_CH1 3 // Timer 1, compare, channel 1
#define DMATRIG_T1_CH2 4 // Timer 1, compare, channel 2
#define DMATRIG_T2_COMP 5 // Timer 2, compare
#define DMATRIG_T2_OVFL 6 // Timer 2, overflow
#define DMATRIG_T3_CH0 7 // Timer 3, compare, channel 0
#define DMATRIG_T3_CH1 8 // Timer 3, compare, channel 1
#define DMATRIG_T4_CH0 9 // Timer 4, compare, channel 0
#define DMATRIG_T4_CH1 10 // Timer 4, compare, channel 1
#define DMATRIG_ST 11 // Sleep Timer compare
#define DMATRIG_IOC_0 12 // Port 0 I/O pin input transition
#define DMATRIG_IOC_1 13 // Port 1 I/O pin input transition
#define DMATRIG_URX0 14 // USART0 RX complete
#define DMATRIG_UTX0 15 // USART0 TX complete
#define DMATRIG_URX1 16 // USART1 RX complete
#define DMATRIG_UTX1 17 // USART1 TX complete
#define DMATRIG_FLASH 18 // Flash data write complete
#define DMATRIG_RADIO 19 // RF packet byte received/transmit
#define DMATRIG_ADC_CHALL 20 // ADC end of a conversion in a sequence, sample ready
#define DMATRIG_ADC_CH0 21 // ADC end of conversion channel 0 in sequence, sample ready
#define DMATRIG_ADC_CH1 22 // ADC end of conversion channel 1 in sequence, sample ready
#define DMATRIG_ADC_CH2 23 // ADC end of conversion channel 2 in sequence, sample ready
#define DMATRIG_ADC_CH3 24 // ADC end of conversion channel 3 in sequence, sample ready
#define DMATRIG_ADC_CH4 25 // ADC end of conversion channel 4 in sequence, sample ready
#define DMATRIG_ADC_CH5 26 // ADC end of conversion channel 5 in sequence, sample ready
#define DMATRIG_ADC_CH6 27 // ADC end of conversion channel 6 in sequence, sample ready
#define DMATRIG_ADC_CH7 28 // ADC end of conversion channel 7 in sequence, sample ready
#define DMATRIG_ENC_DW 29 // AES encryption processor requests download input data
#define DMATRIG_ENC_UP 30 // AES encryption processor requests upload output data
#define SRCINC_0 0x00 // Increment source pointer by 0 bytes/words after each transfer
#define SRCINC_1 0x01 // Increment source pointer by 1 bytes/words after each transfer
#define SRCINC_2 0x02 // Increment source pointer by 2 bytes/words after each transfer
#define SRCINC_M1 0x03 // Decrement source pointer by 1 bytes/words after each transfer
#define DESTINC_0 0x00 // Increment destination pointer by 0 bytes/words after each transfer
#define DESTINC_1 0x01 // Increment destination pointer by 1 bytes/words after each transfer
#define DESTINC_2 0x02 // Increment destination pointer by 2 bytes/words after each transfer
#define DESTINC_M1 0x03 // Decrement destination pointer by 1 bytes/words after each transfer
#define IRQMASK_DISABLE 0x00 // Disable interrupt generation
#define IRQMASK_ENABLE 0x01 // Enable interrupt generation upon DMA channel done
#define M8_USE_8_BITS 0x00 // Use all 8 bits for transfer count
#define M8_USE_7_BITS 0x01 // Use 7 LSB for transfer count
#define PRI_LOW 0x00 // Low, CPU has priority
#define PRI_GUARANTEED 0x01 // Guaranteed, DMA at least every second try
#define PRI_HIGH 0x02 // High, DMA has priority
#define PRI_ABSOLUTE 0x03 // Highest, DMA has priority. Reserved for DMA port access.
#pragma bitfields=reversed
typedef struct {
BYTE SRCADDRH;
BYTE SRCADDRL;
BYTE DESTADDRH;
BYTE DESTADDRL;
BYTE VLEN : 3;
BYTE LENH : 5;
BYTE LENL : 8;
BYTE WORDSIZE : 1;
BYTE TMODE : 2;
BYTE TRIG : 5;
BYTE SRCINC : 2;
BYTE DESTINC : 2;
BYTE IRQMASK : 1;
BYTE M8 : 1;
BYTE PRIORITY : 2;
} DMA_DESC;
#pragma bitfields=default
#define DMA_SET_ADDR_DESC0(a) \
do{ \
DMA0CFGH = (BYTE)( (WORD)a >> 8 );\
DMA0CFGL = (BYTE)( (WORD)a ); \
} while(0)
#define DMA_SET_ADDR_DESC1234(a) \
do{ \
DMA1CFGH = (BYTE)( (WORD)a >> 8 );\
DMA1CFGL = (BYTE)( (WORD)a ); \
} while(0)
#define DMA_ARM_CHANNEL(ch) \
do{ \
DMAARM = ((0x01 << ch) & 0x1F); \
} while(0)
#define DMA_ABORT_CHANNEL(ch) DMAARM = (0x80 | ((0x01 << ch) & 0x1F))
#define DMA_MAN_TRIGGER(ch) DMAREQ = (0x01 << ch)
#define DMA_START_CHANNEL(ch) DMA_MAN_TRIGGER(ch)
// Macro for quickly setting the destination address of a DMA structure
#define SET_DMA_DEST(pDmaDesc, dest) \
do{ \
pDmaDesc->DESTADDRH = (BYTE) ((WORD)dest >> 8);\
pDmaDesc->DESTADDRL = (BYTE) (WORD)dest; \
} while (0);
// Macro for quickly setting the source address of a DMA structure
#define SET_DMA_SOURCE(pDmaDesc, source) \
do{ \
pDmaDesc->SRCADDRH = (BYTE) ((WORD)source >> 8);\
pDmaDesc->SRCADDRL = (BYTE) (WORD)source; \
} while (0)
// Macro for quickly setting the number of bytes to be transferred by the DMA.
// max lenght is 0x1FFF
#define SET_DMA_LENGTH(pDmaDesc, length) \
do{ \
pDmaDesc->LENH = (BYTE) ((WORD)length >> 8);\
pDmaDesc->LENL = (BYTE) (WORD)length; \
} while (0)
// Macro for getting the destination address of a DMA channel
#define GET_DMA_DEST(pDmaDesc) \
( (WORD)pDmaDesc->DESTADDRL | ( (WORD)pDmaDesc->DESTADDRH << 8 ))
// Macro for getting the source address of a DMA channel
#define GET_DMA_SOURCE(pDmaDesc) \
( (WORD)pDmaDesc->SRCADDRL | ( (WORD)pDmaDesc->SRCADDRH << 8 ))
/******************************************************************************
******************* Common USART functions/macros *******************
******************************************************************************/
// The macros in this section are available for both SPI and UART operation.
//*****************************************************************************
// Example usage:
// USART0_FLUSH();
#define USART_FLUSH(num) (U##num##UCR |= 0x80)
#define USART0_FLUSH() USART_FLUSH(0)
#define USART1_FLUSH() USART_FLUSH(1)
// Example usage:
// if (USART0_BUSY())
// ...
#define USART_BUSY(num) (U##num##CSR & 0x01 == 0x01)
#define USART0_BUSY() USART_BUSY(0)
#define USART1_BUSY() USART_BUSY(1)
// Example usage:
// while(!USART1_BYTE_RECEIVED())
// ...
#define USART_BYTE_RECEIVED(num) ((U##num##CSR & 0x04) == 0x04)
#define USART0_BYTE_RECEIVED() USART_BYTE_RECEIVED(0)
#define USART1_BYTE_RECEIVED() USART_BYTE_RECEIVED(1)
// Example usage:
// if(USART1_BYTE_TRANSMITTED())
// ...
#define USART_BYTE_TRANSMITTED(num) ((U##num##CSR & 0x02) == 0x02)
#define USART0_BYTE_TRANSMITTED() USART_BYTE_TRANSMITTED(0)
#define USART1_BYTE_TRANSMITTED() USART_BYTE_TRANSMITTED(1)
/******************************************************************************
******************* USART-UART specific functions/macros *******************
******************************************************************************/
// The macros in this section simplify UART operation.
#define BAUD_E(baud, clkDivPow) ( \
(baud==2400) ? 6 +clkDivPow : \
(baud==4800) ? 7 +clkDivPow : \
(baud==9600) ? 8 +clkDivPow : \
(baud==14400) ? 8 +clkDivPow : \
(baud==19200) ? 9 +clkDivPow : \
(baud==28800) ? 9 +clkDivPow : \
(baud==38400) ? 10 +clkDivPow : \
(baud==57600) ? 10 +clkDivPow : \
(baud==76800) ? 11 +clkDivPow : \
(baud==115200) ? 11 +clkDivPow : \
(baud==153600) ? 12 +clkDivPow : \
(baud==230400) ? 12 +clkDivPow : \
(baud==307200) ? 13 +clkDivPow : \
0 )
#define BAUD_M(baud) ( \
(baud==2400) ? 59 : \
(baud==4800) ? 59 : \
(baud==9600) ? 59 : \
(baud==14400) ? 216 : \
(baud==19200) ? 59 : \
(baud==28800) ? 216 : \
(baud==38400) ? 59 : \
(baud==57600) ? 216 : \
(baud==76800) ? 59 : \
(baud==115200) ? 216 : \
(baud==153600) ? 59 : \
(baud==230400) ? 216 : \
(baud==307200) ? 59 : \
0)
//*****************************************************************************
// Macro for setting up a UART transfer channel. The macro sets the appropriate
// pins for peripheral operation, sets the baudrate, and the desired options of
// the selected uart. _uart_ indicates which uart to configure and must be
// either 0 or 1. _baudRate_ must be one of 2400, 4800, 9600, 14400, 19200,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -