z-stack协议uart分析(DMA)
2016-03-30 15:19
99 查看
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通道等
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);
9、至此就可以正常使用该串口了,但是具体如何调用呢,有如下函数
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通道等
/****************************************************************************** * @fn HalUARTInitDMA * * @brief Initialize the UART * * @param none * * @return none *****************************************************************************/ static void HalUARTInitDMA(void) { halDMADesc_t *ch; P2DIR &= ~P2DIR_PRIPO; P2DIR |= HAL_UART_PRIPO; #if (HAL_UART_DMA == 1) PERCFG &= ~HAL_UART_PERCFG_BIT; // Set UART0 I/O to Alt. 1 location on P0. #else PERCFG |= HAL_UART_PERCFG_BIT; // Set UART1 I/O to Alt. 2 location on P1. #endif PxSEL |= UxRX_TX; // Enable Tx and Rx peripheral functions on pins. ADCCFG &= ~UxRX_TX; // Make sure ADC doesnt use this. UxCSR = CSR_MODE; // Mode is UART Mode. UxUCR = UCR_FLUSH; // Flush it. // Setup Tx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_TX ); // The start address of the destination. HAL_DMA_SET_DEST( ch, DMA_UDBUF ); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); // One byte is transferred each time. HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_BYTE ); // The bytes are transferred 1-by-1 on Tx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_TX ); // The source address is incremented by 1 byte after each transfer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_1 ); // The destination address is constant - the Tx Data Buffer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_0 ); // The DMA Tx done is serviced by ISR in order to maintain full thruput. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_ENABLE ); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); // Setup Rx by DMA. ch = HAL_DMA_GET_DESC1234( HAL_DMA_CH_RX ); // The start address of the source. HAL_DMA_SET_SOURCE( ch, DMA_UDBUF ); // Using the length field to determine how many bytes to transfer. HAL_DMA_SET_VLEN( ch, HAL_DMA_VLEN_USE_LEN ); /* The trick is to cfg DMA to xfer 2 bytes for every 1 byte of Rx. * The byte after the Rx Data Buffer is the Baud Cfg Register, * which always has a known value. So init Rx buffer to inverse of that * known value. DMA word xfer will flip the bytes, so every valid Rx byte * in the Rx buffer will be preceded by a DMA_PAD char equal to the * Baud Cfg Register value. */ HAL_DMA_SET_WORD_SIZE( ch, HAL_DMA_WORDSIZE_WORD ); // The bytes are transferred 1-by-1 on Rx Complete trigger. HAL_DMA_SET_TRIG_MODE( ch, HAL_DMA_TMODE_SINGLE_REPEATED ); HAL_DMA_SET_TRIG_SRC( ch, DMATRIG_RX ); // The source address is constant - the Rx Data Buffer. HAL_DMA_SET_SRC_INC( ch, HAL_DMA_SRCINC_0 ); // The destination address is incremented by 1 word after each transfer. HAL_DMA_SET_DST_INC( ch, HAL_DMA_DSTINC_1 ); HAL_DMA_SET_DEST( ch, dmaCfg.rxBuf ); HAL_DMA_SET_LEN( ch, HAL_UART_DMA_RX_MAX ); // The DMA is to be polled and shall not issue an IRQ upon completion. HAL_DMA_SET_IRQ( ch, HAL_DMA_IRQMASK_DISABLE ); // Xfer all 8 bits of a byte xfer. HAL_DMA_SET_M8( ch, HAL_DMA_M8_USE_8_BITS ); // DMA has highest priority for memory access. HAL_DMA_SET_PRIORITY( ch, HAL_DMA_PRI_HIGH ); }
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);
/****************************************************************************** * @fn HalUARTOpenDMA * * @brief Open a port according tp the configuration specified by parameter. * * @param config - contains configuration information * * @return none *****************************************************************************/ static void HalUARTOpenDMA(halUARTCfg_t *config) { dmaCfg.uartCB = config->callBackFunc; // Only supporting subset of baudrate for code size - other is possible. HAL_UART_ASSERT((config->baudRate == HAL_UART_BR_9600) || (config->baudRate == HAL_UART_BR_19200) || (config->baudRate == HAL_UART_BR_38400) || (config->baudRate == HAL_UART_BR_57600) || (config->baudRate == HAL_UART_BR_115200)); if (config->baudRate == HAL_UART_BR_57600 || config->baudRate == HAL_UART_BR_115200) { UxBAUD = 216; } else { UxBAUD = 59; } switch (config->baudRate) { case HAL_UART_BR_9600: UxGCR = 8; dmaCfg.txTick = 35; // (32768Hz / (9600bps / 10 bits)) // 10 bits include start and stop bits. break; case HAL_UART_BR_19200: UxGCR = 9; dmaCfg.txTick = 18; break; case HAL_UART_BR_38400: UxGCR = 10; dmaCfg.txTick = 9; break; case HAL_UART_BR_57600: UxGCR = 10; dmaCfg.txTick = 6; break; default: // HAL_UART_BR_115200 UxGCR = 11; dmaCfg.txTick = 3; break; } // 8 bits/char; no parity; 1 stop bit; stop bit hi. if (config->flowControl) { UxUCR = UCR_FLOW | UCR_STOP; PxSEL |= HAL_UART_Px_CTS; // DMA Rx is always on (self-resetting). So flow must be controlled by the S/W polling the Rx // buffer level. Start by allowing flow. PxOUT &= ~HAL_UART_Px_RTS; PxDIR |= HAL_UART_Px_RTS; } else { UxUCR = UCR_STOP; } dmaCfg.rxBuf[0] = *(volatile uint8 *)DMA_UDBUF; // Clear the DMA Rx trigger. HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX); HAL_DMA_ARM_CH(HAL_DMA_CH_RX); osal_memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF), HAL_UART_DMA_RX_MAX*2); UxCSR |= CSR_RE; UxDBUF = 0; // Prime the DMA-ISR pump. // Initialize that TX DMA is not pending dmaCfg.txDMAPending = FALSE; dmaCfg.txShdwValid = FALSE; }
9、至此就可以正常使用该串口了,但是具体如何调用呢,有如下函数
相关文章推荐
- IOS实现一个简单的浏览器
- mac端如何使用homebrew安装git
- 宏:整数常量 O_ACCMODE
- [leetcode] 339. Nested List Weight Sum 解题报告
- 【转】有关onpropertychange事件
- 正则表达式,验证文件上传类型
- 我所知道的云计算
- Glide与OkHttp3集成
- 2016sdau课程练习专题一 1006 problemG
- Unity ZTest 深度测试 & ZWrite 深度写入
- android 数据库更新
- 常见Android App错误说明
- SQL中Group By的使用
- javascript 微信企业号APP应用URL转换成PC端可正常访问的URL
- 创建和使用Android Library工程
- redis配置文件redis.conf详细说明
- 嵌套循环问题
- lightoj 1126 - Building Twin Towers DP
- B树和B+树
- java过滤器-双向过滤