📄 hwctxt.cpp
字号:
RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread()\r\n")));
DWORD dwRet;
BOOL fIntInitialized = FALSE;
PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;
//
// Create the interrupt event
//
pContext->hevInterrupt = CreateEvent(0, FALSE, FALSE, NULL); //reset=auto, bInitialState=non-signaled
if (pContext->hevInterrupt == NULL) {
dwRet = GetLastError();
RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - Error creating interrupt event. Error = %d\r\n"), dwRet));
goto EXIT;
}
fIntInitialized = InterruptInitialize(pContext->dwSysIntr, pContext->hevInterrupt, NULL, 0);
if (fIntInitialized == FALSE) {
dwRet = ERROR_GEN_FAILURE;
RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - interrupt initialization failed\r\n")));
goto EXIT;
}
InterruptDone(pContext->dwSysIntr);
pContext->fExitIST = FALSE;
//
// Create the read pending release event
//
pContext->hevReadPending = CreateEvent(0, TRUE, FALSE, NULL); //reset=manual, bInitialState=non-signaled
if (pContext->hevReadPending == NULL) {
dwRet = GetLastError();
RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - Error creating read pending event. Error = %d\r\n"), dwRet));
goto EXIT;
}
pContext->hIST = CreateThread((LPSECURITY_ATTRIBUTES) NULL,
0,
(LPTHREAD_START_ROUTINE) CallISTMain,
this,
0,
NULL);
if (pContext->hIST == NULL) {
RETAILMSG(MDSMSG, (TEXT("UDGContext::StartInterruptThread() - IST creation failed\r\n")));
dwRet = GetLastError();
goto EXIT;
}
pContext->fRunning = TRUE;
dwRet = ERROR_SUCCESS;
CeSetThreadPriority(pContext->hIST, pContext->dwISTPriority);
EXIT:
if (pContext->fRunning == FALSE) {
if (fIntInitialized) InterruptDisable(pContext->dwSysIntr);
if (pContext->hevInterrupt) CloseHandle(pContext->hevInterrupt);
if (pContext->hevReadPending) CloseHandle(pContext->hevReadPending);
pContext->hevInterrupt = NULL;
pContext->hevReadPending=NULL;
}
return dwRet;
}
DWORD
UDGContext::StopInterruptThread(PVOID pvContext)
{
RETAILMSG(MDSMSG, (TEXT("UDGContext::StopInterruptThread()\r\n")));
PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;
//
// Stop the IST
//
pContext->fExitIST = TRUE;
InterruptDisable(pContext->dwSysIntr);
SetEvent(pContext->hevInterrupt);
WaitForSingleObject(pContext->hIST, INFINITE);
CloseHandle(pContext->hevInterrupt);
CloseHandle(pContext->hevReadPending);
CloseHandle(pContext->hIST);
pContext->hIST = NULL;
pContext->hevInterrupt = NULL;
pContext->hevReadPending = NULL;
ResetDevice();
pContext->fRunning = FALSE;
RETAILMSG(MDSMSG, (TEXT("UDGContext::StopInterruptThread() - interrupt thread stop\r\n")));
return ERROR_SUCCESS;
}
//
// interrupt service routine.
//
DWORD WINAPI
CallISTMain(PVOID pvContext)
{
RETAILMSG(MDSMSG, (TEXT("CallISTMain()\r\n")));
UDGContext *pUDGContext = (UDGContext *)pvContext;
pUDGContext->ISTMain(pUDGContext->m_pHWContext);
return (TRUE);
}
DWORD
UDGContext::ISTMain(PVOID pvContext)
{
RETAILMSG(MDSMSG, (TEXT("UDGContext::ISTMain()\r\n")));
PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;
while (!pContext->fExitIST)
{
pContext->fRestartIST = FALSE;
// Enable Suspend Mode in the Power Register
SetClearReg(PWR_REG_OFFSET, SUSPEND_MODE_ENABLE_CTRL, SET);
// Disable All Endpoint interrupts
WriteReg(EP_INT_EN_REG_OFFSET, 0); // Disable All
// Enable Device interrupts
WriteReg(USB_INT_EN_REG_OFFSET, (USB_RESET_INTR | USB_SUSPEND_INTR));
// Enable Endpoint interrupt 0
BYTE irqEnBit = EpToIrqStatBit(0);
SetClearReg(EP_INT_EN_REG_OFFSET, irqEnBit, SET);
while (TRUE) {
RETAILMSG(MDSMSG, (_T("TEST33333\r\n")));
DWORD dwWait = WaitForSingleObject(pContext->hevInterrupt, INFINITE);
RETAILMSG(MDSMSG, (_T("TEST4\r\n")));
if (pContext->fExitIST || pContext->fRestartIST) {
RETAILMSG(MDSMSG, (_T("TEST5\r\n")));
break;
}
if (dwWait == WAIT_OBJECT_0) {
// HandleUSBEvent(pContext); ..read event flag 悸且巴...
// InterruptDone(m_dwSysInterrupt);
/* RETAILMSG(MDSMSG, (_T("TEST6\r\n")));
const DWORD dwSetupPacketSize = ReadIndexedReg(0, OUT_FIFO_CNT1_REG_OFFSET);
RETAILMSG(MDSMSG, (TEXT("UDGContext::ISTMain() - dwSetupPacketSize :0x%x\r\n"), dwSetupPacketSize));
if(dwSetupPacketSize >0) {
RETAILMSG(MDSMSG, (_T("TEST7\r\n")));
SetEvent(pContext->hevReadPending);
}
*/ }
else {
RETAILMSG(MDSMSG, (_T("UDGContext::ISTMain() - %s WaitForSingleObject failed. Exiting IST.\r\n")));
break;
}
}
// Disable Device interrupts - write Zeros to Disable
WriteReg(USB_INT_EN_REG_OFFSET, 0);
// Disable endpoint interrupts - write Zeros to Disable
WriteReg(EP_INT_EN_REG_OFFSET, 0);
// Clear any outstanding device & endpoint interrupts
// USB Device Interrupt Status - Write a '1' to Clear
WriteReg(USB_INT_REG_OFFSET, (USB_RESET_INTR | USB_RESUME_INTR | USB_SUSPEND_INTR));
// End point Interrupt Status - Write a '1' to Clear
WriteReg(EP_INT_REG_OFFSET, CLEAR_ALL_EP_INTRS);
}
return 0;
}
// Return the irq bit for this endpoint.
inline BYTE
UDGContext::EpToIrqStatBit(DWORD dwEndpoint)
{
return (1 << (BYTE)dwEndpoint);
}
/*++
Enable the interrupt of an endpoint.
Arguments: dwEndpoint - the target endpoint
Return Value: None.
--*/
inline VOID
UDGContext::EnableEndpointInterrupt(DWORD dwEndpoint)
{
FUNCTION_ENTER_MSG(dwEndpoint);
// End Point Zero is always enabled (after Run)
if (dwEndpoint == 0) {
FUNCTION_LEAVE_MSG(dwEndpoint);
return;
}
// Enable the Endpoint Interrupt
BYTE irqEnBit = EpToIrqStatBit(dwEndpoint);
SetClearReg(EP_INT_EN_REG_OFFSET, irqEnBit, SET);
FUNCTION_LEAVE_MSG(dwEndpoint);
} // _EnableEpInterrupt
/*++
Disable the interrupt of an endpoint.
Arguments: dwEndpoint - the target endpoint
Return Value: None.
--*/
inline VOID
UDGContext::DisableEndpointInterrupt(DWORD dwEndpoint)
{
// FUNCTION_ENTER_MSG(dwEndpoint);
// End Point Zero is always enabled (after Run)
if (dwEndpoint == 0) {
FUNCTION_LEAVE_MSG(dwEndpoint);
return;
}
// Disable the Endpoint Interrupt
BYTE irqEnBit = EpToIrqStatBit(dwEndpoint);
SetClearReg(EP_INT_EN_REG_OFFSET, irqEnBit, CLEAR);
// FUNCTION_LEAVE_MSG(dwEndpoint);
} // DisableEndpointInterrupt
/*++
Clear the interrupt status register index of an endpoint.
Arguments: dwEndpoint - the target endpoint
Return Value: None.
--*/
inline VOID
UDGContext::ClearEndpointInterrupt(DWORD dwEndpoint)
{
FUNCTION_ENTER_MSG(dwEndpoint);
// Clear the Endpoint Interrupt
BYTE bIntBit = EpToIrqStatBit(dwEndpoint);
WriteReg(EP_INT_REG_OFFSET, bIntBit);
FUNCTION_LEAVE_MSG(dwEndpoint);
} // _ClearInterrupt
// Reset an endpoint
inline VOID
UDGContext::ResetEndpoint(DWORD dwEndpointNumber)
{
FUNCTION_ENTER_MSG(dwEndpointNumber);
// Since Reset can be called before/after an Endpoint has been configured,
// it is best to clear all IN and OUT bits associated with endpoint.
DWORD dwEndpoint = dwEndpointNumber;
if(dwEndpoint == 0 ){
// Clear all EP0 Status bits
WriteIndexedReg(0, IN_CSR1_REG_OFFSET, (SERVICED_OUT_PKY_RDY | SERVICED_SETUP_END));
}
else if(dwEndpoint < ENDPOINT_COUNT)
{
// Clear the desired Endpoint - Clear both the In & Out Status bits
BYTE bRegIn;
BYTE bRegOut;
if(m_fInitialized){
// First Read the CSR2 Reg bit so that it can be restored
bRegIn = ReadIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET);
bRegOut = ReadIndexedReg(dwEndpoint, OUT_CSR2_REG_OFFSET);
}
// Clear the in register - Must set the Mode_in to IN
WriteIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET,(SET_MODE_IN | IN_DMA_INT_DISABLE));
WriteIndexedReg(dwEndpoint, IN_CSR1_REG_OFFSET, ( FLUSH_IN_FIFO | IN_CLR_DATA_TOGGLE));
// Clear the Out register - Must set the Mode_in to OUT
//WriteIndexedReg(pContext, dwEndpoint, IN_CSR2_REG_OFFSET, (IN_DMA_INT_DISABLE)); // mode_in bit = OUT
WriteIndexedReg(dwEndpoint, OUT_CSR1_REG_OFFSET, (FLUSH_OUT_FIFO | OUT_CLR_DATA_TOGGLE));
WriteIndexedReg(dwEndpoint, OUT_CSR2_REG_OFFSET, OUT_DMA_INT_DISABLE);
if(m_fInitialized){
// Set the Mode_In, ISO and other Modality type bits back to the way it was - this allows
// ResetEndpoint to be called without having to re-init the endpoint.
WriteIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET, bRegIn);
WriteIndexedReg(dwEndpoint, OUT_CSR2_REG_OFFSET, bRegOut);
}
}
else {
FUNCTION_LEAVE_MSG(dwEndpointNumber);
}
// Clear any outstanding Interrupts
// Note that Endpoint 0 WILL NOT BE DISABLED
DisableEndpointInterrupt(dwEndpointNumber);
FUNCTION_LEAVE_MSG(dwEndpointNumber);
}
// Reset the device and EP0.
inline VOID
UDGContext::ResetDevice(VOID)
{
// Disable Device interrupts - write Zeros to Disable
WriteReg(USB_INT_EN_REG_OFFSET, 0);
// Disable endpoint interrupts - write Zeros to Disable
WriteReg(EP_INT_EN_REG_OFFSET, 0);
// Clear any outstanding device & endpoint interrupts
// USB Device Interrupt Status - Write a '1' to Clear
WriteReg(USB_INT_REG_OFFSET, (USB_RESET_INTR | USB_RESUME_INTR | USB_SUSPEND_INTR));
// End point Interrupt Status - Write a '1' to Clear
WriteReg(EP_INT_REG_OFFSET, CLEAR_ALL_EP_INTRS);
// Reset all endpoints -> ENDPOINT_COUNT == 5(HLP)
for (DWORD dwEpIdx = 0; dwEpIdx < ENDPOINT_COUNT; ++dwEpIdx) {
ResetEndpoint(dwEpIdx);
}
}
// Write data to an endpoint.
DWORD
UDGContext::WriteEndpoint(DWORD dwEndpoint,
LPVOID pBuffer,
DWORD dwCount,
BOOL fEnableInterrupts)
{
BOOL fCompleted = FALSE;
DEBUGCHK(m_bInitialized);
DWORD dwWritten=0, dwRetWritten=0;
ULONG i=0;
__try {
volatile ULONG *pulFifoReg = GetDataRegister(dwEndpoint);
SetClearIndexedReg(dwEndpoint, IN_CSR2_REG_OFFSET, SET_MODE_IN, SET); //IN
BYTE *pbuf = (BYTE *) pBuffer;
RETAILMSG(MDSMSG, (_T("UDGContext::WriteEndpoint() - Endpoint Address: %x, dwCount: %d\r\n"),
pulFifoReg, dwCount));
for(i=0; i< (dwCount / FIFO_IN_PACKET_MAX_SIZE); i++)
{
RETAILMSG(MDSMSG, (_T("UDGContext::WriteEndpoint() - loop: %d\r\n"), i+1));
// if(fEnableInterrupts) EnableEndpointInterrupt(dwEndpoint);
// Write to the FIFO directly to send the bytes.
for (dwWritten = 0; dwWritten <FIFO_IN_PACKET_MAX_SIZE; dwWritten++) {
*pulFifoReg = (ULONG) *pbuf++;
}
dwRetWritten += dwWritten;
// DisableEndpointInterrupt(dwEndpoint);
// ClearEndpointInterrupt(dwEndpoint);
SetClearIndexedReg(dwEndpoint, IN_CSR1_REG_OFFSET, IN_PACKET_READY, SET);
// DisableEndpointInterrupt(dwEndpoint);
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
RETAILMSG(MDSMSG, (_T("UDGContext::WriteEndpoint() - EXCEPTION_EXECUTE_HANDLER\r\n")));
}
return dwRetWritten;
}
// Read data from an endpoint.
DWORD
UDGContext::ReadEndpoint(DWORD dwEndpoint,
LPVOID pBuffer,
DWORD dwCount)
{
BOOL fCompleted = FALSE;
DWORD dwBytesRead=0, dwRetBytesRead=0;
ULONG i=0;
__try {
volatile ULONG *pulFifoReg = GetDataRegister(dwEndpoint);
BYTE *pbuf = (BYTE *) pBuffer;
RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - Endpoint Address: %x, dwCount: %d\r\n"),
pulFifoReg, dwCount));
for(i=0; i< (dwCount / FIFO_OUT_PACKET_MAX_SIZE); i++)
{
// RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - loop: %d\r\n"), i+1));
// Read From the FIFO
for(dwBytesRead = 0; dwBytesRead < FIFO_OUT_PACKET_MAX_SIZE; dwBytesRead++) {
pbuf[dwBytesRead] = (UCHAR) *pulFifoReg;
}
RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - %s \r\n"), pbuf));
dwRetBytesRead += dwBytesRead;
if(dwEndpoint != 0) {
//Clear Receive Packet Complete - Allow next packet to come in.
BYTE bEpIrqStat = ReadIndexedReg(dwEndpoint, OUT_CSR1_REG_OFFSET);
if (bEpIrqStat & OUT_PACKET_READY) {
SetClearIndexedReg( dwEndpoint, OUT_CSR1_REG_OFFSET, OUT_PACKET_READY, CLEAR);
}
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
RETAILMSG(MDSMSG, (_T("UDGContext::ReadEndpoint() - EXCEPTION_EXECUTE_HANDLER\r\n")));
}
return dwRetBytesRead;
}
DWORD
UDGContext::StartTransfer(PVOID pvContext,
LPVOID pBuffer,
DWORD dwCount,
DWORD dwEndpoint)
{
LOCK_ENDPOINT(dwEndpoint);
DWORD dwRet=0;
PCTRLR_CONTEXT pContext = (PCTRLR_CONTEXT)pvContext;
if (IN_TRANSFER == dwEndpoint) { //send
dwRet = WriteEndpoint(dwEndpoint, pBuffer, dwCount, FALSE);
}
else if (OUT_TRANSFER == dwEndpoint) { //receive
// Set the Max Packet Size Register
WriteIndexedReg(dwEndpoint, MAX_PKT_SIZE_REG_OFFSET, 4);//(FIFO_OUT_PACKET_MAX_SIZE >> 3)); //0x4(32byte)
EnableEndpointInterrupt(dwEndpoint);
/////////////
RETAILMSG(MDSMSG, (_T("TEST11111\r\n")));
WaitForSingleObject(pContext->hevReadPending, INFINITE);
///////
// There may be a packet available. If so process it...
BYTE bEpIrqStat = ReadIndexedReg(dwEndpoint, OUT_CSR1_REG_OFFSET);
if (bEpIrqStat & OUT_PACKET_READY) {
dwRet = ReadEndpoint(dwEndpoint, pBuffer, dwCount);
}
/////////
InterruptDone(pContext->dwSysIntr);
ResetEvent(pContext->hevReadPending);
///////////
}
UNLOCK_ENDPOINT(dwEndpoint);
return dwRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -