smckbpdd.cpp

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

CPP
2,209
字号
           rmwOp.Size = sizeof(immr->pip_pbpar);
        #endif
        break;
    }


    rmwOp.AndMask = ~(smc->PortpinMask); 
    rmwOp.OrMask = smc->PortpinMask; 

    KernelIoControl(OEM_IOCTL_RD_MODIFY_WRT, 
                    &rmwOp, 
                    NOTUSED, 
                    &result, 
                    NOTUSED, 
                    &size);


// Modify value of Port data direction register to
// select what the SMC is used for.  ~smc->PortpinMask re-sets either
// PB24/PB25, PB20/PB21 or PA8/A9 (depending on which SMC and processor
// we are using), to 0, to choose RX, TX out.

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

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

        #if defined ( MOTO_821 ) || defined ( MOTO_860 )
            rmwOp.Address = (PVOID) (&(immr->pip_pbdir));
            rmwOp.Size = sizeof(immr->pip_pbdir);
        #endif


        break;
    }

    rmwOp.AndMask = ~smc->PortpinMask; 
    rmwOp.OrMask = 0; 

    KernelIoControl(OEM_IOCTL_RD_MODIFY_WRT, 
                    &rmwOp, 
                    NOTUSED, 
                    &result, 
                    NOTUSED, 
                    &size);


    // The SMCx clock source is defined at the same relative offset 
    // of each 16-bit half of the SI mode register, (see pg. 16-113).  
    // Thus, the BRG value is first shifted left by SIMODE_SMCxCS_SHIFT, 
    // and then shifted left by the value defined in smc->SiModeShift, 
    // to put the BRGC value in bits 1-3 for SMC2, or bits 17-19 for SMC1.

    // NOTE:  smc->BRGCnum (and 821 UM) number BRGC's from 1. (pg. 16-113)
    //        smc->SiModeBrgSelect counts BRG's starting from 0.

    smc->SiModeBrgSelect = (smc->BRGCnum - 1) << SIMODE_SMCxCS_SHIFT;

    /*
     * SCM:  NMSI mode, Tx/Rx Clocks are BRGx
     */

    /* Modify value of immr->si_simode */

    rmwOp.Address = (PVOID) (&(immr->si_simode));
    rmwOp.Size = sizeof(immr->si_simode);
    rmwOp.AndMask = ~(SIMODE_SMC_MODE_BRG_MASK << smc->SiModeShift);
    rmwOp.OrMask = (smc->SiModeBrgSelect << smc->SiModeShift);

    KernelIoControl(OEM_IOCTL_RD_MODIFY_WRT, 
                    &rmwOp, 
                    NOTUSED, 
                    &result, 
                    NOTUSED, 
                    &size);


    /*
     * Set Pointer to SMC PRAM
     */

    smc->PramPtr =
        &(immr->pram[smc->PramOffset].scc.pothers.smc_modem.psmc.u);

    DEBUGMSG( ZONE_INIT, ( TEXT("PRAM Pointer = %08x\r\n"), smc->PramPtr ) );

    /*
     * Set RXBD Buffer Descriptor Ring start for CPM
     *
     *  SMC_PRAM->rbase is the 16-bit offset into the 821 DualPort
     *  RAM where the first Buffer Descriptor in the Rx BD ring is
     *  located.
     */

    smc->PramPtr->rbase = (unsigned short) & p_rtx->rxbd[0];
    smc->PramPtr->rbptr = smc->PramPtr->rbase;

    /*
     * Set RXBD Buffer Descriptor Ring start for CPU
     */

    smc->RxBDbase = smc->ProcRxBD = (SMC_BD *) & v_rtx->rxbd[0];

    DEBUGMSG( ZONE_INIT, 
      ( TEXT("Virtual RX BD base Pointer = %08x\r\n"), smc->RxBDbase ) );

    /*
     * Set TXBD Buffer Descriptor Ring start in PRAM parm "tbase" -
     *  SMC_PRAM->tbase is the 16-bit offset into the 821 DualPort
     *  RAM where the first Buffer Descriptor in the Tx BD ring is
     *  located.
     */

    smc->PramPtr->tbase = (unsigned short) & p_rtx->txbd[0];
    smc->PramPtr->tbptr = smc->PramPtr->tbase;

    DEBUGMSG( ZONE_INIT, 
      ( TEXT("TX BD tbase /(offset/) = %08x\r\n"), smc->PramPtr->tbase ) );

    smc->TxBDbase = smc->ProcTxBD = (SMC_BD *) & v_rtx->txbd[0];

    DEBUGMSG( ZONE_INIT, 
      ( TEXT("Virtual TX BD base Pointer = %08x\r\n"), smc->TxBDbase ) );

    /*
     * Set TXBD Buffer Descriptor Ring start
     */

    smc->LastRxBD = &( (smc->RxBDbase)[NUMBER_RX_BUFFERS - 1] );
    smc->LastTxBD = &( (smc->TxBDbase)[NUMBER_TX_BUFFERS - 1] );

    /*
     * Save pointer to PRAM current BD parameter "rbptr/tbptr"
     */
    smc->CurRxBDptr = &(smc->PramPtr->rbptr);
    smc->CurTxBDptr = &(smc->PramPtr->tbptr);


   /*
    * Issue command to Initialize Rx and Tx Params for SMCx (set FLG bit).
    * Spin until CPCR FLG bit is cleared (command complete).
    */

    if( !KernelIoControl(
            OEM_IOCTL_ISSUE_CPM_CMD,
            (LPVOID) smc->CpmChNum,
            INIT_RX_TX_PARAMS,
            NOTUSED,
            NOTUSED,
            NOTUSED
            ) )
    {
        DEBUGMSG(ZONE_ERROR, 
       (TEXT("SmcKbd_SmcInit: KernelIoControl error issuing CPM command\r\n")));

        DEBUGMSG(ZONE_ERROR, (TEXT("SmcKbd_SmcInit: Error Exit\r\n")));

        return( FALSE );
    }


   /* 
    * Set the function code for RX and TX (PowerPC Big Endian mode)
    */

// INTERNAL BUFFERS

    smc->PramPtr->rfcr = SMC_FC_BO_MOT;
    smc->PramPtr->tfcr = SMC_FC_BO_MOT;

    /*
     *  Protocol (SMC UART) Specific Parameter Ram Setup
     *
     *  - mblr ---- Max buffer length
     *  - max_idl - Max idle time (character times) - 0 = Disable
     *  - brkln --- Last received break length (char times)
     *  - brkec --- Number of break conditions detected (any length)
     *  - brkcr --- Number of break chars sent on STOP TX command
     */

    /* set max receive buffer size for single character/event packet */
    smc->PramPtr->mrblr = 4;

    /* Disable idle checking */
    smc->PramPtr->max_idl = 0;

    /* Clear CPM updated counts */
    smc->PramPtr->brkln = 0;
    smc->PramPtr->brkec = 0;

    /* Single break on StopTx */
    smc->PramPtr->brkcr = 1;

    /*
     * Allocate and/or Init Receive/Transmit Buffer Space
     */


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


    OEM_IOCTL_INT_MEM_REQUEST dbRequest;

    // set up memory request for RECEIVE data buffer 
 
    dbRequest.MemoryType = MEMORY_DATA;
    dbRequest.NumberOfBytes = 
                    sizeof(unsigned char) * RX_BUFFER_SIZE * NUMBER_RX_BUFFERS;

    DWORD dbOffset = 0xffff;
    DWORD dbSize = 0x0;


    if( ! KernelIoControl(
            OEM_IOCTL_ALLOC_MEM,
            &dbRequest,
            NOTUSED,
            &dbOffset,
            NOTUSED,
            &dbSize
            ) )
    {
        DEBUGMSG( ZONE_ERROR, 
          ( TEXT("Rcv Data Buffer Allocation Failure -\r\n") )); 
        DEBUGMSG( ZONE_ERROR, 
          ( TEXT("- Returned Offset = %04x - Size = %04 -\r\n"),
                dbOffset, dbSize ) );

        return( FALSE );
    }

    DEBUGMSG( ZONE_INIT, 
(TEXT("KernelIoControl returned rcv data buf dbOffset = %04x and Size = %04x.\
\r\n"), dbOffset, dbSize));

    // virtual data buffer pointer
    unsigned char *v_rxbuf = ((unsigned char *)v_pDPRam + dbOffset); 
    // physical data buffer pointer
    unsigned char *p_rxbuf = ((unsigned char *)p_pDPRam  + dbOffset); 

    DEBUGMSG( ZONE_INIT, 
      ( TEXT("Virtual RX Data Buffer Area (v_rxbuf) = %8x\r\n"), v_rxbuf ) );
    DEBUGMSG( ZONE_INIT, 
      ( TEXT("Physical RX Data Buffer Area (p_rxbuf) = %8x\r\n"), p_rxbuf) );


    // set up memory request for TRANSMIT data buffer 
 
    dbRequest.MemoryType = MEMORY_DATA;
    dbRequest.NumberOfBytes = 
                    sizeof(unsigned char) * TX_BUFFER_SIZE * NUMBER_TX_BUFFERS;

    dbOffset = 0xffff;
    dbSize = 0x0;

    if( ! KernelIoControl(
            OEM_IOCTL_ALLOC_MEM,
            &dbRequest,
            NOTUSED,
            &dbOffset,
            NOTUSED,
            &dbSize
            ) )
    {
        DEBUGMSG(ZONE_ERROR, 
          (TEXT("Xmt Data Buffer Allocation Failure -\r\n"))); 
        DEBUGMSG(ZONE_ERROR,
          (TEXT("- Returned Offset = %04x - Size = %04 -\r\n"),
            dbOffset, dbSize ) );

        return( FALSE );
    }

    DEBUGMSG( ZONE_INIT, 
(TEXT("KernelIoControl returned xmt data buf dbOffset = %04x and Size = %04x.\
\r\n"), dbOffset, dbSize));

    // virtual data buffer pointer
    unsigned char *v_txbuf = ((unsigned char *)v_pDPRam + dbOffset); 
    // physical data buffer pointer
    unsigned char *p_txbuf = ((unsigned char *)p_pDPRam  + dbOffset); 

    DEBUGMSG( ZONE_INIT, 
      ( TEXT("Virtual TX Data Buffer Area (v_txbuf) = %8x\r\n"), v_txbuf ) );
    DEBUGMSG( ZONE_INIT, 
      ( TEXT("Physical TX Data Buffer Area (p_rxbuf) = %8x\r\n"), p_txbuf) );


#ifdef SMC_KBD_DEBUG
    smc->rx_buf_base = v_rxbuf;
    smc->tx_buf_base = v_txbuf;
#endif



    /**************************************
     * Init Receive/Transmit Buffer Space
     **************************************/

    unsigned char *clr_ptr;
    int i;

    DEBUGMSG( ZONE_SMC_BUFFER_INIT_DEBUG, 
      ( TEXT("v_rxbuf = %8x\r\n"), v_rxbuf ) );

    for( clr_ptr = v_rxbuf, i = 0;
                            i < RX_BUFFER_SIZE * NUMBER_RX_BUFFERS;
                            i++ )
    {
        *clr_ptr++ = 0;
    }

    DEBUGMSG( ZONE_SMC_BUFFER_INIT_DEBUG, 
      ( TEXT("v_txbuf = %8x\r\n"), v_txbuf ) );

    for( clr_ptr = v_txbuf, i = 0;
                            i < TX_BUFFER_SIZE * NUMBER_TX_BUFFERS;
                            i++ )
    {
        *clr_ptr++ = 0;
    }


    /**************************************
     * Setup Receiver Buffer Descriptors
     */

    DEBUGMSG(ZONE_SMC_PROGRESS_DEBUG, ( TEXT("Initializing Rx BDs . . .\r\n")));

    for( int bd_index = 0; bd_index < NUMBER_RX_BUFFERS; bd_index++ )
    {
        /* Empty/Enable, Set RX bit in event reg.when buffer closes */
        v_rtx->rxbd[bd_index].bd_status = RBD_EMPTY | RBD_INT;
        v_rtx->rxbd[bd_index].bd_length = 0;          /* Reset */
        v_rtx->rxbd[bd_index].bd_addr = &p_rxbuf[bd_index * RX_BUFFER_SIZE];

    DEBUGMSG( ZONE_SMC_BD_INIT_DEBUG, ( TEXT("v_rtx->rxbd[%2x] = %8x\r\n"),
                          bd_index, &v_rtx->rxbd[bd_index].bd_status ) );

#ifdef SMC_KBD_DEBUG
        smc->rx_buf_ptr[bd_index] = &v_rxbuf[bd_index * RX_BUFFER_SIZE];
#endif
    }

    v_rtx->rxbd[bd_index - 1].bd_status |= RBD_WRAP; /* Last BD in ring */

    /*
     * Setup Transmitter Buffer Descriptors
     */

    DEBUGMSG(ZONE_SMC_PROGRESS_DEBUG,(TEXT("Initializing Tx BD(s) . . .\r\n")));

    for( bd_index = 0; bd_index < NUMBER_TX_BUFFERS; bd_index++ )
    {
        /* Buffer not Ready, Set TX bit in event reg. when complete */
        v_rtx->txbd[bd_index].bd_status = TBD_INT;
        v_rtx->txbd[bd_index].bd_length = TX_BUFFER_SIZE;  /* TX count */
        v_rtx->txbd[bd_index].bd_addr = &p_txbuf[bd_index * TX_BUFFER_SIZE];

    DEBUGMSG( ZONE_SMC_BD_INIT_DEBUG, ( TEXT("v_rtx->txbd[%2x] = %8x\r\n"),
                          bd_index, &v_rtx->txbd[bd_index].bd_status ) );

#ifdef SMC_KBD_DEBUG
        smc->tx_buf_ptr[bd_index] = &v_txbuf[bd_index * TX_BUFFER_SIZE];
#endif
    }

    v_rtx->txbd[bd_index - 1].bd_status |= TBD_WRAP; /* Last BD in ring */

    /*
     * Clear any pending events in SMC Event register.
     *  Mask all event interrupts, do polling.
     */

    smc->RegsPtr = &(immr->smc_regs[smc->RegsOffset]);

    DEBUGMSG( ZONE_INIT, ( TEXT("SMC RegsPtr = %8x\r\n"), smc->RegsPtr ) );

    DEBUGMSG( ZONE_INIT, ( TEXT("Clearing SMC Event Status\r\n") ) );

    smc->RegsPtr->smc_smce = 0xff;
    smc->RegsPtr->smc_smcm = 0;

    /*
     * SMC Mode register setup
     * 
     * - 8-bit mode - CLEN_10 (8d+1p+1s)
     * - 1 stop-bit - SL_1 (0)
     * - Odd parity - PEN_ODD
     * - UART SMC Mode - SM_UART
     * - Normal operation - DM_NORMAL
     * - SMC Transmitter/Receiver Enabled (TEN, REN)
     */

    smc->RegsPtr->smc_smcmr =
        ( SMC_CHAR_10 | SMC_STOP_1 | SMC_PARITY_ODD | SMC_MODE_UART | DM_NORMAL );

    smc->RegsPtr->smc_smcmr |= ( SMCMR_TEN | SMCMR_REN );   /* enable */

