⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_drv_stm32.c

📁 STM3240G-Eval_uCOS-III
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*                                     SERIAL (BYTE) COMMUNICATION
*
*                         (c) Copyright 2007-2009; Micrium, Inc.; Weston, FL
*
*               All rights reserved.  Protected by international copyright laws.
*               Knowledge of the source code may NOT be used to develop a similar product.
*               Please help us continue to provide the Embedded community with the finest
*               software available.  Your honesty is greatly appreciated.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*
*                                     SERIAL (BYTE) COMMUNICATION
*                                            DEVICE DRIVER
*
*                                                STM32
*
* Filename      : serial_drv_stm32.c
* Version       : V2.00
* Programmer(s) : FGK
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                            INCLUDE FILES
*********************************************************************************************************
*/

#include  <serial.h>
#include  <serial_drv_stm32.h>


/*
*********************************************************************************************************
*                                            LOCAL DEFINES
*********************************************************************************************************
*/

#define  SR_TXE                 DEF_BIT_07
#define  SR_TC                  DEF_BIT_06
#define  SR_RXNE                DEF_BIT_05
#define  SR_ORE                 DEF_BIT_03


#define  CR1_UE                 DEF_BIT_13
#define  CR1_M                  DEF_BIT_12
#define  CR1_PCE                DEF_BIT_10
#define  CR1_PS                 DEF_BIT_09
#define  CR1_TXEIE              DEF_BIT_07
#define  CR1_TCIE               DEF_BIT_06
#define  CR1_RXNEIE             DEF_BIT_05
#define  CR1_TE                 DEF_BIT_03
#define  CR1_RE                 DEF_BIT_02

#define  CR1_PARITY_NONE        DEF_BIT_NONE
#define  CR1_PARITY_EVEN        DEF_BIT_10
#define  CR1_PARITY_ODD         DEF_BIT_FIELD(2,  9)


#define  CR2_STOP_BITS_1        DEF_BIT_MASK (0, 12)
#define  CR2_STOP_BITS_2        DEF_BIT_MASK (2, 12)
#define  CR2_STOP_BITS_1_5      DEF_BIT_MASK (3, 12)

#define  CR2_STOP_MASK          DEF_BIT_FIELD(2, 12)
#define  CR2_CLKEN              DEF_BIT_11
#define  CR2_CPOL               DEF_BIT_10
#define  CR2_CPHA               DEF_BIT_09
#define  CR2_LBCL               DEF_BIT_08

#define  CR3_CTSE               DEF_BIT_09
#define  CR3_RTSE               DEF_BIT_08


/*
*********************************************************************************************************
*                                          LOCAL DATA TYPES
*********************************************************************************************************
*/

typedef  struct  serial_reg {                                   /* Serial dev reg struct.                               */
    CPU_REG16  SR;
    CPU_REG16  RESERVED0;
    CPU_REG16  DR;
    CPU_REG16  RESERVED1;
    CPU_REG16  BRR;
    CPU_REG16  RESERVED2;
    CPU_REG16  CR1;
    CPU_REG16  RESERVED3;
    CPU_REG16  CR2;
    CPU_REG16  RESERVED4;
    CPU_REG16  CR3;
    CPU_REG16  RESERVED5;
    CPU_REG16  GTPR;
    CPU_REG16  RESERVED6;
} SERIAL_REG;


/*
*********************************************************************************************************
*                                      LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
                                                                /* Driver initialization.                               */
static  void        SerialDrv_Init       (SERIAL_ERR     *perr);

                                                                /* Driver open.                                         */
static  void        SerialDrv_Open       (SERIAL_DEV     *pdev,
                                          SERIAL_IF_CFG  *pcfg,
                                          SERIAL_ERR     *perr);

                                                                /* Driver close.                                        */
static  void        SerialDrv_Close      (SERIAL_DEV     *pdev,
                                          SERIAL_ERR     *perr);

                                                                /* Driver receiver start.                               */
static  void        SerialDrv_RxStart    (SERIAL_DEV     *pdev,
                                          SERIAL_ERR     *perr);

                                                                /* Driver receiver stop.                                */
static  void        SerialDrv_RxStop     (SERIAL_DEV     *pdev,
                                          SERIAL_ERR     *perr);

                                                                /* Driver octet receive.                                */
static  void        SerialDrv_RxOctet    (SERIAL_DEV     *pdev,
                                          CPU_INT08U     *pdatum,
                                          SERIAL_ERR     *perr);

                                                                /* Driver transmitter start.                            */
static  void        SerialDrv_TxStart    (SERIAL_DEV     *pdev,
                                          SERIAL_ERR     *perr);

                                                                /* Driver transmitter stop.                             */
static  void        SerialDrv_TxStop     (SERIAL_DEV     *pdev,
                                          SERIAL_ERR     *perr);

                                                                /* Driver octet transmit.                               */
static  void        SerialDrv_TxOctet    (SERIAL_DEV     *pdev,
                                          CPU_INT08U      datum,
                                          SERIAL_ERR     *perr);

                                                                /* Driver ISR handler.                                  */
static  void        SerialDrv_ISR_Handler(SERIAL_DEV     *pdev,
                                          CPU_INT08U      type);


/*
*********************************************************************************************************
*********************************************************************************************************
*                                 SERIAL INTERFACE DEVICE DRIVER API
*********************************************************************************************************
*********************************************************************************************************
*/

SERIAL_DRV_API  SerialDrv_STM32_API = {
    SerialDrv_Init,
    SerialDrv_Open,
    SerialDrv_Close,
    SerialDrv_RxStart,
    SerialDrv_RxStop,
    SerialDrv_RxOctet,
    SerialDrv_TxStart,
    SerialDrv_TxStop,
    SerialDrv_TxOctet,
    SerialDrv_ISR_Handler
};


/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
*                                     DRIVER INTERFACE FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/

/*
*********************************************************************************************************
*                                          SerialDrv_Init()
*
* Description : Initialize serial device driver.
*
* Argument(s) : perr        Pointer to variable that will receive the return error code from this function :
*
*                               SERIAL_ERR_NONE                 Driver initialized.
*
* Return(s)   : None.
*
* Caller(s)   : Serial_DrvAdd() via 'pdrv_api->Init()'.
*
* Note(s)     : None.
*********************************************************************************************************
*/

static  void  SerialDrv_Init (SERIAL_ERR  *perr)
{
   *perr = SERIAL_ERR_NONE;
}


/*$PAGE*/
/*
*********************************************************************************************************
*                                          SerialDrv_Open()
*
* Description : Open a serial device for communication.
*
* Argument(s) : pdev        Pointer to device.
*
*               pcfg        Pointer to interface configuration.
*
*               perr        Pointer to variable that will receive the return error code from this function :
*
*                               SERIAL_ERR_NONE                 Device              opened.
*                               SERIAL_ERR_DRV_OPEN             Device could NOT be opened.
*                               SERIAL_ERR_DRV_INVALID          Device configuration invalid.
*                               SERIAL_ERR_MEM_ALLOC            Memory could NOT be allocated for device
*                                                                   internal data.
*
* Return(s)   : None.
*
* Caller(s)   : Serial_Open() via 'pdev->Drv_API->Open()'.
*
* Note(s)     : (1) Interrupts are assumed to be disabled when this function is called.
*********************************************************************************************************
*/

static  void  SerialDrv_Open (SERIAL_DEV     *pdev,
                              SERIAL_IF_CFG  *pcfg,
                              SERIAL_ERR     *perr)
{
    SERIAL_DEV_CFG  *p_cfg;
    SERIAL_REG      *p_reg;
    CPU_BOOLEAN      flow_ctrl;
    CPU_INT16U       cr1;
    CPU_INT16U       cr2;
    CPU_INT16U       stop;
    CPU_INT16U       parity;
    CPU_INT32U       clk_freq;
    CPU_INT32U       baudrate;
    CPU_INT32U       div_int;
    CPU_INT32U       div_frac;


    p_cfg = pdev->Dev_Cfg;    
    p_cfg->BSP_API->ClkEn(perr);                                /* En dev-specific HW clk.                              */
    if (*perr != SERIAL_ERR_NONE) {
         return;
    }

    p_reg = (SERIAL_REG *)p_cfg->BaseAddr;

    switch (pcfg->StopBits) {
        case SERIAL_STOPBITS_1:
             stop = CR2_STOP_BITS_1;
             break;


        case SERIAL_STOPBITS_1_5:
             stop = CR2_STOP_BITS_1_5;
             break;


        case SERIAL_STOPBITS_2:
        default:
             stop = CR2_STOP_BITS_2;
             break;
    }

    cr2         =  p_reg->CR2;
    cr2        &= ~CR2_STOP_MASK;
    cr2        |=  stop;
    p_reg->CR2  =  cr2;


    switch (pcfg->DataBits) {
        case SERIAL_DATABITS_8:
             break;


        case SERIAL_DATABITS_5:
        case SERIAL_DATABITS_6:
        case SERIAL_DATABITS_7:
        default:
            *perr = SERIAL_ERR_DRV_INVALID;
             return;
    }

    switch (pcfg->Parity) {
        case SERIAL_PARITY_ODD:
             parity = CR1_PARITY_ODD;
             break;


        case SERIAL_PARITY_EVEN:
             parity = CR1_PARITY_EVEN;
             break;


        case SERIAL_PARITY_NONE:
             parity = CR1_PARITY_NONE;
             break;


        case SERIAL_PARITY_MARK:
        case SERIAL_PARITY_SPACE:
        default:
            *perr = SERIAL_ERR_DRV_INVALID;
             return;
    }

    cr1         =   p_reg->CR1;
    cr1        &= ~(CR1_M   |
                    CR1_PCE |
                    CR1_PS);
    cr1        |=   parity |
                    CR1_TE |
                    CR1_RE;
    p_reg->CR1  =   cr1;

    switch (pcfg->FlowCtrl) {
        case SERIAL_FLOW_CTRL_HARDWARE:
             flow_ctrl = DEF_ENABLED;

             p_reg->CR3 |= CR3_CTSE |
                           CR3_RTSE;
             break;


        case SERIAL_FLOW_CTRL_NONE:
        default:
             flow_ctrl = DEF_DISABLED;

             p_reg->CR3 &= ~(CR3_CTSE |
                             CR3_RTSE);
             break;
    }

    p_cfg->BSP_API->CfgGPIO(flow_ctrl, perr);                   /* Cfg dev-specific GPIO.                               */
    if (*perr != SERIAL_ERR_NONE) {
         return;
    }
    p_cfg->BSP_API->CfgInt(pdev, perr);                         /* Cfg dev-specific int.                                */
    if (*perr != SERIAL_ERR_NONE) {
         return;
    }

                                                                /* ------------------- CFG BAUD RATE ------------------ */
    baudrate = pcfg->Baudrate;
    clk_freq = p_cfg->BSP_API->ClkFreqGet();                    /* Get periph clk freq.                                 */
    div_int  = (25 * clk_freq + 2 * baudrate) / (4 * baudrate);
    div_frac = ((div_int % 100) * 16 + 50) / 100;
    div_int /= 100;
    if (div_int > 4095) {
       *perr = SERIAL_ERR_DRV_INVALID;
        return;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -