📄 ser_arch.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:串口驱动---硬件相关层
版本号: 1.0.0
开发时期:2003-07-01
作者: 肖远钢
修改记录:
2004-03-18:凡是带有这个标记的,跟不同板子的调试串口 是相关的
******************************************************/
//root include
#include <ewindows.h>
//arm\ebook_ include
#include <s2410.h>
#include <oalintr.H>
#include <serbaud.h> //add by xyg
//driver include
#include <sertbl.h> //add by xyg
//current
//added by xyg 2004-09-28
//#include "ser_rwbuf.h"
#include "drv_glob.h"
#include "ser_arch.h" //add by xyg
#ifndef CANCEL_XYG_SER_RX
static DRIVER_GLOBALS * lpGlobal =(DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START;
#endif
/*************** 全局区 定义, 声明 *****************/
//-----------------------------------------
//调试部分的定义
//-----------------------------------------
//
//#define DEBUG_SERARCH //
//#define xyg_ser_sub_mask
//
#ifdef DEBUG_SERARCH
//
static PSERARCH_INFO g_pDebugSerArch = NULL;
//调试函数
#define DEBUGTO_NONE 0
#define DEBUGTO_SERIAL 1
#define DEBUGTO_DESKTOP 2
extern DWORD SerDebug_Enable( DWORD dwFlag );
extern void SerDebug_CleanScreen( );
extern void OEM_WriteDebugByte_ToWnd(unsigned char c);
extern void dcb_Debug( LPDCB lpDCB, LPTSTR pszText );
static void Debug_Arch( PVOID pHead );
#endif
//-----------------------------------------
//正常的定义
//-----------------------------------------
#define UART_DEBUGPORT UART3_BASE_VIRTUAL
//-----------------------------------------
extern void msWait(unsigned msVal);
extern void usWait(unsigned usVal);
extern void ser_NotifyCommEvent(PVOID pHead, ULONG fdwEventMask);
extern void ser_HandleInterrupt( LPVOID pData );
//-----------------------------------------
//wait interrupt
static DWORD WINAPI ser_WaitInterrupt( DWORD pHead );
static void Debug_Arch( PVOID pHead );
//help fun
static BOOL ser_InitInfoOfHardware( PSERARCH_INFO pInfoSerArch, ULONG Identifier );
static void ser_CheckLine(PSERARCH_INFO pInfoSerArch, volatile PS2410_UART_REG pUART);
static void ser_OpenMode( PSERARCH_INFO pInfoSerArch );
static void ser_CloseMode( PSERARCH_INFO pInfoSerArch );
static BOOL ser_CheckDCB( LPDCB lpDCB, PSERARCH_INFO pInfoSerArch );
static BOOL ser_CheckFlowOff( PSERARCH_INFO pInfoSerArch );
//init, deinit
static PVOID SerArch_Init( ULONG Identifier, PVOID pHeadDrv, PVOID lpDCB );
static VOID SerArch_InitLast( PVOID pHead );
static BOOL SerArch_Deinit( PVOID pHead );
static ULONG SerArch_Close( PVOID pHead );
static BOOL SerArch_Open( PVOID pHead );
static BOOL SerArch_PowerOff(PVOID pHead);
static BOOL SerArch_PowerOn(PVOID pHead);
static BOOL SerArch_IOControl(PVOID pHead, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut);
//
static BOOL SerArch_IREnable(PVOID pHead,ULONG BaudRate);
static BOOL SerArch_IRDisable(PVOID pHead);
//
static ULONG SerArch_Recv( PVOID pHead, LPBYTE pBufDes, LONG* pnLenBuf );
static ULONG SerArch_Send( PVOID pHead, LPBYTE pBufSrc, LONG* pnLenBuf );
static BOOL SerArch_XMitChar(PVOID pHead, UCHAR ComChar);
//
static DWORD SerArch_IntrTypeQuery( PVOID pHead );
static DWORD SerArch_IntrHandleModem(PVOID pHead);
static VOID SerArch_IntrHandleLine(PVOID pHead);
static VOID SerArch_IntrHandleTx(PVOID pHead);
//
static VOID SerArch_ClearPinDTR( PVOID pHead );
static VOID SerArch_SetPinDTR( PVOID pHead );
static VOID SerArch_ClearPinRTS( PVOID pHead );
static VOID SerArch_SetPinRTS( PVOID pHead );
//
static VOID SerArch_ClearBreak( PVOID pHead );
static VOID SerArch_SetBreak( PVOID pHead );
//
static VOID SerArch_PurgeComm(PVOID pHead,DWORD fdwAction);
//
static ULONG SerArch_GetComStat(PVOID pHead, LPCOMSTAT lpStat);
static VOID SerArch_GetCommProperties(PVOID pHead,LPCOMMPROP pCommProp);
static VOID SerArch_GetModemStatus(PVOID pHead, LPDWORD pModemStatus);
static BOOL SerArch_SetDCB( PVOID pHead, LPDCB lpDCB, DWORD dwFlagSetDCB );
//-----------------------------------------
//inline function
static WORD ser_ReadMSR( PSERARCH_INFO pInfoSerArch );
#if defined( HW_PCB_VERSION_C )
static void ser_SelectSIR( PSERARCH_INFO pInfoSerArch );
#endif
/******************************************************/
//-----------------------------------------
// ********************************************************************
// 声明:WORD ser_ReadMSR( PSERARCH_INFO pInfoSerArch )
// 参数:
// IN pGPIO-GPIO的地址
// 返回值:
// 返回MODEM的状态
// 功能描述:读取MODEM的状态
// 引用:
// ********************************************************************
WORD ser_ReadMSR( PSERARCH_INFO pInfoSerArch )
{
volatile WORD msr_ret;
ULONG msr_val;
//读硬件
//msr_ret = 0;
//if( !pGPIO->gplr.gp14 )
//{
// msr_ret |= MS_CTS_ON;
//}
//if( !pGPIO->gplr.gp13 )
//{
// msr_ret |= MS_DSR_ON;
// msr_ret |= MS_RLSD_ON;
//}
msr_ret = MS_DSR_ON;
msr_val = INREG(pInfoSerArch,rUMSTAT);
if (msr_val & COM2410_MSR_CTS)
{
msr_ret |= MS_CTS_ON;
}
return msr_ret;
}
// ********************************************************************
// 声明:VOID ClearPendingInts( PVOID pHead )
// 参数:
// IN PVOID pHead - 指向PDD层的全局结构变量
// 返回值:
// 无
// 功能描述:设置寄存器,使由未知状态为已知状态
// 引用:在 SL_Init( ) 中调用
// ********************************************************************
VOID ClearPendingInts( PVOID pHead )
{
volatile PSERARCH_INFO pInfoSerArch = (PSERARCH_INFO)pHead;
UINT32 tmpReg;
//RETAILMSG(1,(TEXT("ClearPendingInts\n")));
SETREG(pInfoSerArch,rUFCON,0x6); // tx, rx fifo reset
ClearSubINTPnd(pInfoSerArch, pInfoSerArch->bTxINT | pInfoSerArch->bRxINT | pInfoSerArch->bErrINT); //清除SUBSRCPND中串口的 Tx,Rx,Err中断
//RETAILMSG(1,(TEXT("**After ClearSubINTPnd:%x\n"),pInfoSerArch->pIrqCtrlAddr->rSUBSRCPND));
ClearINTPnd(pInfoSerArch, pInfoSerArch->bINT); //清除SRCPND中串口中断
//RETAILMSG(1,(TEXT("**SRCPND:%x\n"),pInfoSerArch->UART_INTSRCPND));
//if ((*pInfoSerArch->UART_INTPND) & pInfoSerArch->bINT )
//{
// (*pInfoSerArch->UART_INTPND) |= pInfoSerArch->bINT; //#define BIT_UART0 ( 0x1 << 28 )
//}
//RETAILMSG(1,(TEXT("pInfoSerArch->UART_INTPND --- :%x\n"),pInfoSerArch->UART_INTPND));
tmpReg = INREG(pInfoSerArch,rUERSTAT); //进行读之后,该位清除
}
#if defined( HW_PCB_VERSION_C )
// ********************************************************************
// 声明:void ser_SelectSIR( PSERARCH_INFO pInfoSerArch )
// 参数:
// IN pInfoSerArch-ARCH信息
// 返回值:
// 无
// 功能描述:选择红外功能
// 引用:
// ********************************************************************
//Select SIR function: set param, open power, open recv and send register
void ser_SelectSIR( PSERARCH_INFO pInfoSerArch )
{
//设置模式
WRITE_BITFIELD(struct hscr0Bits,&pInfoSerArch->pHSSP->hscr0,itr,0);
WRITE_BITFIELD(struct utcr4Bits,&pInfoSerArch->pUART->utcr4,hse,1);
WRITE_BITFIELD(struct utcr4Bits,&pInfoSerArch->pUART->utcr4,lpm,0);
//打开电源
pInfoSerArch->pGPIO->gpdr.gp15 = 1; // 输出 方向
pInfoSerArch->pGPIO->gpsr.gp15 = 1; // 打开电源
{ DWORD iDlay; for( iDlay=0; iDlay<0xA000; iDlay++ ) ; }
//打开硬件的 收
WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,rxe,1);
WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,txe,0);
WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,rie,1);
WRITE_BITFIELD(struct utcr3Bits,&pInfoSerArch->pUART->utcr3,tie,1);
}
#endif
//-----------------------------------------
// ********************************************************************
// 声明:void ser_CheckLine( PSERARCH_INFO pInfoSerArch, volatile PS2410_UART_REG pUART)
// 参数:
// IN pInfoSerArch-ARCH信息
// IN pUART-UART的地址
// 返回值:
// 无
// 功能描述:检查串口的状态
// 引用:
// ********************************************************************
//check line status, if error occurs, then notify and clear status
void ser_CheckLine( PSERARCH_INFO pInfoSerArch, volatile PS2410_UART_REG pUART)
{
ULONG LineEvents;
ULONG LineStatus;
int nCntTry;
//UCHAR cCharRx;
//OEM_WriteDebugByte_ToWnd( 'z' );
//EdbgOutputDebugString("\r\ne_1: sr0=%x, sr1=%x, cr0=%x\r\n", pUART->utsr0, pUART->utsr1, pUART->utcr0 );
//出现错误
LineEvents = 0;
LineStatus = 0;
nCntTry = 0;
//RETAILMSG(1,TEXT("\r\n SerArch_CheckLine() ---- Debug_Arch \r\n"));
//Debug_Arch( pInfoSerArch );
while( nCntTry++<100 )
{
LineStatus = pUART->rUERSTAT;//INREG(pInfoSerArch,rUERSTAT); //取寄存器状态值
//RETAILMSG(1,(TEXT("Line Status Register:%x"),LineStatus));
// 判断控制状态 [溢出 | 奇偶 | 帧] 错误
if ( LineStatus & (COM2410_LSR_OE | COM2410_LSR_PE | COM2410_LSR_FE))
{
if ( LineStatus & COM2410_LSR_OE ) //溢出错误
{
//When overrun error occurs, S2410 rURXH must be read.
pInfoSerArch->CommErrors |= CE_OVERRUN;
LineEvents |= EV_ERR;
RETAILMSG(1,TEXT("\r\n CLine_ov"));
}
if ( LineStatus & COM2410_LSR_PE ) //奇偶错误
{
pInfoSerArch->CommErrors |= CE_RXPARITY;
LineEvents |= EV_ERR;
//RETAILMSG(1,TEXT("\r\n CLine_pp"));
}
if ( LineStatus & COM2410_LSR_FE ) //帧错误
{
pInfoSerArch->CommErrors |= CE_FRAME;
LineEvents |= EV_ERR;
//RETAILMSG(1,TEXT("\r\n CLine_fr"));
}
//cCharRx = *(pInfoSerArch->pUFRXH);
}
else
{
break;
}
}
if ( LineStatus & COM2410_LSR_BI ) //中断错误
{
LineEvents |= EV_BREAK;
pInfoSerArch->CommErrors |= CE_BREAK;
//EdbgOutputDebugString("\r\nEV_BREAK\r\n" );
}
//EdbgOutputDebugString( ",d=%d", nDiscard );
//EdbgOutputDebugString("\r\ne_2: sr0=%x, sr1=%x, cr0=%x\r\n", pUART->utsr0, pUART->utsr1, pUART->utcr0 );
if( LineEvents )
{
//通知WaitCommEvent
pInfoSerArch->lpfnEventNotify(pInfoSerArch->pHeadDrv, LineEvents);
}
//清除Pending串口中断
ClearSubINTPnd(pInfoSerArch, pInfoSerArch->bErrINT );
ClearINTPnd(pInfoSerArch, pInfoSerArch->bINT);
#ifdef xyg_ser_sub_mask
//if ((*pInfoSerArch->UART_INTPND) & pInfoSerArch->bINT )
//{
// (*pInfoSerArch->UART_INTPND) |= pInfoSerArch->bINT;
//}
//
EnINT(pInfoSerArch, pInfoSerArch->bINT);
EnSubINT(pInfoSerArch, (pInfoSerArch->bRxINT|pInfoSerArch->bErrINT) );
//EnSubINT(pInfoSerArch, (pInfoSerArch->bErrINT) );
#endif
//RETAILMSG(1,TEXT("\r\n SerArch_CheckLine() ---- Debug_Arch OVER\r\n"));
//Debug_Arch( pInfoSerArch );
}
// ********************************************************************
// 声明:void ser_OpenMode( PSERARCH_INFO pInfoSerArch )
// 参数:
// IN pInfoSerArch-ARCH信息
// 返回值:
// 无
// 功能描述:结构初始化 和 硬件初始化打开
// 引用:
// ********************************************************************
void ser_OpenMode( PSERARCH_INFO pInfoSerArch )
{
volatile PS2410_UART_REG pUART;//UART-registers
//初始化操作信息的变量
pInfoSerArch->fPowerOff = 0;
pInfoSerArch->msrChange = 0;
pInfoSerArch->CommErrors = 0;
pInfoSerArch->FlowOffDSR = 0;
pInfoSerArch->FlowOffCTS = 0;
pInfoSerArch->RestartTxForFlow = 0;
//pInfoSerArch->fWaitTxim = 0;
//
//if( pInfoSerArch->dwOpt & OPT_MODEM )
{
pInfoSerArch->ModemStatus = ser_ReadMSR( pInfoSerArch );
}
//else
//{
// pInfoSerArch->ModemStatus = ( MS_CTS_ON | MS_DSR_ON | MS_RLSD_ON );
//}
//
//硬件的参数设置和状态清除( 注意:之前已经调用了HWSetDCB )
//
pUART = pInfoSerArch->pUART;
// 设置波特率
SerArch_SetDCB( pInfoSerArch, pInfoSerArch->lpDCB, SETDCB_ALL );
//OUTREG(pInfoSerArch,rUCON,0x2c5); // Select Clock,Tx and Rx Interrupt Type,Transmit and Receive Mode.
OUTREG(pInfoSerArch,rUCON,0x02c5); // Select Clock,Tx and Rx Interrupt Type,Transmit and Receive Mode.
OUTREG(pInfoSerArch,rUFCON,0x6); // Reset FIFO
//OUTREG(pInfoSerArch,rUFCON,0x41); // FIFO enable : tx-4bytes, rx-4bytes
OUTREG(pInfoSerArch,rUFCON,0x01); // FIFO enable : tx-4bytes, rx-4bytes
OUTREG(pInfoSerArch,rUMCON,0x00); // Disable auto flow control.
//OUTREG(pInfoSerArch,rUMCON,0x10); // Disable auto flow control.
OUTREG(pInfoSerArch,rULCON,0x3); // Normal mode, N81
RETAILMSG(1,(TEXT("\n*******************************\n")));
RETAILMSG(1,(TEXT("**rUFCON:%x\n"),pUART->rUFCON));
RETAILMSG(1,(TEXT("**rUCON:%x\n"),pUART->rUCON));
RETAILMSG(1,(TEXT("\n*******************************\n")));
// 中断有效
EnINT(pInfoSerArch, pInfoSerArch->bINT);
//RETAILMSG(1,(TEXT("\r\n [%x] \r\n"),pInfoSerArch->pIrqCtrlAddr->rINTMSK));
//RETAILMSG(1,(TEXT("Before EnSubInt function,INTSUBMSK:%x\n"),pInfoSerArch->pIrqCtrlAddr->rINTSUBMSK));
EnSubINT(pInfoSerArch, (pInfoSerArch->bRxINT|pInfoSerArch->bErrINT));
//EnSubINT(pInfoSerArch, pInfoSerArch->bRxINT);
//EnSubINT(pInfoSerArch, pInfoSerArch->bErrINT);
ser_CheckLine( pInfoSerArch, pInfoSerArch->pUART );
ClearPendingInts( pInfoSerArch );
#ifndef CANCEL_XYG_SER_RX
EnterCriticalSection(&(pInfoSerArch->csBufRW));
RWBuf_SetZero( pInfoSerArch->lpRWBuf, TRUE );
LeaveCriticalSection(&(pInfoSerArch->csBufRW));
#endif
return ;
}
// ********************************************************************
// 声明:VOID S2410_SetIrDAIOP( PVOID pHead )
// 参数:
// IN PVOID pHead - PDD层全局结构变量
// 返回值:
// 无
// 功能描述:设置 IO 端口,使串口能够有效使用
// 引用:在SL_Init( )中调用
// ********************************************************************
VOID S2410_SetIrDAIOP( PVOID pHead )
{
volatile PSERARCH_INFO pInfoSerArch = (PSERARCH_INFO)pHead;
switch( pInfoSerArch->dwIndex )
{
case ID_COM1:
pInfoSerArch->pGPIO->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6); // clear uart 0 - rx, tx, rts, cts
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -