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

📄 trmpc860.c

📁 ppc860平台上移植uc OS的实例
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Save it off for our use in the recv routine */    
    tlMpc860RecvRefillBufDescPtr=tlMpc860RecvBufDescStartPtr=
            tlMpc860RecvIsrBufDescPtr=tlMpc860RecvBufDescPtr=
            tempBufDescPtr;
    tlUserRefillBufferPtr=tlUserBufferPtr=tlUserBufferList;

    for(i=0;i< maxBd;i++,tempBufDescPtr++ ) 
    {
/* bdDataPtr need to be aligned on a 4-byte boundary */
        tempBufDescPtr->bdDataPtr=
                    (tfGetEthernetBuffer(&userBuffer) - TM_ETHER_IP_ALIGN);
        if (tempBufDescPtr->bdDataPtr==(char TM_FAR *)0)
        {
/* No memory so stop the create here */
            break;
        }
        tlUserBufferList[i]=userBuffer;
        tempBufDescPtr->bdLength = 0;
        tempBufDescPtr->bdStatus = (TM_MPC860_RECV_EMPTY|TM_MPC860_RECV_INTR);
    }
    --tempBufDescPtr;
 /* signify last bit on */
    tempBufDescPtr->bdStatus |= TM_MPC860_RECV_WRAP;

}

/*
 * General function
 * Can be used to configure the device
 * or refill the receive pool
 */
int tfMpc860Ioctl (ttUserInterface interfaceHandle, int flag,
                  void TM_FAR * optionPtr, int optionLen)
{
    if (flag&TM_MPC860_REFILL_SCC1)
    {
        tfMpc860RefillScc1RecvPool();
    }
#ifndef TM_TASK_SEND
    if (flag&TM_MPC860_SEND_COMPLETE)
    {
        tfMpc860Scc1SendComplete(interfaceHandle);
    }
#endif /* NOT TM_TASK_SEND */
#ifdef TM_IGMP
    if (flag&TM_DEVICE_ADD_MCAST)
    {
/* Add multicast address */
    }
    if (flag&TM_DEVICE_DELETE_MCAST)
    {
/* Delete multicast addresss */
    }
#endif /* TM_IGMP */
    return TM_ENOERROR;
}
 

/*
 * Walk through receive list and allocate new buffers
 * after they have been processed
 */
void tfMpc860RefillScc1RecvPool()
{
    ttUserBuffer userBuffer;
    unsigned short *bdStatusPtr;
    void          **bdDataPtrPtr;

    bdDataPtrPtr = &tlMpc860RecvRefillBufDescPtr->bdDataPtr;
    bdStatusPtr  = &tlMpc860RecvRefillBufDescPtr->bdStatus;
/* Loop while it is empty or an error */
    while (*bdDataPtrPtr==(void TM_FAR *)0 ||
           (*bdStatusPtr & TM_MPC860_ERROR_RECV))
    {
/* Check to see if it is an error */
        if (!(*bdStatusPtr & TM_MPC860_ERROR_RECV))
        {
/* If it is not get a new buffer, otherwise just reuse it */
/* bdDataPtr need to be aligned on a 4-byte boundary */
            tlMpc860RecvRefillBufDescPtr->bdDataPtr=
                    (tfGetEthernetBuffer(&userBuffer) - TM_ETHER_IP_ALIGN);
            if (*bdDataPtrPtr == (char TM_FAR *)0)
            {
/* No memory so stop the refill */
                break;
            }
            *tlUserRefillBufferPtr=userBuffer;
        }
        tlMpc860RecvRefillBufDescPtr->bdLength = 0;
/* Clear the status Except for the wrap bit */
        *bdStatusPtr &= TM_MPC860_RECV_WRAP;
/* Mark this BD as ready to use */
        *bdStatusPtr |= (TM_MPC860_RECV_EMPTY|TM_MPC860_RECV_INTR);
        if (*bdStatusPtr & TM_MPC860_RECV_WRAP)
        {
            tlMpc860RecvRefillBufDescPtr = tlMpc860RecvBufDescStartPtr;
            tlUserRefillBufferPtr=tlUserBufferList;
        }
        else
        {
            tlMpc860RecvRefillBufDescPtr++;
            tlUserRefillBufferPtr++;
        }
        bdDataPtrPtr = &tlMpc860RecvRefillBufDescPtr->bdDataPtr;
        bdStatusPtr  = &tlMpc860RecvRefillBufDescPtr->bdStatus;
    }
}

#ifndef TM_TASK_SEND
/*
 * Walk through send list and post send completes
 */
void tfMpc860Scc1SendComplete(ttUserInterface interfaceHandle)
{
    unsigned short *bdStatusPtr;
    void          **bdDataPtrPtr;

    bdStatusPtr = &tlMpc860XmitIsrBufDescPtr->bdStatus;
    bdDataPtrPtr = &tlMpc860XmitIsrBufDescPtr->bdDataPtr;
/* An ethernet frame has completed transmitting so notify the user*/
    while ((*bdStatusPtr & TM_MPC860_XMIT_READY)==0 &&
            tlMpc860XmitIsrBufDescPtr != tlScatterBufferStart && 
            *bdDataPtrPtr != (void TM_FAR *)0)
    {
/* Zero it out so we know that we have freed this one before */
        *bdDataPtrPtr=(void TM_FAR *)0;
        if (*bdStatusPtr & TM_MPC860_XMIT_WRAP)
        {
            tlMpc860XmitIsrBufDescPtr = tlMpc860XmitBufDescStartPtr;
        }
        else
        {
            tlMpc860XmitIsrBufDescPtr++;
        }
/* Only call send complete when the last piece has been transmitted */
        if (*bdStatusPtr & TM_MPC860_XMIT_LAST)
        {
            tfSendCompleteInterface(interfaceHandle,TM_DEV_SEND_COMPLETE_DRIVER);
        }
        bdStatusPtr = &tlMpc860XmitIsrBufDescPtr->bdStatus;
        bdDataPtrPtr = &tlMpc860XmitIsrBufDescPtr->bdDataPtr;
    }
}
#endif /* NOT TM_TASK_SEND */


/* 
 * Prepare a transmit pool, set the status bits in the buffer descriptors
 * to be not READY to transmit and set the last buffer descriptor to
 * be wrapped
 */
void tfMpc860CreateXmitPool(int channel, int maxBd)
{
    int i;
    ttMpc860BufDescPtr tempBufDescPtr;
    struct ethernet_pram *enetPramAddr;
    struct scc_regs *regs;

/* Save the ethernet parameter address */
    enetPramAddr = &tlMpc860Ptr->pram[channel].enet_scc;
    regs = &tlMpc860Ptr->scc_regs[channel];

    tempBufDescPtr = TM_MPC860_XMIT_BD_ADDR(tlMpc860Ptr,enetPramAddr);

/* Save it off for our use in the xmit routine */    
    tlMpc860XmitIsrBufDescPtr=tlMpc860XmitBufDescStartPtr=
            tlMpc860XmitBufDescPtr=tempBufDescPtr;
    for(i=0;i< maxBd;i++,tempBufDescPtr++ ) {
        tempBufDescPtr-> bdStatus = 0;
        tempBufDescPtr-> bdLength = 0;
        tempBufDescPtr-> bdDataPtr = (void TM_FAR *)0;
    }
    --tempBufDescPtr;
/* signify last bit on */
    tempBufDescPtr->bdStatus |= TM_MPC860_XMIT_WRAP; 
}

/*
 *
 *
 * SERIAL INTERFACE
 *
 *
 */



/* 
 * Initialize SCC4 to be an UART channel
 */
void tfMpc860SerialScc4Init()
{
    struct uart_pram *rs232_pram;
    struct scc_regs  *regs;


    rs232_pram = &tlMpc860Ptr->pram[3].scc.pscc.u;
    regs = &tlMpc860Ptr->scc_regs[3];

/* Disable transmit/receive */
    regs->scc_gsmrl = 0;



/* points to start of receiving ring */
    rs232_pram->rbase =   TM_MPC860_SCC4_RECV_BASE;
/* points to start of transmiting ring */
    rs232_pram->tbase =   TM_MPC860_SCC4_XMIT_BASE;   

/* Function Codes for Transmit and Receive */
    rs232_pram->rfcr =    TM_MPC860_SCC4_RECV_FUNC_CODE;
    rs232_pram->tfcr =    TM_MPC860_SCC4_XMIT_FUNC_CODE;

/* We always receive a full ethernet frame so we set it to 1518 */
    rs232_pram->mrblr =   TM_MPC860_SCC4_MAX_RECV_BUF_LEN;
/* maximum idle characters */
    rs232_pram->max_idl = TM_MPC860_SCC4_MAX_IDL16;        

/* Tell the CP to initialize our Recv/Xmit parameters */
    tfMpc860IssueCommand(TM_MPC860_INIT_RXTX_SCC4);
}




/* 
 * Initialize SCC1 to be an ethernet channel    
 */
void tfMpc860SerialScc4BoardInit()
{
    unsigned char  scc4Vector;
    unsigned long  scc4Location;

/*  tlMpc860Ptr->sim_mcr =   0x608f; */

/*
 * IMPLEMENTATION NOTE:
 *
 * This routine is very board specific
 * In this example we use the Atlas Communications Engines
 * HSB devlopment board for an example
 * Please refer to your boards design to modify this routine
 */

/* Atlas HSB Setup */
    tlMpc860Ptr->si_sicr |=   TM_MPC860_SI_SCC4_RCS_BRG1 |
                             TM_MPC860_SI_SCC4_TCS_BRG1;

/* Set the divider to 0x130 and RESET and no DIV16 
 * NOTE: The divider starts in bit location 1 not 0
 * The formula is
 * Divider=ClockRate/DesiredBaudRate/16-1*2
 * Example for 24.576 clock
 * 318=((24576000/9600)/16)-1*2
 * 0x130=318
 */
    tlMpc860Ptr->brgc1 = 0x130|TM_MPC860_BRGC_RST;                            

/* Make PortA Pins 6,7 for onchip use */
    tlMpc860Ptr->pio_padir &= ~(TM_MPC860_PORTA_PA6 |
                               TM_MPC860_PORTA_PA7);
    
/* 
 * pins 6,7 for SCC4 Xmit and Recv
 */
    tlMpc860Ptr->pio_papar |= TM_MPC860_PORTA_PA6 |
                             TM_MPC860_PORTA_PA7;
                            
/* Clear the pending and in-service registers */
    tlMpc860Ptr->intr_cipr = TM_MPC860_SCC4_INT_MASK;
    tlMpc860Ptr->intr_cisr = TM_MPC860_SCC4_INT_MASK;
/* Set the CP mask register to accept interrupts from SCC4 */
    tlMpc860Ptr->intr_cimr |= TM_MPC860_SCC4_INT_MASK;

    tlMpc860Ptr->sdma_sdcr=TM_MPC860_SDMA_ARB_ID; 

    
/* PortC Pins 10 & 11 ar CD and CTS */
    tlMpc860Ptr->pio_pcpar &=   ~(TM_MPC860_PORTC_PC10 |
                                 TM_MPC860_PORTC_PC11);

    tlMpc860Ptr->pio_pcdir &=   ~(TM_MPC860_PORTC_PC10 |
                                 TM_MPC860_PORTC_PC11);
                                 
/*
 * Use Pins 10 and 11 (SCC4 CTS and CD)
 */
    tlMpc860Ptr->pio_pcso|=    TM_MPC860_PORTC_PC10|
                              TM_MPC860_PORTC_PC11;


/* Port B pin 12 is Ethernet TENA for HSB */
    tlMpc860Ptr->pip_pbpar |= TM_MPC860_PORTB_PB15;
    tlMpc860Ptr->pip_pbdir |= TM_MPC860_PORTB_PB15;
    

/*
 * IMPLEMENTATION NOTE:
 *
 * The Actual SCC4 ISR Wrapper Function in installed here
 * It must call the tfMpc860Scc1HandlerIsr function
 * This routine may be in "C" if it is supported
 * or assembly if not.  It is VERY RTOS dependent
 * so it cannot be provided with the driver
 *
 * With some RTOS's a wrapper function may not be
 * needed.  All the driver cares about is that the
 * function tfMpc860Scc1HandlerIsr function is called
 * when the interrupt occurs.
 *
 */

/* Install the wrapper function */
/* NOTE: TO ADD ISR HANDLER */
/*    tfKernelInstallIsrHandler(tfMpc860Scc4Isr,TM_MPC860_SCCD_INT); */
}

/* 
 * The main initialization routine for the mpc860 and the scc's 
 */
int tfMpc860SerialOpen(ttUserInterface interfaceHandle)
{

    unsigned long  mpc860Registers;

    mpc860Registers=TM_MPC860_IMMR_LOC;
    tlMpc860Ptr = (ttMpc860 *)(mpc860Registers&0xfffffffc);

/* Interface handle is not used, but could be for multiple ethernets */
    interfaceHandle=interfaceHandle;
/* Initialize default Ethernet parameters */
    tfMpc860SerialScc4Init();
/* Initial board specific parameters */
    tfMpc860SerialScc4BoardInit();
/* Bring the ethernet scc port online */
    tfMpc860SerialUp(TM_MPC860_SCC4_CHANNEL);

/* Save our interfaceHandle for ISR use */
    tlInterfaceArray[TM_MPC860_SCC4_CHANNEL]=interfaceHandle;
    return TM_ENOERROR;
}


/*
 * Disable the Serial (RS-232) on SCC4
 */
int tfMpc860SerialClose(ttUserInterface interfaceHandle)
{
    tfMpc860Down(TM_MPC860_SCC4_CHANNEL);
    return 0;
}

/* 
 * Enable the SCC's  to recieve and transmit 
 */
void tfMpc860SerialUp(int channel)
{
    struct scc_regs *regs;


    regs = &tlMpc860Ptr->scc_regs[channel];

/* clear all events on the SCC event register and CP event reg*/
    regs->scc_scce=0xffff;

/* Clear the appropriate bit in the CISR */
    switch (channel)
    {
        case TM_MPC860_SCC1_CHANNEL:
            tlMpc860Ptr->intr_cisr = TM_MPC860_SCC1_INT_MASK;
            break;
        case TM_MPC860_SCC2_CHANNEL:
            tlMpc860Ptr->intr_cisr = TM_MPC860_SCC2_INT_MASK;
            break;
        case TM_MPC860_SCC3_CHANNEL:
            tlMpc860Ptr->intr_cisr = TM_MPC860_SCC3_INT_MASK;
            break;
        case TM_MPC860_SCC4_CHANNEL:
            tlMpc860Ptr->intr_cisr = TM_MPC860_SCC4_INT_MASK;
            break;
        default:
            break;
    }


/* 
 * mask the events we sich to interrupt on
 */
    regs->scc_sccm = 
/* A buffer has completed transmitting */
                     TM_MPC860_INTR_SERIAL_XMIT_B |
/* A ethernet frame has been received */
                     TM_MPC860_INTR_SERIAL_RECV_B |
/* The busy condition has occured */
                     TM_MPC860_INTR_SERIAL_BUSY;
    
/* protocol specific mode register */
    regs->scc_psmr = 
/* CTS Flow Control On */
                     TM_MPC860_UART_FLOW |
/* CHaracters are 8 Bits */
                     TM_MPC860_CHAR_8;
                     


/* SCC general mode reg */
/* Set receive FIFO to 1 byte for UART mode */
    regs->scc_gsmrh = TM_MPC860_UART_RECV_FIFO_1;

/* SCC general mode reg */
    regs->scc_gsmrl = 
/* 16x Sample Rate */
                      TM_MPC860_UART_RECV_SAMPLE | 
                      TM_MPC860_UART_XMIT_SAMPLE | 
/* Serial UART Mode */
                      TM_MPC860_UART;

/* enable SCC1 receive/transmit operation */
    regs->scc_gsmrl |= TM_MPC860_ENABLE_RECV | TM_MPC860_ENABLE_XMIT;
     
}



⌨️ 快捷键说明

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