⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmdx500.cpp

📁 WinCE5.0部分核心源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
// Copyright 2001, Cisco Systems, Inc.  All rights reserved.
// No part of this source, or the resulting binary files, may be reproduced,
// transmitted or redistributed in any form or by any means, electronic or
// mechanical, for any purpose, without the express written permission of Cisco.
//---------------------------------------------------------------------------
// CmdX500.cpp
//---------------------------------------------------------------------------
// Description:
//
// Revision History:
//
// Date         
//---------------------------------------------------------------------------
// 09/22/00     jbeaujon        -modified cmdConfigSet, cmdSSIDSet, cmdAPsSet so 
//                               that if the second parameter is NULL, we use the
//                               copy stored in card.
// 11/10/00     jbeaujon        -In AckCommand: clear the EVNT_STAT_CMD bit in
//                               card->m_IntActive so we don;t ack the same 
//                               command twice.
//
// 06/05/01     spb009          -Send the disconnect status when we disable the
//                               Radio
//
// 06/12/01     spb010          -Make sure the buffer is an even number of bytes
//                               during a RidSet and RidGet 
//
//---------------------------------------------------------------------------

#pragma code_seg("LCODE")
#include "NDISVER.h"
extern "C"{
    #include    <ndis.h>
}

extern ULONG fidCounter;
#include "CmdX500.h"
#include "support.h"
#include "memory.h"
#include "Airodef.h"
#include "CardX500.h"


BOOLEAN         
exec(PCARD card)
{
    return(exec(card, 100));
}

BOOLEAN         
exec(PCARD card, int delay )

{
    if( !WaitBusy(card, 10 ) ) {
        return FALSE;
        }
            
    if ( ! WaitLastCmd( card, delay ) ) {
        return FALSE;
        }

    WriteCommand( card );
    CmdRestoreInterrupts(card);

    return TRUE;
}

BOOLEAN         
exec(PCARD card, int delay, USHORT p0 )
{
    if( !WaitBusy(card, 10 ) ) {
        return FALSE;
        }
            
    if ( ! WaitLastCmd( card, delay ) ) {
        return FALSE;
        }

    WriteCommand( card, p0 );
    CmdRestoreInterrupts(card);

    return TRUE;
}

BOOLEAN         
WaitComplete(PCARD card, int delay)// delay in us, 1 second default          
{
#ifndef CE_FLAG_USE_NDISM_SLEEP
    for( ; ! IsCmdComplete(card) && delay > 0; delay -=10 ){
        DelayUS( 10 );
    }   

#else
    //
	//	CE can't guarantee granularity of < 1 ms.
	//

	for( ; ! IsCmdComplete(card) && delay > 0; delay -=1000 ){
        DelayUS( 1000 );
    } 

#endif

    if( ! IsCmdComplete(card) ) {
        return FALSE;
        }
    
    return TRUE;
}

BOOLEAN         
WaitAllocComplete(PCARD card, int delay )
{
    while( ! IsAllocComplete(card) && --delay ){
        DelayMS( 1 );
    }
    
    if( ! IsAllocComplete(card) )
        return FALSE;
    
    return TRUE;
}

CMD_STATUS_X500 
GetCmdStatus(PCARD card, CMD_X500 cmd )
{
    USHORT  usWord;
    
    NdisRawReadPortUshort( card->m_IOBase+REG_CMD_STATUS, &usWord );

    if ( 0xFFFF != cmd && (0x3f & cmd) != (usWord & 0x3f) ){
        return CMD_STATUS_NOTCMD;
    }   
    if ( 0x0000 == (usWord & 0x7F00) )
        return CMD_STATUS_SUCCESS;

    if ( 0x0100 == (usWord & 0x7F00) )
        return CMD_STATUS_NOTASSOC;

    if ( 0x0200 == (usWord & 0x7F00) )
        return CMD_STATUS_FAILURE;

    if ( 0x3F00 == (usWord & 0x7F00) )
        return CMD_STATUS_CMDERROR;

    return CMD_STATUS_UKNOWNERROR;
}

void            
WriteCommand(PCARD card )
{
    card->m_PrevCmdTick = 1;
    card->m_PrevCmdDone = FALSE;
    NdisRawWritePortUshort( card->m_IOBase+REG_CMD, card->m_cmd );
    card->m_PrevCommand = card->m_cmd;
}

void            
WriteCommand(PCARD card, USHORT p0 )
{
    NdisRawWritePortUshort( card->m_IOBase+REG_CMD_P0, p0 );
    WriteCommand(card);
}

void            
GetResponce(PCARD card, USHORT *p0,USHORT *p1,USHORT *p2)
{
    if( p0 )    ReadRespParam( card, (REGX500)(card->m_IOBase+REG_CMD_RESP0) , p0 );                        
    if( p1 )    ReadRespParam(  card, (REGX500)(card->m_IOBase+REG_CMD_RESP1), p1 );                        
    if( p2 )    ReadRespParam(  card, (REGX500)(card->m_IOBase+REG_CMD_RESP2), p2 );                        
}

BOOLEAN         
IsCmdReady(PCARD card)           
{
    USHORT  usWord;
    NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
    return 0 == (0x8000&usWord);
}

BOOLEAN         
IsEventAllocReady(PCARD card)
{
    USHORT  usWord;
    NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
    return  0 != (0x0008&usWord);
}

BOOLEAN         
IsResponceReady(PCARD card)
{
    USHORT  usWord;
    NdisRawReadPortUshort( card->m_IOBase+REG_CMD_STATUS, &usWord );
    return  0 != (0x8000&usWord);
}

BOOLEAN         
IsCmdComplete(PCARD card)
{
    USHORT  usWord;
    if( card->m_PrevCmdDone )
        return TRUE;
    
//  if( ! card->m_IsPolling )
//      return FALSE;

    NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
    
    if( EVNT_STAT_CMD & usWord ){
        AckCommand(card);
        return TRUE;
    }
    return FALSE;
}

BOOLEAN         
IsAllocComplete(PCARD card)
{
    USHORT  usWord;
    NdisRawReadPortUshort( card->m_IOBase+REG_INT_STAT, &usWord );
    return EVNT_STAT_Alloc & usWord;
}

void            
AckCommand(PCARD card)
{
    NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, EVNT_ACK_CMD );
    // 
    // Clear the command bit in our copy in case we get here before cbHandleInterrupt()
    // gets invoked.  (jbeaujon  11/09/00)
    // 
    card->m_IntActive &= ~EVNT_STAT_CMD;

    card->m_PrevCmdDone = TRUE;
}

void            
AckAlloc(PCARD card)
{
    NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, EVNT_ACK_Alloc );
}
/*
BOOLEAN         
WaitBusy(PCARD card, int us)
{
    USHORT  usWord = 0xFFFF;
    int delay = 0; 
    while( (usWord & 0x8000) && delay <= us){
        DelayUS(2);
        delay   += 2;
        NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
    }
    return 0 == (0x8000&usWord);
}
*/
void            
UnstickBusyCommand(PCARD card )
{
    USHORT  usWord;
    NdisRawWritePortUshort( card->m_IOBase+REG_INT_ACK, 0x4000 );
    NdisRawReadPortUshort( card->m_IOBase+REG_CMD,  &usWord );
    if( 0x7FFF & usWord && 0==(0x8000 & usWord))
        NdisRawWritePortUshort( card->m_IOBase+REG_CMD, usWord );
}

BOOLEAN         
WaitBusy(PCARD card, int us)
{
    USHORT  usWord = 0xFFFF;
    int     timeout = 1000 * 100;   // 100 milliseconds
    int delay = 0; 
    
    while( (usWord & 0x8000) && delay <= timeout){
#ifndef CE_FLAG_USE_NDISM_SLEEP
        DelayUS(10);
        delay   += 10;
#else
		//
		//	CE can't guarantee granularity of < 1 ms.
		//

		DelayUS(1000);
		delay	+= 1000;
#endif
        NdisRawReadPortUshort( card->m_IOBase+REG_CMD, &usWord );
        
        if( (0x8000 & usWord) && 0==(delay%200) ){
            UnstickBusyCommand(card);
            card->m_PrevCmdDone = TRUE;
        }
    }
    return 0 == (0x8000&usWord);
}

BOOLEAN         
WaitLastCmd(PCARD card, int delay)
{
    BOOLEAN res;    
    int tmp = 0;  

    while( !(res = IsCmdComplete(card))&& tmp <= delay ){ 
        tmp += 10;
        DelayUS( 10 );
    }   
    
    if( ! res ) {
        return FALSE;
        }

    CmdDisableInterrupts(card);
    
    tmp = delay - tmp;  
    while( !(res = IsCmdComplete(card))&& tmp <= delay ){ 
        tmp += 10;
        DelayUS( 10 );
    }

    if ( ! res ){
        CmdRestoreInterrupts(card);     
        return FALSE;
    }
    
    return  TRUE;
}
#if 1
//BOOLEAN IsBapStuck(int IOBase, USHORT BapRegSel );
//void BapStuck(int IOBase,  USHORT BapRegSel, USHORT fid, USHORT off );

BOOLEAN IsBapStuck(int IOBase, USHORT BapRegSel )
{
    USHORT  usWord;
    NdisRawReadPortUshort( IOBase+BapRegSel, &usWord ); 
    return 0==usWord;   
}
void BapStuck(PCARD card, USHORT BapRegSel, USHORT fid, USHORT off )
{
//  1) disable interrupts
//  2) rewrite the Selector
//  3) rewrite the Offset
//  4) read SwSupport0
//  5) write SwSupport1     // -- this step MAY not actually be necessary
//  6) reenable interrupts
//  7) wait for busy to become unstuck
//  8) restart the entire bap access
    

    USHORT  usWord;
    USHORT  usInt;
    NdisRawReadPortUshort(card->m_IOBase+REG_INT_EN, &usInt );  // read ints enable
    NdisRawWritePortUshort(card->m_IOBase+REG_INT_EN, 0 );      // disable ints
    //spb024
    //If m_IntActive is set, then it means we got an interrupt after
    //reading active interrupts but before we were able to disable
    //interrupts.  Therefore interupts really should be disabled
    //when we return from this routine. 
    //Trust me this happens.  (Caused lost fids at Microsoft)
    if (card->m_IntActive) {
        usInt=0;
    }
    
    NdisRawWritePortUshort(card->m_IOBase+BapRegSel, fid );     
    NdisRawWritePortUshort(card->m_IOBase+BapRegSel+4, off );

    NdisRawReadPortUshort(card->m_IOBase+REG_SWS0, &usWord );  
    NdisRawWritePortUshort(card->m_IOBase+REG_SWS1, 0 );
                        
    NdisRawWritePortUshort(card->m_IOBase+REG_INT_EN, usInt );      // renable

    NdisRawWritePortUshort(card->m_IOBase+BapRegSel, fid );
    NdisRawWritePortUshort(card->m_IOBase+BapRegSel+BAPOFF_OFFSET_BAPX, off );
}

#endif

BOOLEAN         
BapSet(PCARD card, USHORT BAPOff, FID fid, int FidOff)
{
    USHORT  offValue;   
    int     delay = 0;  
    int     stuck = 0;
    
    while( delay <= 3000 ) {
        
        NdisRawWritePortUshort( card->m_IOBase+BAPOff, fid );
        NdisRawWritePortUshort( card->m_IOBase+BAPOff+BAPOFF_OFFSET_BAPX, (USHORT)FidOff );

        do {
            
            DelayUS( 25 );
            delay += 25;
            NdisRawReadPortUshort( card->m_IOBase+BAPOff+BAPOFF_OFFSET_BAPX, &offValue );
            
            if( IsFidRdy(offValue) )
                return TRUE;

            if( 300 <= stuck ){
                BapStuck(card, BAPOff, fid, (USHORT)FidOff );
                stuck =25;
                continue;
            }
            stuck +=25;
            
        }while( IsFidBusy(offValue) && 1000 >= delay );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -