📄 serial_drv_stm32.c
字号:
/*
*********************************************************************************************************
* 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 + -