z-stack协议uart分析(DMA)

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、至此就可以正常使用该串口了,但是具体如何调用呢,有如下函数

 

posted @ 2016-03-30 15:19  小健V5  阅读(1025)  评论(0编辑  收藏  举报