📄 webserver.c
字号:
if (! speed100) {
opmode |= EMAC2_RMII_10;// RMII at 10 Mbits
}
}
if (full_dpx) {
opmode |= EMAC2_FDX; // select full duplex
} else {
opmode |= EMAC2_HDX; // select half duplex
}
//////////////////////////
// TX modes
//////////////////////////
opmode = //EMAC2_DTXCRC | // Disable automatic TX FCS generation
//EMAC2_DTXPAD | // Disable automatic TX Pad generation
//EMAC2_LCTRE | // Late Collision Retry Enable
//EMAC2_BOLMT_1 | // back-off limit:
//EMAC2_DC | // Deferral Check
//EMAC2_DRTY | // Disable TX Retry on collision
//EMAC2_DRO | // Disable Receiving of our Own Transmitted Frames
//EMAC2_LB | // Enable internal loopback
opmode;
//////////////////////////
// RX modes
//////////////////////////
opmode = //EMAC2_RA | // Receive all
//EMAC2_PSF | // Pass all short frames
//EMAC2_PBF | // Pass all bad frames
//EMAC2_DBF | // dicard the broadcast frame
//EMAC2_IF | // Inverse filtering
EMAC2_PR | // Receive all promiscuous = address accepts all address
//EMAC2_PAM | // Pass all multicast frames
//EMAC2_HM | // Hash filter multicast
//EMAC2_HU | // Hash filter unicast
//EMAC2_ASTP|
opmode;
PollMdcDone();
*pEMAC_OPMODE = opmode;
//----------------------------------------------------------------------//
// initialization is finished -> now we can work with the EMAC //
//----------------------------------------------------------------------//
// now poll for completion on the tx and rx buffers
// the first linked list will be linked to the txbuf
txbuf = txfst;
NoTx = 0;
txcnt = 0;
itxh = 0;
rxbuf = rxfst;
NoRx = 0;
rxcnt = 0;
*pEMAC_RXC_OK =0;
irxh = 0;
run =1;
uip_len =0;
//for debug
rxbuf->StatusWord = 0;
txbuf->StatusWord = 0;
// for debug
//opmode = 0x00010001;
*pEMAC_OPMODE |= 0x1 ;
ssync();
while (RunFlag && ((rxbuf!=NULL) || (txbuf!=NULL)) ) {
if ((txbuf != NULL) &&
((txbuf->StatusWord & EMAC2_TransmitComplete) !=0)
) {
txstatus = txbuf->StatusWord; // save the status
txbuf->StatusWord = 0;
NoTx++;
// store current status in history list
TxStsHistory[itxh] = txstatus;
if (++itxh >= NO_TX_BUFS) itxh = 0;
// disnable the transmit DMA for the sending the next packets
emac_tx_stop();
//reset after successfully trransfer
STACK_BUSY = false;
uip_len = 0;
}
if ((rxbuf != NULL) &&
((rxbuf->StatusWord & EMAC2_ReceiveComplete) !=0)
) {
//frame marked as received
rxstatus = rxbuf->StatusWord; // save the status
rxbuf->StatusWord = 0;
NoRx1++;
//printf(" rxbuf->StatusWord = %x outer loop ReceiveOK failed\n" ,rxstatus );
if (rxstatus & EMAC2_ReceiveOK && !STACK_BUSY) {
run=0;
// received OK
rxlnth = EMAC2_RxFrameLength(rxstatus);
NoRx++;
rxcnt += *pEMAC_RXC_OK;
//store packet length minus length field
uip_len = rxlnth - 0x4;
memcpy((void *)uip_buf,(void *)rxbuf->Data->Dest,uip_len);
ssync();
//verify this data moving, otherwise try it again
error = memcmp((void *)uip_buf[6],(void *)rxbuf->Data->Srce[0],6);
if(error !=0 )
{
memcpy((void *)uip_buf,(void *)rxbuf->Data->Dest,uip_len);
ssync();
printf("**errors** occured during memcpy of iup_buf\n");
}
// flag buffer in use and pkt avail
STACK_BUSY = true;
}// if (rxstatus & EMAC2_ReceiveOK && run)
rxbuf = rxbuf->pNext;
// store current status in history list
RxStsHistory[irxh] = rxstatus;
if (++irxh >= NO_RX_BUFS) irxh = 0;
} // end if((rxbuf != NULL) && ....
//--------------------------------------------------------------------------//
// Function: Main loop for the UIP STACK //
// //
// //
// Description: look for a packet; uip_len controlled the flow //
// //
//--------------------------------------------------------------------------//
if(uip_len == 0)
{
// if timed out, call periodic function for each connection
// poll the uIP periodic function every ~0.5 sec
if(timerCounter > TIMERCOUNTER_PERIODIC_TIMEOUT)
{
timerCounter = 0;
for(i = 0; i < UIP_CONNS; i++)
{
uip_periodic(i);
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0.
transmit a packet, if one is ready
*/
if(uip_len > 0)
{
uip_arp_out();
// send packet, using data in uip_buf , uip_appdata start at address [54]
// be care, the uip used uip_appdata,
// in the current driver is this not included !!
if( uip_len <= TOTAL_HEADER_LENGTH ){
memcpy((void *)txbuf->Data->Dest,(void *)uip_buf,uip_len);
txbuf->Data->NoBytes = uip_len;
}
else
{
//memcpy((void *)(uip_buf[uip_appdata_length]),(void *)uip_appdata,uip_len-uip_appdata_length);
//above memcpy was the original code , double check if this is still valid --> "if( uip_len <= TOTAL_HEADER_LENGTH ){"
memcpy((void *)txbuf->Data->Dest,(void *)uip_buf,uip_len);
txbuf->Data->NoBytes = uip_len;
}
// enable DMA transfer
emac_tx_start();
}
}
/* Call the ARP timer function every 10 seconds. 0.125ms*4000*20=80000=10s */
if(arptimer > 0x13880) {
uip_arp_timer();
arptimer = 0;
}
}
STACK_BUSY = false;
}
else // packet received
{
// process an IP packet
if(BUF->type == htons(UIP_ETHTYPE_IP))
{
// add the source to the ARP cache
// also correctly set the ethernet packet length before processing
uip_arp_ipin();
uip_input(); //if any is wrong uip_len will be set to 0
// transmit a packet, if one is ready
if(uip_len > 0)
{
uip_arp_out();
if( uip_len <= TOTAL_HEADER_LENGTH ){
txbuf->Data->NoBytes = uip_len;
memcpy((void *)txbuf->Data->Dest,(void *)uip_buf,uip_len);
}
else
{
//memcpy((void *)(uip_buf[uip_appdata_length]),(void *)uip_appdata,uip_len-uip_appdata_length);
//above memcpy was the original code , double check if this is still valid --> "if( uip_len <= TOTAL_HEADER_LENGTH ){"
memcpy((void *)txbuf->Data->Dest,(void *)uip_buf,uip_len);
txbuf->Data->NoBytes = uip_len;
}
// enable DMA transfer
emac_tx_start();
}
}
// process an ARP packet
else if(BUF->type == htons(UIP_ETHTYPE_ARP))
{
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0.
transmit a packet, if one is ready
*/
if(uip_len > 0){
// send packet, using data in uip_buf , uip_appdata start at address [54]
// be care, the uip used uip_appdata,
// in the current driver is this not included !!
if( uip_len <= TOTAL_HEADER_LENGTH ){
memcpy((void *)txbuf->Data->Dest,(void *)uip_buf,uip_len);
txbuf->Data->NoBytes = uip_len;
}else{
//memcpy((void *)(uip_buf[uip_appdata_length]),(void *)uip_appdata,uip_len-uip_appdata_length);
//above memcpy was the original code , double check if this is still valid --> "if( uip_len <= TOTAL_HEADER_LENGTH ){"
memcpy((void *)txbuf->Data->Dest,(void *)uip_buf,uip_len);
txbuf->Data->NoBytes = uip_len;
}
// enable DMA transfer
emac_tx_start();
} // end if (uip_len)
} // end else if
} // end else // packet received
STACK_BUSY =false; //get free for new receive
} // end while
*pEMAC_OPMODE = 0;
return 0;
} // end main()
//--------------------------------------------------------------------------//
// Function: Init_Flags //
// //
// Parameters: , //
// //
// Return: None //
// //
// Description: Configure PORTF flags to control ADC and DAC RESETs //
// //
//--------------------------------------------------------------------------//
void Init_Flags(void)
{
int temp;
// configure programmable flags
// set PORTF function enable register (need workaround in Rev0.0)
temp = *pPORTF_FER;
temp++;
#if (__SILICON_REVISION__ < 0x0001)
*pPORTF_FER = 0x0000;
*pPORTF_FER = 0x0000;
#else
*pPORTF_FER = 0x0000;
#endif
// set PORTF direction register, LED's as outputs
*pPORTFIO_DIR = 0x1FC0;
// set PORTF input enable register
*pPORTFIO_INEN = 0x003C;
// set PORTF clear register
*pPORTFIO_CLEAR = 0x0FC0;
*pPORTFIO_SET = 0x0FC0;
}
//--------------------------------------------------------------------------//
// Function: Init_Timers //
// //
// Parameters: SCLK = 150MHz, //
// //
// Return: None //
// //
// Description: This function initialises Timer0 for PWM mode. //
// It is used as reference for the 'shift-clock'. //
//--------------------------------------------------------------------------//
void Init_Timers(void)
{
*pTIMER_DISABLE = 0x0003;
//TIMER0 settings
*pTIMER0_CONFIG = 0x0019; //IRQ enable,Count to end of period,PWM Out mode enable
*pTIMER0_PERIOD = 0x0000493e; // timer is set to 0.125ms
*pTIMER0_WIDTH = 0x0000249f; // the half velue of timer_period
//TIMER1 settings
*pTIMER1_CONFIG = 0x0019; //IRQ enable,Count to end of period,PWM Out mode enable
*pTIMER1_PERIOD = 0x0000493e; // timer is set to 0.125ms
*pTIMER1_WIDTH = 0x0000249f; // the half velue of timer_period
/*inline assembly for debug only: CYCLES counter set to zero */
//asm("R2=0;CYCLES=R2;CYCLES2=R2;R2=SYSCFG;BITSET(R2,1);SYSCFG=R2;");
*pTIMER_ENABLE = 0x0001;
timerCounter = 0 ;
timerCounter_wait = 0;
}
//--------------------------------------------------------------------------//
// Function: INT_RX_EMAC //
// //
// Parameters: None //
// //
// Return: None //
// //
// Description: This ISR is executed every time a transfer is completed //
// //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(INT_RX_EMAC) // <--|declaration in exception.h -->
{ // |declaration with _pragma(interrupt) the ISR Startaddress
int i, itxh=0;
int time;
u32 NoTx=0, opmode;
u32 rxstatus=0;
u32 txcnt=0;
// confirm the DMA interrupt
*pDMA1_IRQ_STATUS = 0x1;
rxstatus = rxbuf->StatusWord;
//store packet length minus length field
uip_len = EMAC2_RxFrameLength(rxstatus) - 0x4;
}
//--------------------------------------------------------------------------//
// Function: INT_TX_EMAC //
// //
// Parameters: None //
// //
// Return: None //
// //
// Description: This ISR is executed every time a transfer is completed //
// //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(INT_TX_EMAC) // <--|declaration in exception.h -->
{ // |declaration with _pragma(interrupt) the ISR Startaddress
int i, itxh=0;
int time;
u32 NoTx=0, opmode;
u32 txstatus=0;
u32 txcnt=0;
// confirm the DMA interrupt
*pDMA2_IRQ_STATUS = 0x1;
// disable the DMA transmit channel
*pDMA2_CONFIG &= 0xfffe;
// frame marked as transmitted
txstatus = txbuf->StatusWord; // save the status
txbuf->StatusWord = 0;
if (txstatus & EMAC2_TransmitOK) {
// xmitted OK
txcnt += *pEMAC_TXC_OK;
///test implementation code with LED toggle
printf("\n BuB_A has transfered next packet, interrupt occured\n ");
}
txbuf = txbuf->pNext;
*pPORTFIO_TOGGLE = 0xf;
// store current status in history list
TxStsHistory[itxh] = txstatus;
if (++itxh >= NO_TX_BUFS) itxh = 0;
}
//--------------------------------------------------------------------------//
// Function: Timer0_ISR //
// //
// Parameters: None //
// //
// Return: None //
// //
// Description: This ISR is executed every time Timer0 expires. //
// //
//--------------------------------------------------------------------------//
EX_INTERRUPT_HANDLER(Timer0_ISR)
{
//timer interrupt occurs every 0.125ms
timerCounter++; //for uip stack
arptimer++;
uip_arp_timer();
// confirm interrupt handling
*pTIMER_STATUS = 0xFFFF;
}
//--------------------------------------------------------------------------//
// Function: Init_Interrupts initialization //
//--------------------------------------------------------------------------//
void Init_Interrupts(void)
{
// configure interrupt
*pSIC_IAR0 = *pSIC_IAR0 & 0xffffffff | 0x00000000;
*pSIC_IAR1 = *pSIC_IAR1 & 0xffffffff | 0x00000000;
*pSIC_IAR2 = *pSIC_IAR2 & 0xffff0f0f | 0x00005040; // map EMAC interrupt to core ID4 -> IVG11 and Timer0 core ID5 -> IVG12
*pSIC_IAR3 = *pSIC_IAR3 & 0xffffffff | 0x00000000;
// register_handler(ik_ivg11,INT_RX_EMAC); // install IRQ_A handler
register_handler(ik_ivg12, Timer0_ISR); // Timer0 ISR -> IVG 11
// interrupt enable
*pSIC_IMASK=0x00080000; // interrupt Timer 0 (Bit19) enable
//*pIMASK = 0x9400; // !! Important: The MACRO register_handler set this value
}
//--------------------------------------------------------------------------//
// Function: readme online //
//--------------------------------------------------------------------------//
void readme_online(void)
{
printf(" \n\n\
**********************************************************\n\
** uIP web server vers 0.9 \n\
**********************************************************\n\
**\n\
** date: Feb.2005 / RN\n\
**\n\
** IP Address %d.%d.%d.%d\n\
**\n\
** supported PROTOCOLS\n\
** ARP, IP/ICMP, IP/UDP, IP/TCP\n\
**\n\
** status UDP are implemented, but not yet tested\n\
**\n\
** Note: Best printf performance with PCI ICE Emulator\n\
**\n\
**********************************************************\n\n\n "
,UIP_IPADDR0,UIP_IPADDR1,UIP_IPADDR2,UIP_IPADDR3);
printf("NOTE: to get a webpage please open a browser and type http://%d.%d.%d.%d \n ",UIP_IPADDR0,UIP_IPADDR1,UIP_IPADDR2,UIP_IPADDR3);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -