📄 uartser.c
字号:
// in the UART itself. Just set to 0 for now since the
// MDD doesn't take care of this.
pHWHead->Status.cbInQue = 0;
pHWHead->Status.cbOutQue = 0;
memcpy(lpStat, &(pHWHead->Status), sizeof(COMSTAT));
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
RetVal = (ULONG)-1;
}
}
else
RetVal = (ULONG)-1;
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-HW_SA1100GetStatus 0x%X\r\n"), pHead));
return RetVal;
}
//
// @doc OEM
// @func ULONG | HW_SA1100Reset | Perform any operations associated
// with a device reset
//
// @rdesc None.
//
VOID
HW_SA1100Reset(
PVOID pHead // @parm PVOID returned by HWInit.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100Reset 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100Reset 0x%X\r\n"), pHead));
memset(&pHWHead->Status, 0, sizeof(COMSTAT));
try {
HW_EnableTxRx(pHWHead);
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100Reset 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
}
void HW_SA1100ICPEnableUart(PVOID pHead,BOOL EnableUart) // Hardware Head
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("\t**** +HW_SA1100ICPEnableUart ******\r\n")));
IOW_REG_FIELD (struct utcr4Bits, &pHWHead->pUART->utcr4, lpm, 0);
IOW_REG_FIELD (struct utcr4Bits, &pHWHead->pUART->utcr4, hse, (EnableUart ? 0 : 1));
pHWHead->bIr=!EnableUart;
}
void HW_SA1100EnableICPTxd(PSER_HW_INFO pHWHead,BOOL enable)
{
IOW_REG_FIELD (struct utcr3Bits, &pHWHead->pUART->utcr3, txe, (enable ? 1 : 0));
//SA_DumpSerialRegisters(pHWHead);
}
//
// @doc OEM
// @func VOID | HW_SA1100PurgeComm | Purge RX and/or TX
//
// @rdesc None.
//
VOID
HW_SA1100PurgeComm(
PVOID pHead, // @parm PVOID returned by HWInit.
DWORD fdwAction // @parm Action to take.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100PurgeComm 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100PurgeComm 0x%X\r\n"), pHead));
try {
// nor how RX interrupts would ever get turned back on. I suspect that
// RXABORT and TXABORT would both be better implemented in the MDD.
if (fdwAction & PURGE_RXABORT) {
IOW_REG_FIELD (struct utcr3Bits, &pHWHead->pUART->utcr3, rie, 0);
}
if (fdwAction & PURGE_TXCLEAR) {
// Write the TX reset bit. It is self clearing
IOW_REG_FIELD (struct utcr3Bits, &pHWHead->pUART->utcr3, txe, 0);
}
if (fdwAction & PURGE_RXCLEAR) {
// Write the RX reset bit. It is self clearing
IOW_REG_FIELD (struct utcr3Bits, &pHWHead->pUART->utcr3, rxe, 0);
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
HW_EnableTxRx(pHWHead);
DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100PurgeComm 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
}
//
// @doc OEM
// @func BOOL | HW_SA1100XmitComChar | Transmit a char immediately
//
// @rdesc TRUE if succesful
//
BOOL
HW_SA1100XmitComChar(
PVOID pHead, // @parm PVOID returned by HWInit.
UCHAR ComChar // @parm Character to transmit.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
//RETAILMSG(1,(TEXT("+HW_SA1100XmitComChar 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100XmitComChar 0x%X\r\n"), pHead));
// Get critical section, then transmit when buffer empties
DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar wait for CritSec %x.\r\n"),&(pHWHead->TransmitCritSec)));
EnterCriticalSection(&(pHWHead->TransmitCritSec));
DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar got CritSec %x.\r\n"),&(pHWHead->TransmitCritSec)));
try {
while(TRUE) { // We know THR will eventually empty
// Write the character if we can
SA_ReadSR1(pHWHead);
if(pHWHead->pUART->utsr1.tnf) {
// pHWHead->pUART->utdr.data=ComChar;
IOW_REG_FIELD (struct utdrBits, &pHWHead->pUART->utdr, data, ComChar);
DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar wrote x%X\r\n"),ComChar));
break;
}
// If we couldn't write the data yet, then wait for a
// TXINTR to come in and try it again.
// Enable xmit intr.
IOW_REG_FIELD (struct utcr3Bits, & pHWHead->pUART->utcr3, tie, 1);
// Wait until the txintr has signalled.
DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar WaitIntr x%X\r\n"),pHWHead->FlushDone));
//RETAILMSG(1,(TEXT("+HW_SA1100XmitComChar Waiting for TxReadyr\n")));
WaitForSingleObject(pHWHead->FlushDone, (ULONG)1000);
//RETAILMSG(1,(TEXT("+HW_SA1100XmitComChar Awoke on TxReadyr\n")));
}
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
LeaveCriticalSection(&(pHWHead->TransmitCritSec));
DEBUGMSG (ZONE_WRITE, (TEXT("XmitComChar released CritSec %x.\r\n"),
&(pHWHead->TransmitCritSec)));
DEBUGMSG (ZONE_FUNCTION,
(TEXT("-HW_SA1100XmitComChar 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
return TRUE;
}
//
// @doc OEM
// @func BOOL | HW_SA1100PowerOff | Perform powerdown sequence.
//
VOID
HW_SA1100PowerOff(
PVOID pHead // @parm PVOID returned by HWInit.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
/*
pHWHead->uartPowerRegs.utcr0=pHWHead->pUART->utcr0;
pHWHead->uartPowerRegs.utcr3=pHWHead->pUART->utcr3;
if (pHWHead->bIr) {
pHWHead->uartPowerRegs.utcr4=pHWHead->pUART->utcr4; // ICP device only
}
*/
pHWHead->PowerDownFlag=TRUE;
}
//
// @doc OEM
// @func BOOL | HW_SA1100PowerOn | Perform poweron sequence.
//
VOID
HW_SA1100PowerOn(
PVOID pHead // @parm PVOID returned by HWInit.
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
/*
if (pHWHead->PowerDownFlag==TRUE) {
pHWHead->PowerDownFlag=FALSE;
pHWHead->pUART->utcr0=pHWHead->uartPowerRegs.utcr0;
pHWHead->pUART->utcr3=pHWHead->uartPowerRegs.utcr3;
if (pHWHead->bIr) {
pHWHead->pUART->utcr4=pHWHead->uartPowerRegs.utcr4; // ICP device only
}
}
//RETAILMSG(1,(TEXT("+HW_SA1100PowerOn 0x%X\r\n"), pHead));
// And we didn't save the Divisor Reg, so set baud rate
// But don't call HW_SA1100SetBaud, since it does DebugMsg.
// Call our internal function instead.
SA_SetBaudRate(pHWHead,pHWHead->dcb.BaudRate);
*/
}
//
// @doc OEM
// @func BOOL | HW_SA1100SetDCB | Sets new values for DCB. This
// routine gets a DCB from the MDD. It must then compare
// this to the current DCB, and if any fields have changed take
// appropriate action.
//
// @rdesc ULONG
//
BOOL
HW_SA1100SetDCB(
PVOID pHead, // @parm PVOID returned by HWInit.
LPDCB lpDCB // @parm Pointer to DCB structure
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
BOOL retval = TRUE;
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100SetDCB 0x%X\r\n"), pHead));
// If the device is open, scan for changes and do whatever
// is needed for the changed fields. if the device isn't
// open yet, just save the DCB for later use by the open.
if(pHWHead->OpenCount) {
if( lpDCB->BaudRate != pHWHead->dcb.BaudRate ) {
HW_SA1100SetBaudRate( pHWHead, lpDCB->BaudRate );
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB BaudRate\r\n")));
}
if( lpDCB->ByteSize != pHWHead->dcb.ByteSize ) {
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB ByteSize\r\n")));
HW_SA1100SetByteSize( pHWHead, lpDCB->ByteSize );
}
if( lpDCB->Parity != pHWHead->dcb.Parity ) {
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB Parity\r\n")));
HW_SA1100SetParity( pHWHead, lpDCB->Parity );
}
if( lpDCB->StopBits != pHWHead->dcb.StopBits ) {
//RETAILMSG(1,(TEXT("+HW_SA1100SetDCB StopBits\r\n")));
HW_SA1100SetStopBits( pHWHead, lpDCB->StopBits );
}
// Don't worry about fOutxCtsFlow. It is a flag which
// will be examined every time we load the TX buffer.
// No special action required here.
}
// Now that we have done the right thing, store this DCB
pHWHead->dcb = *lpDCB;
DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100SetDCB 0x%X\r\n"), pHead));
//SA_DumpSerialRegisters(pHWHead);
return retval;
}
//
// @doc OEM
// @func BOOL | HW_SA1100SetCommTimeouts | Sets new values for the
// CommTimeouts structure. routine gets a DCB from the MDD. It
// must then compare this to the current DCB, and if any fields
// have changed take appropriate action.
//
// @rdesc ULONG
//
ULONG HW_SA1100SetCommTimeouts(
PVOID pHead, // @parm PVOID returned by HWInit.
LPCOMMTIMEOUTS lpCommTimeouts // @parm Pointer to CommTimeout structure
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
ULONG retval = 0;
//RETAILMSG(1,(TEXT("+HW_SA1100SetCommTimeouts 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION,(TEXT("+HW_SA1100SetCommTimeout 0x%X\r\n"), pHead));
// OK, first check for any changes and act upon them
if( lpCommTimeouts->WriteTotalTimeoutMultiplier !=
pHWHead->CommTimeouts.WriteTotalTimeoutMultiplier ) {
}
// Now that we have done the right thing, store this DCB
pHWHead->CommTimeouts = *lpCommTimeouts;
DEBUGMSG (ZONE_FUNCTION,(TEXT("-HW_SA1100SetCommTimeout 0x%X\r\n"), pHead));
return retval;
}
//
// @doc OEM
// @func BOOL | HW_SA1100Ioctl | Device IO control routine.
// @parm DWORD | dwOpenData | value returned from COM_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PBYTE | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PBYTE | pBufOut | output data from the device
// @parm DWORD | dwLenOut |maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @remark The MDD will pass any unrecognized IOCTLs through to this function.
//
BOOL
HW_SA1100Ioctl(PVOID pHead, DWORD dwCode,PBYTE pBufIn,DWORD dwLenIn,
PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut)
{
BOOL RetVal = TRUE;
//RETAILMSG(1,(TEXT("+HW_SA1100Ioctl 0x%X\r\n"), pHead));
DEBUGMSG (ZONE_FUNCTION, (TEXT("+HW_SA1100Ioctl 0x%X\r\n"), pHead));
switch (dwCode) {
// Currently, no defined IOCTLs
default:
RetVal = FALSE;
DEBUGMSG (ZONE_FUNCTION, (TEXT(" Unsupported ioctl 0x%X\r\n"), dwCode));
break;
}
DEBUGMSG (ZONE_FUNCTION, (TEXT("-HW_SA1100Ioctl 0x%X\r\n"), pHead));
return RetVal;
}
BOOL
HW_SA1100TransmitterBusy(
PVOID pHead
)
{
PSER_HW_INFO pHWHead = (PSER_HW_INFO)pHead;
try {
return (!(pHWHead->pUART->utsr0.tfs) || (pHWHead->pUART->utsr1.tby) || (!(pHWHead->pUART->utsr1.tnf)));
}
except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
}
return TRUE; // Busy,If fail
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -