一、UART的轮询过程: osal_run_system( void ) { ...... Hal_ProcessPoll(); ...... } Hal_ProcessPoll() { ... /* UART Poll */ #if (defined HAL_UART) && (HAL_UART == TRUE) HalUARTPoll(); #endif } HalUARTPoll() { ...... #if HAL_UART_DMA HalUARTPollDMA(); #endif ...... } HalUARTPollDMA() { ...... if ((evt != 0) && (dmaCfg.uartCB != NULL)) { dmaCfg.uartCB(HAL_UART_DMA-1, evt); } ...... } 其中,dmaCfg.uartCB为初始化uart时的回调函数,我们写一个串口读写函数,利用 NPI_InitTransport( npiCBack_t npiCBack )即可将串口读写函数付给dmaCfg.uartCB,从而实现串口的轮询。 二、UART与DMA初始化 1、DMA初始化(包含UART初始化的部分代码) HalDriverInit (void) { ...... #if (defined HAL_DMA) && (HAL_DMA == TRUE) // Must be called before the init call to any module that uses DMA. HalDmaInit(); #endif ...... #if (defined HAL_UART) && (HAL_UART == TRUE) HalUARTInit(); #endif ...... } HalUARTInit() { ...... #if HAL_UART_DMA HalUARTInitDMA(); #endif ...... } 初始化DMA,需要DMA通道描述符,BLE协议栈中定义的DMA通道描述符结构: typedef struct { uint8 srcAddrH; uint8 srcAddrL; uint8 dstAddrH; uint8 dstAddrL; uint8 xferLenV; uint8 xferLenL; uint8 ctrlA; uint8 ctrlB; } halDMADesc_t; UART使用DMA方式时,函数HalUARTInitDMA()设置了UART工作方式以及配置了UART使用的DMA通道,默认开启DMA中断。 2、UART初始化 void NPI_InitTransport( npiCBack_t npiCBack ) { halUARTCfg_t uartConfig; // configure UART uartConfig.configured = TRUE; uartConfig.baudRate = NPI_UART_BR; uartConfig.flowControl = NPI_UART_FC; uartConfig.flowControlThreshold = NPI_UART_FC_THRESHOLD; uartConfig.rx.maxBufSize = NPI_UART_RX_BUF_SIZE; uartConfig.tx.maxBufSize = NPI_UART_TX_BUF_SIZE; uartConfig.idleTimeout = NPI_UART_IDLE_TIMEOUT; uartConfig.intEnable = NPI_UART_INT_ENABLE; uartConfig.callBackFunc = (halUARTCBack_t)npiCBack; // start UART // Note: Assumes no issue opening UART port. (void)HalUARTOpen( NPI_UART_PORT, &uartConfig ); return; } uint8 HalUARTOpen(uint8 port, halUARTCfg_t *config) { ...... #if (HAL_UART_DMA == 1) if (port == HAL_UART_PORT_0) HalUARTOpenDMA(config); #endif ...... } 在HalUARTOpenDMA(halUARTCfg_t *config)中完成主要的UART初始化,未打开RX中断,貌似初始化代码中也没有开启TX中断,TX中断应该是在写DMA函数中开启的: static uint16 HalUARTWriteDMA(uint8 *buf, uint16 len) { #if HAL_UART_TX_BY_ISR ...... // Keep re-enabling ISR as it might be keeping up with this loop due to other ints. IEN2 |= UTXxIE; ...... } #else 三、数据发送与接收 1、数据发送 使用了DMA通道4,单次发送,每次发送一个字节,发送一个字节后触发串口发送完成中断。协议栈默认定义了宏 HAL_UART_TX_BY_ISR,因此在DMA中断中不做任何处理。 2、数据接收 使用了DMA通道3,Repeated word模式,每次一个字,接收完成不触发DMA中断。注意DMA初始化时将rxBuf[]每个字节置为DMA_PAD取反。源地址为U0DBUF+U0BAUD,即每次传送的字包括两个字节,一个字节是接收缓冲U0DBUF,另一个是固定字节波特率,所以说rxBuf[]的高字节是波特率,低字节是接收的有效字节,这样如果高字节与波特率一致则说明是有效字(rxBuf[]全部字节初始化为DMA_PAD^0xff,如果串口没有接收到数据,则高字节是DMA_PAD取反,不相等)。 U0BAUD
|
|