📄 scif.c
字号:
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 12800:
BaudValue = 121;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 14400:
BaudValue = 108;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 19200:
BaudValue = 80;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 23040:
BaudValue = 67;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 28800:
BaudValue = 53;
Clk_div = SCIF_SCSMR_CKS_1;
case 31250:
BaudValue = 49;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 38400:
BaudValue = 40;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 57600:
BaudValue = 26;
Clk_div = SCIF_SCSMR_CKS_1;
break;
case 115200:
BaudValue = 13;
Clk_div = SCIF_SCSMR_CKS_1;
break;
default:
ret = FALSE;
}
}
if ( ret )
{
/* we need to stop transmission */
SCR = READ_REGISTER_USHORT(pHWHead->pSCR);
WRITE_REGISTER_USHORT(pHWHead->pSCR, SCR & (~SCIF_SCSCR_TIE &
~SCIF_SCSCR_RIE & ~SCIF_SCSCR_TE & ~SCIF_SCSCR_RE));
WRITE_REGISTER_UCHAR(pHWHead->pBRR,BaudValue);
WRITE_REGISTER_USHORT(pHWHead->pSMR, ((READ_REGISTER_UCHAR(pHWHead->pSMR)
& ~SCIF_SCSMR_CKS_64) | Clk_div)) ; /* clear those bits */
/* We now need to wait for the time it takes one bit to transfer */
BusyWait(AdjustMicroSecondsToLoopCount((1000000/pHWHead->dcb.BaudRate)+1));
/* re-enable the transmit and receive if needed*/
WRITE_REGISTER_USHORT(pHWHead->pSCR, SCR);
return( TRUE );
}
else
{
return( FALSE );
}
}
/*****************************************************************************
* FUNCTION : SCIF_SetByteSize
* DESCRIPTION : configures SCIF for proper byte size
* INPUTS : The pointer to the hardware struct and the byte size
* OUTPUTS : TRUE/FALSE
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL SCIF_SetByteSize(
PVOID pHead, /* PVOID returned by SCIF_Init */
ULONG ByteSize) /* ULONG ByteSize field from DCB. */
{
PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
switch( ByteSize )
{
case 7:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) |
SCIF_SCSMR_7BIT);
pHWHead->dcb.ByteSize = 7;
break;
case 8:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) &
~SCIF_SCSMR_7BIT);
pHWHead->dcb.ByteSize = 8;
break;
default:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) &
~SCIF_SCSMR_7BIT);
pHWHead->dcb.ByteSize = 8;
return(FALSE);
}
return TRUE;
}
/*****************************************************************************
* FUNCTION : SCIF_SetParity
* DESCRIPTION : configures SCIF for proper parity
* INPUTS : The pointer to the hardware struct and the Parity
* OUTPUTS : TRUE/FALSE
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL SCIF_SetParity(
PVOID pHead, /* PVOID returned by SCIF_Init */
ULONG Parity) /* ULONG parity field from DCB. */
{
PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
pHWHead->dcb.Parity = (BYTE)Parity;
switch( Parity )
{
case ODDPARITY:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) |
SCIF_SCSMR_PE | SCIF_SCSMR_ODD_PAR);
break;
case EVENPARITY:
WRITE_REGISTER_USHORT(pHWHead->pSMR, ((READ_REGISTER_USHORT( pHWHead->pSMR) |
SCIF_SCSMR_PE) & ~SCIF_SCSMR_ODD_PAR));
break;
case NOPARITY:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) &
~SCIF_SCSMR_PE);
break;
default:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) &
~SCIF_SCSMR_PE);
pHWHead->dcb.Parity = NOPARITY;
return(FALSE);
}
return TRUE;
}
/*****************************************************************************
* FUNCTION : SCIF_SetStopBits
* DESCRIPTION : configures SCIF for proper number of stop bits
* INPUTS : The pointer to the hardware struct and the # of stop bits
* OUTPUTS : TRUE/FALSE
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
BOOL
SCIF_SetStopBits(
PVOID pHead, /* PVOID returned by SCIF_Init */
ULONG StopBits /* ULONG StopBits field from DCB. */
)
{
PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
pHWHead->dcb.StopBits = (BYTE)StopBits;
/* Only 1 or 2 stop bits is accepted */
switch( StopBits )
{
case ONESTOPBIT :
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) &
~SCIF_SCSMR_2STOP);
break;
case TWOSTOPBITS :
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) |
SCIF_SCSMR_PE);
break;
default:
WRITE_REGISTER_USHORT(pHWHead->pSMR, READ_REGISTER_USHORT( pHWHead->pSMR) &
~SCIF_SCSMR_2STOP);
pHWHead->dcb.StopBits = ONESTOPBIT;
return(FALSE);
}
return TRUE;
}
/*****************************************************************************
* FUNCTION : SCIF_GetRxBufferSize
* DESCRIPTION : If the Hardware had a real buffer, the size of it
* would be given here. We do not, so our answer is 0
* INPUTS : The pointer to the hardware struct
* OUTPUTS : This routine returns a bitmask indicating which interrupts
* are currently pending.
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
ULONG SCIF_GetRxBufferSize(PVOID pHead)
{
return 0;
}
/*****************************************************************************
* FUNCTION : SCIF_GetRxBufferStart
* DESCRIPTION : If the Hardware had a real buffer, the start of it
* would be given here. We do not, so our answer is NULL
* INPUTS : The pointer to the hardware struct
* OUTPUTS : This routine returns a bitmask indicating which interrupts
* are currently pending.
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
PVOID SCIF_GetRxStart(PVOID pHead)
{
return NULL;
}
/*****************************************************************************
* FUNCTION : SCIF_GetInterruptType
* DESCRIPTION : This function is called by the MDD whenever an interrupt
* occurs. The return code is then checked by the MDD to
* determine which of the four interrupt handling routines
* are to be called.
* INPUTS : The pointer to the hardware struct
* OUTPUTS : This routine returns a bitmask indicating which interrupts
* are currently pending.
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
INTERRUPT_TYPE SCIF_GetInterruptType(
PVOID pHead) /* Pointer to hardware head */
{
PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
INTERRUPT_TYPE interrupts;
USHORT SSR;
USHORT LSR;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("+SCIF_GetInterruptType 0x%X\r\n"), pHead));
SSR = READ_REGISTER_USHORT(pHWHead->pSSR);
LSR = READ_REGISTER_USHORT(pHWHead->pLSR);
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType: SSR = 0x%X, LSR = 0x%X\r\n"), SSR, LSR));
interrupts = INTR_NONE;
if (SSR & (SCIF_SCSSR_ER | SCIF_SCSSR_BRK | SCIF_SCSSR_RDF | SCIF_SCSSR_DR | SCIF_SCSSR_TDFE)
| LSR & SCIF_SCLSR_ORER)
{
if ( SSR & SCIF_SCSSR_ER)
{
interrupts |= INTR_LINE;
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType : Line Interrupt (Error) Detected\r\n") ));
}
if ( SSR & SCIF_SCSSR_BRK)
{
interrupts |= INTR_LINE;
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType : Line Interrupt (Break) Detected\r\n")) );
}
if ( LSR & SCIF_SCLSR_ORER)
{
interrupts |= INTR_LINE;
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType : Line Interrupt (Overrun) Detected\r\n") ));
}
if (SSR & (SCIF_SCSSR_RDF | SCIF_SCSSR_DR))
{
interrupts |= INTR_RX;
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType : Rx Interrupt Detected\r\n") ));
}
if (SSR & SCIF_SCSSR_TDFE)
{
/*
* there is a problem where if the buffer is empty, and an interrupt
* occurs for another reason (like a modem event), we detect an interrupt
* since, the Transmit can not interrupt if Transmit is not enabled, we can
* ignore the fact that the buffer is empty if the TE bit is not set (we
* were not transmitting. This will solve the problem because we will
* only get an interrupt when both the TE bit and the TDFE are set
*/
/* there is another problem where we are in the middle of transmitting
* and we get a receive interrupt. If the buffer empties quickly (and it
* does, then by the time we get here, these flags will show that there
* is also a Trnasmit interrupt. Even though the interrupt is not
* enabled, so we need to check for that also.
*/
if (READ_REGISTER_USHORT(pHWHead->pSCR) & SCIF_SCSCR_TE)
{
if (READ_REGISTER_USHORT(pHWHead->pSCR) & SCIF_SCSCR_TIE)
{
interrupts = INTR_TX;
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType : Tx Interrupt Detected\r\n") ));
}
}
}
}
/*
* lets check for modem interrupts, This can be done most easily by simply
* reading the 7751R's interrupt control unit for Interrupts on IRQ3.
* since we change the Interrupt edge every time we have an interrupt, we
* can rely on this value to only have an interrupt when the line actually
* changes.
*/
/* If there is a DCD change */
if (pHWHead->AddTXIntr)
{
interrupts |= INTR_TX;
pHWHead->AddTXIntr = FALSE;
DEBUGMSG (ZONE_EVENTS,
(TEXT("SCIF_GetInterruptType : Adding Additional Tx Int\r\n") ));
}
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-SCIF_GetInterruptType 0x%X, 0x%X\r\n"),
pHead, interrupts));
return interrupts;
}
/*****************************************************************************
* FUNCTION : SCIF_RxIntr
* DESCRIPTION : This routine gets several characters from the hardware
* receive buffer and puts them in a buffer provided via
* the second argument. It returns the number of bytes lost
* to overrun. this is the HWGetBytes() call (for the MDD).
* INPUTS :
* OUTPUTS : The return value indicates the number of overruns detected.
* The actual number of dropped characters may be higher.
* Especially because we have no way to detect that an over-run
* has occurred. So we can make some assumptions based on
* errors that happen that no one else claims.
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
ULONG SCIF_RxIntr(
PVOID pHead, /* Pointer to hardware head */
PUCHAR pRxBuffer, /* Pointer to receive buffer */
ULONG *pBufflen) /* In = max bytes to read, out = bytes read */
{
PSCIF_INFO pHWHead = (PSCIF_INFO)pHead;
ULONG RetVal = 0;
ULONG TargetRoom = *pBufflen;
int BytesLeft;
int position = 0;
int DsrSensitive = pHWHead->dcb.fDsrSensitivity;
DEBUGMSG (ZONE_FUNCTION, (TEXT("+GetBytes - len %d.\r\n"),
*pBufflen));
while ( TargetRoom &&( BytesLeft = GET_SCFDR_RX_BYTES(READ_REGISTER_USHORT(pHWHead->pFDR))))
{
/* Read the byte */
pRxBuffer[position] = READ_REGISTER_UCHAR(pHWHead->pFRDR);
position++;
--TargetRoom;
}
*pBufflen = position;
if( pHWHead->DroppedBytes )
{
DEBUGMSG (ZONE_WARN, (TEXT("Rx drop %d.\r\n"),
pHWHead->DroppedBytes));
}
DEBUGMSG (ZONE_READ, (TEXT("-GetBytes - rx'ed %d, dropped %d.\r\n"),
*pBufflen,
pHWHead->DroppedBytes));
RetVal = pHWHead->DroppedBytes;
pHWHead->DroppedBytes = 0;
/*
* seeing as how we are here because there was
* an interrupt, we need to clear it
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -