1、从ZMain里面的main函数开始分析
2、进入int main( void );
HalDriverInit(); //硬件相关初始化,有DMA初始化和UART初始化
3、进入HalDriverInit();
/* DMA */
#if (defined HAL_DMA) && (HAL_DMA == TRUE)
// Must be called before the init call to any module that uses DMA.
HalDmaInit();
#endif
/* UART */
#if (defined HAL_UART) && (HAL_UART == TRUE) // HAL_UART已经在IAR里面定义了HAL_UART=TRUE
HalUARTInit();
#endif
4、进入HalUARTInit();
#if HAL_UART_DMA // HAL_UART_DMA已经在hal_board_cfg.h里面定义了HAL_UART_DMA #define HAL_UART_DMA 1
HalUARTInitDMA();
#endif
5、进入HalUARTInitDMA();配置引脚功能和DMA通道等
1 /****************************************************************************** 2 * @fn HalUARTInitDMA 3 * 4 * @brief Initialize the UART 5 * 6 * @param none 7 * 8 * @return none 9 *****************************************************************************/ 10 static void HalUARTInitDMA(void) 11 { 12 halDMADesc_t *ch; 13 14 P2DIR &= ~P2DIR_PRIPO; 15 P2DIR |= HAL_UART_PRIPO; 16 17 #if (HAL_UART_DMA == 1) 18 PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O to Alt. 1 location on P0. 19 #else 20 PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O to Alt. 2 location on P1. 21 #endif 22 PxSEL |= UxRX_TX; // Enable Tx and Rx peripheral functions on pins. 23 ADCCFG &= ~UxRX_TX; // Make sure ADC doesnt use this. 24 UxCSR = CSR_MODE; // Mode is UART Mode. 25 UxUCR = UCR_FLUSH; // Flush it. 26 27 // Setup Tx by DMA. 28 ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX ); 29 30 // The start address of the destination. 31 HAL_DMA_SET_DEST( ch, DMA_UDBUF ); 32 33 // Using the length field to determine how many bytes to transfer. 34 HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); 35 36 // One byte is transferred each time. 37 HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); 38 39 // The bytes are transferred 1-by-1 on Tx Complete trigger. 40 HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); 41 HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX ); 42 43 // The source address is incremented by 1 byte after each transfer. 44 HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 ); 45 46 // The destination address is constant - the Tx Data Buffer. 47 HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 ); 48 49 // The DMA Tx done is serviced by ISR in order to maintain full thruput. 50 HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE ); 51 52 // Xfer all 8 bits of a byte xfer. 53 HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); 54 55 // DMA has highest priority for memory access. 56 HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); 57 58 // Setup Rx by DMA. 59 ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX ); 60 61 // The start address of the source. 62 HAL_DMA_SET_SOURCE( ch, DMA_UDBUF ); 63 64 // Using the length field to determine how many bytes to transfer. 65 HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); 66 67 /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx. 68 * The byte after the Rx Data Buffer is the Baud Cfg Register, 69 * which always has a known value. So init Rx buffer to inverse of that 70 * known value. DMA word xfer will flip the bytes, so every valid Rx byte 71 * in the Rx buffer will be preceded by a DMA_PAD char equal to the 72 * Baud Cfg Register value. 73 */ 74 HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD ); 75 76 // The bytes are transferred 1-by-1 on Rx Complete trigger. 77 HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED ); 78 HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX ); 79 80 // The source address is constant - the Rx Data Buffer. 81 HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 ); 82 83 // The destination address is incremented by 1 word after each transfer. 84 HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); 85 HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf ); 86 HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX ); 87 88 // The DMA is to be polled and shall not issue an IRQ upon completion. 89 HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); 90 91 // Xfer all 8 bits of a byte xfer. 92 HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); 93 94 // DMA has highest priority for memory access. 95 HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); 96 }
6、紧接着需要配置串口
uartConfig.configured = TRUE; // 2x30 don't care - see uart driver.
uartConfig.baudRate = SERIAL_APP_BAUD;
uartConfig.flowControl = FALSE;
uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver.
uartConfig.rx.maxBufSize = SERIAL_APP_RX_SZ; // 2x30 don't care - see uart driver.
uartConfig.tx.maxBufSize = SERIAL_APP_TX_SZ; // 2x30 don't care - see uart driver.
uartConfig.idleTimeout = SERIAL_APP_IDLE; // 2x30 don't care - see uart driver.
uartConfig.intEnable = TRUE; // 2x30 don't care - see uart driver.
uartConfig.callBackFunc = SerialApp_CallBack;
HalUARTOpen (UART0, &uartConfig);
7、进入HalUARTOpen (UART0, &uartConfig);
#if (HAL_UART_DMA == 1)
if (port == HAL_UART_PORT_0) HalUARTOpenDMA(config);
#endif
8、进入HalUARTOpenDMA(config);
1 /****************************************************************************** 2 * @fn HalUARTOpenDMA 3 * 4 * @brief Open a port according tp the configuration specified by parameter. 5 * 6 * @param config - contains configuration information 7 * 8 * @return none 9 *****************************************************************************/ 10 static void HalUARTOpenDMA(halUARTCfg_t *config) 11 { 12 dmaCfg.uartCB = config->callBackFunc; 13 // Only supporting subset of baudrate for code size - other is possible. 14 HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) || 15 (config->baudRate == HAL_UART_BR_19200) || 16 (config->baudRate == HAL_UART_BR_38400) || 17 (config->baudRate == HAL_UART_BR_57600) || 18 (config->baudRate == HAL_UART_BR_115200)); 19 20 if (config->baudRate == HAL_UART_BR_57600 || 21 config->baudRate == HAL_UART_BR_115200) 22 { 23 UxBAUD = 216; 24 } 25 else 26 { 27 UxBAUD = 59; 28 } 29 30 switch (config->baudRate) 31 { 32 case HAL_UART_BR_9600: 33 UxGCR = 8; 34 dmaCfg.txTick = 35; // (32768Hz / (9600bps / 10 bits)) 35 // 10 bits include start and stop bits. 36 break; 37 case HAL_UART_BR_19200: 38 UxGCR = 9; 39 dmaCfg.txTick = 18; 40 break; 41 case HAL_UART_BR_38400: 42 UxGCR = 10; 43 dmaCfg.txTick = 9; 44 break; 45 case HAL_UART_BR_57600: 46 UxGCR = 10; 47 dmaCfg.txTick = 6; 48 break; 49 default: 50 // HAL_UART_BR_115200 51 UxGCR = 11; 52 dmaCfg.txTick = 3; 53 break; 54 } 55 56 // 8 bits/char; no parity; 1 stop bit; stop bit hi. 57 if (config->flowControl) 58 { 59 UxUCR = UCR_FLOW | UCR_STOP; 60 PxSEL |= HAL_UART_Px_CTS; 61 // DMA Rx is always on (self-resetting). So flow must be controlled by the S/W polling the Rx 62 // buffer level. Start by allowing flow. 63 PxOUT &= ~HAL_UART_Px_RTS; 64 PxDIR |= HAL_UART_Px_RTS; 65 } 66 else 67 { 68 UxUCR = UCR_STOP; 69 } 70 71 dmaCfg.rxBuf[0] = *(volatile uint8 *)DMA_UDBUF; // Clear the DMA Rx trigger. 72 HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX); 73 HAL_DMA_ARM_CH(HAL_DMA_CH_RX); 74 osal_memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX*2); 75 76 UxCSR |= CSR_RE; 77 UxDBUF = 0; // Prime the DMA-ISR pump. 78 79 // Initialize that TX DMA is not pending 80 dmaCfg.txDMAPending = FALSE; 81 dmaCfg.txShdwValid = FALSE; 82 }
9、至此就可以正常使用该串口了,但是具体如何调用呢,有如下函数