📄 webserver.c
字号:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <cdefBF537.h>
#include <EMAC2_regbits.h>
#include <sys/exception.h>
#include <time.h>
#include "uip_arp.h"
#include "uipopt.h"
#include "uip.h"
#include "globals.h"
#include "MAC_Definition.h"
#include "protocol_numbers.h"
/*****************************************************************************
* Periodic Timout Functions and variables
*
* The periodic timeout rate can be changed depeding on your application
* Modify these functions and variables based on your ADSP device and clock
* rate
*****************************************************************************/
// poll the uIP periodic function every ~0.5 sec
#define TIMERCOUNTER_PERIODIC_TIMEOUT 4000 //4000*0.125ms = 0.5s
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
// for running the LED's once after succesfully connection
bool START_LED_RUN = false;
//bool STACK_BUSY;
u32 NoTx,NoRx,NoRx1=0,NoRx2=0;
u32 receive_stat_buf[100];
u32 timerCounter, *timerCounter_wait, arptimer;
u32 period;
u16 phydat_temp1;
///////////////////////////////
// proto types are placed here
extern void Init_PLL(void);
void Init_Interrupts(void);
void readme_online(void);
void print_frame(u32 printframe);
void emac_tx_start(void);
void emac_tx_stop(void);
void Init_Timers(void);
void wait(u32 *count);
void Init_Flags(void);
static void SetupPinMux(void);
/*-----------------------------------------------------------------------------------*/
void
uip_log(char *m)
{
printf("uIP log message: %s\n", m);
}
/*-----------------------------------------------------------------------------------*/
//
// Set FER regs to MUX in Ethernet pins
//
static void SetupPinMux(void)
{
volatile unsigned int fer_val;
volatile unsigned int *p = &fer_val;
// FER reg bug work-around
// read it once
fer_val = *pPORTH_FER;
fer_val = 0xffff;
// write it twice to the same value
*pPORTH_FER = fer_val;
*pPORTH_FER = fer_val;
}
/////////////////////////
// Set MAC address
void SetupMacAddr(unsigned char *mac)
{
unsigned int lo;
int i;
unsigned char byt;
lo = 0;
for (i=3;i>=0; i--) {
byt = mac[i];
lo = (lo<<8) | byt;
}
*pEMAC_ADDRLO = lo;
lo = 0;
for (i=5;i>=4; i--) {
byt = mac[i];
lo = (lo<<8) | byt;
}
*pEMAC_ADDRHI = lo;
}
//
// Wait until the previous MDC/MDIO transaction has completed
//
void PollMdcDone(void)
{
// poll the STABUSY bit
while((*pEMAC_STAADD) & EMAC2_STABUSY) {};
}
//
// Read an off-chip register in a PHY through the MDC/MDIO port
//
u16 RdPHYReg(u16 PHYAddr, u16 RegAddr)
{
PollMdcDone();
*pEMAC_STAADD = EMAC2_PHYAD(PHYAddr) | EMAC2_REGAD(RegAddr) |
EMAC2_STAOP_RD | EMAC2_STABUSY;
PollMdcDone();
return (u16)*pEMAC_STADAT;
}
//
// Write an off-chip register in a PHY through the MDC/MDIO port
//
void WrPHYReg(u16 PHYAddr, u16 RegAddr, u32 Data)
{
PollMdcDone();
*pEMAC_STADAT = Data;
ssync();
*pEMAC_STAADD = EMAC2_PHYAD(PHYAddr) | EMAC2_REGAD(RegAddr) |
EMAC2_STAOP_WR | EMAC2_STABUSY;
ssync();
PollMdcDone();
}
//
// Read all current PHY register values into a memory buffer
//
void DumpPHYRegs()
{
int pha;
for (pha = 0; pha < NO_PHY_REGS; pha++) {
PHYregs[pha] = RdPHYReg(BR_EZKIT_PHYADD, pha);
//for debug
//printf(" register PHYregs[%d] = %x \n",pha , PHYregs[pha]);
}
printf("\n register PHYregs[0] Control Register = %x ( should be 0x2100 )\n", PHYregs[0]);
printf(" register PHYregs[1] STATUS Register = %x ( should be 0x7809 )\n", PHYregs[1]);
}
void wait(u32 *count){
// Enable Timers 1
*pTIMER_ENABLE |= 0x0002;
while(*pTIMER1_COUNTER <= *count)
asm("nop;");
*pTIMER_DISABLE |= 0x0002;
}
//
// Setup various system registers
//
void SetupSystemRegs(void)
{
u32 fer_val,i;
u16 sysctl,bits;
u32 wait;
u16 TempReg;
u16 timeout;
volatile u16 phydat;
clock_t ndtime;
clock_t period = ((clock_t)CLOCKS_PER_SEC)/2;
Init_PLL(); //Program PLL settings
SetupPinMux(); // we set the GPIO pins to Ethernet mode
SetupMacAddr(SrcAddr); // next, we set up a MAC ADDRESS
//Program EMAC2 System Control Reg
// set MDC clock divisor (min period is 400 ns)
// sysctl = EMAC2_MDCDIV(26); // %54 for 132 MHz SCLK
// sysctl = EMAC2_MDCDIV(10); // %22 for 54 MHz SCLK
sysctl = EMAC2_MDCDIV(24);
// configure checksum support and rcve frame word alignment
if (ip_chksum) {
sysctl |= EMAC2_RXCKS;
}
if (rxdwa) {
sysctl |= EMAC2_RXDWA;
}
*pEMAC_SYSCTL = sysctl;
//reset PHY
*pEMAC_STADAT = 0x8000;
*pEMAC_STAADD = SET_PHYAD(BR_EZKIT_PHYADD) | SET_REGAD(PHYREG_MODECTL) | EMAC2_STAOP_WR | STABUSY;
period = 300000000; // assume 600 MHZ
ndtime = clock()+period;
while (clock()<ndtime);
/////////////////////////////
// Program PHY registers
// force: ANEG=off
phydat = 0;
if (full_dpx) {
phydat |= (1 << 8); // full duplex
} else {
phydat |= (0 << 8); // half duplex
}
if (speed100) {
phydat |= (1 << 13); // 100 Mbps
} else {
phydat |= (0 << 13); // 10 Mbps
}
// phydat |= (1 << 14); // enable TX->RX loopback
asm("nop;");
if(negotiation) {
phydat = (1 << 12);
asm("nop;");
}
WrPHYReg(BR_EZKIT_PHYADD, PHYREG_MODECTL, phydat);
// stay here until the link is detected
// while ( ((TempReg & 0x4) == 0) && timeout--)
while ( ((phydat & 0x4) == 0) ){
phydat = RdPHYReg(BR_EZKIT_PHYADD, PHYREG_MODESTAT);
START_LED_RUN = true;
};
// run the led once
if(START_LED_RUN){
START_LED_RUN = false;
bits = 0x0FC0;
for(i=0;i<10;i++){
//bits = bits >>2;
*pPORTFIO_TOGGLE = bits;
period = 0xfffffff; // assume 600 MHZ
ndtime = clock()+period;
while (clock()<ndtime);
}
}
//for debug
//DumpPHYRegs();
}
void emac_tx_stop(void){
u32 opmode;
if(NoTx >2){
uip_len = uip_len;
}
PollMdcDone();
opmode = *pEMAC_OPMODE;
opmode &= ~EMAC2_TE;
*pEMAC_OPMODE = opmode;
//txbuf->Dma[0].CONFIG.b_DMA_EN = 0;
txbuf->Dma[1].CONFIG.b_DMA_EN = 0;
*pDMA2_CONFIG = *((u16*)&txbuf->Dma[1].CONFIG);
if(NoTx >2){
uip_len = uip_len;
}
//memset((void*)uip_buf,'\0',uip_len);
txbuf = txfst; //reset the buffer
}
void emac_tx_start(void){
u32 opmode;
if(NoTx >0){
uip_len = uip_len;
}
txbuf->Dma[1].CONFIG.b_DMA_EN = 1;
if (txfst != NULL) {
*pDMA2_NEXT_DESC_PTR = &txfst->Dma[0];
*pDMA2_CONFIG = *((u16*)&txfst->Dma[0].CONFIG);
}
PollMdcDone();
opmode = *pEMAC_OPMODE;
if (NO_TX_BUFS > 0) opmode |= EMAC2_TE;
*pEMAC_OPMODE = opmode;
ssync();
if(NoTx >2){
uip_len = uip_len;
}
}
//
// prepare descriptors for transmitting
//
DMA_REGISTERS* SetupDescriptors();
int main()
{
int i,ib, irxh, itxh, size;
int time, run, error;
u32 opmode,txstatus,rxstatus;
u32 txcnt,rxcnt,rxlnth;
u8 rx_src [] ={'\0'};
u8 rcv_mac_addr[6];
u8 rx_ip_packet[2];
u8 *show;
u8 *pointer_buf;
//-----------------------------------------------------------------------//
// initialization function //
//-----------------------------------------------------------------------//
readme_online(); // readme online the output window shows a short description
Init_Flags();
SetupSystemRegs(); // first, we setup various non-EMAC stuff
Init_Interrupts();
Init_Timers(); // init periodic timer
uip_init(); // init uIP
uip_arp_init();
httpd_init(); // init HTTP server and Filesystem
// initialize the TX DMA channel registers
*pDMA2_X_COUNT = 0;
*pDMA2_X_MODIFY = 4;
// initialize the RX DMA channel registers
*pDMA1_X_COUNT = 0;
*pDMA1_X_MODIFY = 4;
//-----------------------------------------------------------------------//
// creating a linked list for Receive and Transfer DMA //
//-----------------------------------------------------------------------//
// set up a transmit frames and form a chain of them
txlst = NULL;
txfst = NULL;
for (ib=0;ib<NO_TX_BUFS;ib++) {
txbuf = SetupTxBuffer(TXFRM_SIZE,ib);
if (txfst==NULL) txfst = txbuf;
if (txlst != NULL) {
// chain this buffer on
txlst->pNext = txbuf;
// chain the descriptors
txlst->Dma[1].NEXT_DESC_PTR = &txbuf->Dma[0];
// set flow mode
txlst->Dma[1].CONFIG.b_NDSIZE = 5; // five elements
txlst->Dma[1].CONFIG.b_FLOW = 7; // large descriptors
}
////////////////////////////////////////////////
// set interrupt enable into the last descriptor
//if(ib==3)txbuf->Dma[0].CONFIG.b_DI_EN= 1;
txlst = txbuf;
TxStsHistory[ib] = 0;
}
// loop the transmit chain
if (LOOP_TX) {
txlst->Dma[1].NEXT_DESC_PTR = &txfst->Dma[0];
// set flow mode
txlst->Dma[1].CONFIG.b_NDSIZE = 5; // five elements
txlst->Dma[1].CONFIG.b_FLOW = 7; // large descriptors
txlst->pNext = txfst;
}
// set up a receive frames and form a chain of them
rxlst = NULL;
rxfst = NULL;
for (ib=0;ib<NO_RX_BUFS;ib++) {
rxbuf = SetupRxBuffer(ip_chksum);
if (rxfst==NULL) rxfst = rxbuf;
if (rxlst != NULL) {
// chain this buffer on
rxlst->pNext = rxbuf;
// chain the descriptors
rxlst->Dma[1].NEXT_DESC_PTR = &rxbuf->Dma[0];
// set flow mode
rxlst->Dma[1].CONFIG.b_NDSIZE = 5; // five elements
rxlst->Dma[1].CONFIG.b_FLOW = 7; // large descriptors
}
////////////////////////////////////////////////
// set interrupt enable into the last descriptor
//if(ib==NO_RX_BUFS-1)rxbuf->Dma[1].CONFIG.b_DI_EN= 1;
rxlst = rxbuf;
RxStsHistory[ib] = 0;
}
// loop the receive chain
if (LOOP_RX) {
rxlst->Dma[1].NEXT_DESC_PTR = &rxfst->Dma[0];
// set flow mode
rxlst->Dma[1].CONFIG.b_NDSIZE = 5; // five elements
rxlst->Dma[1].CONFIG.b_FLOW = 7; // large descriptors
rxlst->pNext = rxfst;
}
//-----------------------------------------------------------------------//
// start DMA with pointing the linked list to the next descriptor //
//-----------------------------------------------------------------------//
// NOTE: The TX Start is removed to the function emac_tx_start()
// start the TX DMA channel before enabling the MAC
/* txbuf = txfst;
if (txfst != NULL) {
*pDMA2_NEXT_DESC_PTR = &txfst->Dma[0];
*pDMA2_CONFIG = *((u16*)&txfst->Dma[0].CONFIG);
}
*/
// start the RX DMA channel before enabling the MAC
rxbuf = rxfst;
if (rxfst != NULL) {
*pDMA1_NEXT_DESC_PTR = &rxfst->Dma[0];
*pDMA1_CONFIG = *((u16*)&rxfst->Dma[0].CONFIG);
}
//----------------------------------------------------------------------//
// EMAC Settings //
//----------------------------------------------------------------------//
// reset counters, clear on read, allow rollover, enable counters
//*pEMAC_MMC_CTL = 0x0f;
// reset counters, allow rollover, enable counters
*pEMAC_MMC_CTL = EMAC2_RSTC | EMAC2_CROLL | EMAC2_MMCE;
// finally enable sending/receiving at the mac
// enable RX and TX
opmode = 0;
//if (NO_TX_BUFS > 0) opmode |= EMAC2_TE;
if (NO_RX_BUFS > 0) opmode |= EMAC2_RE;
if (rmii) {
opmode |= EMAC2_RMII; // RMII at 100 Mbits
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -