📄 comm.c
字号:
/*
Copyright(c) 1998,1999 SIC/Hitachi,Ltd.
Module Name:
comm.c
Revision History:
26th May 1999 Released
8th July 1999 Modified value of pTOCR
1999-Oct-22 cea Removed setup of TMU2
*/
//#define OUTMSG
#include "nsc.h"
#include "firregs.h"
/******************************************************************************
* Modification Done by Maneesh Gupta
*
* S1.h has been replaced by platform.h
* Mobytel.h has been removed as it is no longer needed.
*****************************************************************************/
//#include "platform.h"
/******************************************************************************
* End of modification Done by Maneesh Gupta
*****************************************************************************/
#include "cc.h"
#include "hw16550.h"
#include "Settings.h"
//#include "oalintr.h"
/*
* These arrays give default IO/IRQ settings by COM port number.
*/
USHORT comPortIOBase[] = { 0xFFFF, 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
USHORT comPortIRQ[] = { 0xFFFF, 4, 3, 9, 11 };
/*
*************************************************************************
* SetRegInit
*************************************************************************
*/
VOID SetRegInit()
{
USHORT currentVal;
UCHAR imstcr;
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetRegInit -->\r\n")));
currentVal = READ_REGISTER_USHORT(pNIMR);
if(currentVal & CC_INTC_NIMR_IRDAM_MASK){
WRITE_REGISTER_USHORT(pNIMR,currentVal & CC_INTC_NIMR_IRDAM_UNMASK);//unmask irda interrupts
}
currentVal = READ_REGISTER_USHORT(pSMSCR);
if(currentVal & CC_SYS_SMSCR_IRDAST){
WRITE_REGISTER_USHORT(pSMSCR,currentVal & ~CC_SYS_SMSCR_IRDAST);//wakeup irda
}
//
// Set up the transceiver.
//
// This code assumes that the IrDA transceiver is the Hewlett-Packard HSDL-3600
//
// The HSDL-3600 mode pins are connected to the HD64465 port D bits 0 and 1.
//
// Note: The IrDA dongle is also connected to port D bits 0, 1 and 2.
//
// This code does the following:
// reset the IrDA peripherial controller in the HD64465.
// set HD64465 port D bits 0 and 1 as output bits.
// set the HDSL-3600 mode bits for full power mode.
// set the HD64465 FIR/SIR interface into SIR mode.
//
while (READ_REGISTER_USHORT(pSPSRCR) & CC_SYS_SMSCR_IRDAST); // wait for reset to clear
WRITE_REGISTER_USHORT(pSPSRCR, CC_SYS_SMSCR_IRDAST); // reset IrDA module
while (READ_REGISTER_USHORT(pSPSRCR) & CC_SYS_SMSCR_IRDAST); // wait for reset to clear
WRITE_REGISTER_USHORT(pGPDCR ,(READ_REGISTER_USHORT(pGPDCR) & 0xFFF0) | 0x05); // Set port D bits 0 and 1 as output
WRITE_REGISTER_UCHAR((PBYTE)pGPDDR ,(READ_REGISTER_UCHAR((PBYTE)pGPDDR) & 0x03) | 0x00); // Select full power for the HSDL-3600 tranceiver from HP
WRITE_REGISTER_UCHAR(pITMCR, CC_FIR_ITMCR_TMCR_66); // CKIO:66MHz
WRITE_REGISTER_UCHAR(pISIRR ,0x00); // Select FIR mode
WRITE_REGISTER_UCHAR(pIFIRCR, READ_REGISTER_UCHAR(pIFIRCR) | CC_FIR_IFIRCR_TMODE);//Select IBM-like transceiver mode
imstcr = READ_REGISTER_UCHAR(pIMSTCR);
WRITE_REGISTER_UCHAR(pIMSTCR, imstcr | CC_FIR_IMSTCR_BANK2);//Select Bank2
WRITE_REGISTER_UCHAR(pIIRTCR, READ_REGISTER_UCHAR(pIIRTCR) & ~CC_FIR_IIRTCR_MODSEL);//MODESEL pin to LOW
WRITE_REGISTER_UCHAR(pIMSTCR, imstcr);//Select original Bank
WRITE_REGISTER_UCHAR(pISIRR ,CC_FIR_ISIRR_SIRMOD);//HP-SIR
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetRegInit <--\r\n")));
}
/*
*************************************************************************
* SetFIFOCR /
*************************************************************************
*/
VOID SetFIFOCR(IrDevice *thisDev,BOOLEAN enable)
{
UCHAR newVal;
DBGOUT((TEXT("==>SetFIFOCR")));
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetFIFOCR -->\r\n")));
if(enable){
if(thisDev->currentSpeed > MAX_SIR_SPEED){
WRITE_REGISTER_UCHAR(pIMSTCR, CC_FIR_IMSTCR_IEN|CC_FIR_IMSTCR_TXEN|CC_FIR_IMSTCR_RXEN); /* IEN, TXEN, RXEN On */
WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_RXFIFO); /* Rx FIFO Pointer Reaet */
WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_TXFIFO); /* Tx FIFO Pointer Reaet */
}else{
WRITE_REGISTER_UCHAR(pIrFCR, SERIAL_FCR_ENABLE | SERIAL_1_BYTE_HIGH_WATER
| SERIAL_FCR_RCVR_RESET | SERIAL_FCR_TXMT_RESET);
DEBUGMSG(ZONE_SIRMODE, (TEXT(" pIrFCR [0x%x(0x%x)]\r\n"),
(UCHAR)READ_REGISTER_UCHAR(pIrFCR), SERIAL_FCR_ENABLE
| SERIAL_1_BYTE_HIGH_WATER
| SERIAL_FCR_RCVR_RESET
| SERIAL_FCR_TXMT_RESET
));
}
}else{
if(thisDev->currentSpeed > MAX_SIR_SPEED){
newVal = newVal & ~CC_FIR_IMSTCR_TXEN;
newVal = newVal & ~CC_FIR_IMSTCR_RXEN;
//SetComPort(comBase, pIMSTCR, newVal);
WRITE_REGISTER_UCHAR(pIMSTCR, 0x00); /* IEN, TXEN, RXEN Off */
}else{
WRITE_REGISTER_UCHAR(pIrFCR, 0x0000);
DEBUGMSG(ZONE_SIRMODE, (TEXT(" pIrFCR [0x%x(0x0000)]\r\n"),
(UCHAR)READ_REGISTER_UCHAR(pIrFCR)));
}
}
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetFIFOCR <--\r\n")));
}
/*
*************************************************************************
* SetCOMInterrupts
*************************************************************************
*/
VOID SetCOMInterrupts(IrDevice *thisDev, BOOLEAN enable)
{
UCHAR newMask;
DBGISR((TEXT("Enable interrupts = %s"), enable ? TEXT("TRUE") : TEXT("FALSE")));
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetCOMMInterrupt -->\r\n")));
if(thisDev->currentSpeed > MAX_SIR_SPEED){
newMask = READ_REGISTER_UCHAR(pIMSTCR);
if (enable){
/******************************************************************************
* Modification Done by Maneesh Gupta
*
* While interrupt enabling of FIR interrupt RX is also enabled.
*****************************************************************************/
WRITE_REGISTER_UCHAR(pIMSTCR, newMask | CC_FIR_IMSTCR_IEN | CC_FIR_IMSTCR_RXEN );
/******************************************************************************
* End of modification Done by Maneesh Gupta
*****************************************************************************/
}else{
WRITE_REGISTER_UCHAR(pIMSTCR, newMask & ~CC_FIR_IMSTCR_IEN );
}
}else{
if (enable){
if(thisDev->portInfo.writePending){
WRITE_REGISTER_UCHAR(pIrIER, SERIAL_IER_THR|SERIAL_IER_RDA);
}else{
WRITE_REGISTER_UCHAR(pIrIER, SERIAL_IER_RDA);
}
}else{
WRITE_REGISTER_UCHAR(pIrIER, 0x00);
}
}
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetCOMMInterrupt <--\r\n")));
}
/*
*************************************************************************
* IsCommReadyForTransmit
*************************************************************************
*
*
*/
BOOLEAN IsCommReadyForTransmit(IrDevice *thisDev)
{
DEBUGMSG(ZONE_FIRMODE, (TEXT("IsCommReadyForTransmit <-->\r\n")));
return !thisDev->portInfo.writePending;
}
/*
*************************************************************************
* DoOpen
*************************************************************************
*
* Open COMM port
*
*/
BOOLEAN DoOpen(IrDevice *thisDev)
{
BOOLEAN result;
DBGOUT((TEXT("DoOpen(%d)"), thisDev->portInfo.ioBase));
DEBUGMSG(ZONE_FIRMODE, (TEXT("DoOpen -->\r\n")));
#ifdef UNDER_CE
// Windows CE. We get a chunk of memory from our contiguous physical
// buffer. See externs.h for detailed information.
ASSERT(g_pvDmaVirtualBase);
thisDev->portInfo.readBuf = LIST_ENTRY_TO_RCV_BUF(
(PUCHAR)g_pvDmaVirtualBase + PORTINFO_OFFSET);
thisDev->portInfo.writeBuf =
(PUCHAR)g_pvDmaVirtualBase + PORTINFO_OFFSET + RCV_BUFFER_SIZE;
#else // UNDER_CE
/*
* This buffer gets swapped with the rcvBuffer data pointer
* and must be the same size.
*/
thisDev->portInfo.readBuf = LIST_ENTRY_TO_RCV_BUF(MyMemAlloc(RCV_BUFFER_SIZE, TRUE)); // Was FALSE -SWA
if (!thisDev->portInfo.readBuf){
return FALSE;
}
/*
* The write buffer is also used as a DMA buffer.
*/
thisDev->portInfo.writeBuf = MyMemAlloc(MAX_IRDA_DATA_SIZE * 8, TRUE);
if (!thisDev->portInfo.writeBuf){
return FALSE;
}
#endif // !UNDER_CE
/*
* Initialize send/receive FSMs before OpenCOM(), which enables rcv interrupts.
*/
thisDev->portInfo.rcvState = STATE_INIT;
thisDev->portInfo.writePending = FALSE;
DBGOUT((TEXT("writePending = FALSE")));
result = OpenCOM(thisDev);
DBGOUT((TEXT("DoOpen %s"), (CHAR *)(result ? "succeeded" : "failed")));
DEBUGMSG(ZONE_FIRMODE, (TEXT("DoOpen <--\r\n")));
return result;
}
/*
*************************************************************************
* DoClose
*************************************************************************
*
* Close COMM port
*
*/
VOID DoClose(IrDevice *thisDev)
{
DBGOUT((TEXT("DoClose(COM%d)"), thisDev->portInfo.ioBase));
DEBUGMSG(ZONE_FIRMODE, (TEXT("DoClose -->\r\n")));
#ifdef UNDER_CE
// Windows CE. Don't need to free since it is just a pointer in our
// reserved physical memory.
thisDev->portInfo.readBuf = NULL;
thisDev->portInfo.writeBuf = NULL;
#else // UNDER_CE
if (thisDev->portInfo.readBuf){
MyMemFree(RCV_BUF_TO_LIST_ENTRY(thisDev->portInfo.readBuf),
RCV_BUFFER_SIZE, TRUE); // Was FALSE -SWA
thisDev->portInfo.readBuf = NULL;
}
if (thisDev->portInfo.writeBuf){
MyMemFree(thisDev->portInfo.writeBuf, MAX_IRDA_DATA_SIZE * 8, TRUE);
thisDev->portInfo.writeBuf = NULL;
}
#endif //!UNDER_CE
CloseCOM(thisDev);
DEBUGMSG(ZONE_FIRMODE, (TEXT("DoClose <--\r\n")));
}
/*
*************************************************************************
* SetUARTSpeed
*************************************************************************
*
*
*/
VOID SetUARTSpeed(IrDevice *thisDev, UINT bitsPerSec)
{
USHORT divisor;
UINT i;
NDIS_STATUS stat;
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetUARTSpeed -->\r\n")));
if (bitsPerSec <= MAX_SIR_SPEED){
if(thisDev->currentSpeed > MAX_SIR_SPEED){//change from MIR/FIR to SIR
if(READ_REGISTER_UCHAR(pISIRR) & CC_FIR_ISIRR_SIRMOD){//unexpected status
}else{
if (thisDev->AdapterState==ADAPTER_RX) {
NdisMCompleteDmaTransfer(&stat, thisDev->DmaHandle,
thisDev->rcvDmaBuffer,
thisDev->rcvDmaOffset,
thisDev->rcvDmaSize, FALSE);
}
WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_HW);
NdisStallExecution( 50 );
#ifdef OUTMSG
RETAILMSG(1,(TEXT("NdisStallExecution\r\n")));
#endif
WRITE_REGISTER_UCHAR(pIMSTCR,CC_FIR_IMSTCR_BANK0);//Switch Bank 0
i=0;
while(i<10000){//Clean up FIR Tx_FIFO
if(READ_REGISTER_UCHAR(pITSR) & CC_FIR_ITSR_EOM){
break;
}else{
}
i++;
}
i=0;
while(i<10000){//Clean up FIR Rx_FIFO
if(READ_REGISTER_UCHAR(pIRSR) & CC_FIR_IRSR_RFEM){
READ_REGISTER_UCHAR(pIRFR);
}else{
break;
}
i++;
}
WRITE_REGISTER_UCHAR(pIMSTCR,CC_FIR_IMSTCR_BANK2);//Switch Bank 2
WRITE_REGISTER_UCHAR(pIIRC2R,READ_REGISTER_UCHAR(pIIRC2R) & 0xfc | CC_FIR_IIRC2R_DFIRI);//FIR to SIR
WRITE_REGISTER_UCHAR(pIIRC1R,CC_FIR_IIRC1R_IRMOD_HPSIR);
WRITE_REGISTER_UCHAR(pISIRR,CC_FIR_ISIRR_SIRMOD);
}
}else{// SIR to SIR
}
i=0;
while(i<10000){//Clean up UART Tx_FIFO
if((READ_REGISTER_UCHAR(pIrLSR) & (SERIAL_LSR_TEMT|SERIAL_LSR_THRE))==(SERIAL_LSR_TEMT|SERIAL_LSR_THRE)){
break;
}else{
}
i++;
}
i=0;
while(i<10000){//Clean up UART Rx_FIFO
if(READ_REGISTER_UCHAR(pIrLSR) & SERIAL_LSR_DR){
READ_REGISTER_UCHAR(pIrRBR);
}else{
break;
}
i++;
}
/*
* Set speed in the standard UART divisor latch
*
* 1. Set up to access the divisor latch.
*
* 2. In divisor-latch mode:
* the transfer register doubles as the low divisor latch
* the int-enable register doubles as the hi divisor latch
*
* Set the divisor for the given speed.
* The divisor divides the maximum Slow IR speed of 115200 bits/sec.
*
* 3. Take the transfer register out of divisor-latch mode.
*
*/
if (!bitsPerSec){
bitsPerSec = 9600;
}
divisor = DivisorOfRate(bitsPerSec);
if ( divisor ){
WRITE_REGISTER_UCHAR(pIrLCR, SERIAL_LCR_DLAB|SERIAL_8_DATA );
WRITE_REGISTER_UCHAR(pIrDLL, divisor & 0xff);
WRITE_REGISTER_UCHAR(pIrDLM, (divisor >> 8) & 0xff);
WRITE_REGISTER_UCHAR(pIrLCR, SERIAL_8_DATA);
}else{
DEBUGMSG(ZONE_ERROR,(TEXT("-SetUARTSpeed - Bad BaudRate %d\r\n"),bitsPerSec));
}
NdisStallExecution(5000);
#ifdef OUTMSG
RETAILMSG(1,(TEXT("NdisStallExecution\r\n")));
#endif
}
DBGOUT((TEXT("<==SetUARTSpeed")));
DEBUGMSG(ZONE_FIRMODE, (TEXT("SetUARTSpeed <--\r\n")));
}
USHORT DivisorOfRate( ULONG BaudRate )
{
ULONG errorcode = 0;
USHORT divisor;
DEBUGMSG(ZONE_FIRMODE, (TEXT("DivisorOfRate -->\r\n")));
divisor = (USHORT)LookUpValue(BaudRate, &errorcode);
if ( errorcode )
divisor = 0;
DEBUGMSG(ZONE_FIRMODE, (TEXT("DivisorofRate <--\r\n")));
return divisor;
}
ULONG LookUpValue( ULONG Key,PULONG pErrorCode )
{
ULONG val;
DEBUGMSG(ZONE_FIRMODE, (TEXT("LookUpValue -->\r\n")));
*pErrorCode = 0;
switch(Key){
case 50: val = 2307; break;
case 75: val = 1538; break;
case 110: val = 1049; break;
case 135: val = 858; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -