| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973 | /****************************************************************************** * 串口功能函数 * Copyright 2014, . * * File Name  : Uart.c * Description: 串口功能函数 * * modification history * -------------------- * V1.1, 21-aug-2015, Simon modify: 增加DMA发送方式,DEVICE_FLAG_DMA_TX标志有 *                  效时使用DMA发送;注: DMA发送的缓存是发送时的指针,所以 *                  利用DMA发送可能有风险。 * V1.0, 11-jun-2014, Simon written * -------------------- ******************************************************************************/#include <stdint.h>#include <stdlib.h>#include "uart.h"#include "queue.h"#include "wdg.h"#include "hw_cfg.h"#define USART1_DR_Base  ((uint32_t)&USART1->DR)#define USART2_DR_Base  ((uint32_t)&USART2->DR)#define USART3_DR_Base  ((uint32_t)&USART3->DR)#define USART4_DR_Base  ((uint32_t)&UART4->DR)#define USART5_DR_Base  ((uint32_t)&UART5->DR)/* USART1_REMAP = 0 */#define UART1_GPIO_PIN_RX       GPIO_Pin_7#define UART1_GPIO_PIN_TX       GPIO_Pin_6#define UART1_GPIO_RX           GPIOB#define UART1_GPIO_TX           GPIOB#define UART1_GPIO_RX_CLK           RCC_APB2Periph_GPIOB#define UART1_GPIO_TX_CLK           RCC_APB2Periph_GPIOB#define RCC_APBPeriph_UART1 RCC_APB2Periph_USART1#define UART1_RX_DMA        DMA1_Channel5#define UART1_TX_DMA        DMA1_Channel4#if defined(STM32F10X_LD) || defined(STM32F10X_MD)#define UART2_GPIO_PIN_RX       GPIO_Pin_6#define UART2_GPIO_PIN_TX       GPIO_Pin_5#define UART2_GPIO_RX           GPIOD#define UART2_GPIO_TX           GPIOD#define UART2_GPIO_RX_CLK           RCC_APB2Periph_GPIOD#define UART2_GPIO_TX_CLK           RCC_APB2Periph_GPIOD#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2#else /* for STM32F10X_HD *//* USART2_REMAP = 0 */#define UART2_GPIO_PIN_RX       GPIO_Pin_3#define UART2_GPIO_PIN_TX       GPIO_Pin_2#define UART2_GPIO_RX           GPIOA#define UART2_GPIO_TX           GPIOA#define UART2_GPIO_RX_CLK           RCC_APB2Periph_GPIOA#define UART2_GPIO_TX_CLK           RCC_APB2Periph_GPIOA#define RCC_APBPeriph_UART2 RCC_APB1Periph_USART2#define UART2_RX_DMA        DMA1_Channel6#define UART2_TX_DMA        DMA1_Channel7#endif/* USART3_REMAP[1:0] = 00 */#define UART3_GPIO_PIN_RX       GPIO_Pin_11#define UART3_GPIO_PIN_TX       GPIO_Pin_10#define UART3_GPIO_RX           GPIOB#define UART3_GPIO_TX           GPIOB#define UART3_GPIO_RX_CLK           RCC_APB2Periph_GPIOB#define UART3_GPIO_TX_CLK           RCC_APB2Periph_GPIOB#define RCC_APBPeriph_UART3 RCC_APB1Periph_USART3#define UART3_RX_DMA        DMA1_Channel3#define UART3_TX_DMA        DMA1_Channel2/* UART4_REMAP = 0 */#define UART4_GPIO_PIN_RX       GPIO_Pin_11#define UART4_GPIO_PIN_TX       GPIO_Pin_10#define UART4_GPIO_RX           GPIOC#define UART4_GPIO_TX           GPIOC#define UART4_GPIO_RX_CLK           RCC_APB2Periph_GPIOC#define UART4_GPIO_TX_CLK           RCC_APB2Periph_GPIOC#define RCC_APBPeriph_UART4 RCC_APB1Periph_UART4#define UART4_RX_DMA        DMA2_Channel3#define UART4_TX_DMA        DMA2_Channel5/* UART5_REMAP = 0 */#define UART5_GPIO_PIN_RX       GPIO_Pin_2  //PD2#define UART5_GPIO_PIN_TX       GPIO_Pin_12 //PC12#define UART5_GPIO_RX           GPIOD#define UART5_GPIO_TX           GPIOC#define UART5_GPIO_RX_CLK           RCC_APB2Periph_GPIOD#define UART5_GPIO_TX_CLK           RCC_APB2Periph_GPIOC#define RCC_APBPeriph_UART5 RCC_APB1Periph_UART5static Uart_t uart1 ={    USART1,    NULL,    0,    NULL,    UART1_GPIO_RX,    UART1_GPIO_TX,    UART1_GPIO_PIN_RX,    UART1_GPIO_PIN_TX,    UART1_GPIO_RX_CLK,    UART1_GPIO_TX_CLK,    EXTI_Line10,    USART1_IRQn,    0,0,0,    {UART1_TX_DMA, RCC_AHBPeriph_DMA1, DMA1_FLAG_TC4, DMA1_Channel4_IRQn, NULL, NULL}};static Uart_t uart2 ={    USART2,    NULL,    0,    NULL,    UART2_GPIO_RX,    UART2_GPIO_TX,    UART2_GPIO_PIN_RX,    UART2_GPIO_PIN_TX,    UART2_GPIO_RX_CLK,    UART2_GPIO_TX_CLK,    EXTI_Line3,    USART2_IRQn,    0,1,0,    {UART2_TX_DMA, RCC_AHBPeriph_DMA1, DMA1_FLAG_TC7, DMA1_Channel7_IRQn, NULL, NULL}};static Uart_t uart3 ={    USART3,    NULL,    0,    NULL,    UART3_GPIO_RX,    UART3_GPIO_TX,    UART3_GPIO_PIN_RX,    UART3_GPIO_PIN_TX,    UART3_GPIO_RX_CLK,    UART3_GPIO_TX_CLK,    EXTI_Line11,    USART3_IRQn,    0,2,0,    {UART3_TX_DMA, RCC_AHBPeriph_DMA1, DMA1_FLAG_TC2, DMA1_Channel2_IRQn, NULL, NULL}};static Uart_t uart4 ={    UART4,    NULL,    0,    NULL,    UART4_GPIO_RX,    UART4_GPIO_TX,    UART4_GPIO_PIN_RX,    UART4_GPIO_PIN_TX,    UART4_GPIO_RX_CLK,    UART4_GPIO_TX_CLK,    EXTI_Line11,    UART4_IRQn,    0,3,0,    #ifdef STM32F10X_CL    {UART4_TX_DMA, RCC_AHBPeriph_DMA2, DMA2_FLAG_TC5, DMA2_Channel5_IRQn, NULL, NULL}    #else    {UART4_TX_DMA, RCC_AHBPeriph_DMA2, DMA2_FLAG_TC5, DMA2_Channel4_5_IRQn, NULL, NULL}    #endif};static Uart_t uart5 ={    UART5,    NULL,    0,    NULL,    UART5_GPIO_RX,    UART5_GPIO_TX,    UART5_GPIO_PIN_RX,    UART5_GPIO_PIN_TX,    UART5_GPIO_RX_CLK,    UART5_GPIO_TX_CLK,    EXTI_Line2,    UART5_IRQn,    0,4,0,    {0, 0, 0, 0, NULL, NULL}};/****************************************************************************** * Uart_RccConfig - Enables the APB peripheral clock of UART. * * Input: none * Output: none * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/static void Uart_RccConfig(USART_TypeDef* USARTx){    /* Enable USART clocks */    switch((uint32_t)USARTx)    {        case (uint32_t)USART1:            RCC_APB2PeriphClockCmd(RCC_APBPeriph_UART1, ENABLE);            if(UART1_GPIO_PIN_TX != GPIO_Pin_9)            {                RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);                GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);            }            break;        case (uint32_t)USART2:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART2, ENABLE);            break;        case (uint32_t)USART3:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART3, ENABLE);            break;        case (uint32_t)UART4:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART4, ENABLE);            break;        case (uint32_t)UART5:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART5, ENABLE);            break;        default:            break;    }}/****************************************************************************** * Uart_SetGPIO - Configuration GPIO of the UART * * Input: uart, UART interface pointer * Output: none * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/static void Uart_SetGPIO(Uart_t *uart){    GPIO_InitTypeDef GPIO_InitStructure;    /* Enable GPIO clocks */    RCC_APB2PeriphClockCmd(uart->GPIO_RX_CLK | uart->GPIO_TX_CLK, ENABLE);    GPIO_InitStructure.GPIO_Pin = uart->GPIO_PIN_RX;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    GPIO_Init(uart->GPIOx_RX, &GPIO_InitStructure);    GPIO_InitStructure.GPIO_Pin = uart->GPIO_PIN_TX;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    GPIO_Init(uart->GPIOx_TX, &GPIO_InitStructure);    #ifdef UART1_PWR_GPIO    if(uart->uart_device == USART1)    {        GPIO_InitTypeDef GPIO_InitStructure;        RCC_APB2PeriphClockCmd(UART1_PWR_CLK, ENABLE);        GPIO_InitStructure.GPIO_Pin   = UART1_PWR_PIN;        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;       /*推挽输出 */        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        GPIO_Init(UART1_PWR_GPIO, &GPIO_InitStructure);    }    #endif}/****************************************************************************** * Uart_SetNVIC - Set NVIC of the UART * * Input: *  uart, UART interface pointer *  state, Specifies whether the IRQ channel defined in NVIC_IRQChannel will be enabled or *      disabled. This parameter can be set either to ENABLE or DISABLE. * Output: * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/static void Uart_SetNVIC(Uart_t *uart, FunctionalState state){    NVIC_InitTypeDef NVIC_InitStructure;    NVIC_InitStructure.NVIC_IRQChannel = uart->Channel;    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = uart->PreemptionPriority;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = uart->SubPriority;    NVIC_InitStructure.NVIC_IRQChannelCmd = state;    NVIC_Init(&NVIC_InitStructure);}/****************************************************************************** * Uart_DMAConfig - Configuration DMA of the UART * * Input: none * Output: none * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/static void Uart_DMAConfig(Uart_t *uart, uint16_t flag){    DMA_InitTypeDef DMA_InitStructure;    NVIC_InitTypeDef NVIC_InitStructure;    if((uint32_t)uart->uart_device == (uint32_t)UART5)    {        return;    }    RCC_AHBPeriphClockCmd(uart->dma_tx.dma_rcc, ENABLE);    //tx dma    /* fill init structure */    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;    /* DMA1 Channel7 (triggered by USART2 Tx event) Config */    DMA_DeInit(uart->dma_tx.dma_channel);    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&uart->uart_device->DR;    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;    /* As we will set them before DMA actually enabled, the DMA_MemoryBaseAddr     * and DMA_BufferSize are meaningless. So just set them to proper values     * which could make DMA_Init happy.     */    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)0;    DMA_InitStructure.DMA_BufferSize = 1;    DMA_Init(uart->dma_tx.dma_channel, &DMA_InitStructure);    if(flag & DEVICE_FLAG_INT_TX)        DMA_ITConfig(uart->dma_tx.dma_channel, DMA_IT_TC | DMA_IT_TE, ENABLE);    DMA_ClearFlag(uart->dma_tx.dma_flag_tc);    if(flag & DEVICE_FLAG_INT_TX)    {        /* Enable the DMA1 Channel2 Interrupt */        NVIC_InitStructure.NVIC_IRQChannel = uart->dma_tx.dma_irqn;        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        NVIC_Init(&NVIC_InitStructure);        /* Enable USART3 DMA Tx request */        USART_DMACmd(uart->uart_device, USART_DMAReq_Tx , ENABLE);    }}/****************************************************************************** * Uart_SetBaudRate - Set baudrate of the UART * * Input: *  uart, UART interface pointer *  BaudRate, 9600/19200/38400/57600/115200 * Output: * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/static void Uart_SetBaudRate(Uart_t *uart, uint32_t baudrate){    USART_InitTypeDef USART_InitStructure;    USART_Cmd(uart->uart_device, DISABLE);    USART_InitStructure.USART_BaudRate = baudrate;    USART_InitStructure.USART_WordLength = USART_WordLength_8b;    USART_InitStructure.USART_StopBits = USART_StopBits_1;    USART_InitStructure.USART_Parity = USART_Parity_No;    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    USART_Init(uart->uart_device, &USART_InitStructure);    USART_Cmd(uart->uart_device, ENABLE);}/****************************************************************************** * Uart_BufferMalloc - 串口缓存申请 * * Input: *  uart,自定义串口结构体指针 *  tx_buf_size, 发送缓存大小 *  rx_buf_size, 接收缓存大小 * Output: *  uart->rx_buf *  uart->tx_buf * Returns: -1 of error, 0 of OK. * modification history * -------------------- * 27-aug-2014, Simon written * -------------------- ******************************************************************************/static int Uart_BufferMalloc(Uart_t *uart, uint32_t rx_buf_size, uint32_t tx_buf_size){    if(!rx_buf_size)    {        uart->rx_buf = NULL;    }    else    {        uart->rx_buf = (uint8_t *)malloc(rx_buf_size);        if(uart->rx_buf == NULL)        {            return -1;        }    }    if(!tx_buf_size)    {        uart->tx_buf = NULL;    }    else    {        uart->tx_buf = (uint8_t *)malloc(tx_buf_size);        if(uart->tx_buf == NULL)        {            if(uart->rx_buf != NULL)            {                free(uart->rx_buf);                uart->rx_buf = NULL;            }            return -1;        }    }    return 0;}static void Uart_DmaEnable(DMA_Channel_TypeDef* dma_channel,    uint32_t address, uint32_t size){    /* disable DMA */    DMA_Cmd(dma_channel, DISABLE);    /* set buffer address */    dma_channel->CMAR = address;    /* set size */    dma_channel->CNDTR = size;    /* enable DMA */    DMA_Cmd(dma_channel, ENABLE);}static void Uart_SetParity(Uart_t *uart, uint16_t parity){    uint16_t tmpreg = 0x00;    assert_param(IS_USART_PARITY(parity));    tmpreg = uart->uart_device->CR1;    /* Clear M, PCE, PS bits */    tmpreg &= 0xE9FF;    /* Configure the USART Word Length, Parity and mode ----------------------- */    /* Set the M bits according to USART_WordLength value */    /* Set PCE and PS bits according to USART_Parity value */    if(parity == USART_Parity_No)    {        tmpreg |= USART_WordLength_8b | parity;    }    else    {        tmpreg |= USART_WordLength_9b | parity;    }    /* Write to USART CR1 */    uart->uart_device->CR1 = tmpreg;}static uint32_t Uart_Read(Dev_t dev, uint32_t pos, void *buffer, uint32_t size){    uint32_t read_size;    uint8_t *ptr;    Uart_t *uart = (Uart_t *)dev->user_data;    ptr = buffer;    read_size = Queue_Size(uart->rx_buf);    if(read_size > size)        read_size = size;    while(read_size)    {        /* 队列为空则终止读取 */        if(Queue_Read(uart->rx_buf, ptr) != QUEUE_OK)            break;        ++ptr;        --read_size;    }    return (uint32_t)ptr - (uint32_t)buffer;}static uint32_t Uart_Write(Dev_t dev, uint32_t pos, const void *buffer, uint32_t size){    uint8_t *ptr;    Uart_t *uart = (Uart_t *)dev->user_data;    uint32_t retry = 0;    if(dev->open_flag == DEVICE_OFLAG_CLOSE)    {        return 0;    }    ptr = (uint8_t *)buffer;    if (dev->flag & DEVICE_FLAG_DMA_TX)    {        /* DMA mode Tx */        if(dev->flag & DEVICE_FLAG_INT_TX)        {            /* allocate a data node */            Uart_Node_t* data_node = (Uart_Node_t*)malloc(sizeof(Uart_Node_t));            if(data_node == NULL)            {                return 0;            }            else            {                /* fill data node */                data_node->data_ptr     = ptr;                data_node->data_size    = size;                /* insert to data link */                data_node->next = NULL;                /* disable interrupt */                __set_PRIMASK(1);                data_node->prev = uart->dma_tx.list_tail;                if (uart->dma_tx.list_tail != NULL)                    uart->dma_tx.list_tail->next = data_node;                uart->dma_tx.list_tail = data_node;                if (uart->dma_tx.list_head == NULL)                {                    /* start DMA to transmit data */                    uart->dma_tx.list_head = data_node;                    /* Enable DMA Channel */                    Uart_DmaEnable(uart->dma_tx.dma_channel,                        (uint32_t)uart->dma_tx.list_head->data_ptr,                        uart->dma_tx.list_head->data_size);                }                /* enable interrupt */                __set_PRIMASK(0);                return size;            }        }        else        {            Uart_DmaEnable(uart->dma_tx.dma_channel, (uint32_t)ptr, size);            while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)            {//              IWDGFeed();                if(++retry >= 0xffffff)                {                    break;                }            }            DMA_ClearFlag(DMA1_FLAG_TC4);            DMA_Cmd(uart->dma_tx.dma_channel, DISABLE);            return size;        }    }    else    {        /* interrupt mode Tx, does not support *///      ASSERT((dev->flag & DEVICE_FLAG_INT_TX) == 0);        /* polling mode */        while(size)        {            USART_SendData(uart->uart_device, *ptr);            ++ptr;            --size;            while(USART_GetFlagStatus(uart->uart_device, USART_FLAG_TXE)==RESET)            {                if(++retry >= 0x1ffff)  /* 127ms @72MHz */                {                    break;                }            }        }        /* 等待最后一个数据帧传送完毕, 485通信可确定何时切换到读模式 */        while(USART_GetFlagStatus(uart->uart_device, USART_FLAG_TC)==RESET)        {            if(++retry >= 0x1ffff)  /* 127ms @72MHz */            {                break;            }        }    }    return (uint32_t)ptr - (uint32_t)buffer;}static Dev_Err_t Uart_Control(Dev_t dev, uint8_t cmd, void *args){    Uart_t *uart = (Uart_t *)dev->user_data;    switch(cmd)    {        case DEVICE_CTRL_SUSPEND:            /* suspend device */            if(dev->open_flag == DEVICE_OFLAG_CLOSE)                return DEV_ERR;            dev->flag |= DEVICE_FLAG_SUSPENDED;            USART_Cmd(uart->uart_device, DISABLE);            break;        case DEVICE_CTRL_RESUME:            /* resume device */            if(dev->open_flag == DEVICE_OFLAG_CLOSE)                return DEV_ERR;            dev->flag &= ~DEVICE_FLAG_SUSPENDED;            USART_Cmd(uart->uart_device, ENABLE);            break;        case UART_DEVICE_CTRL_SET_BPS:            Uart_SetBaudRate(uart, *(uint32_t *)args);            break;        case UART_DEVICE_CTRL_FLUSH:            Queue_Flush(uart->rx_buf);            break;        case UART_DEVICE_CTRL_SET_PARITY:            Uart_SetParity(uart, *(uint16_t *)args);            break;        default:            break;    }    return DEV_OK;}static Dev_Err_t Uart_Open(Dev_t dev, uint16_t oflag){    Uart_t *uart = dev->user_data;    GPIO_InitTypeDef GPIO_InitStructure;    switch((uint32_t)uart->uart_device)    {        case (uint32_t)USART1:            RCC_APB2PeriphClockCmd(RCC_APBPeriph_UART1, ENABLE);            #ifdef UART1_PWR_GPIO            GPIO_ResetBits(GPIOE, GPIO_Pin_0);            #endif            break;        case (uint32_t)USART2:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART2, ENABLE);            break;        case (uint32_t)USART3:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART3, ENABLE);            break;        case (uint32_t)UART4:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART4, ENABLE);            break;        case (uint32_t)UART5:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART5, ENABLE);            break;        default:            return DEV_ERR;//          break;    }    GPIO_InitStructure.GPIO_Pin = uart->GPIO_PIN_TX;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    GPIO_Init(uart->GPIOx_TX, &GPIO_InitStructure);    if(dev->flag & DEVICE_FLAG_DMA_TX)    {        Uart_DMAConfig(uart, dev->flag);        USART_DMACmd(uart->uart_device, USART_DMAReq_Tx, ENABLE);    }    return DEV_OK;}static Dev_Err_t Uart_Close(Dev_t dev){    Uart_t *uart = dev->user_data;    GPIO_InitTypeDef GPIO_InitStructure;    switch((uint32_t)uart->uart_device)    {        case (uint32_t)USART1:            RCC_APB2PeriphClockCmd(RCC_APBPeriph_UART1, DISABLE);            #ifdef UART1_PWR_GPIO            GPIO_SetBits(GPIOE, GPIO_Pin_0);            #endif            break;        case (uint32_t)USART2:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART2, DISABLE);            break;        case (uint32_t)USART3:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART3, DISABLE);            break;        case (uint32_t)UART4:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART4, DISABLE);            break;        case (uint32_t)UART5:            RCC_APB1PeriphClockCmd(RCC_APBPeriph_UART5, DISABLE);            break;        default:            return DEV_ERR;//          break;    }    GPIO_InitStructure.GPIO_Pin = uart->GPIO_PIN_TX;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    GPIO_Init(uart->GPIOx_TX, &GPIO_InitStructure);    if(dev->flag & DEVICE_FLAG_DMA_TX)    {        USART_DMACmd(uart->uart_device, USART_DMAReq_Tx, DISABLE);    }    return DEV_OK;}/****************************************************************************** * Uart_Register - UART register for STM32 * * Input: * Output: * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/static Dev_Err_t Uart_Register(const char *name, uint16_t flag, Uart_t *uart){    struct DevStruct dev = {0};    /* set device virtual interface */    dev.init = NULL;    dev.open = Uart_Open;    dev.close = Uart_Close;    dev.read = Uart_Read;    dev.write = Uart_Write;    dev.control = Uart_Control;    dev.rx_indicate = NULL;    dev.tx_complete = NULL;    dev.user_data = uart;    return Dev_Register(&dev, name, flag);}/****************************************************************************** * Uart_Isr - ISR for UART interrupt * * Input: dev, device pointer * Output: none * modification history * -------------------- * 12-jun-2014, Simon written * -------------------- ******************************************************************************/void Uart_Isr(Dev_t dev){    volatile Uart_t *uart = (Uart_t *)dev->user_data;    if(USART_GetITStatus(uart->uart_device, USART_IT_RXNE) != RESET)    {        /* save character */        if(Queue_Write(uart->rx_buf, USART_ReceiveData(uart->uart_device)) == QUEUE_OK)            uart->rx_size++;        else        {            /* invoke callback */            if(dev->rx_indicate != NULL)                dev->rx_indicate(dev, uart->rx_size);            uart->rx_size = 0;        }        /* clear interrupt */        USART_ClearITPendingBit(uart->uart_device, USART_IT_RXNE);    }    if (USART_GetITStatus(uart->uart_device, USART_IT_TC) != RESET)    {        /* invoke callback */        if(dev->tx_complete != NULL)            dev->tx_complete(dev, (void *)0);        /* clear interrupt */        USART_ClearITPendingBit(uart->uart_device, USART_IT_TC);    }    if (USART_GetITStatus(uart->uart_device, USART_IT_IDLE) != RESET)    {        volatile uint8_t clear_idle;        if(uart->uart_device == UART5)        {        if(dev->tx_complete != NULL)            dev->tx_complete(dev, (void *)0);        }        /* clear interrupt */        USART_GetFlagStatus(uart->uart_device, USART_FLAG_IDLE);        USART_ReceiveData(uart->uart_device);        /* invoke callback */        if(dev->rx_indicate != NULL)            dev->rx_indicate(dev, uart->rx_size);        uart->rx_size = 0;    }}void Uart_DmaTxIsr(Dev_t dev){    Uart_Node_t* data_node;    Uart_t *uart = (Uart_t *)dev->user_data;    /* get the first data node */    data_node = uart->dma_tx.list_head;    /* invoke call to notify tx complete */    if (dev->tx_complete != NULL)        dev->tx_complete(dev, data_node->data_ptr);    /* disable interrupt */    __set_PRIMASK(1);    /* remove list head */    uart->dma_tx.list_head = data_node->next;    if (uart->dma_tx.list_head == NULL) /* data link empty */        uart->dma_tx.list_tail = NULL;    /* disable interrupt */    __set_PRIMASK(0);    /* release data node memory */    free(data_node);    if (uart->dma_tx.list_head != NULL)    {        /* transmit next data node */        Uart_DmaEnable(uart->dma_tx.dma_channel,            (uint32_t)uart->dma_tx.list_head->data_ptr,            uart->dma_tx.list_head->data_size);    }    else    {        /* no data to be transmitted, disable DMA */        DMA_Cmd(uart->dma_tx.dma_channel, DISABLE);    }}/****************************************************************************** * Uart_Config - Init all related hardware in here, it will register all supported USART device. * * Input: *  USARTx, 串口 *  baudrate, 波特率 *  tx_buf_size, 发送缓存大小 *  rx_buf_size, 接收缓存大小 *  flag, 注册串口属性标志 * Output: * Returns: -1 of error, 0 of OK. * modification history * -------------------- * 27-aug-2014, Simon modify: 分立串口配置,并可指定缓存大小 * 12-jun-2014, Simon written * -------------------- ******************************************************************************/int Uart_Config(USART_TypeDef* USARTx,    uint32_t baudrate,    uint32_t rx_buf_size,    uint32_t tx_buf_size,    uint16_t flag){    if(!rx_buf_size)    {        return -1;    }    Uart_RccConfig(USARTx);    switch((uint32_t)USARTx)    {        case (uint32_t)USART1:            if(Uart_BufferMalloc(&uart1, rx_buf_size, tx_buf_size) == -1)            {                return -1;            }            Queue_Create(uart1.rx_buf, rx_buf_size, NULL, NULL);            Uart_SetGPIO(&uart1);            Uart_SetNVIC(&uart1, ENABLE);            Uart_SetBaudRate(&uart1,baudrate);            USART_ITConfig(uart1.uart_device, USART_IT_RXNE, ENABLE);            USART_ITConfig(uart1.uart_device, USART_IT_IDLE, ENABLE);            Uart_Register("uart1", flag, &uart1);            USART_GetITStatus(uart1.uart_device, USART_IT_TC);            break;        case (uint32_t)USART2:            if(Uart_BufferMalloc(&uart2, rx_buf_size, tx_buf_size) == -1)            {                return -1;            }            Queue_Create(uart2.rx_buf, rx_buf_size, NULL, NULL);            Uart_SetGPIO(&uart2);            Uart_SetNVIC(&uart2, ENABLE);            Uart_SetBaudRate(&uart2,baudrate);            USART_ITConfig(uart2.uart_device, USART_IT_RXNE, ENABLE);            USART_ITConfig(uart2.uart_device, USART_IT_IDLE, ENABLE);            Uart_Register("uart2", flag, &uart2);            USART_GetITStatus(uart2.uart_device, USART_IT_TC);            break;        case (uint32_t)USART3:            if(Uart_BufferMalloc(&uart3, rx_buf_size, tx_buf_size) == -1)            {                return -1;            }            Queue_Create(uart3.rx_buf, rx_buf_size, NULL, NULL);            Uart_SetGPIO(&uart3);            Uart_SetNVIC(&uart3, ENABLE);            Uart_SetBaudRate(&uart3,baudrate);            USART_ITConfig(uart3.uart_device, USART_IT_RXNE, ENABLE);            USART_ITConfig(uart3.uart_device, USART_IT_IDLE, ENABLE);            Uart_Register("uart3", flag, &uart3);            USART_GetITStatus(uart3.uart_device, USART_IT_TC);            break;        case (uint32_t)UART4:            if(Uart_BufferMalloc(&uart4, rx_buf_size, tx_buf_size) == -1)            {                return -1;            }            Queue_Create(uart4.rx_buf, rx_buf_size, NULL, NULL);            Uart_SetGPIO(&uart4);            Uart_SetNVIC(&uart4, ENABLE);            Uart_SetBaudRate(&uart4,baudrate);            USART_ITConfig(uart4.uart_device, USART_IT_RXNE, ENABLE);            USART_ITConfig(uart4.uart_device, USART_IT_IDLE, ENABLE);            Uart_Register("uart4", flag, &uart4);            USART_GetITStatus(uart4.uart_device, USART_IT_TC);            break;        case (uint32_t)UART5:            if(Uart_BufferMalloc(&uart5, rx_buf_size, tx_buf_size) == -1)            {                return -1;            }            Queue_Create(uart5.rx_buf, rx_buf_size, NULL, NULL);            Uart_SetGPIO(&uart5);            Uart_SetNVIC(&uart5, ENABLE);            Uart_SetBaudRate(&uart5,baudrate);            USART_ITConfig(uart5.uart_device, USART_IT_RXNE, ENABLE);            USART_ITConfig(uart5.uart_device, USART_IT_IDLE, ENABLE);            Uart_Register("uart5", flag, &uart5);            USART_GetITStatus(uart5.uart_device, USART_IT_TC);            break;        default:            return -1;//          break;    }    return 0;}int fputc(int ch, FILE *f){    Dev_t _console_device = Dev_Find("uart1");    if(_console_device == NULL)        return EOF;    Dev_Write(_console_device, 0, &ch, 1);    return ch;}
 |