- /******************** (C) COPYRIGHT 2008 litt ********************
- * File Name : usart.c
- * Author : luo yi ming
- * Version : V1.0.0
- * Date : 2012年12月28日
- * Description : This file provides a set of functions needed to manage the
- * communication between usart peripheral and RS485/HW/PLC.
- ********************************************************************************/
- /* Includes ------------------------------------------------------------------*/
- #include "includes.h"
- #include "usart.h"
- /* Private typedef -----------------------------------------------------------*/
- struct UartFifo{
- //rx 12byte
- u8* rxBuf; //4
- vu16 rxSize; //2
- vu16 rxPush; //2
- vu16 rxPop; //2
- u16 rxCnt; //2
- //tx 12byte
- u8* txBuf; //4
- vu16 txSize; //2
- vu16 txPush; //2
- vu16 txPop; //2
- u16 txCnt; //2
- //Isr 4byte
- void (*isr)(uint8_t,enum UartIsrMod);
- };//28
- struct UartCfg{
- struct UartFifo fifo;
- USART_TypeDef* uart;
- DMA_Channel_TypeDef* rxdma;
- DMA_Channel_TypeDef* txdma;
- };
- /*struct UartReg{
- USART_TypeDef* uart;
- DMA_Channel_TypeDef* rxdma;
- DMA_Channel_TypeDef* txdma;
- };*/
- /* Private define ------------------------------------------------------------*/
- #define UART1_DMA_RX DMA1_Channel5
- #define UART1_DMA_TX DMA1_Channel4
- #define UART2_DMA_RX DMA1_Channel6
- #define UART2_DMA_TX DMA1_Channel7
- #define UART3_DMA_RX DMA1_Channel3
- #define UART3_DMA_TX DMA1_Channel2
- #define UART_REG_1 {USART1,UART1_DMA_RX,UART1_DMA_TX}
- #define UART_REG_2 {USART2,UART2_DMA_RX,UART2_DMA_TX}
- #define UART_REG_3 {USART3,UART3_DMA_RX,UART3_DMA_TX}
- #define UART_REG_4 {UART4,NULL,NULL}
- #define UART_REG_5 {UART5,NULL,NULL}
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- struct UartCfg UartCfgTab[UART_PORT_MAX];
- //const struct UartReg UartRegTab[UART_PORT_MAX] = {UART_REG_1,UART_REG_2,UART_REG_3,UART_REG_4,UART_REG_5};
- /*
- UART running by interrupt model
- */
- /*************************************************************************************************
- * Name : UartIntIsr
- * Describe : 串口中断服务程序
- * Input : pfifo,uart
- * Output : 无
- * Create by : 罗一鸣 2012-12-03
- * Moid by :
- *************************************************************************************************/
- static __inline void UartIntIsr(uint8_t port,struct UartFifo *pfifo,USART_TypeDef *uart)
- {
- uint32_t ie;
- uint8_t c;
- ie = __get_PRIMASK();
- __set_PRIMASK(1);
- if((uart->CR1 & 0x0020) && (uart->SR & 0x0020))
- {
- c = uart->DR;
- if(pfifo->rxCnt < pfifo->rxSize)
- {
- pfifo->rxBuf[pfifo->rxPush] = c;
- pfifo->rxPush += 1;
- pfifo->rxPush %= pfifo->rxSize;
- pfifo->rxCnt += 1;
- if(pfifo->rxCnt == (pfifo->rxSize - SERIAL_RXFULL_LINE))
- {
- if(NULL != pfifo->isr)
- {
- pfifo->isr(port,RxFull);
- }
- }
- }
- }
- //IDLE IRQ
- if((uart->CR1 & 0x0010)&&(uart->SR & 0x0010))
- {
- c = uart->DR;
- if(pfifo->rxCnt < (pfifo->rxSize - SERIAL_RXFULL_LINE))
- {
- if(NULL != pfifo->isr)
- {
- pfifo->isr(port,RxTimeout);
- }
- }
- }
- //TXE IRQ
- if((uart->SR & 0x0080) && (uart->CR1 & 0x0080))
- {
- uart->CR1 &= (uint16_t)~0x0080; //off TX
- if(pfifo->txCnt)
- {
- c = pfifo->txBuf[pfifo->txPop];
- uart->DR = c;
- uart->CR1 |= (uint16_t)0x0080;
- pfifo->txPop += 1;
- pfifo->txPop %= pfifo->txSize;
- pfifo->txCnt -= 1;
- if(pfifo->txCnt == 0)
- {
- if(NULL != pfifo->isr)
- {
- pfifo->isr(port,TxEmpty);
- }
- }
- }
- }
- __set_PRIMASK(ie);
- }
- /*************************************************************************************************
- * Name : UartRead
- * Describe : 串口读取函数
- * Input :
- * Output :
- * Create by :
- * Moid by :
- *************************************************************************************************/
- static uint16_t UartReadInt(struct UartFifo *pfifo,USART_TypeDef *uart,uint8_t *data,uint16_t len)
- {
- uint16_t n;
- if(len == 0)
- {
- return 0;
- }
- else if(len > pfifo->rxSize)
- {
- len = pfifo->rxSize;
- }
-
- for(n=0;n<len;n++)
- {
- USART_ITConfig(uart,USART_IT_RXNE ,DISABLE);
- if(pfifo->rxCnt > 0)
- {
- *data++ = pfifo->rxBuf[pfifo->rxPop];
- pfifo->rxPop += 1;
- pfifo->rxPop %= pfifo->rxSize;
- pfifo->rxCnt--;
- USART_ITConfig(uart,USART_IT_RXNE ,ENABLE);
- }
- else
- {
- USART_ITConfig(uart,USART_IT_RXNE ,ENABLE);
- break;
- }
- }
-
- return n;
- }
- /*************************************************************************************************
- * Name : UartWrite
- * Describe : 串口发送函数
- * Input :
- * Output :
- * Create by :
- * Moid by :
- *************************************************************************************************/
- static uint16_t UartWriteInt(struct UartFifo *pfifo,USART_TypeDef *uart,uint8_t *data,uint16_t len)
- {
- uint16_t n;
- if(len == 0)
- {
- return 0;
- }
- else if(len > pfifo->txSize)
- {
- len = pfifo->txSize;
- }
- USART_ITConfig(uart,USART_IT_TXE ,DISABLE);
- for(n=0;n<len;n++)
- {
- if(pfifo->txCnt < pfifo->txSize)
- {
- pfifo->txBuf[pfifo->txPush] = *data++;
- pfifo->txPush += 1;
- pfifo->txPush %= pfifo->txSize;
- pfifo->txCnt++;
- }
- else
- {
- break;
- }
- }
- USART_ITConfig(uart,USART_IT_TXE ,ENABLE);
- return n;
- }
- /*************************************************************************************************
- * Name : USART_ISR
- * Describe : 串口中断服务
- * Input :
- * Output :
- * Create by :
- * Moid by :
- *************************************************************************************************/
- void USART_ISR(uint8_t port)
- {
- UartIntIsr(port,&UartCfgTab[port].fifo,UartCfgTab[port].uart);
- }
- /*
- */
- __inline void UartDmaIsr(uint8_t port,struct UartFifo *pfifo,USART_TypeDef *uart)
- {
-
-
- }
- /*
- UART API
- */
- /*************************************************************************************************
- * Name : SerialPortConfig
- * Describe :
- * Input :
- * Output :
- * Create by : 罗一鸣 Date: 2012-12-03
- * Moid by :
- *************************************************************************************************/
- void UartNvicSet(uint8_t port,uint8_t preprio,uint8_t subprio)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- if(UART_PORT_1 == port)
- {
- // config USART1 clock
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
- // Configure USART1 Tx (PA.09) as alternate function push-pull
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- // Configure USART1 Rx (PA.10) as input floating
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- // Set Interrupt Priority
- NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preprio;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = subprio;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- //CLI();
- NVIC_Init(&NVIC_InitStructure);
- //SEI();
- }
- else if(UART_PORT_2 == port)
- {
- // config USART2 clock
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
- // Configure USART2 Tx (PA.02) as alternate function push-pull
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- // Configure USART2 Rx (PA.03) as input floating
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- // Set Interrupt Priority
- NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preprio;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = subprio;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- //CLI();
- NVIC_Init(&NVIC_InitStructure);
- //SEI();
- }
- else if(UART_PORT_3 == port)
- {
- // config USART3 clock
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
- // Configure USART2 Tx (PB.10) as alternate function push-pull
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- // Configure USART2 Rx (PB.11) as input floating
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- // Set Interrupt Priority
- NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = preprio;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = subprio;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- //CLI();
- NVIC_Init(&NVIC_InitStructure);
- //SEI();
- }
- }
- /*************************************************************************************************
- * Name : UartConfig
- * Describe :
- * Input :
- * Output :
- * Create by : 罗一鸣 Date: 2012-12-03
- * Moid by :
- *************************************************************************************************/
- void UartConfig(uint8_t port,uint8_t *buf,uint16_t size,void (*isr)(uint8_t,enum UartIsrMod),FunctionalState dma)
- {
- switch(port)
- {
- case UART_PORT_1: UartCfgTab[port].uart = USART1;UartCfgTab[port].rxdma = UART1_DMA_RX;UartCfgTab[port].txdma = UART1_DMA_TX;break;
- case UART_PORT_2: UartCfgTab[port].uart = USART2;UartCfgTab[port].rxdma = UART2_DMA_RX;UartCfgTab[port].txdma = UART2_DMA_TX;break;
- case UART_PORT_3: UartCfgTab[port].uart = USART3;UartCfgTab[port].rxdma = UART3_DMA_RX;UartCfgTab[port].txdma = UART3_DMA_TX;break;
- case UART_PORT_4: UartCfgTab[port].uart = UART4;break;
- case UART_PORT_5: UartCfgTab[port].uart = UART5;break;
- default : return;
- }
- UartCfgTab[port].fifo.rxBuf = buf;
- UartCfgTab[port].fifo.txBuf = buf+size/2;
- UartCfgTab[port].fifo.rxSize = UartCfgTab[port].fifo.txSize = size/2;
- UartCfgTab[port].fifo.rxPush = UartCfgTab[port].fifo.rxPop = UartCfgTab[port].fifo.rxCnt = 0;
- UartCfgTab[port].fifo.txPush = UartCfgTab[port].fifo.txPop = UartCfgTab[port].fifo.txCnt = 0;
- UartCfgTab[port].fifo.isr = isr;
- if(DISABLE == dma)
- {
- UartCfgTab[port].rxdma = NULL;
- UartCfgTab[port].txdma = NULL;
- USART_ITConfig(UartCfgTab[port].uart,USART_IT_TXE ,DISABLE);
- USART_ITConfig(UartCfgTab[port].uart,USART_IT_RXNE,ENABLE);
- USART_ITConfig(UartCfgTab[port].uart,USART_IT_IDLE,ENABLE);
- USART_Cmd(UartCfgTab[port].uart, ENABLE);
- }
- else
- {
- USART_ITConfig(UartCfgTab[port].uart,USART_IT_IDLE,ENABLE);
- USART_Cmd(UartCfgTab[port].uart, ENABLE);
- }
- }
- /*************************************************************************************************
- * Name : UartOpen
- * Describe :
- * Input :
- * Output :
- * Create by : 罗一鸣 Date: 2013-02-27
- * Moid by :
- *************************************************************************************************/
- void UartOpen(uint8_t port,uint32_t baud,uint8_t mod)
- {
- USART_InitTypeDef init;
- init.USART_BaudRate = baud;
- init.USART_WordLength = USART_WordLength_8b;
- init.USART_StopBits = USART_StopBits_1;
- init.USART_Parity = USART_Parity_No ;
- if(mod & UART_FLOW_EN)
- {
- init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- }
- init.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(UartCfgTab[port].uart, &init);
- }
- /*************************************************************************************************
- * Name : UartRead
- * Describe :
- * Input :
- * Output :
- * Create by : 罗一鸣 Date: 2012-12-03
- * Moid by :
- *************************************************************************************************/
- uint16_t UartRead(uint8_t port,uint8_t *data,uint16_t len)
- {
- if(UART_PORT_MAX <= port)
- {
- return 0;
- }
- if((NULL != UartCfgTab[port].rxdma))
- {
- return 0;
- }
- else
- {
- return UartReadInt(&UartCfgTab[port].fifo,UartCfgTab[port].uart,data,len);
- }
- }
- /*************************************************************************************************
- * Name : UartWrite
- * Describe :
- * Input :
- * Output :
- * Create by : 罗一鸣 Date: 2012-12-03
- * Moid by :
- *************************************************************************************************/
- uint16_t UartWrite(uint8_t port,uint8_t *data,uint16_t len)
- {
- if(UART_PORT_MAX <= port)
- {
- return 0;
- }
- if((NULL != UartCfgTab[port].txdma))
- {
- return 0;
- }
- else
- {
- return UartWriteInt(&UartCfgTab[port].fifo,UartCfgTab[port].uart,data,len);
- }
- }
- /*************************************************************************************************
- * Name : UartRxCnt
- * Describe :
- * Input :
- * Output :
- * Create by :
- * Moid by :
- *************************************************************************************************/
- uint16_t UartRxCnt(uint8_t port)
- {
- return UartCfgTab[port].fifo.rxCnt;
- }
- /*************************************************************************************************
- * Name : UartTxCnt
- * Describe :
- * Input :
- * Output :
- * Create by :
- * Moid by :
- *************************************************************************************************/
- uint16_t UartTxCnt(uint8_t port)
- {
- return UartCfgTab[port].fifo.txCnt;
- }
- /****************************************************************************
- *************************** End of File *************************************
- ****************************************************************************/