📄 trmpc860.c
字号:
/* 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 + -