#if (defined(MOTO_ADS) || defined(MOTO_FADS)) 

    DEBUGMSG( ZONE_INIT, ( TEXT("Enabling SMC Tranceiver In BCSR1 . . .\r\n")));

    /*
     *  Enable SMCx RS-232 transceiver on ADS board via BCSR1
     */

    /* Get the base address of BCSR1 (BSCR int array 0-3) */ 
    BCSR * bcsr = (BCSR *) v_pBCSR;

    bcsr->bcsr1 &= smc->Rs232Enable;   /* Assert the SMCx RS232EN* bit */

// #else

//    KernelIoControl( ENABLE_EXT_HW or POWER_ON or RD_AND_OR_WT, ...);

#endif // MOTO_ADS || MOTO_FADS

#if (defined(SDB_RPXL) || defined(SDB_CLLF))

    DEBUGMSG( ZONE_INIT, ( TEXT("Enabling SMC Tranceiver In BCSR . . .\r\n")));

    /*
     *  Enable SMCx RS-232 transceiver on via BCSR
     */

    /* Get the base address of BCSR0 of CPU (smc1) or HIOX (smc2) */
    #if FW_DEFAULT_KBD_SMC==1
       CPU_BCSR * bcsr = (CPU_BCSR *) v_pBCSR;
       bcsr->bcsr0 |= smc->Rs232Enable;   /* Assert the transceiver enable */
    #else
       #if defined(SDB_HIOX)
       HIOX_BCSR * bcsr = (HIOX_BCSR *) v_pBCSR;

⌨️ 快捷键说明

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