comm.c
来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 1,352 行 · 第 1/3 页
C
1,352 行
*claimingInterrupt = TRUE;
*requireDeferredCallback = FALSE;
while ((IntPndVal & portInfo->bINT) && (loops++ < 0x10)){
// while ((IntPndVal & portInfo->bINT) ){
if(IntSubPndVal & (thisDev->portInfo.bErrINT) ) {
// RETAILMSG (1, (TEXT("SL_GetInterruptType: INTR_LINE\r\n")));
g_pComm1Reg->UFCON |=(1<<2|1<<1);
ClearSubINTPnd(portInfo, portInfo->bTxINT | portInfo->bRxINT | portInfo->bErrINT);
ClearINTPnd(portInfo, portInfo->bINT);
}else if(IntSubPndVal & (portInfo->bRxINT) ) {
DBGOUT((TEXT("COM INTERRUPT: rcv data available!")));
DisEnSubINT(portInfo, portInfo->bRxINT);
thisDev->nowReceiving = TRUE;
if (!thisDev->mediaBusy){
thisDev->mediaBusy = TRUE;
thisDev->haveIndicatedMediaBusy = FALSE;
*requireDeferredCallback = TRUE;
}
if (StepReceiveFSM(thisDev)){
/*
* The receive engine has accumulated an entire frame.
* Request a deferred callback so we can deliver the frame
* when not in interrupt context.
*/
*requireDeferredCallback = TRUE;
thisDev->nowReceiving = FALSE;
}
EnSubINT(portInfo, portInfo->bRxINT);
}
else if (IntSubPndVal & (portInfo->bTxINT)) {
DEBUGFIR(1,(_T("COM_ISR tx INTERRUPT\r\n")));
if (thisDev->portInfo.writePending){
SetCOMInterrupts(thisDev, FALSE);
/*
* Try to send a few more bytes
*/
CLEARREG(UCON , 3);
if (StepSendFSM(thisDev)){
/*
* There are no more bytes to send;
* reset interrupts for receive mode.
*/
thisDev->portInfo.writePending = FALSE;
g_pComm1Reg->UFCON |= (1<<1);
// SetCOMInterrupts(thisDev, TRUE);
CLEARREG(UCON , (3<<2));
ClearSubINTPnd(portInfo, portInfo->bTxINT | portInfo->bRxINT | portInfo->bErrINT);
ClearINTPnd(portInfo, portInfo->bINT);
SETREG(UCON , UCON_RX_INTPOL_MODE);
/*
* If we just sent the last frame to be sent at the old speed,
* set the hardware to the new speed.
*/
if (thisDev->setSpeedAfterCurrentSendPacket){
thisDev->setSpeedAfterCurrentSendPacket = FALSE;
thisDev->setSpeedNow = TRUE;
}
/*
* Request a DPC so that we can try
* to send other pending write packets.
*/
*requireDeferredCallback = TRUE;
}
#if 0
else{
EnSubINT(portInfo, portInfo->bTxINT);
}
#endif
}
}
/*
* After we service each interrupt condition, we read the line status register.
* This clears the current interrupt, and a new interrupt may then appear in
* the interrupt-id register.
*/
try {
IntPndVal = *(portInfo->UART_INTSRCPND);
IntSubPndVal = *(portInfo->UART_INTSUBSRCPND);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
RETAILMSG(1, (TEXT("ACCESS VIOLATION ERROR \r\n")));
IntPndVal = SER24A0_INT_INVALID; // simulate no interrupt
}
ClearSubINTPnd(portInfo, portInfo->bTxINT | portInfo->bRxINT | portInfo->bErrINT);
ClearINTPnd(portInfo, portInfo->bINT);
DEBUGFIR(1,(_T("COM_ISR Intsrc pnd %x subsrcpnd %x \r\n"),IntPndVal,IntSubPndVal));
}
}
if(! (*requireDeferredCallback))
SetCOMInterrupts(thisDev, TRUE);
// EnSubINT(portInfo, portInfo->bRxINT);
// EnSubINT(portInfo, portInfo->bTxINT);
// EnSubINT(portInfo, portInfo->bErrINT);
// EnINT(portInfo, portInfo->bINT);
}
/*
*************************************************************************
* OpenCOM
*************************************************************************
*
* Initialize UART registers
*
*/
BOOLEAN OpenCOM(IrDevice *thisDev)
{
DBGOUT((TEXT("-> OpenCOM")));
DBGOUT((TEXT("-> OpenCOM SetCOMInterrupts :false")));
/*
* Set dongle- or part-specific info to default
*/
// thisDev->portInfo.hwCaps.supportedSpeedsMask = ALL_SLOW_IRDA_SPEEDS;
thisDev->portInfo.hwCaps.supportedSpeedsMask = ALL_IRDA_SPEEDS;
thisDev->portInfo.hwCaps.turnAroundTime_usec = DEFAULT_TURNAROUND_usec;
thisDev->portInfo.hwCaps.extraBOFsRequired = 0;
Comm_hw_Init(thisDev);
// SetCOMInterrupts(thisDev, FALSE);
thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];
thisDev->currentSpeed = thisDev->linkSpeedInfo->bitsPerSec;
SetSpeed(thisDev);
SetCOMInterrupts(thisDev, TRUE);
DBGOUT((TEXT("-> OpenCOM SetCOMInterrupts :true")));
DBGOUT((TEXT("OpenCOM succeeded")));
return TRUE;
}
/*
*************************************************************************
* CloseCOM
*************************************************************************
*
*/
VOID CloseCOM(IrDevice *thisDev)
{
/*
* Do special deinit for dongles.
* Some dongles can only rcv cmd sequences at 9600, so set this speed first.
*/
thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];;
SetSpeed(thisDev);
SetCOMInterrupts(thisDev, FALSE);
}
/*
*************************************************************************
* DoRcvDirect
*************************************************************************
*
* Read up to maxBytes bytes from the UART's receive FIFO.
* Return the number of bytes read or (UINT)-1 if an error occurred.
*
*/
UINT DoRcvDirect(struct IrDevice *thisDev, UCHAR *data, UINT maxBytes)
{
ULONG TargetRoom = maxBytes;
comPortInfo *portInfo = &thisDev->portInfo;
ULONG rFifoStat, RxFifoCnt, RxDataReady, bytesRead= 0,errStat;
#if 0
UINT i;
#endif
UCHAR cRXChar,*pRxBuffer = data;
rFifoStat = INREG(UFSTAT);
RxFifoCnt = rFifoStat & 0x3f;
if((rFifoStat & (1<<6))||(RxFifoCnt > 0))
RxDataReady = 1;
else
RxDataReady = 0;
while ( TargetRoom && RxDataReady) {
errStat = INREG(UERSTAT);
if(errStat) {
g_pComm1Reg->UFCON |= 6;
RETAILMSG(1, (TEXT("Rx Error 0x%x \r\n"), errStat));
}
cRXChar = g_pComm1Reg->URXH;
// RETAILMSG(1, (TEXT(" %2x"), cRXChar));
*pRxBuffer++ = cRXChar;
bytesRead++;
rFifoStat = INREG(UFSTAT);
RxFifoCnt = rFifoStat & 0x3f;
--TargetRoom;
// if((rFifoStat & (1<<6))||(RxFifoCnt > 0))
if(RxFifoCnt > 0)
RxDataReady = 1;
else
RxDataReady = 0;
}
ClearSubINTPnd(portInfo,portInfo->bRxINT);
if ( *(portInfo->UART_INTSUBSRCPND) & ( portInfo->bRxINT | portInfo->bErrINT ) )
{
// RETAILMSG (1, (TEXT("*(portInfo->UART_INTSUBSRCPND) = %x \r\n"), *(portInfo->UART_INTSUBSRCPND)));
// RETAILMSG (1, (TEXT("Do Not Clear bINT \r\n")));
;
}
else
ClearINTPnd(portInfo, portInfo->bINT);
// RETAILMSG(1,(TEXT("-> Number of bytes received %x\r\n"),bytesRead));
#if 0
RETAILMSG(1,(TEXT("Rx")));
for (i=0;i<bytesRead;i++) {
RETAILMSG(1,(TEXT("%2x "),data[i]));
if(data[i] == 0xC1)
RETAILMSG(1,(TEXT("\r\n")));
}
#endif
return bytesRead;
}
VOID Comm_hw_Init(IrDevice *thisDev)
{
comPortInfo *portInfo = &thisDev->portInfo;
UINT32 temp;
DBGOUT((TEXT("-> Comm_hw_Init")));
// return;
portInfo->bINT = BIT_UART1;
portInfo->bTxINT = INTSUB_TXD1;
portInfo->bRxINT = INTSUB_RXD1;
portInfo->bErrINT = INTSUB_ERR1;
portInfo->UART_INTMASK = (volatile unsigned int *)&(g_pINTregs->INTMSK);
portInfo->UART_INTSUBMASK = (volatile unsigned int *)&(g_pINTregs->INTSUBMSK);
portInfo->UART_INTPND = (volatile unsigned int *)&(g_pINTregs->INTPND);
portInfo->UART_INTSRCPND = (volatile unsigned int *)&(g_pINTregs->SRCPND);
portInfo->UART_INTSUBSRCPND = (volatile unsigned int *)&(g_pINTregs->SUBSRCPND);
/*
* Disable all COM interrupts while setting up.
*/
g_pClkPwrRegs->CLKCON |= UART1_CLK_ON;
g_pINTregs->INTMSK |= (BIT_UART1);
g_pINTregs->INTSUBMSK |=(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);
Irda_GPIO_Conf(TRUE) ;
g_pComm1Reg->ULCON=(0<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,One stop bit, 8bit
g_pComm1Reg->UCON = (1<<9)|(1<<8)|(1<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<2)|(0);
//rUFCON1=(1<<6)|(11<<4)|(1<<2)|(1<<1)|(1);
g_pComm1Reg->UFCON=(2<<6)|(2<<4)|(1<<2)|(1<<1)|(1);
// g_pComm1Reg->UFCON= 0;//(2<<6)|(3<<4)|(1<<2)|(1<<1)|(1);
g_pComm1Reg->ULCON |= (1<<6); // IrDA mode
g_pComm1Reg->UMCON=0x0; // Disable Uart1 AFC
// g_pIOPregs->GPCON_U = (g_pIOPregs->GPCON_U&~(3<<20))|(1<<20); // GP29(IrDA_SDBW) is output
// g_pIOPregs->GPDAT &=~(1<<29); // IrDA_SDBW output is low
g_pComm1Reg->UBRDIV = (int)(S3C24A0_PCLK/16/9600+0.5)-1;
temp = INREG(UERSTAT);
if(temp)
temp =INREG(URXH);
DBGOUT((TEXT("-> Comm_hw_Init Initialization done, errstat %x"),temp));
thisDev->portInfo.haveFIFO = TRUE;
// Clear Int Pending and Unmask
g_pINTregs->SUBSRCPND =(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);
// g_pINTregs->INTSUBMSK &= ~(BIT_SUB_RXD1|BIT_SUB_ERR1);
g_pINTregs->SRCPND = BIT_UART1;
g_pINTregs->INTPND = g_pINTregs->INTPND;
g_pINTregs->INTPND;
// g_pINTregs->INTMSK &= ~(BIT_UART1);
g_pComm1Reg->UCON |= 1; // interrupt enable, Rx start
DBGOUT((TEXT("<- Comm_hw_Init Done")));
}
VOID Comm_hw_ReInit(IrDevice *thisDev)
{
comPortInfo *portInfo = &thisDev->portInfo;
DBGOUT((TEXT("-> Comm_hw_ReInit")));
Irda_GPIO_Conf(TRUE) ; // Set up GPIO for SIR mode
g_pClkPwrRegs->CLKCON |= UART1_CLK_ON;
g_pComm1Reg->ULCON=(1<<6)|(0<<3)|(0<<2)|(3); // Normal,No parity,One stop bit, 8bit
g_pComm1Reg->UCON = (1<<9)|(1<<8)|(1<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<2)|(0);
//rUFCON1=(1<<6)|(11<<4)|(1<<2)|(1<<1)|(1);
g_pComm1Reg->UFCON=(2<<6)|(2<<4)|(1<<2)|(1<<1)|(1);
g_pComm1Reg->UMCON=0x0; // Disable Uart1 AFC
DBGOUT((TEXT("-> Comm_hw_Init Initialization done, errstat ")));
thisDev->portInfo.haveFIFO = TRUE;
// Clear Int Pending and Unmask
g_pINTregs->SUBSRCPND =(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);
g_pINTregs->SRCPND = BIT_UART1;
g_pINTregs->INTPND = g_pINTregs->INTPND;
g_pINTregs->INTPND;
g_pComm1Reg->UCON |= 1; // interrupt enable, Rx start
DBGOUT((TEXT("<- Comm_hw_Init Done")));
}
VOID Comm_hw_Stop(IrDevice *thisDev)
{
comPortInfo *portInfo = &thisDev->portInfo;
DBGOUT((TEXT("-> Comm_hw_Stop")));
/*
* Disable all COM interrupts.
*/
g_pINTregs->INTMSK |= (BIT_UART1);
g_pINTregs->INTSUBMSK |=(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);
/*
* Reset all UART1 registers
*/
g_pComm1Reg->ULCON= 0;
g_pComm1Reg->UCON = 0;
g_pComm1Reg->UFCON= 6;
g_pComm1Reg->UMCON=0x0;
/*
* Stop UART1 clock
*/
g_pClkPwrRegs->CLKCON &= ~UART1_CLK_ON;
DBGOUT((TEXT("<- Comm_hw_Stop Done")));
}
#if COMM_DEBUG
void DumpCommReg(void)
{
RETAILMSG (1, (TEXT("DumpCommReg \r\n")));
RETAILMSG (1, (TEXT("ULCON 0x%X, UCON 0x%x FCON 0X%x MCON 0x%x \r\n"),g_pComm1Reg->ULCON,g_pComm1Reg->UCON,g_pComm1Reg->UFCON,g_pComm1Reg->UMCON));
RETAILMSG (1, (TEXT("UTRSTAT 0x%X, UERSTAT 0x%x UFSTAT 0X%x rUMSTAT 0x%x \r\n"),
g_pComm1Reg->UTRSTAT,g_pComm1Reg->UERSTAT,g_pComm1Reg->UFSTAT,g_pComm1Reg->UMSTAT));
RETAILMSG (1, (TEXT("rUTXH0x%X, URXH 0x%x UBRDIV 0X%x \r\n"),
g_pComm1Reg->UTXH,g_pComm1Reg->URXH,g_pComm1Reg->UBRDIV));
RETAILMSG (1, (TEXT("rGPCON_U 0x%X, rGPPU 0x%x rGPDAT 0X%x \r\n"),
g_pIOPregs->GPCON_U,g_pIOPregs->GPPU,g_pIOPregs->GPDAT));
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?