smckbpdd.cpp

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C++ 代码 · 共 2,209 行 · 第 1/5 页

CPP
2,209
字号
//  Take out two's complement for negative "y" values: they are positive in the frame buffer 
        dyIr = (dyIr - 1) ^ 0x000000FF;  
//  Check if equals 0
    else if (dyIr == 0x00)                
            dyIr = 0x00;
          //must also make positive keyboard values negative (2's comp) for screen
          else                            
          {
            dyIr = (dyIr ^ 0x000000FF) + 1;
            dyIr |= 0xFFFFFF00;
          }

    //CALLBACK to O/S
    mouse_event( dwFlagIr, dxIr, dyIr, 0, 0 );  

//  Clean up for next time through
    Event_devIdLast = mouse_event_ID ;
    dxIr = 0x00; 
    dyIr=0x00;  
    dwFlagIr = 0x00;

#endif
        }

        ////////////////////////////////////////////////
        //
        // Re-enable buffer for reception
        //

        rbd->bd_status |= RBD_EMPTY;

        ////////////////////////////////////////////////
        //
        // Adjust InProcess BD pointer for wrap
        //

        if( smc->ProcRxBD == smc->LastRxBD )
        {
          DEBUGMSG(ZONE_EVENT_HANDLER_DEBUG,
            (TEXT("KeybdPdd_GetEvent: Rx BD pointer reset !!!!!\r\n") ) );
          smc->ProcRxBD = smc->RxBDbase;
        }
        else
        {
          DEBUGMSG(ZONE_EVENT_HANDLER_DEBUG,
            (TEXT("KeybdPdd_GetEvent: Rx BD pointer adjustment !!!!!\r\n") ) );
          smc->ProcRxBD += 1;
        }

#ifdef SMC_KBD_DEBUG
        smc->pkt_count++;
#endif
//  If all of the data has NOT been processed in the DP-Ram, go back and continue to process
//  Repeat this until the BD queue is empty.  This code fixed the delay effect in the mouse.

        rbd = smc->ProcRxBD;
        if( !(rbd->bd_status & RBD_EMPTY) )
        {
            DEBUGMSG(ZONE_EVENT_HANDLER_DEBUG, 
                (TEXT("next_bd\r\n")));
            goto next_bd;
        }
        if( ! status_ok )
        {
            v_PrevKeyScanCode = 0;

            SMCKBD_DEBUG(
                smc,
                "SmcKbd_GetEvent: Rx Error OR Out Of Sync Error !!!!!\r\n" );

            DEBUGMSG(ZONE_EVENT_HANDLER_DEBUG, 
          (TEXT("KeybdPdd_GetEvent: Rx Error OR Out Of Sync Error !!!!!\r\n")));

            // Errors are ignored here.  An error counter could be
            // implemented in the driver and the channel could be
            // reset if a certain number of errors occurred, but
            // this would normally indicate a hardware problem.

            // ASSERT( FALSE );   // for now
            // SmcKbd_ErrorReset( smc );
        }

    }    // end Rx Event handling

    //////////////////////////////////////////////////////////////
    //
    // Check for transmit event
    //

    if( smcEvent & EVENT_TX )
    {
        // Verify that this Tx event was expected
        // If not, dump error message.

        if( ! smc->txEventExpected )
        {
            SMCKBD_DEBUG( smc, "Unexpected Tx Event!\r\n" );
        }
        else
        {
            smc->txEventExpected = FALSE;    // clear flag

            DEBUGMSG( ZONE_EVENT_HANDLER_DEBUG, 
              ( TEXT("Clearing Tx Event Flag\r\n") ) );
        }

        // Clear event(s) at end of event handler
    }

    //////////////////////////////////////////////////////////////
    //
    // Check for error event
    //

    if( smcEvent & (EVENT_BUSY | EVENT_BRK | EVENT_BRKE) )
    {
        DEBUGMSG(ZONE_ERROR, ( TEXT("Event Errors being processed . . .\r\n")));
        // Clear event(s) at end of handler

        if( smcEvent & EVENT_BUSY )
            SMCKBD_DEBUG( smc, "BUSY Error detected\r\n" );
        if( smcEvent & EVENT_BRK )
            SMCKBD_DEBUG( smc, "BREAK Error detected\r\n" );
        if( smcEvent & EVENT_BRKE )
            SMCKBD_DEBUG( smc, "BREAK_END Error detected\r\n" );

        // Errors are ignored here.  An error counter could be
        // implemented in the driver and the channel could be
        // reset if a certain number of errors occurred, but
        // this would normally indicate a hardware problem.

        // go to error_reset;
    }

    //
    // Ack the interrupt(s) as required.
    //
    // Clear event(s)
    //
    smc->RegsPtr->smc_smce = smcEvent;

    DEBUGMSG(ZONE_EVENT_HANDLER_DEBUG, (TEXT("KeybdPdd_GetEvent: Exit\r\n")));

    return nEvents;
}



////////////////////////////////////////////////////////////////////////////////
//
//  @doc EXTERNAL
//
//  @func
//
//  Called by the MDD on system power state changes.
//
//  @ comm
//  
//  This routine runs in kernel context and assumes that interrupts are
//  disabled since it monkeys directly with registers.  It may not make
//  any system calls or cause a reschedule in any way.  You can read and
//  write to your own memory and that is about it.  If you put any 
//  subroutines inside here, they must also follow this restriction.
//
//  @parm   TRUE, the system is powering off; 
//          FALSE, the system is powering up.
//
////////////////////////////////////////////////////////////////////////////////

void WINAPI 
KeybdPdd_PowerHandler(
    BOOL    bOff
    )
{
    return;
}


////////////////////////////////////////////////////////////////////////////////
//
//  @doc EXTERNAL
//
//  @func
//
//  Called by the MDD on Dll state changes. 
//
//  @parm   HANDLE hinstDLL:  Standard Dll entry arg 
//  @parm   DWORD Op:  Standard Dll entry arg 
//  @parm   LPVOID lpvReserved:  Standard Dll entry arg 
//
////////////////////////////////////////////////////////////////////////////////

BOOL WINAPI KeybdPdd_DllEntry(
    HANDLE  hinstDLL,        
    DWORD   Op,              
    LPVOID  lpvReserved      
    )
{
    return TRUE;
}



////////////////////////////////////////////////////////////////////////////////
//
//  @doc EXTERNAL
//
//  @func
//
//  The SMCx is initialized as an UART at 9600 Baud.
//
//  @parm   SMC_CHANNEL structure pointer
//
//  @rdesc  Return TRUE if SMC is initialized as a UART.
//          Otherwise, return FALSE.
//
////////////////////////////////////////////////////////////////////////////////

BOOLEAN
SmcKbd_SmcInit(
    SMC_CHANNEL *smc
    )
{

    DEBUGMSG(ZONE_FUNCTION, (TEXT("SmcKbd_SmcInit: Entry\r\n")));
    DEBUGMSG( ZONE_INIT, ( TEXT("SMC_CHANNEL Pointer = %08x\r\n"), smc ) );

    /*
     * get pointer to MPC8xx internal register map
     *************************************************
     */
    IMM *immr = (IMM *) v_pDPRam;
    DEBUGMSG( ZONE_INIT, ( TEXT("IMMR = %8x\r\n"), immr ) );


    /**************************************
     * Get pointer to BD area in DPRAM
     **************************************/


////////////////////////////////////////////////////////////////////////
// Use Internal Data buffers (in Dual Port RAM)
////////////////////////////////////////////////////////////////////////

    DEBUGMSG(ZONE_INIT, 
      (TEXT("SmcKbd_SmcInit: INTERNAL DATA BUFFERS being used!!!\r\n")));


    DEBUGMSG(ZONE_INIT, 
      (TEXT("SmcKbd_SmcInit: OEM_DRIVER_ALLOC_MEM_AVAILABLE\r\n")));

    OEM_IOCTL_INT_MEM_REQUEST dpramRequest;

    // allocate space for BDs

    dpramRequest.MemoryType = MEMORY_BD;
    dpramRequest.NumberOfBytes = sizeof(RTXBD);

    DWORD dpramOffset = 0xffff;
    DWORD dpramSize = 0x0;

    // Note:  OEM_IOCTL_ALLOC_MEM returns 8-byte aligned address, as 
    // required by the RBASE and TBASE entries of this BD, (see pg. 16-338
    // of the MPC821 User's Manual, para. 16.15.4.1, "BD Table Pointer")

    if( ! KernelIoControl(
            OEM_IOCTL_ALLOC_MEM,
            &dpramRequest,
            NOTUSED,
            &dpramOffset,
            NOTUSED,
            &dpramSize
            ) )
    {
        DEBUGMSG( ZONE_ERROR, ( TEXT("BD Allocation Failure -\r\n") )); 
        DEBUGMSG( ZONE_ERROR, 
          ( TEXT("- Returned Offset = %04x - Size = %04 -\r\n"),
                dpramOffset, dpramSize ) );

        return( FALSE );
    }

    DEBUGMSG( ZONE_INIT, 
      (TEXT("KernelIoControl returned dpramOffset = %04x and Size = %04x.\r\n"),
                                                    dpramOffset, dpramSize));


    // virtual BD struct pointer
    RTXBD *v_rtx = (RTXBD *) ((unsigned char *)v_pDPRam + dpramOffset); 
    // physical BD struct pointer
    RTXBD *p_rtx = (RTXBD *) ((unsigned char *)p_pDPRam  + dpramOffset); 


    DEBUGMSG( ZONE_INIT, 
              (TEXT("Virtual BD/Buffer Area (v_rtx) = %8x\r\n"), v_rtx ) );
    DEBUGMSG( ZONE_INIT, 
              (TEXT("Physical BD/Buffer Area (p_rtx) = %8x\r\n"), p_rtx ) );



#ifdef SMC_KBD_DEBUG

    // save BD structure pointers

    smc->v_rtxbd_ptr = (unsigned char *) v_rtx;    // virtual
    smc->p_rtxbd_ptr = (unsigned char *) p_rtx;    // physical

#endif

    /*******************************************************
     * System configuration dependent parameter variables
     *******************************************************/

    smc->SmcNum = FW_DEFAULT_KBD_SMC;

    DEBUGMSG( ZONE_INIT, 
      ( TEXT("SMC Channel #%8x Being Used for Keyboard\r\n"), smc->SmcNum ) );



    /*********************************************************************
     * Set Baud Rate to 9600 Baud because IR rcvr only works at 9600,
     * and enable BRG. 
     ********************************************************************/

    BAUD_RATE_DATA kbdBaudRateData;

    kbdBaudRateData.Action = NEW_BRG + SET_BAUD_RATE + ENABLE_BRG;
    kbdBaudRateData.BaudRate = 9600;
    kbdBaudRateData.Multiplier = 16; // See last paragraph on pg. 16-142
    kbdBaudRateData.Generator = -1;
    if (smc->SmcNum == 1) {
        kbdBaudRateData.Device = SMC1;
    }
    else {
        kbdBaudRateData.Device = SMC2_PIP;
    }


    if (!KernelIoControl(
            OEM_IOCTL_SET_BAUD_RATE, 
            &kbdBaudRateData, 
            NOTUSED, 
            &(smc->BRGCnum), 
            NOTUSED, 
            NOTUSED
        )) 
    {
        DEBUGMSG( ZONE_ERROR, ( TEXT("BRG Allocation Failure -\r\n")));
        return(FALSE);
    }

/*
    DEBUGMSG( ZONE_INIT, 
(TEXT("KernelIoControl(OEM_IOCTL_SET_BAUD_RATE...): Returned pGen= %04x\r\n"), 
smc->BRGCnum) );
*/

    //
    // set up parameters based on SMC channel number / token
    //

    switch( smc->SmcNum )
    {
    case 1:
#ifndef OEM_DRIVER_PORT_PINS_AVAILABLE
        smc->PortpinMask = SMC1_PORT_B_PINS;
#endif
        smc->CpmChNum = SMC1_CH_NUM;
        smc->PramOffset = SMC1_PRAM;
        smc->RegsOffset = SMC1_REGS;
        smc->SiModeShift = SIMODE_SMC1_SHIFT;
#if (defined(MOTO_ADS) || defined(MOTO_FADS)) 
        smc->Rs232Enable = ADS_SMC1_RS232_EN_MASK;
#endif
#if (defined(SDB_RPXL) || defined(SDB_CLLF)) 
        smc->Rs232Enable = BCSR0_ENMONXCVR;
#endif
        break;

    case 2:
#ifndef OEM_DRIVER_PORT_PINS_AVAILABLE

#if (defined(MOTO_821) || defined(MOTO_860)) 
        smc->PortpinMask = SMC2_PORT_B_PINS;
#endif

#if (defined(MOTO_823) || defined(MOTO_850)) 
        smc->PortpinMask = SMC2_PORT_A_PINS;
#endif
#endif
        smc->CpmChNum = SMC2_CH_NUM;
        smc->PramOffset = SMC2_PRAM;
        smc->RegsOffset = SMC2_REGS;
        smc->SiModeShift = SIMODE_SMC2_SHIFT;
#if (defined(MOTO_ADS) || defined(MOTO_FADS)) 
        smc->Rs232Enable = ADS_SMC2_RS232_EN_MASK;
#endif
#if (defined(SDB_RPXL) || defined(SDB_CLLF)) 
        smc->Rs232Enable = HIOX_BCSR0_EN232SMC2XCVR;
#endif
        break;

    default:
        SMCKBD_DEBUG(smc, "Invalid SMC Number\r\n");
        return(FALSE);
    }

    /*********************************************************************
     * Set up Port B to Allow SMC TX, RX out -- Table 16-40
     *********************************************************************
     * NOTE: Need a way to know whether port B is available for SMC2
     *        or if parallel port is using these lines.
     *        If NOT, fail driver init.
     *********************************************************************/

unsigned long result, size;

RMW_OP  rmwOp;

// Modify value of Port pin assignment register to configure Port pins 
// as on-chip peripheral pins, (for SMC), rather than general-purpose 
// I/O pins.   smc->PortpinMask sets either PB24/B25, PB20/PB21 or PA8/A9, 
// depending on which SMC  and processor we are using.
// (See pg. 16-454, Table 16-40: MPC821 User's Manual Port B Pin Assignment)
// (See pg. 16-469, Table 16-41: MPC823 User's Manual Port A Pin Assignment)

    switch( smc->SmcNum )
    {
    case 1:
        rmwOp.Address = (PVOID) (&(immr->pip_pbpar));
        rmwOp.Size = sizeof(immr->pip_pbpar);
        break;

    case 2:
        #if defined ( MOTO_823 ) || defined ( MOTO_850 )
           rmwOp.Address = (PVOID) (&(immr->pio_papar));
           rmwOp.Size = sizeof(immr->pio_papar);
        #endif

        #if defined ( MOTO_821 ) || defined ( MOTO_860 )
           rmwOp.Address = (PVOID) (&(immr->pip_pbpar));

⌨️ 快捷键说明

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