Ethernet working in the Kinetis K60 demo.
parent
9d181af847
commit
326b6a2c95
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* File: enet.c
|
||||||
|
* Purpose: Driver for the ENET controller
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "enet.h"
|
||||||
|
#include "nbuf.h"
|
||||||
|
#include "eth.h"
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/* Initialize the MIB counters
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ch FEC channel
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_mib_init(int ch)
|
||||||
|
{
|
||||||
|
//To do
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/* Display the MIB counters
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ch FEC channel
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_mib_dump(int ch)
|
||||||
|
{
|
||||||
|
//To do
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* Set the duplex on the selected FEC controller
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ch FEC channel
|
||||||
|
* duplex enet_MII_FULL_DUPLEX or enet_MII_HALF_DUPLEX
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_duplex (int ch, ENET_DUPLEX duplex)
|
||||||
|
{
|
||||||
|
switch (duplex)
|
||||||
|
{
|
||||||
|
case MII_HDX:
|
||||||
|
ENET_RCR/*(ch)*/ |= ENET_RCR_DRT_MASK;
|
||||||
|
ENET_TCR/*(ch)*/ &= (uint32_t)~ENET_TCR_FDEN_MASK;
|
||||||
|
break;
|
||||||
|
case MII_FDX:
|
||||||
|
default:
|
||||||
|
ENET_RCR/*(ch)*/ &= ~ENET_RCR_DRT_MASK;
|
||||||
|
ENET_TCR/*(ch)*/ |= ENET_TCR_FDEN_MASK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* Generate the hash table settings for the given address
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* addr 48-bit (6 byte) Address to generate the hash for
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* The 6 most significant bits of the 32-bit CRC result
|
||||||
|
*/
|
||||||
|
uint8_t
|
||||||
|
enet_hash_address(const uint8_t* addr)
|
||||||
|
{
|
||||||
|
uint32_t crc;
|
||||||
|
uint8_t byte;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
crc = 0xFFFFFFFF;
|
||||||
|
for(i=0; i<6; ++i)
|
||||||
|
{
|
||||||
|
byte = addr[i];
|
||||||
|
for(j=0; j<8; ++j)
|
||||||
|
{
|
||||||
|
if((byte & 0x01)^(crc & 0x01))
|
||||||
|
{
|
||||||
|
crc >>= 1;
|
||||||
|
crc = crc ^ 0xEDB88320;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
crc >>= 1;
|
||||||
|
byte >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (uint8_t)(crc >> 26);
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* Set the Physical (Hardware) Address and the Individual Address
|
||||||
|
* Hash in the selected FEC
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ch FEC channel
|
||||||
|
* pa Physical (Hardware) Address for the selected FEC
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_set_address (int ch, const uint8_t *pa)
|
||||||
|
{
|
||||||
|
uint8_t crc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the Physical Address
|
||||||
|
*/
|
||||||
|
ENET_PALR/*(ch)*/ = (uint32_t)((pa[0]<<24) | (pa[1]<<16) | (pa[2]<<8) | pa[3]);
|
||||||
|
ENET_PAUR/*(ch)*/ = (uint32_t)((pa[4]<<24) | (pa[5]<<16));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate and set the hash for given Physical Address
|
||||||
|
* in the Individual Address Hash registers
|
||||||
|
*/
|
||||||
|
crc = enet_hash_address(pa);
|
||||||
|
if(crc >= 32)
|
||||||
|
ENET_IAUR/*(ch)*/ |= (uint32_t)(1 << (crc - 32));
|
||||||
|
else
|
||||||
|
ENET_IALR/*(ch)*/ |= (uint32_t)(1 << crc);
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* Reset the selected FEC controller
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* ch FEC channel
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_reset (int ch)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Set the Reset bit and clear the Enable bit */
|
||||||
|
ENET_ECR/*(ch)*/ = ENET_ECR_RESET_MASK;
|
||||||
|
|
||||||
|
/* Wait at least 8 clock cycles */
|
||||||
|
for (i=0; i<10; ++i)
|
||||||
|
asm( "NOP" );
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* Initialize the selected FEC
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* config: ENET parameters
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
enet_init (ENET_CONFIG *config)
|
||||||
|
{
|
||||||
|
/* Clear the Individual and Group Address Hash registers */
|
||||||
|
ENET_IALR/*(ch)*/ = 0;
|
||||||
|
ENET_IAUR/*(ch)*/ = 0;
|
||||||
|
ENET_GALR/*(ch)*/ = 0;
|
||||||
|
ENET_GAUR/*(ch)*/ = 0;
|
||||||
|
|
||||||
|
/* Set the Physical Address for the selected FEC */
|
||||||
|
enet_set_address(config->ch, config->mac);
|
||||||
|
|
||||||
|
/* Mask all FEC interrupts */
|
||||||
|
ENET_EIMR/*(ch)*/ = 0;//FSL:ENET_EIMR_MASK_ALL_MASK;
|
||||||
|
|
||||||
|
/* Clear all FEC interrupt events */
|
||||||
|
ENET_EIR/*(ch)*/ = 0xFFFFFFFF;//FSL:ENET_EIR_CLEAR_ALL_MASK;
|
||||||
|
|
||||||
|
/* Initialize the Receive Control Register */
|
||||||
|
ENET_RCR/*(ch)*/ = 0
|
||||||
|
| ENET_RCR_MAX_FL(ETH_MAX_FRM)
|
||||||
|
| ENET_RCR_MII_MODE_MASK /*always*/
|
||||||
|
| ENET_RCR_CRCFWD_MASK; /*no CRC pad required*/
|
||||||
|
|
||||||
|
if ( config->interface == mac_rmii )
|
||||||
|
{
|
||||||
|
ENET_RCR/*(ch)*/ |= ENET_RCR_RMII_MODE_MASK;
|
||||||
|
|
||||||
|
/*only set speed in RMII mode*/
|
||||||
|
if( config->speed == MII_10BASET )
|
||||||
|
{
|
||||||
|
ENET_RCR/*(ch)*/ |= ENET_RCR_RMII_10T_MASK;
|
||||||
|
}
|
||||||
|
}/*no need to configure MAC MII interface*/
|
||||||
|
|
||||||
|
ENET_TCR/*(ch)*/ = 0;
|
||||||
|
|
||||||
|
/* Set the duplex */
|
||||||
|
enet_duplex(config->ch, config->duplex);
|
||||||
|
|
||||||
|
if (config->prom)
|
||||||
|
{
|
||||||
|
ENET_RCR/*(ch)*/ |= ENET_RCR_PROM_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENHANCED_BD
|
||||||
|
ENET_ECR/*(ch)*/ = ENET_ECR_EN1588_MASK;
|
||||||
|
#else
|
||||||
|
ENET_ECR/*(ch)*/ = 0;//clear register
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(config->loopback == INTERNAL_LOOPBACK)
|
||||||
|
{
|
||||||
|
/*seems like RMII internal loopback works, even if it's not supported*/
|
||||||
|
ENET_RCR/*(0)*/ |= ENET_RCR_LOOP_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
void
|
||||||
|
enet_start (int ch)
|
||||||
|
{
|
||||||
|
// Enable FEC
|
||||||
|
ENET_ECR/*(ch)*/ |= ENET_ECR_ETHEREN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
int
|
||||||
|
enet_wait_for_frame_receive(int ch, int timeout)
|
||||||
|
{
|
||||||
|
int i, return_val = 1;
|
||||||
|
|
||||||
|
for (i=0; i < timeout; i++)
|
||||||
|
{
|
||||||
|
if (ENET_EIR/*(ch)*/ & ENET_EIR_RXF_MASK)
|
||||||
|
{
|
||||||
|
ENET_EIR/*(ch)*/ = ENET_EIR_RXF_MASK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i == timeout)
|
||||||
|
{
|
||||||
|
return_val = 0;
|
||||||
|
}
|
||||||
|
return return_val;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* File: enet.h
|
||||||
|
* Purpose: Driver for the ENET controller
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ENET_H_
|
||||||
|
#define _ENET_H_
|
||||||
|
|
||||||
|
#include "nbuf.h"
|
||||||
|
|
||||||
|
/********INTERFACE**********/
|
||||||
|
typedef enum {
|
||||||
|
mac_mii,
|
||||||
|
mac_rmii,
|
||||||
|
} ENET_INTERFACE;
|
||||||
|
/********AUTONEG**********/
|
||||||
|
typedef enum {
|
||||||
|
autoneg_on,
|
||||||
|
autoneg_off
|
||||||
|
} ENET_AUTONEG;
|
||||||
|
/********SPEED**********/
|
||||||
|
typedef enum {
|
||||||
|
MII_10BASET,
|
||||||
|
MII_100BASET
|
||||||
|
} ENET_SPEED;
|
||||||
|
/********DUPLEX**********/
|
||||||
|
/* MII Duplex Settings */
|
||||||
|
typedef enum {
|
||||||
|
MII_HDX, /*!< half-duplex */
|
||||||
|
MII_FDX /*!< full-duplex */
|
||||||
|
} ENET_DUPLEX;
|
||||||
|
/********LOOPBACK**********/
|
||||||
|
typedef enum {
|
||||||
|
INTERNAL_LOOPBACK,
|
||||||
|
EXTERNAL_LOOPBACK,
|
||||||
|
NO_LOOPBACK
|
||||||
|
} ENET_LOOPBACK;
|
||||||
|
/********EXTERNAL**********/
|
||||||
|
typedef enum {
|
||||||
|
EXTERNAL_NONE,
|
||||||
|
EXTERNAL_YES
|
||||||
|
} ENET_EXTERNAL_CONN;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FEC Configuration Parameters
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t ch; /* FEC channel */
|
||||||
|
ENET_INTERFACE interface; /* Transceiver mode */
|
||||||
|
ENET_AUTONEG neg; /* FEC autoneg */
|
||||||
|
ENET_SPEED speed; /* Ethernet Speed */
|
||||||
|
ENET_DUPLEX duplex; /* Ethernet Duplex */
|
||||||
|
ENET_LOOPBACK loopback; /* Loopback Mode */
|
||||||
|
ENET_EXTERNAL_CONN external; /* outside test? */
|
||||||
|
uint8_t prom; /* Promiscuous Mode? */
|
||||||
|
uint8_t mac[6]; /* Ethernet Address */
|
||||||
|
} ENET_CONFIG;
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_mib_init(int);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_mib_dump(int);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_reg_dump(int);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_duplex (int, ENET_DUPLEX);
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
enet_hash_address(const uint8_t*);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_set_address (int, const uint8_t*);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_reset (int);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_init (ENET_CONFIG *config);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_start (int ch);
|
||||||
|
|
||||||
|
int
|
||||||
|
enet_wait_for_frame_receive(int,int);
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
|
||||||
|
#endif /* _ENET_H_ */
|
@ -0,0 +1,58 @@
|
|||||||
|
/*!
|
||||||
|
* \file eth.h
|
||||||
|
* \brief Definitinos for Ethernet Frames
|
||||||
|
* \version $Revision: 1.1 $
|
||||||
|
* \author Michael Norman
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ETH_H
|
||||||
|
#define _ETH_H
|
||||||
|
|
||||||
|
/*b06862*/
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
/* Ethernet standard lengths in bytes*/
|
||||||
|
#define ETH_ADDR_LEN (6)
|
||||||
|
#define ETH_TYPE_LEN (2)
|
||||||
|
#define ETH_CRC_LEN (4)
|
||||||
|
#define ETH_MAX_DATA (1500)
|
||||||
|
#define ETH_MIN_DATA (46)
|
||||||
|
#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN)
|
||||||
|
|
||||||
|
/* Defined Ethernet Frame Types */
|
||||||
|
#define ETH_FRM_IP (0x0800)
|
||||||
|
#define ETH_FRM_ARP (0x0806)
|
||||||
|
#define ETH_FRM_RARP (0x8035)
|
||||||
|
#define ETH_FRM_TEST (0xA5A5)
|
||||||
|
|
||||||
|
/* Maximum and Minimum Ethernet Frame Sizes */
|
||||||
|
#define ETH_MAX_FRM (ETH_HDR_LEN + ETH_MAX_DATA + ETH_CRC_LEN)
|
||||||
|
#define ETH_MIN_FRM (ETH_HDR_LEN + ETH_MIN_DATA + ETH_CRC_LEN)
|
||||||
|
#define ETH_MTU (ETH_HDR_LEN + ETH_MAX_DATA)
|
||||||
|
|
||||||
|
/* Ethernet Addresses */
|
||||||
|
typedef uint8_t ETH_ADDR[ETH_ADDR_LEN];
|
||||||
|
|
||||||
|
/* 16-bit Ethernet Frame Type, ie. Protocol */
|
||||||
|
typedef uint16_t ETH_FRM_TYPE;
|
||||||
|
|
||||||
|
/* Ethernet Frame Header definition */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ETH_ADDR dest;
|
||||||
|
ETH_ADDR src;
|
||||||
|
ETH_FRM_TYPE type;
|
||||||
|
} ETH_HDR;
|
||||||
|
|
||||||
|
/* Ethernet Frame definition */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ETH_HDR head;
|
||||||
|
uint8_t* data;
|
||||||
|
} ETH_FRAME;
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
#endif /* _ETH_H */
|
@ -0,0 +1,413 @@
|
|||||||
|
/*!
|
||||||
|
* \file eth_phy.c
|
||||||
|
* \brief Ethernet Physical Layer Interface Driver
|
||||||
|
* \version $Revision: 1.3 $
|
||||||
|
* \author Michael Norman
|
||||||
|
*
|
||||||
|
* This is a generic driver for all Ethernet PHYs with the basic MII registers
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "eth_phy.h"
|
||||||
|
#include "mii.h"
|
||||||
|
|
||||||
|
/* Variable to save off auto-negotiate settings */
|
||||||
|
int eth_phy_anar = 0
|
||||||
|
| PHY_ANAR_100BTX_FDX
|
||||||
|
| PHY_ANAR_100BTX
|
||||||
|
| PHY_ANAR_10BT_FDX
|
||||||
|
| PHY_ANAR_10BT;
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_reset(int ch, int phy_addr)
|
||||||
|
{
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
int timeout;
|
||||||
|
#endif
|
||||||
|
int settings;
|
||||||
|
|
||||||
|
/* Reset the PHY */
|
||||||
|
if (mii_write(ch, phy_addr, PHY_BMCR, PHY_BMCR_RESET))
|
||||||
|
return 1;
|
||||||
|
/* Wait for reset to complete */
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
for (timeout = 0; timeout < MII_LINK_TIMEOUT; ++timeout)
|
||||||
|
#endif
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
/* Read back the contents of the CTRL register and verify
|
||||||
|
* that RESET is not set - this is a sanity check to ensure
|
||||||
|
* that we are talking to the PHY correctly. RESET should
|
||||||
|
* always be cleared. */
|
||||||
|
if (!(mii_read(ch, phy_addr, PHY_BMCR, &settings)) && !(settings & PHY_BMCR_RESET))
|
||||||
|
break;/*FSL: ready*/
|
||||||
|
}
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_LINK_TIMEOUT || (settings & PHY_BMCR_RESET))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Enable the Ethernet PHY in auto-negotiate mode
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param speed Desired speed (MII_10BASE_T or MII_100BASE_TX)
|
||||||
|
* \param duplex Desired duplex (MII_FDX or MII_HDX)
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_autoneg(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex)
|
||||||
|
{
|
||||||
|
int timeout, settings;
|
||||||
|
|
||||||
|
/* Reset the PHY */
|
||||||
|
eth_phy_reset(ch, phy_addr);
|
||||||
|
|
||||||
|
/* Set the Auto-Negotiation Advertisement Register */
|
||||||
|
if (speed == MII_10BASET)
|
||||||
|
{
|
||||||
|
settings = (duplex == MII_FDX)
|
||||||
|
? PHY_ANAR_10BT_FDX | PHY_ANAR_10BT
|
||||||
|
: PHY_ANAR_10BT;
|
||||||
|
}
|
||||||
|
else /* (speed == MII_100BASET) */
|
||||||
|
{
|
||||||
|
settings = (duplex == MII_FDX)
|
||||||
|
? PHY_ANAR_100BTX_FDX |
|
||||||
|
PHY_ANAR_100BTX |
|
||||||
|
PHY_ANAR_10BT_FDX |
|
||||||
|
PHY_ANAR_10BT
|
||||||
|
: PHY_ANAR_10BT_FDX |
|
||||||
|
PHY_ANAR_10BT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save off the settings we just advertised */
|
||||||
|
eth_phy_anar = settings;
|
||||||
|
|
||||||
|
if (mii_write(ch, phy_addr, PHY_ANAR, settings))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Enable Auto-Negotiation */
|
||||||
|
if (mii_write(ch, phy_addr, PHY_BMCR, PHY_BMCR_AN_ENABLE | PHY_BMCR_AN_RESTART))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Wait for auto-negotiation to complete */
|
||||||
|
for (timeout = 0; timeout < MII_LINK_TIMEOUT; ++timeout)
|
||||||
|
{
|
||||||
|
if (mii_read(ch, phy_addr, PHY_BMSR, &settings))
|
||||||
|
return 1;
|
||||||
|
if (settings & PHY_BMSR_AN_COMPLETE)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Read the BMSR one last time */
|
||||||
|
if (mii_read(ch, phy_addr, PHY_BMSR, &settings))
|
||||||
|
return 1;
|
||||||
|
if (timeout == MII_LINK_TIMEOUT || !(settings & PHY_BMSR_LINK))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Enable the Ethernet PHY in manual mode
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param speed Desired speed (MII_10BASE_T or MII_100BASE_TX)
|
||||||
|
* \param duplex Desired duplex (MII_FDX or MII_HDX)
|
||||||
|
* \param loop Put PHY in loopback mode?
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_manual(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex, int loop)
|
||||||
|
{
|
||||||
|
int timeout;
|
||||||
|
int settings = 0;
|
||||||
|
|
||||||
|
/* Reset the PHY */
|
||||||
|
/* Reset the PHY */
|
||||||
|
eth_phy_reset(ch, phy_addr);
|
||||||
|
|
||||||
|
if (loop)
|
||||||
|
settings |= PHY_BMCR_LOOP;
|
||||||
|
if (duplex == MII_FDX)
|
||||||
|
settings |= PHY_BMCR_FDX;
|
||||||
|
if (speed == MII_100BASET)
|
||||||
|
settings |= PHY_BMCR_SPEED;
|
||||||
|
|
||||||
|
if (mii_write(ch, phy_addr, PHY_BMCR, settings))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Wait for link */
|
||||||
|
for (timeout = 0; timeout < MII_LINK_TIMEOUT; ++timeout)
|
||||||
|
{
|
||||||
|
if (mii_read(ch, phy_addr, PHY_BMSR, &settings))
|
||||||
|
return 1;
|
||||||
|
if (settings & PHY_BMSR_LINK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_LINK_TIMEOUT || !(settings & PHY_BMSR_LINK))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Get the auto-negotiated speed
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param speed Pointer where speed data is stored
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_get_speed(int ch, int phy_addr, int *speed)
|
||||||
|
{
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
int timeout;
|
||||||
|
#endif
|
||||||
|
int settings = 0;
|
||||||
|
|
||||||
|
/* Get Link Partner settings */
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
|
||||||
|
#endif
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if (mii_read(ch, phy_addr, PHY_ANLPAR, &settings))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
settings &= eth_phy_anar;
|
||||||
|
if (settings & PHY_ANLPAR_100BT4 ||
|
||||||
|
settings & PHY_ANLPAR_100BTX_FDX ||
|
||||||
|
settings & PHY_ANLPAR_100BTX)
|
||||||
|
*speed = MII_100BASET;
|
||||||
|
else
|
||||||
|
*speed = MII_10BASET;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Get the auto-negotiated duplex
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param speed Pointer where speed data is stored
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_get_duplex(int ch, int phy_addr, int *speed)
|
||||||
|
{
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
int timeout;
|
||||||
|
#endif
|
||||||
|
int settings = 0;
|
||||||
|
|
||||||
|
/* Get Link Partner settings */
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
|
||||||
|
#endif
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if (mii_read(ch, phy_addr, PHY_ANLPAR, &settings))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
settings &= eth_phy_anar;
|
||||||
|
if (settings & PHY_ANLPAR_100BTX_FDX ||
|
||||||
|
settings & PHY_ANLPAR_10BTX_FDX)
|
||||||
|
*speed = MII_FDX;
|
||||||
|
else
|
||||||
|
*speed = MII_HDX;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Get the manual speed
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param speed Pointer where speed data is stored
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_get_manual_speed(int ch, int phy_addr, int *speed)
|
||||||
|
{
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
int timeout;
|
||||||
|
#endif
|
||||||
|
int settings = 0;
|
||||||
|
|
||||||
|
/* Get Link Partner settings */
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
|
||||||
|
#endif
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
#ifdef TWR_K60N512
|
||||||
|
if (mii_read(ch, phy_addr, PHY_PHYCTRL2, &settings))//Micrel
|
||||||
|
#else
|
||||||
|
if (mii_read(ch, phy_addr, PHY_PHYSTS, &settings))//National Semiconductors
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TWR_K60N512
|
||||||
|
/*FSL: obtain speed/duplex*/
|
||||||
|
settings = (settings & PHY_PHYCTRL2_OP_MOD_MASK)>>PHY_PHYCTRL2_OP_MOD_SHIFT;
|
||||||
|
|
||||||
|
if (settings == PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD ||
|
||||||
|
settings == PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_FD)
|
||||||
|
*speed = MII_10BASET;
|
||||||
|
else
|
||||||
|
*speed = MII_100BASET;
|
||||||
|
#else
|
||||||
|
if (settings & PHY_PHYSTS_SPEEDSTATUS)
|
||||||
|
*speed = MII_10BASET;
|
||||||
|
else
|
||||||
|
*speed = MII_100BASET;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Get the manual duplex
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param duplex Pointer where duplex data is stored
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_get_manual_duplex(int ch, int phy_addr, int *duplex)
|
||||||
|
{
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
int timeout;
|
||||||
|
#endif
|
||||||
|
int settings = 0;
|
||||||
|
|
||||||
|
/* Get Link Partner settings */
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
|
||||||
|
#endif
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
#ifdef TWR_K60N512
|
||||||
|
if (mii_read(ch, phy_addr, PHY_PHYCTRL2, &settings))//Micrel
|
||||||
|
#else
|
||||||
|
if (mii_read(ch, phy_addr, PHY_PHYSTS, &settings))//National Semiconductors
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TWR_K60N512
|
||||||
|
/*FSL: obtain speed/duplex*/
|
||||||
|
settings = (settings & PHY_PHYCTRL2_OP_MOD_MASK)>>PHY_PHYCTRL2_OP_MOD_SHIFT;
|
||||||
|
|
||||||
|
if (settings == PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD ||
|
||||||
|
settings == PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_HD)
|
||||||
|
*duplex = MII_HDX;
|
||||||
|
else
|
||||||
|
*duplex = MII_FDX;
|
||||||
|
#else
|
||||||
|
if (settings & PHY_PHYSTS_DUPLEXSTATUS)
|
||||||
|
*duplex = MII_FDX;
|
||||||
|
else
|
||||||
|
*duplex = MII_HDX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Get the manual speed
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param loop set if loopback is needed
|
||||||
|
* \return 0 if successful; non-zero otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_set_remote_loopback(int ch, int phy_addr, int loop)
|
||||||
|
{
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
int timeout;
|
||||||
|
#endif
|
||||||
|
int settings = 0;
|
||||||
|
|
||||||
|
/* Get Link Partner settings */
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; ++timeout)
|
||||||
|
#endif
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if (mii_read(ch, phy_addr, PHY_PHYCTRL1, &settings))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if MII_CHECK_TIMEOUT
|
||||||
|
if (timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
/*set remote loopback flag*/
|
||||||
|
if(loop)
|
||||||
|
settings |= PHY_PHYCTRL1_REMOTE_LOOP; /*set bit*/
|
||||||
|
else
|
||||||
|
settings &= ~PHY_PHYCTRL1_REMOTE_LOOP; /*clear bit*/
|
||||||
|
|
||||||
|
if (mii_write(ch, phy_addr, PHY_PHYCTRL1, settings))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Print all the MII registers (0x00-0x1F)
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eth_phy_reg_dump(int ch, int phy_addr)
|
||||||
|
{
|
||||||
|
int j, settings;
|
||||||
|
|
||||||
|
printf("\n MII Register Block\n");
|
||||||
|
printf("--------------------------------");
|
||||||
|
for (j = 0; j < 32; j++)
|
||||||
|
{
|
||||||
|
mii_read(ch, phy_addr, j, &settings);
|
||||||
|
if (!(j % 4))
|
||||||
|
printf("\n0x%02X-0x%02X : %04X ", j, j + 3, settings);
|
||||||
|
else
|
||||||
|
printf("%04X ", settings);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,175 @@
|
|||||||
|
/*!
|
||||||
|
* \file eth.h
|
||||||
|
* \brief Definitions for Ethernet Physical Layer Interface
|
||||||
|
* \version $Revision: 1.3 $
|
||||||
|
* \author Michael Norman
|
||||||
|
* \modif b06862
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ETH_PHY_H
|
||||||
|
#define _ETH_PHY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "enet.h"
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_reset(int ch, int phy_addr);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_autoneg(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_manual(int ch, int phy_addr, ENET_SPEED speed, ENET_DUPLEX duplex, int loop);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_get_speed(int, int, int*);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_get_duplex(int, int, int*);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_get_manual_speed(int, int, int*);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_get_manual_duplex(int, int, int*);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_set_remote_loopback(int, int, int);
|
||||||
|
|
||||||
|
int
|
||||||
|
eth_phy_reg_dump(int, int);
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
/* MII Register Addresses */
|
||||||
|
#define PHY_BMCR (0x00)
|
||||||
|
#define PHY_BMSR (0x01)
|
||||||
|
#define PHY_PHYIDR1 (0x02)
|
||||||
|
#define PHY_PHYIDR2 (0x03)
|
||||||
|
#define PHY_ANAR (0x04)
|
||||||
|
#define PHY_ANLPAR (0x05)
|
||||||
|
#define PHY_ANLPARNP (0x05)
|
||||||
|
#define PHY_ANER (0x06)
|
||||||
|
#define PHY_ANNPTR (0x07)
|
||||||
|
#define PHY_PHYSTS (0x10)
|
||||||
|
#define PHY_MICR (0x11)
|
||||||
|
#define PHY_MISR (0x12)
|
||||||
|
#define PHY_PAGESEL (0x13)
|
||||||
|
|
||||||
|
/*TSI-EVB definition: National Semiconductor*/
|
||||||
|
#define PHY_PHYCR2 (0x1C)
|
||||||
|
|
||||||
|
/*TWR definition: Micrel*/
|
||||||
|
#define PHY_PHYCTRL1 (0x1E)
|
||||||
|
#define PHY_PHYCTRL2 (0x1F)
|
||||||
|
|
||||||
|
/* Bit definitions and macros for PHY_BMCR */
|
||||||
|
#define PHY_BMCR_RESET (0x8000)
|
||||||
|
#define PHY_BMCR_LOOP (0x4000)
|
||||||
|
#define PHY_BMCR_SPEED (0x2000)
|
||||||
|
#define PHY_BMCR_AN_ENABLE (0x1000)
|
||||||
|
#define PHY_BMCR_POWERDOWN (0x0800)
|
||||||
|
#define PHY_BMCR_ISOLATE (0x0400)
|
||||||
|
#define PHY_BMCR_AN_RESTART (0x0200)
|
||||||
|
#define PHY_BMCR_FDX (0x0100)
|
||||||
|
#define PHY_BMCR_COL_TEST (0x0080)
|
||||||
|
|
||||||
|
/* Bit definitions and macros for PHY_BMSR */
|
||||||
|
#define PHY_BMSR_100BT4 (0x8000)
|
||||||
|
#define PHY_BMSR_100BTX_FDX (0x4000)
|
||||||
|
#define PHY_BMSR_100BTX (0x2000)
|
||||||
|
#define PHY_BMSR_10BT_FDX (0x1000)
|
||||||
|
#define PHY_BMSR_10BT (0x0800)
|
||||||
|
#define PHY_BMSR_NO_PREAMBLE (0x0040)
|
||||||
|
#define PHY_BMSR_AN_COMPLETE (0x0020)
|
||||||
|
#define PHY_BMSR_REMOTE_FAULT (0x0010)
|
||||||
|
#define PHY_BMSR_AN_ABILITY (0x0008)
|
||||||
|
#define PHY_BMSR_LINK (0x0004)
|
||||||
|
#define PHY_BMSR_JABBER (0x0002)
|
||||||
|
#define PHY_BMSR_EXTENDED (0x0001)
|
||||||
|
|
||||||
|
/* Bit definitions and macros for PHY_ANAR */
|
||||||
|
#define PHY_ANAR_NEXT_PAGE (0x8001)
|
||||||
|
#define PHY_ANAR_REM_FAULT (0x2001)
|
||||||
|
#define PHY_ANAR_PAUSE (0x0401)
|
||||||
|
#define PHY_ANAR_100BT4 (0x0201)
|
||||||
|
#define PHY_ANAR_100BTX_FDX (0x0101)
|
||||||
|
#define PHY_ANAR_100BTX (0x0081)
|
||||||
|
#define PHY_ANAR_10BT_FDX (0x0041)
|
||||||
|
#define PHY_ANAR_10BT (0x0021)
|
||||||
|
#define PHY_ANAR_802_3 (0x0001)
|
||||||
|
|
||||||
|
/* Bit definitions and macros for PHY_ANLPAR */
|
||||||
|
#define PHY_ANLPAR_NEXT_PAGE (0x8000)
|
||||||
|
#define PHY_ANLPAR_ACK (0x4000)
|
||||||
|
#define PHY_ANLPAR_REM_FAULT (0x2000)
|
||||||
|
#define PHY_ANLPAR_PAUSE (0x0400)
|
||||||
|
#define PHY_ANLPAR_100BT4 (0x0200)
|
||||||
|
#define PHY_ANLPAR_100BTX_FDX (0x0100)
|
||||||
|
#define PHY_ANLPAR_100BTX (0x0080)
|
||||||
|
#define PHY_ANLPAR_10BTX_FDX (0x0040)
|
||||||
|
#define PHY_ANLPAR_10BT (0x0020)
|
||||||
|
|
||||||
|
|
||||||
|
/* Bit definitions of PHY_PHYSTS: National */
|
||||||
|
#define PHY_PHYSTS_MDIXMODE (0x4000)
|
||||||
|
#define PHY_PHYSTS_RX_ERR_LATCH (0x2000)
|
||||||
|
#define PHY_PHYSTS_POL_STATUS (0x1000)
|
||||||
|
#define PHY_PHYSTS_FALSECARRSENSLAT (0x0800)
|
||||||
|
#define PHY_PHYSTS_SIGNALDETECT (0x0400)
|
||||||
|
#define PHY_PHYSTS_PAGERECEIVED (0x0100)
|
||||||
|
#define PHY_PHYSTS_MIIINTERRUPT (0x0080)
|
||||||
|
#define PHY_PHYSTS_REMOTEFAULT (0x0040)
|
||||||
|
#define PHY_PHYSTS_JABBERDETECT (0x0020)
|
||||||
|
#define PHY_PHYSTS_AUTONEGCOMPLETE (0x0010)
|
||||||
|
#define PHY_PHYSTS_LOOPBACKSTATUS (0x0008)
|
||||||
|
#define PHY_PHYSTS_DUPLEXSTATUS (0x0004)
|
||||||
|
#define PHY_PHYSTS_SPEEDSTATUS (0x0002)
|
||||||
|
#define PHY_PHYSTS_LINKSTATUS (0x0001)
|
||||||
|
|
||||||
|
|
||||||
|
/* Bit definitions of PHY_PHYCR2 */
|
||||||
|
#define PHY_PHYCR2_SYNC_ENET_EN (0x2000)
|
||||||
|
#define PHY_PHYCR2_CLK_OUT_RXCLK (0x1000)
|
||||||
|
#define PHY_PHYCR2_BC_WRITE (0x0800)
|
||||||
|
#define PHY_PHYCR2_PHYTER_COMP (0x0400)
|
||||||
|
#define PHY_PHYCR2_SOFT_RESET (0x0200)
|
||||||
|
#define PHY_PHYCR2_CLK_OUT_DIS (0x0001)
|
||||||
|
|
||||||
|
/* Bit definition and macros for PHY_PHYCTRL1 */
|
||||||
|
#define PHY_PHYCTRL1_LED_MASK (0xC000)
|
||||||
|
#define PHY_PHYCTRL1_POLARITY (0x2000)
|
||||||
|
#define PHY_PHYCTRL1_MDX_STATE (0x0800)
|
||||||
|
#define PHY_PHYCTRL1_REMOTE_LOOP (0x0080)
|
||||||
|
|
||||||
|
/* Bit definition and macros for PHY_PHYCTRL2 */
|
||||||
|
#define PHY_PHYCTRL2_HP_MDIX (0x8000)
|
||||||
|
#define PHY_PHYCTRL2_MDIX_SELECT (0x4000)
|
||||||
|
#define PHY_PHYCTRL2_PAIRSWAP_DIS (0x2000)
|
||||||
|
#define PHY_PHYCTRL2_ENERGY_DET (0x1000)
|
||||||
|
#define PHY_PHYCTRL2_FORCE_LINK (0x0800)
|
||||||
|
#define PHY_PHYCTRL2_POWER_SAVING (0x0400)
|
||||||
|
#define PHY_PHYCTRL2_INT_LEVEL (0x0200)
|
||||||
|
#define PHY_PHYCTRL2_EN_JABBER (0x0100)
|
||||||
|
#define PHY_PHYCTRL2_AUTONEG_CMPLT (0x0080)
|
||||||
|
#define PHY_PHYCTRL2_ENABLE_PAUSE (0x0040)
|
||||||
|
#define PHY_PHYCTRL2_PHY_ISOLATE (0x0020)
|
||||||
|
#define PHY_PHYCTRL2_OP_MOD_MASK (0x001C)
|
||||||
|
#define PHY_PHYCTRL2_EN_SQE_TEST (0x0002)
|
||||||
|
#define PHY_PHYCTRL2_DATA_SCRAM_DIS (0x0001)
|
||||||
|
|
||||||
|
|
||||||
|
/* Bit definitions of PHY_PHYCTRL2_OP_MOD_MASK */
|
||||||
|
#define PHY_PHYCTRL2_OP_MOD_SHIFT 2
|
||||||
|
#define PHY_PHYCTRL2_MODE_OP_MOD_STILL_NEG 0
|
||||||
|
#define PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_HD 1
|
||||||
|
#define PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_HD 2
|
||||||
|
#define PHY_PHYCTRL2_MODE_OP_MOD_10MBPS_FD 5
|
||||||
|
#define PHY_PHYCTRL2_MODE_OP_MOD_100MBPS_FD 6
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
#endif /* _ETH_PHY_H */
|
@ -0,0 +1,130 @@
|
|||||||
|
/*!
|
||||||
|
* \file mii.c
|
||||||
|
* \brief Media Independent Interface (MII) driver
|
||||||
|
* \version $Revision: 1.2 $
|
||||||
|
* \author Michael Norman
|
||||||
|
*
|
||||||
|
* \warning This driver assumes that FEC0 is used for all MII management
|
||||||
|
* communications. For dual PHYs, etc. Insure that FEC0_MDC and
|
||||||
|
* FEC0_MDIO are connected to the PHY's MDC and MDIO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "mii.h"
|
||||||
|
|
||||||
|
/********************************************************************/
|
||||||
|
/*
|
||||||
|
* \brief Initialize the MII interface controller
|
||||||
|
* \param System Clock Frequency (in MHz)
|
||||||
|
* \warning The system clock in this case is the clock that drives
|
||||||
|
* the FEC logic. This may be different from the speed at which
|
||||||
|
* the CPU is operating.
|
||||||
|
*
|
||||||
|
* Initialize the MII clock (EMDC) frequency. The desired MII clock is 2.5MHz:
|
||||||
|
*
|
||||||
|
* MII Speed Setting = System_Clock / (2.5MHz * 2)
|
||||||
|
* (plus 1 to round up)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
mii_init(int ch, int sys_clk_mhz)
|
||||||
|
{
|
||||||
|
ENET_MSCR/*(ch)*/ = 0
|
||||||
|
#ifdef TSIEVB/*TSI EVB requires a longer hold time than default 10 ns*/
|
||||||
|
| ENET_MSCR_HOLDTIME(2)
|
||||||
|
#endif
|
||||||
|
| ENET_MSCR_MII_SPEED((2*sys_clk_mhz/5)+1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Write a value to a PHY's MII register.
|
||||||
|
*
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param reg_addr Address of the register in the PHY
|
||||||
|
* \param data Data to be written to the PHY register
|
||||||
|
* \return 0 if write is successful; 1 if write times out
|
||||||
|
*
|
||||||
|
* mii_write() polls for the FEC's MII interrupt event (which should
|
||||||
|
* be masked from the interrupt handler) and clears it. If after a
|
||||||
|
* suitable amount of time the event isn't triggered, a non-zero value
|
||||||
|
* is returned.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
mii_write(int ch, int phy_addr, int reg_addr, int data)
|
||||||
|
{
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
/* Clear the MII interrupt bit */
|
||||||
|
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
|
||||||
|
|
||||||
|
/* Initiatate the MII Management write */
|
||||||
|
ENET_MMFR/*(ch)*/ = 0
|
||||||
|
| ENET_MMFR_ST(0x01)
|
||||||
|
| ENET_MMFR_OP(0x01)
|
||||||
|
| ENET_MMFR_PA(phy_addr)
|
||||||
|
| ENET_MMFR_RA(reg_addr)
|
||||||
|
| ENET_MMFR_TA(0x02)
|
||||||
|
| ENET_MMFR_DATA(data);
|
||||||
|
|
||||||
|
/* Poll for the MII interrupt (interrupt should be masked) */
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
|
||||||
|
{
|
||||||
|
if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Clear the MII interrupt bit */
|
||||||
|
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
||||||
|
/*!
|
||||||
|
* \brief Read a value from a PHY's MII register.
|
||||||
|
* \param phy_addr Address of the PHY
|
||||||
|
* \param reg_addr Address of the register in the PHY
|
||||||
|
* \param data Pointer to location were read data will be stored
|
||||||
|
* \return 0 if write is successful; 1 if write times out
|
||||||
|
*
|
||||||
|
* mii_read() polls for the FEC's MII interrupt event (which should
|
||||||
|
* be masked from the interrupt handler) and clears it. If after a
|
||||||
|
* suitable amount of time the event isn't triggered, a non-zero value
|
||||||
|
* is returned.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
mii_read(int ch, int phy_addr, int reg_addr, int *data)
|
||||||
|
{
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
/* Clear the MII interrupt bit */
|
||||||
|
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
|
||||||
|
|
||||||
|
/* Initiatate the MII Management read */
|
||||||
|
ENET_MMFR/*(ch)*/ = 0
|
||||||
|
| ENET_MMFR_ST(0x01)
|
||||||
|
| ENET_MMFR_OP(0x2)
|
||||||
|
| ENET_MMFR_PA(phy_addr)
|
||||||
|
| ENET_MMFR_RA(reg_addr)
|
||||||
|
| ENET_MMFR_TA(0x02);
|
||||||
|
|
||||||
|
/* Poll for the MII interrupt (interrupt should be masked) */
|
||||||
|
for (timeout = 0; timeout < MII_TIMEOUT; timeout++)
|
||||||
|
{
|
||||||
|
if (ENET_EIR/*(ch)*/ & ENET_EIR_MII_MASK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(timeout == MII_TIMEOUT)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Clear the MII interrupt bit */
|
||||||
|
ENET_EIR/*(ch)*/ = ENET_EIR_MII_MASK;
|
||||||
|
|
||||||
|
*data = ENET_MMFR/*(ch)*/ & 0x0000FFFF;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/********************************************************************/
|
@ -0,0 +1,30 @@
|
|||||||
|
/*!
|
||||||
|
* \file mii.h
|
||||||
|
* \brief Media Independent Interface (MII) driver
|
||||||
|
* \version $Revision: 1.2 $
|
||||||
|
* \author Michael Norman
|
||||||
|
*
|
||||||
|
* \warning
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MII_H_
|
||||||
|
#define _MII_H_
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
#define MII_TIMEOUT 0x1FFFF
|
||||||
|
#define MII_LINK_TIMEOUT 0x1FFFF
|
||||||
|
|
||||||
|
void
|
||||||
|
mii_init(int, int);
|
||||||
|
|
||||||
|
int
|
||||||
|
mii_write(int, int, int, int);
|
||||||
|
|
||||||
|
int
|
||||||
|
mii_read(int, int, int, int*);
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
#endif /* _MII_H_ */
|
@ -0,0 +1,233 @@
|
|||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// File: nbuf.h
|
||||||
|
// Purpose: Definitions for Network Buffer Allocation.
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef _NBUF_H_
|
||||||
|
#define _NBUF_H_
|
||||||
|
|
||||||
|
// Define number of MACs
|
||||||
|
#define NUM_CHANNELS 1/*b06862*/
|
||||||
|
|
||||||
|
// Choose Enhanced Buffer Descriptor or Legacy
|
||||||
|
#define ENHANCED_BD
|
||||||
|
|
||||||
|
//b06862: define Endianess for Little Endian architectures like ARM.
|
||||||
|
//Motorola/Freescale uses Big Endian or Register-Endianess
|
||||||
|
#define NBUF_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
// Transmit packet directly or copy to dedicated buffers. If packets
|
||||||
|
// are not alligned dedicated Tx buffers can be used
|
||||||
|
//#define USE_DEDICATED_TX_BUFFERS
|
||||||
|
|
||||||
|
// Buffer sizes in bytes (must be divisible by 16)
|
||||||
|
#define RX_BUFFER_SIZE 256
|
||||||
|
#define TX_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
// Number of Receive and Transmit Buffers and Buffer Descriptors
|
||||||
|
#define NUM_RXBDS 20//10
|
||||||
|
#define NUM_TXBDS 20//10
|
||||||
|
|
||||||
|
// Buffer Descriptor Format
|
||||||
|
#ifdef ENHANCED_BD
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t status; /* control and status */
|
||||||
|
uint16_t length; /* transfer length */
|
||||||
|
uint8_t *data; /* buffer address */
|
||||||
|
uint32_t ebd_status;
|
||||||
|
uint16_t length_proto_type;
|
||||||
|
uint16_t payload_checksum;
|
||||||
|
uint32_t bdu;
|
||||||
|
uint32_t timestamp;
|
||||||
|
uint32_t reserverd_word1;
|
||||||
|
uint32_t reserverd_word2;
|
||||||
|
} NBUF;
|
||||||
|
#else
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t status; /* control and status */
|
||||||
|
uint16_t length; /* transfer length */
|
||||||
|
uint8_t *data; /* buffer address */
|
||||||
|
} NBUF;
|
||||||
|
#endif /* ENHANCED_BD */
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Function Declarations
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
nbuf_alloc(int ch);
|
||||||
|
|
||||||
|
void
|
||||||
|
nbuf_init(int);
|
||||||
|
|
||||||
|
void
|
||||||
|
nbuf_start_rx(int);
|
||||||
|
|
||||||
|
void
|
||||||
|
nbuf_flush(int);
|
||||||
|
|
||||||
|
//NM - return value
|
||||||
|
void
|
||||||
|
enet_get_received_packet(int, NBUF *);
|
||||||
|
|
||||||
|
//NM - return value
|
||||||
|
void
|
||||||
|
enet_fill_txbds(int, NBUF *);
|
||||||
|
|
||||||
|
void
|
||||||
|
enet_transmit_packet(int,NBUF *);
|
||||||
|
|
||||||
|
#ifdef NBUF_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
//For Freescale ARM Architecture
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// TX Buffer Descriptor Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
#define TX_BD_R 0x0080
|
||||||
|
#define TX_BD_TO1 0x0040
|
||||||
|
#define TX_BD_W 0x0020
|
||||||
|
#define TX_BD_TO2 0x0010
|
||||||
|
#define TX_BD_L 0x0008
|
||||||
|
#define TX_BD_TC 0x0004
|
||||||
|
#define TX_BD_ABC 0x0002
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// TX Enhanced BD Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
#define TX_BD_INT 0x00000040
|
||||||
|
#define TX_BD_TS 0x00000020
|
||||||
|
#define TX_BD_PINS 0x00000010
|
||||||
|
#define TX_BD_IINS 0x00000008
|
||||||
|
#define TX_BD_TXE 0x00800000
|
||||||
|
#define TX_BD_UE 0x00200000
|
||||||
|
#define TX_BD_EE 0x00100000
|
||||||
|
#define TX_BD_FE 0x00080000
|
||||||
|
#define TX_BD_LCE 0x00040000
|
||||||
|
#define TX_BD_OE 0x00020000
|
||||||
|
#define TX_BD_TSE 0x00010000
|
||||||
|
|
||||||
|
#define TX_BD_BDU 0x00000080
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// RX Buffer Descriptor Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Offset 0 flags - status: Big Endian
|
||||||
|
#define RX_BD_E 0x0080
|
||||||
|
#define RX_BD_R01 0x0040
|
||||||
|
#define RX_BD_W 0x0020
|
||||||
|
#define RX_BD_R02 0x0010
|
||||||
|
#define RX_BD_L 0x0008
|
||||||
|
#define RX_BD_M 0x0001
|
||||||
|
#define RX_BD_BC 0x8000
|
||||||
|
#define RX_BD_MC 0x4000
|
||||||
|
#define RX_BD_LG 0x2000
|
||||||
|
#define RX_BD_NO 0x1000
|
||||||
|
#define RX_BD_CR 0x0400
|
||||||
|
#define RX_BD_OV 0x0200
|
||||||
|
#define RX_BD_TR 0x0100
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// RX Enhanced BD Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
#define RX_BD_ME 0x00000080
|
||||||
|
#define RX_BD_PE 0x00000004
|
||||||
|
#define RX_BD_CE 0x00000002
|
||||||
|
#define RX_BD_UC 0x00000001
|
||||||
|
|
||||||
|
#define RX_BD_INT 0x00008000
|
||||||
|
|
||||||
|
#define RX_BD_ICE 0x20000000
|
||||||
|
#define RX_BD_PCR 0x10000000
|
||||||
|
#define RX_BD_VLAN 0x04000000
|
||||||
|
#define RX_BD_IPV6 0x02000000
|
||||||
|
#define RX_BD_FRAG 0x01000000
|
||||||
|
|
||||||
|
#define RX_BD_BDU 0x00000080
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
//For Freescale ColdFire Architecture
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// TX Buffer Descriptor Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
#define TX_BD_R 0x8000
|
||||||
|
#define TX_BD_TO1 0x4000
|
||||||
|
#define TX_BD_W 0x2000
|
||||||
|
#define TX_BD_TO2 0x1000
|
||||||
|
#define TX_BD_L 0x0800
|
||||||
|
#define TX_BD_TC 0x0400
|
||||||
|
#define TX_BD_ABC 0x0200
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// TX Enhanced BD Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
#define TX_BD_INT 0x40000000
|
||||||
|
#define TX_BD_TS 0x20000000
|
||||||
|
#define TX_BD_PINS 0x10000000
|
||||||
|
#define TX_BD_IINS 0x08000000
|
||||||
|
#define TX_BD_TXE 0x00008000
|
||||||
|
#define TX_BD_UE 0x00002000
|
||||||
|
#define TX_BD_EE 0x00001000
|
||||||
|
#define TX_BD_FE 0x00000800
|
||||||
|
#define TX_BD_LCE 0x00000400
|
||||||
|
#define TX_BD_OE 0x00000200
|
||||||
|
#define TX_BD_TSE 0x00000100
|
||||||
|
|
||||||
|
#define TX_BD_BDU 0x80000000
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// RX Buffer Descriptor Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Offset 0 flags - status
|
||||||
|
#define RX_BD_E 0x8000
|
||||||
|
#define RX_BD_R01 0x4000
|
||||||
|
#define RX_BD_W 0x2000
|
||||||
|
#define RX_BD_R02 0x1000
|
||||||
|
#define RX_BD_L 0x0800
|
||||||
|
#define RX_BD_M 0x0100
|
||||||
|
#define RX_BD_BC 0x0080
|
||||||
|
#define RX_BD_MC 0x0040
|
||||||
|
#define RX_BD_LG 0x0020
|
||||||
|
#define RX_BD_NO 0x0010
|
||||||
|
#define RX_BD_CR 0x0004
|
||||||
|
#define RX_BD_OV 0x0002
|
||||||
|
#define RX_BD_TR 0x0001
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// RX Enhanced BD Bit Definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
#define RX_BD_ME 0x80000000
|
||||||
|
#define RX_BD_PE 0x04000000
|
||||||
|
#define RX_BD_CE 0x02000000
|
||||||
|
#define RX_BD_UC 0x01000000
|
||||||
|
#define RX_BD_INT 0x00800000
|
||||||
|
#define RX_BD_ICE 0x00000020
|
||||||
|
#define RX_BD_PCR 0x00000010
|
||||||
|
#define RX_BD_VLAN 0x00000004
|
||||||
|
#define RX_BD_IPV6 0x00000002
|
||||||
|
#define RX_BD_FRAG 0x00000001
|
||||||
|
|
||||||
|
#define RX_BD_BDU 0x80000000
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Defines for word offsets of various fields of RX Enhanced BDs
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//#define RX_EBD_HEADER_LENGTH_OFFSET 12
|
||||||
|
//#define RX_EBD_PROTOCOL_TYPE_OFFSET 12
|
||||||
|
//#define RX_EBD_PAYLOAD_CHKSM_OFFSET 14
|
||||||
|
//#define RX_EBD_BDU_OFFSET 16
|
||||||
|
//#define RX_EBD_TIMESTAMP_MSB_OFFSET 20
|
||||||
|
//#define RX_EBD_TIMESTAMP_LSB_OFFSET 22
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _NBUF_H_ */
|
@ -0,0 +1,354 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Scheduler includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
|
/* uip includes. */
|
||||||
|
#include "net/uip.h"
|
||||||
|
#include "net/uip_arp.h"
|
||||||
|
#include "apps/httpd/httpd.h"
|
||||||
|
#include "sys/timer.h"
|
||||||
|
#include "net/clock-arch.h"
|
||||||
|
#include "emac.h"
|
||||||
|
|
||||||
|
/* Demo includes. */
|
||||||
|
#include "ParTest.h"
|
||||||
|
|
||||||
|
/* The buffer used by the uIP stack to both receive and send. In this case,
|
||||||
|
because the Ethernet driver has been modified to be zero copy - the uip_buf
|
||||||
|
variable is just a pointer to an Ethernet buffer, and not a buffer in its own
|
||||||
|
right. */
|
||||||
|
extern unsigned char *uip_buf;
|
||||||
|
|
||||||
|
/* The ARP timer and the periodic timer share a callback function, so the
|
||||||
|
respective timer IDs are used to determine which timer actually expired. These
|
||||||
|
constants are assigned to the timer IDs. */
|
||||||
|
#define uipARP_TIMER 0
|
||||||
|
#define uipPERIODIC_TIMER 1
|
||||||
|
|
||||||
|
/* The length of the queue used to send events from timers or the Ethernet
|
||||||
|
driver to the uIP stack. */
|
||||||
|
#define uipEVENT_QUEUE_LENGTH 10
|
||||||
|
|
||||||
|
/* A block time of zero simply means "don't block". */
|
||||||
|
#define uipDONT_BLOCK 0UL
|
||||||
|
|
||||||
|
/* How long to wait before attempting to connect the MAC again. */
|
||||||
|
#define uipINIT_WAIT ( 100 / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/* Shortcut to the header within the Rx buffer. */
|
||||||
|
#define xHeader ((struct uip_eth_hdr *) &uip_buf[ 0 ])
|
||||||
|
|
||||||
|
/* Standard constant. */
|
||||||
|
#define uipTOTAL_FRAME_HEADER_SIZE 54
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the MAC address in the MAC itself, and in the uIP stack.
|
||||||
|
*/
|
||||||
|
static void prvSetMACAddress( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform any uIP initialisation required to ready the stack for http
|
||||||
|
* processing.
|
||||||
|
*/
|
||||||
|
static void prvInitialise_uIP( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The callback function that is assigned to both the periodic timer and the
|
||||||
|
* ARP timer.
|
||||||
|
*/
|
||||||
|
static void prvUIPTimerCallback( xTimerHandle xTimer );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port functions required by the uIP stack.
|
||||||
|
*/
|
||||||
|
clock_time_t clock_time( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The queue used to send TCP/IP events to the uIP stack. */
|
||||||
|
xQueueHandle xEMACEventQueue = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
clock_time_t clock_time( void )
|
||||||
|
{
|
||||||
|
return xTaskGetTickCount();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vuIP_Task( void *pvParameters )
|
||||||
|
{
|
||||||
|
portBASE_TYPE i;
|
||||||
|
unsigned long ulNewEvent = 0UL, ulUIP_Events = 0UL;
|
||||||
|
unsigned short usPacketLength;
|
||||||
|
|
||||||
|
/* Just to prevent compiler warnings about the unused parameter. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
/* Initialise the uIP stack, configuring for web server usage. */
|
||||||
|
prvInitialise_uIP();
|
||||||
|
|
||||||
|
/* Initialise the MAC and PHY. */
|
||||||
|
vEMACInit();
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Is there received data ready to be processed? */
|
||||||
|
usPacketLength = usEMACRead();
|
||||||
|
|
||||||
|
/* Statements to be executed if data has been received on the Ethernet. */
|
||||||
|
if( ( usPacketLength > 0U ) && ( uip_buf != NULL ) )
|
||||||
|
{
|
||||||
|
uip_len = usPacketLength;
|
||||||
|
|
||||||
|
/* Standard uIP loop taken from the uIP manual. */
|
||||||
|
if( xHeader->type == htons( UIP_ETHTYPE_IP ) )
|
||||||
|
{
|
||||||
|
uip_arp_ipin();
|
||||||
|
uip_input();
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
if( uip_len > 0 )
|
||||||
|
{
|
||||||
|
uip_arp_out();
|
||||||
|
vEMACWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( xHeader->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. */
|
||||||
|
if( uip_len > 0 )
|
||||||
|
{
|
||||||
|
vEMACWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clear the RX event latched in ulUIP_Events - if one was latched. */
|
||||||
|
ulUIP_Events &= ~uipETHERNET_RX_EVENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Statements to be executed if the TCP/IP period timer has expired. */
|
||||||
|
if( ( ulUIP_Events & uipPERIODIC_TIMER_EVENT ) != 0UL )
|
||||||
|
{
|
||||||
|
ulUIP_Events &= ~uipPERIODIC_TIMER_EVENT;
|
||||||
|
|
||||||
|
if( uip_buf != NULL )
|
||||||
|
{
|
||||||
|
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. */
|
||||||
|
if( uip_len > 0 )
|
||||||
|
{
|
||||||
|
uip_arp_out();
|
||||||
|
vEMACWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Statements to be executed if the ARP timer has expired. */
|
||||||
|
if( ( ulUIP_Events & uipARP_TIMER_EVENT ) != 0 )
|
||||||
|
{
|
||||||
|
ulUIP_Events &= ~uipARP_TIMER_EVENT;
|
||||||
|
uip_arp_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If all latched events have been cleared - block until another event
|
||||||
|
occurs. */
|
||||||
|
if( ulUIP_Events == pdFALSE )
|
||||||
|
{
|
||||||
|
xQueueReceive( xEMACEventQueue, &ulNewEvent, portMAX_DELAY );
|
||||||
|
ulUIP_Events |= ulNewEvent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetMACAddress( void )
|
||||||
|
{
|
||||||
|
struct uip_eth_addr xAddr;
|
||||||
|
|
||||||
|
/* Configure the MAC address in the uIP stack. */
|
||||||
|
xAddr.addr[ 0 ] = configMAC_ADDR0;
|
||||||
|
xAddr.addr[ 1 ] = configMAC_ADDR1;
|
||||||
|
xAddr.addr[ 2 ] = configMAC_ADDR2;
|
||||||
|
xAddr.addr[ 3 ] = configMAC_ADDR3;
|
||||||
|
xAddr.addr[ 4 ] = configMAC_ADDR4;
|
||||||
|
xAddr.addr[ 5 ] = configMAC_ADDR5;
|
||||||
|
uip_setethaddr( xAddr );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInitialise_uIP( void )
|
||||||
|
{
|
||||||
|
uip_ipaddr_t xIPAddr;
|
||||||
|
xTimerHandle xARPTimer, xPeriodicTimer;
|
||||||
|
|
||||||
|
uip_init();
|
||||||
|
uip_ipaddr( &xIPAddr, configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
|
||||||
|
uip_sethostaddr( &xIPAddr );
|
||||||
|
uip_ipaddr( &xIPAddr, configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 );
|
||||||
|
uip_setnetmask( &xIPAddr );
|
||||||
|
prvSetMACAddress();
|
||||||
|
httpd_init();
|
||||||
|
|
||||||
|
/* Create the queue used to sent TCP/IP events to the uIP stack. */
|
||||||
|
xEMACEventQueue = xQueueCreate( uipEVENT_QUEUE_LENGTH, sizeof( unsigned long ) );
|
||||||
|
|
||||||
|
/* Create and start the uIP timers. */
|
||||||
|
xARPTimer = xTimerCreate( ( signed char * ) "ARPTimer", /* Just a name that is helpful for debugging, not used by the kernel. */
|
||||||
|
( 10000UL / portTICK_RATE_MS ), /* Timer period. */
|
||||||
|
pdTRUE, /* Autor-reload. */
|
||||||
|
( void * ) uipARP_TIMER,
|
||||||
|
prvUIPTimerCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
xPeriodicTimer = xTimerCreate( ( signed char * ) "PeriodicTimer",
|
||||||
|
( 500UL / portTICK_RATE_MS ),
|
||||||
|
pdTRUE, /* Autor-reload. */
|
||||||
|
( void * ) uipPERIODIC_TIMER,
|
||||||
|
prvUIPTimerCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Sanity check that the timers were indeed created. */
|
||||||
|
configASSERT( xARPTimer );
|
||||||
|
configASSERT( xPeriodicTimer );
|
||||||
|
configASSERT( xEMACEventQueue );
|
||||||
|
|
||||||
|
/* These commands will block indefinitely until they succeed, so there is
|
||||||
|
no point in checking their return values. */
|
||||||
|
xTimerStart( xARPTimer, portMAX_DELAY );
|
||||||
|
xTimerStart( xPeriodicTimer, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvUIPTimerCallback( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
static const unsigned long ulARPTimerExpired = uipARP_TIMER_EVENT;
|
||||||
|
static const unsigned long ulPeriodicTimerExpired = uipPERIODIC_TIMER_EVENT;
|
||||||
|
|
||||||
|
/* This is a time callback, so calls to xQueueSend() must not attempt to
|
||||||
|
block. As this callback is assigned to both the ARP and Periodic timers, the
|
||||||
|
first thing to do is ascertain which timer it was that actually expired. */
|
||||||
|
switch( ( int ) pvTimerGetTimerID( xTimer ) )
|
||||||
|
{
|
||||||
|
case uipARP_TIMER : xQueueSend( xEMACEventQueue, &ulARPTimerExpired, uipDONT_BLOCK );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case uipPERIODIC_TIMER : xQueueSend( xEMACEventQueue, &ulPeriodicTimerExpired, uipDONT_BLOCK );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default : /* Should not get here. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationProcessFormInput( char *pcInputString )
|
||||||
|
{
|
||||||
|
char *c;
|
||||||
|
|
||||||
|
/* Only interested in processing form input if this is the IO page. */
|
||||||
|
c = strstr( pcInputString, "io.shtml" );
|
||||||
|
|
||||||
|
if( c )
|
||||||
|
{
|
||||||
|
/* Is there a command in the string? */
|
||||||
|
c = strstr( pcInputString, "?" );
|
||||||
|
if( c )
|
||||||
|
{
|
||||||
|
/* Turn the LED's on or off in accordance with the check box status. */
|
||||||
|
if( strstr( c, "LED0=1" ) != NULL )
|
||||||
|
{
|
||||||
|
/* Turn the LEDs on. */
|
||||||
|
vParTestSetLED( 3, 1 );
|
||||||
|
vParTestSetLED( 4, 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Turn the LEDs off. */
|
||||||
|
vParTestSetLED( 3, 0 );
|
||||||
|
vParTestSetLED( 4, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Commands to turn LEDs off are not always explicit. */
|
||||||
|
vParTestSetLED( 3, 0 );
|
||||||
|
vParTestSetLED( 4, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
@ -0,0 +1,620 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Freescale includes. */
|
||||||
|
#include "common.h"
|
||||||
|
#include "eth_phy.h"
|
||||||
|
#include "enet.h"
|
||||||
|
#include "mii.h"
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
|
||||||
|
/* uIP includes. */
|
||||||
|
#include "net/uip.h"
|
||||||
|
|
||||||
|
/* The time to wait between attempts to obtain a free buffer. */
|
||||||
|
#define emacBUFFER_WAIT_DELAY_ms ( 3 / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/* The number of times emacBUFFER_WAIT_DELAY_ms should be waited before giving
|
||||||
|
up on attempting to obtain a free buffer all together. */
|
||||||
|
#define emacBUFFER_WAIT_ATTEMPTS ( 30 )
|
||||||
|
|
||||||
|
/* The number of Rx descriptors. */
|
||||||
|
#define emacNUM_RX_DESCRIPTORS 8
|
||||||
|
|
||||||
|
/* The number of Tx descriptors. When using uIP there is not point in having
|
||||||
|
more than two. */
|
||||||
|
#define emacNUM_TX_BUFFERS 2
|
||||||
|
|
||||||
|
/* The total number of EMAC buffers to allocate. */
|
||||||
|
#define emacNUM_BUFFERS ( emacNUM_RX_DESCRIPTORS + emacNUM_TX_BUFFERS )
|
||||||
|
|
||||||
|
/* The time to wait for the Tx descriptor to become free. */
|
||||||
|
#define emacTX_WAIT_DELAY_ms ( 10 / portTICK_RATE_MS )
|
||||||
|
|
||||||
|
/* The total number of times to wait emacTX_WAIT_DELAY_ms for the Tx descriptor to
|
||||||
|
become free. */
|
||||||
|
#define emacTX_WAIT_ATTEMPTS ( 50 )
|
||||||
|
|
||||||
|
#define emacTX_INTERRUPT_NO ( 76 )
|
||||||
|
#define emacRX_INTERRUPT_NO ( 77 )
|
||||||
|
#define emacERROR_INTERRUPT_NO ( 78 )
|
||||||
|
#define emacLINK_DELAY ( 500 / portTICK_RATE_MS )
|
||||||
|
#define emacPHY_STATUS ( 0x1F )
|
||||||
|
#define emacPHY_DUPLEX_STATUS ( 4 << 2 )
|
||||||
|
#define emacPHY_SPEED_STATUS ( 1 << 2 )
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise both the Rx and Tx descriptors.
|
||||||
|
*/
|
||||||
|
static void prvInitialiseDescriptors( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer to a free buffer within xEthernetBuffers.
|
||||||
|
*/
|
||||||
|
static unsigned char *prvGetNextBuffer( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a buffer to the list of free buffers.
|
||||||
|
*/
|
||||||
|
static void prvReturnBuffer( unsigned char *pucBuffer );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Examine the status of the next Rx descriptor to see if it contains new data.
|
||||||
|
*/
|
||||||
|
static unsigned short prvCheckRxStatus( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Something has gone wrong with the descriptor usage. Reset all the buffers
|
||||||
|
* and descriptors.
|
||||||
|
*/
|
||||||
|
static void prvResetEverything( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* The buffers and descriptors themselves. */
|
||||||
|
#pragma data_alignment=16
|
||||||
|
volatile NBUF xRxDescriptors[ emacNUM_RX_DESCRIPTORS ];
|
||||||
|
|
||||||
|
#pragma data_alignment=16
|
||||||
|
volatile NBUF xTxDescriptors[ emacNUM_TX_BUFFERS ];
|
||||||
|
|
||||||
|
#pragma data_alignment=16
|
||||||
|
char xEthernetBuffers[ emacNUM_BUFFERS ][ UIP_BUFSIZE ];
|
||||||
|
|
||||||
|
/* Used to indicate which buffers are free and which are in use. If an index
|
||||||
|
contains 0 then the corresponding buffer in xEthernetBuffers is free, otherwise
|
||||||
|
the buffer is in use or about to be used. */
|
||||||
|
static unsigned char ucBufferInUse[ emacNUM_BUFFERS ];
|
||||||
|
|
||||||
|
/* Points to the Rx descriptor currently in use. */
|
||||||
|
static volatile NBUF *pxCurrentRxDesc = NULL;
|
||||||
|
|
||||||
|
/* pxCurrentRxDesc points to descriptor within the xRxDescriptors array that
|
||||||
|
has an index defined by ulRxDescriptorIndex. */
|
||||||
|
static unsigned long ulRxDescriptorIndex = 0UL;
|
||||||
|
|
||||||
|
/* The buffer used by the uIP stack to both receive and send. This points to
|
||||||
|
one of the Ethernet buffers when its actually in use. */
|
||||||
|
unsigned char *uip_buf = NULL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
#define ENET_HARDWARE_CHECKSUM 0 //_RB_ for test only
|
||||||
|
void vEMACInit( void )
|
||||||
|
{
|
||||||
|
int iData;
|
||||||
|
extern int periph_clk_khz;
|
||||||
|
const unsigned portCHAR ucMACAddress[] =
|
||||||
|
{
|
||||||
|
configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Enable the ENET clock. */
|
||||||
|
SIM_SCGC2 |= SIM_SCGC2_ENET_MASK;
|
||||||
|
|
||||||
|
/* Allow concurrent access to MPU controller to avoid bus errors. */
|
||||||
|
MPU_CESR = 0;
|
||||||
|
|
||||||
|
prvInitialiseDescriptors();
|
||||||
|
|
||||||
|
/* Reset and enable. */
|
||||||
|
ENET_ECR = ENET_ECR_RESET_MASK;
|
||||||
|
|
||||||
|
/* Wait at least 8 clock cycles */
|
||||||
|
vTaskDelay( 2 );
|
||||||
|
|
||||||
|
/* Start the MII interface*/
|
||||||
|
mii_init( 0, periph_clk_khz / 1000L );
|
||||||
|
|
||||||
|
/* Configure the transmit interrupt. */
|
||||||
|
set_irq_priority( emacTX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
enable_irq( emacTX_INTERRUPT_NO );
|
||||||
|
|
||||||
|
/* Configure the receive interrupt. */
|
||||||
|
set_irq_priority( emacRX_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
enable_irq( emacRX_INTERRUPT_NO );
|
||||||
|
|
||||||
|
/* Configure the error interrupt. */
|
||||||
|
set_irq_priority( emacERROR_INTERRUPT_NO, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
||||||
|
enable_irq( emacERROR_INTERRUPT_NO );
|
||||||
|
|
||||||
|
/* Configure the pins to the PHY - RMII mode used. */
|
||||||
|
PORTB_PCR0 = PORT_PCR_MUX( 4 ); /* RMII0_MDIO / MII0_MDIO. */
|
||||||
|
PORTB_PCR1 = PORT_PCR_MUX( 4 ); /* RMII0_MDC / MII0_MDC */
|
||||||
|
PORTA_PCR14 = PORT_PCR_MUX( 4 ); /* RMII0_CRS_DV / MII0_RXDV */
|
||||||
|
PORTA_PCR12 = PORT_PCR_MUX( 4 ); /* RMII0_RXD1 / MII0_RXD1 */
|
||||||
|
PORTA_PCR13 = PORT_PCR_MUX( 4 ); /* RMII0_RXD0/MII0_RXD0 */
|
||||||
|
PORTA_PCR15 = PORT_PCR_MUX( 4 ); /* RMII0_TXEN/MII0_TXEN */
|
||||||
|
PORTA_PCR16 = PORT_PCR_MUX( 4 ); /* RMII0_TXD0/MII0_TXD0 */
|
||||||
|
PORTA_PCR17 = PORT_PCR_MUX( 4 ); /* RMII0_TXD1/MII0_TXD1 */
|
||||||
|
|
||||||
|
/* Is there communication with the PHY? */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
vTaskDelay( emacLINK_DELAY );
|
||||||
|
iData = 0xFFFF;
|
||||||
|
mii_read( 0, configPHY_ADDRESS, PHY_PHYIDR1, &iData );
|
||||||
|
|
||||||
|
} while( iData == 0xFFFF );
|
||||||
|
|
||||||
|
/* Start to auto negotiate. */
|
||||||
|
mii_write( 0, configPHY_ADDRESS, PHY_BMCR, ( PHY_BMCR_AN_RESTART | PHY_BMCR_AN_ENABLE ) );
|
||||||
|
|
||||||
|
/* Wait for auto negotiate to complete. */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
vTaskDelay( emacLINK_DELAY );
|
||||||
|
mii_read( 0, configPHY_ADDRESS, PHY_BMSR, &iData );
|
||||||
|
|
||||||
|
} while( !( iData & PHY_BMSR_AN_COMPLETE ) );
|
||||||
|
|
||||||
|
/* A link has been established. What was negotiated? */
|
||||||
|
iData = 0;
|
||||||
|
mii_read( 0, configPHY_ADDRESS, emacPHY_STATUS, &iData );
|
||||||
|
|
||||||
|
/* Clear the Individual and Group Address Hash registers */
|
||||||
|
ENET_IALR = 0;
|
||||||
|
ENET_IAUR = 0;
|
||||||
|
ENET_GALR = 0;
|
||||||
|
ENET_GAUR = 0;
|
||||||
|
|
||||||
|
/* Set the Physical Address for the selected ENET */
|
||||||
|
enet_set_address( 0, ucMACAddress );
|
||||||
|
|
||||||
|
ENET_RCR = ENET_RCR_MAX_FL( UIP_BUFSIZE ) | ENET_RCR_MII_MODE_MASK | ENET_RCR_CRCFWD_MASK | ENET_RCR_RMII_MODE_MASK;
|
||||||
|
|
||||||
|
/* Clear the control registers. */
|
||||||
|
ENET_TCR = 0;
|
||||||
|
|
||||||
|
if( iData & emacPHY_DUPLEX_STATUS )
|
||||||
|
{
|
||||||
|
/* Full duplex */
|
||||||
|
ENET_RCR &= ( unsigned long )~ENET_RCR_DRT_MASK;
|
||||||
|
ENET_TCR |= ENET_TCR_FDEN_MASK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Half duplex */
|
||||||
|
ENET_RCR |= ENET_RCR_DRT_MASK;
|
||||||
|
ENET_TCR &= (unsigned portLONG)~ENET_TCR_FDEN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iData & emacPHY_SPEED_STATUS )
|
||||||
|
{
|
||||||
|
/* 10Mbps */
|
||||||
|
ENET_RCR |= ENET_RCR_RMII_10T_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENET_ECR = ENET_ECR_EN1588_MASK;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//_RB_
|
||||||
|
// Enable Ethernet header alignment for rx
|
||||||
|
ENET_RACC |= 0
|
||||||
|
| ENET_RACC_SHIFT16_MASK
|
||||||
|
;
|
||||||
|
|
||||||
|
// Enable Ethernet header alignment for tx
|
||||||
|
ENET_TACC |= 0
|
||||||
|
| ENET_TACC_SHIFT16_MASK
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Store and forward checksum. */
|
||||||
|
ENET_TFWR = ENET_TFWR_STRFWD_MASK;
|
||||||
|
|
||||||
|
/* Set Rx Buffer Size */
|
||||||
|
ENET_MRBR = ( unsigned short ) UIP_BUFSIZE;
|
||||||
|
|
||||||
|
/* Point to the start of the circular Rx buffer descriptor queue */
|
||||||
|
ENET_RDSR = ( unsigned long ) &( xRxDescriptors[ 0 ] );
|
||||||
|
|
||||||
|
/* Point to the start of the circular Tx buffer descriptor queue */
|
||||||
|
ENET_TDSR = ( unsigned long ) &( xTxDescriptors[ 0 ] );
|
||||||
|
|
||||||
|
/* Clear all ENET interrupt events */
|
||||||
|
ENET_EIR = ( unsigned long ) -1;
|
||||||
|
|
||||||
|
/* Enable interrupts. */
|
||||||
|
ENET_EIMR = 0
|
||||||
|
/*rx irqs*/
|
||||||
|
| ENET_EIMR_RXF_MASK/*FSL: only for complete frame, not partial buffer descriptor | ENET_EIMR_RXB_MASK*/
|
||||||
|
/*xmit irqs*/
|
||||||
|
| ENET_EIMR_TXF_MASK/*FSL: only for complete frame, not partial buffer descriptor | ENET_EIMR_TXB_MASK*/
|
||||||
|
/*enet irqs*/
|
||||||
|
| ENET_EIMR_UN_MASK | ENET_EIMR_RL_MASK | ENET_EIMR_LC_MASK | ENET_EIMR_BABT_MASK | ENET_EIMR_BABR_MASK | ENET_EIMR_EBERR_MASK
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Enable the MAC itself. */
|
||||||
|
ENET_ECR |= ENET_ECR_ETHEREN_MASK;
|
||||||
|
|
||||||
|
/* Indicate that there have been empty receive buffers produced */
|
||||||
|
ENET_RDAR = ENET_RDAR_RDAR_MASK;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInitialiseDescriptors( void )
|
||||||
|
{
|
||||||
|
volatile NBUF *pxDescriptor;
|
||||||
|
long x;
|
||||||
|
|
||||||
|
for( x = 0; x < emacNUM_BUFFERS; x++ )
|
||||||
|
{
|
||||||
|
/* Ensure none of the buffers are shown as in use at the start. */
|
||||||
|
ucBufferInUse[ x ] = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialise the Rx descriptors. */
|
||||||
|
for( x = 0; x < emacNUM_RX_DESCRIPTORS; x++ )
|
||||||
|
{
|
||||||
|
pxDescriptor = &( xRxDescriptors[ x ] );
|
||||||
|
pxDescriptor->data = ( uint8_t* ) &( xEthernetBuffers[ x ][ 0 ] );
|
||||||
|
pxDescriptor->data = ( uint8_t* ) __REV( ( unsigned long ) pxDescriptor->data );
|
||||||
|
pxDescriptor->length = 0;
|
||||||
|
pxDescriptor->status = RX_BD_E;
|
||||||
|
pxDescriptor->bdu = 0;
|
||||||
|
pxDescriptor->ebd_status = RX_BD_INT;
|
||||||
|
|
||||||
|
/* Mark this buffer as in use. */
|
||||||
|
ucBufferInUse[ x ] = pdTRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The last descriptor points back to the start. */
|
||||||
|
pxDescriptor->status |= RX_BD_W;
|
||||||
|
|
||||||
|
/* Initialise the Tx descriptors. */
|
||||||
|
for( x = 0; x < emacNUM_TX_BUFFERS; x++ )
|
||||||
|
{
|
||||||
|
pxDescriptor = &( xTxDescriptors[ x ] );
|
||||||
|
|
||||||
|
/* A buffer is not allocated to the Tx descriptor until a send is
|
||||||
|
actually required. */
|
||||||
|
pxDescriptor->data = NULL;
|
||||||
|
pxDescriptor->length = 0;
|
||||||
|
pxDescriptor->status = TX_BD_TC;
|
||||||
|
pxDescriptor->ebd_status = TX_BD_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The last descriptor points back to the start. */
|
||||||
|
pxDescriptor->status |= TX_BD_W;
|
||||||
|
|
||||||
|
/* Use the first Rx descriptor to start with. */
|
||||||
|
ulRxDescriptorIndex = 0UL;
|
||||||
|
pxCurrentRxDesc = &( xRxDescriptors[ 0 ] );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEMACWrite( void )
|
||||||
|
{
|
||||||
|
long x;
|
||||||
|
|
||||||
|
/* Wait until the second transmission of the last packet has completed. */
|
||||||
|
for( x = 0; x < emacTX_WAIT_ATTEMPTS; x++ )
|
||||||
|
{
|
||||||
|
if( ( xTxDescriptors[ 1 ].status & TX_BD_R ) != 0 )
|
||||||
|
{
|
||||||
|
/* Descriptor is still active. */
|
||||||
|
vTaskDelay( emacTX_WAIT_DELAY_ms );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is the descriptor free after waiting for it? */
|
||||||
|
if( ( xTxDescriptors[ 1 ].status & TX_BD_R ) != 0 )
|
||||||
|
{
|
||||||
|
/* Something has gone wrong. */
|
||||||
|
prvResetEverything();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup both descriptors to transmit the frame. */
|
||||||
|
xTxDescriptors[ 0 ].data = ( uint8_t * ) __REV( ( unsigned long ) uip_buf );
|
||||||
|
xTxDescriptors[ 0 ].length = __REVSH( uip_len );
|
||||||
|
xTxDescriptors[ 1 ].data = ( uint8_t * ) __REV( ( unsigned long ) uip_buf );
|
||||||
|
xTxDescriptors[ 1 ].length = __REVSH( uip_len );
|
||||||
|
|
||||||
|
/* uip_buf is being sent by the Tx descriptor. Allocate a new buffer
|
||||||
|
for use by the stack. */
|
||||||
|
uip_buf = prvGetNextBuffer();
|
||||||
|
|
||||||
|
/* Clear previous settings and go. */
|
||||||
|
xTxDescriptors[ 0 ].status |= ( TX_BD_R | TX_BD_L );
|
||||||
|
xTxDescriptors[ 1 ].status |= ( TX_BD_R | TX_BD_L );
|
||||||
|
|
||||||
|
/* Start the Tx. */
|
||||||
|
ENET_TDAR = ENET_TDAR_TDAR_MASK;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static unsigned char *prvGetNextBuffer( void )
|
||||||
|
{
|
||||||
|
long x;
|
||||||
|
unsigned char *pucReturn = NULL;
|
||||||
|
unsigned long ulAttempts = 0;
|
||||||
|
|
||||||
|
while( pucReturn == NULL )
|
||||||
|
{
|
||||||
|
/* Look through the buffers to find one that is not in use by
|
||||||
|
anything else. */
|
||||||
|
for( x = 0; x < emacNUM_BUFFERS; x++ )
|
||||||
|
{
|
||||||
|
if( ucBufferInUse[ x ] == pdFALSE )
|
||||||
|
{
|
||||||
|
ucBufferInUse[ x ] = pdTRUE;
|
||||||
|
pucReturn = ( unsigned char * ) &( xEthernetBuffers[ x ][ 0 ] );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Was a buffer found? */
|
||||||
|
if( pucReturn == NULL )
|
||||||
|
{
|
||||||
|
ulAttempts++;
|
||||||
|
|
||||||
|
if( ulAttempts >= emacBUFFER_WAIT_ATTEMPTS )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait then look again. */
|
||||||
|
vTaskDelay( emacBUFFER_WAIT_DELAY_ms );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pucReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvResetEverything( void )
|
||||||
|
{
|
||||||
|
/* Temporary code just to see if this gets called. This function has not
|
||||||
|
been implemented. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
unsigned short usEMACRead( void )
|
||||||
|
{
|
||||||
|
unsigned short usBytesReceived;
|
||||||
|
|
||||||
|
usBytesReceived = prvCheckRxStatus();
|
||||||
|
usBytesReceived = __REVSH( usBytesReceived );
|
||||||
|
|
||||||
|
if( usBytesReceived > 0 )
|
||||||
|
{
|
||||||
|
/* Mark the pxDescriptor buffer as free as uip_buf is going to be set to
|
||||||
|
the buffer that contains the received data. */
|
||||||
|
prvReturnBuffer( uip_buf );
|
||||||
|
|
||||||
|
/* Point uip_buf to the data about to be processed. */
|
||||||
|
uip_buf = ( void * ) pxCurrentRxDesc->data;
|
||||||
|
uip_buf = ( void * ) __REV( ( unsigned long ) uip_buf );
|
||||||
|
|
||||||
|
/* Allocate a new buffer to the descriptor, as uip_buf is now using it's
|
||||||
|
old descriptor. */
|
||||||
|
pxCurrentRxDesc->data = ( uint8_t * ) prvGetNextBuffer();
|
||||||
|
pxCurrentRxDesc->data = ( uint8_t* ) __REV( ( unsigned long ) pxCurrentRxDesc->data );
|
||||||
|
|
||||||
|
/* Prepare the descriptor to go again. */
|
||||||
|
pxCurrentRxDesc->status |= RX_BD_E;
|
||||||
|
|
||||||
|
/* Move onto the next buffer in the ring. */
|
||||||
|
ulRxDescriptorIndex++;
|
||||||
|
if( ulRxDescriptorIndex >= emacNUM_RX_DESCRIPTORS )
|
||||||
|
{
|
||||||
|
ulRxDescriptorIndex = 0UL;
|
||||||
|
}
|
||||||
|
pxCurrentRxDesc = &( xRxDescriptors[ ulRxDescriptorIndex ] );
|
||||||
|
|
||||||
|
/* Restart Ethernet if it has stopped */
|
||||||
|
ENET_RDAR = ENET_RDAR_RDAR_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return usBytesReceived;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvReturnBuffer( unsigned char *pucBuffer )
|
||||||
|
{
|
||||||
|
unsigned long ul;
|
||||||
|
|
||||||
|
/* Return a buffer to the pool of free buffers. */
|
||||||
|
for( ul = 0; ul < emacNUM_BUFFERS; ul++ )
|
||||||
|
{
|
||||||
|
if( &( xEthernetBuffers[ ul ][ 0 ] ) == ( void * ) pucBuffer )
|
||||||
|
{
|
||||||
|
ucBufferInUse[ ul ] = pdFALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static unsigned short prvCheckRxStatus( void )
|
||||||
|
{
|
||||||
|
unsigned long usReturn = 0;
|
||||||
|
|
||||||
|
if( ( pxCurrentRxDesc->status & RX_BD_E ) != 0 )
|
||||||
|
{
|
||||||
|
/* Current descriptor is still active. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The descriptor contains a frame. Because of the size of the buffers
|
||||||
|
the frame should always be complete. */
|
||||||
|
usReturn = pxCurrentRxDesc->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return usReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEMAC_TxISRHandler( void )
|
||||||
|
{
|
||||||
|
/* Check the buffers have not already been freed in the first of the
|
||||||
|
two Tx interrupts - which could potentially happen if the second Tx completed
|
||||||
|
during the interrupt for the first Tx. */
|
||||||
|
if( xTxDescriptors[ 0 ].data != NULL )
|
||||||
|
{
|
||||||
|
if( ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) && ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) )
|
||||||
|
{
|
||||||
|
configASSERT( xTxDescriptors[ 0 ].data == xTxDescriptors[ 1 ].data );
|
||||||
|
|
||||||
|
xTxDescriptors[ 0 ].data = ( uint8_t* ) __REV( ( unsigned long ) xTxDescriptors[ 0 ].data );
|
||||||
|
prvReturnBuffer( xTxDescriptors[ 0 ].data );
|
||||||
|
|
||||||
|
/* Just to mark the fact that the buffer has already been released. */
|
||||||
|
xTxDescriptors[ 0 ].data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEMAC_RxISRHandler( void )
|
||||||
|
{
|
||||||
|
const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;
|
||||||
|
long lHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
extern xQueueHandle xEMACEventQueue;
|
||||||
|
|
||||||
|
/* An Ethernet Rx event has occurred. */
|
||||||
|
xQueueSendFromISR( xEMACEventQueue, &ulRxEvent, &lHigherPriorityTaskWoken );
|
||||||
|
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEMAC_ErrorISRHandler( void )
|
||||||
|
{
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
volatile unsigned long ulEvent, ulMask;
|
||||||
|
void vEMAC_ISRHandler( void )
|
||||||
|
{
|
||||||
|
//unsigned long ulEvent;
|
||||||
|
long lHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;
|
||||||
|
extern xQueueHandle xEMACEventQueue;
|
||||||
|
|
||||||
|
/* What caused the interrupt? */
|
||||||
|
ulMask = ENET_EIMR;
|
||||||
|
ulEvent = ENET_EIR;
|
||||||
|
ulEvent &= ulMask;
|
||||||
|
|
||||||
|
ENET_EIR = ulEvent;
|
||||||
|
|
||||||
|
if( ( ulEvent & ENET_EIR_TXF_MASK ) != 0UL )
|
||||||
|
{
|
||||||
|
/* Transmit complete.
|
||||||
|
Check the buffers have not already been freed in the first of the
|
||||||
|
two Tx interrupts - which could potentially happen if the second Tx completed
|
||||||
|
during the interrupt for the first Tx. */
|
||||||
|
if( xTxDescriptors[ 0 ].data != NULL )
|
||||||
|
{
|
||||||
|
if( ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) && ( ( xTxDescriptors[ 0 ].status & TX_BD_R ) == 0 ) )
|
||||||
|
{
|
||||||
|
configASSERT( xTxDescriptors[ 0 ].data == xTxDescriptors[ 1 ].data );
|
||||||
|
|
||||||
|
xTxDescriptors[ 0 ].data = ( uint8_t* ) __REV( ( unsigned long ) xTxDescriptors[ 0 ].data );
|
||||||
|
prvReturnBuffer( xTxDescriptors[ 0 ].data );
|
||||||
|
|
||||||
|
/* Just to mark the fact that the buffer has already been released. */
|
||||||
|
xTxDescriptors[ 0 ].data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ( ulEvent & ENET_EIR_RXF_MASK ) != 0UL )
|
||||||
|
{
|
||||||
|
/* Packet Rxed. */
|
||||||
|
xQueueSendFromISR( xEMACEventQueue, &ulRxEvent, &lHigherPriorityTaskWoken );
|
||||||
|
portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ulEvent & ( ENET_EIR_UN_MASK | ENET_EIR_RL_MASK | ENET_EIR_LC_MASK | ENET_EIR_EBERR_MASK | ENET_EIR_BABT_MASK | ENET_EIR_BABR_MASK | ENET_EIR_EBERR_MASK ) )
|
||||||
|
{
|
||||||
|
/* Error. */
|
||||||
|
prvInitialiseDescriptors();
|
||||||
|
ENET_RDAR = ENET_RDAR_RDAR_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.1 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FR_EMAC_H
|
||||||
|
#define FR_EMAC_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure all the ethernet components (MAC, DMA, PHY) ready for communication.
|
||||||
|
*/
|
||||||
|
void vEMACInit( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the Rx status, and return the number of bytes received if any.
|
||||||
|
*/
|
||||||
|
unsigned short usEMACRead( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send uip_len bytes from uip_buf to the Tx descriptors and initiate a Tx.
|
||||||
|
*/
|
||||||
|
void vEMACWrite( void );
|
||||||
|
|
||||||
|
#endif /* FR_EMAC_H */
|
@ -0,0 +1,277 @@
|
|||||||
|
/**
|
||||||
|
* \addtogroup httpd
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* Web server script interface
|
||||||
|
* \author
|
||||||
|
* Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2006, Adam Dunkels.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the uIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* $Id: httpd-cgi.c,v 1.2 2006/06/11 21:46:37 adam Exp $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "net/uip.h"
|
||||||
|
#include "net/psock.h"
|
||||||
|
#include "apps/httpd/httpd.h"
|
||||||
|
#include "apps/httpd/httpd-cgi.h"
|
||||||
|
#include "apps/httpd/httpd-fs.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
HTTPD_CGI_CALL( file, "file-stats", file_stats );
|
||||||
|
HTTPD_CGI_CALL( tcp, "tcp-connections", tcp_stats );
|
||||||
|
HTTPD_CGI_CALL( net, "net-stats", net_stats );
|
||||||
|
HTTPD_CGI_CALL( rtos, "rtos-stats", rtos_stats );
|
||||||
|
HTTPD_CGI_CALL( run, "run-time", run_time );
|
||||||
|
HTTPD_CGI_CALL( io, "led-io", led_io );
|
||||||
|
|
||||||
|
static const struct httpd_cgi_call *calls[] = { &file, &tcp, &net, &rtos, &run, &io, NULL };
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static PT_THREAD( nullfunction ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
( void ) ptr;
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
httpd_cgifunction httpd_cgi( char *name )
|
||||||
|
{
|
||||||
|
const struct httpd_cgi_call **f;
|
||||||
|
|
||||||
|
/* Find the matching name in the table, return the function. */
|
||||||
|
for( f = calls; *f != NULL; ++f )
|
||||||
|
{
|
||||||
|
if( strncmp((*f)->name, name, strlen((*f)->name)) == 0 )
|
||||||
|
{
|
||||||
|
return( *f )->function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullfunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static unsigned short generate_file_stats( void *arg )
|
||||||
|
{
|
||||||
|
char *f = ( char * ) arg;
|
||||||
|
return sprintf( ( char * ) uip_appdata, "%5u", httpd_fs_count(f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static PT_THREAD( file_stats ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
|
||||||
|
PSOCK_GENERATOR_SEND( &s->sout, generate_file_stats, strchr(ptr, ' ') + 1 );
|
||||||
|
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static const char closed[] = /* "CLOSED",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0 };
|
||||||
|
static const char syn_rcvd[] = /* "SYN-RCVD",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x52, 0x43, 0x56, 0x44, 0 };
|
||||||
|
static const char syn_sent[] = /* "SYN-SENT",*/ { 0x53, 0x59, 0x4e, 0x2d, 0x53, 0x45, 0x4e, 0x54, 0 };
|
||||||
|
static const char established[] = /* "ESTABLISHED",*/ { 0x45, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x49, 0x53, 0x48, 0x45, 0x44, 0 };
|
||||||
|
static const char fin_wait_1[] = /* "FIN-WAIT-1",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x31, 0 };
|
||||||
|
static const char fin_wait_2[] = /* "FIN-WAIT-2",*/ { 0x46, 0x49, 0x4e, 0x2d, 0x57, 0x41, 0x49, 0x54, 0x2d, 0x32, 0 };
|
||||||
|
static const char closing[] = /* "CLOSING",*/ { 0x43, 0x4c, 0x4f, 0x53, 0x49, 0x4e, 0x47, 0 };
|
||||||
|
static const char time_wait[] = /* "TIME-WAIT,"*/ { 0x54, 0x49, 0x4d, 0x45, 0x2d, 0x57, 0x41, 0x49, 0x54, 0 };
|
||||||
|
static const char last_ack[] = /* "LAST-ACK"*/ { 0x4c, 0x41, 0x53, 0x54, 0x2d, 0x41, 0x43, 0x4b, 0 };
|
||||||
|
|
||||||
|
static const char *states[] = { closed, syn_rcvd, syn_sent, established, fin_wait_1, fin_wait_2, closing, time_wait, last_ack };
|
||||||
|
|
||||||
|
static unsigned short generate_tcp_stats( void *arg )
|
||||||
|
{
|
||||||
|
struct uip_conn *conn;
|
||||||
|
struct httpd_state *s = ( struct httpd_state * ) arg;
|
||||||
|
|
||||||
|
conn = &uip_conns[s->count];
|
||||||
|
return sprintf( ( char * ) uip_appdata,
|
||||||
|
"<tr><td>%d</td><td>%u.%u.%u.%u:%u</td><td>%s</td><td>%u</td><td>%u</td><td>%c %c</td></tr>\r\n", htons(conn->lport),
|
||||||
|
htons(conn->ripaddr.u16[0]) >> 8, htons(conn->ripaddr.u16[0]) & 0xff, htons(conn->ripaddr.u16[1]) >> 8,
|
||||||
|
htons(conn->ripaddr.u16[1]) & 0xff, htons(conn->rport), states[conn->tcpstateflags & UIP_TS_MASK], conn->nrtx, conn->timer,
|
||||||
|
(uip_outstanding(conn)) ? '*' : ' ', (uip_stopped(conn)) ? '!' : ' ' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static PT_THREAD( tcp_stats ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
( void ) ptr;
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
for( s->count = 0; s->count < UIP_CONNS; ++s->count )
|
||||||
|
{
|
||||||
|
if( (uip_conns[s->count].tcpstateflags & UIP_TS_MASK) != UIP_CLOSED )
|
||||||
|
{
|
||||||
|
PSOCK_GENERATOR_SEND( &s->sout, generate_tcp_stats, s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static unsigned short generate_net_stats( void *arg )
|
||||||
|
{
|
||||||
|
struct httpd_state *s = ( struct httpd_state * ) arg;
|
||||||
|
return sprintf( ( char * ) uip_appdata, "%5u\n", (( uip_stats_t * ) &uip_stat)[s->count] );
|
||||||
|
}
|
||||||
|
|
||||||
|
static PT_THREAD( net_stats ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
( void ) ptr;
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
#if UIP_STATISTICS
|
||||||
|
for( s->count = 0; s->count < sizeof(uip_stat) / sizeof(uip_stats_t); ++s->count )
|
||||||
|
{
|
||||||
|
PSOCK_GENERATOR_SEND( &s->sout, generate_net_stats, s );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UIP_STATISTICS */
|
||||||
|
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
extern void vTaskList( signed char *pcWriteBuffer );
|
||||||
|
extern char *pcGetTaskStatusMessage( void );
|
||||||
|
static char cCountBuf[128];
|
||||||
|
long lRefreshCount = 0;
|
||||||
|
static unsigned short generate_rtos_stats( void *arg )
|
||||||
|
{
|
||||||
|
( void ) arg;
|
||||||
|
lRefreshCount++;
|
||||||
|
sprintf( cCountBuf, "<p><br>Refresh count = %d<p><br>%s", ( int ) lRefreshCount, pcGetTaskStatusMessage() );
|
||||||
|
vTaskList( uip_appdata );
|
||||||
|
strcat( uip_appdata, cCountBuf );
|
||||||
|
|
||||||
|
return strlen( uip_appdata );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static PT_THREAD( rtos_stats ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
( void ) ptr;
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
PSOCK_GENERATOR_SEND( &s->sout, generate_rtos_stats, NULL );
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
char *pcStatus;
|
||||||
|
unsigned long ulString;
|
||||||
|
|
||||||
|
static unsigned short generate_io_state( void *arg )
|
||||||
|
{
|
||||||
|
extern long lParTestGetLEDState( unsigned long ulLED );
|
||||||
|
( void ) arg;
|
||||||
|
|
||||||
|
/* Are the dynamically setable LEDs currently on or off? */
|
||||||
|
if( lParTestGetLEDState( 8 ) )
|
||||||
|
{
|
||||||
|
pcStatus = "checked";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pcStatus = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf( uip_appdata, "<input type=\"checkbox\" name=\"LED0\" value=\"1\" %s>LED<p><p>", pcStatus );
|
||||||
|
|
||||||
|
return strlen( uip_appdata );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
extern void vTaskGetRunTimeStats( signed char *pcWriteBuffer );
|
||||||
|
extern unsigned short usMaxJitter;
|
||||||
|
static char cJitterBuffer[ 200 ];
|
||||||
|
static unsigned short generate_runtime_stats( void *arg )
|
||||||
|
{
|
||||||
|
( void ) arg;
|
||||||
|
lRefreshCount++;
|
||||||
|
sprintf( cCountBuf, "<p><br>Refresh count = %d", ( int ) lRefreshCount );
|
||||||
|
|
||||||
|
#ifdef INCLUDE_HIGH_FREQUENCY_TIMER_TEST
|
||||||
|
{
|
||||||
|
sprintf( cJitterBuffer, "<p><br>Max high frequency timer jitter = %d peripheral clock periods.<p><br>", ( int ) usMaxJitter );
|
||||||
|
vTaskGetRunTimeStats( uip_appdata );
|
||||||
|
strcat( uip_appdata, cJitterBuffer );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
( void ) cJitterBuffer;
|
||||||
|
strcpy( uip_appdata, "<p>Run time stats are only available in the debug_with_optimisation build configuration.<p>" );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
strcat( uip_appdata, cCountBuf );
|
||||||
|
|
||||||
|
return strlen( uip_appdata );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static PT_THREAD( run_time ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
( void ) ptr;
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
PSOCK_GENERATOR_SEND( &s->sout, generate_runtime_stats, NULL );
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static PT_THREAD( led_io ( struct httpd_state *s, char *ptr ) )
|
||||||
|
{
|
||||||
|
PSOCK_BEGIN( &s->sout );
|
||||||
|
( void ) ptr;
|
||||||
|
( void ) PT_YIELD_FLAG;
|
||||||
|
PSOCK_GENERATOR_SEND( &s->sout, generate_io_state, NULL );
|
||||||
|
PSOCK_END( &s->sout );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
@ -0,0 +1,8 @@
|
|||||||
|
<html>
|
||||||
|
<body bgcolor="white">
|
||||||
|
<center>
|
||||||
|
<h1>404 - file not found</h1>
|
||||||
|
<h3>Go <a href="/">here</a> instead.</h3>
|
||||||
|
</center>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeRTOS.org uIP WEB server demo</title>
|
||||||
|
</head>
|
||||||
|
<BODY onLoad="window.setTimeout("location.href='index.shtml'",100)">
|
||||||
|
<font face="arial">
|
||||||
|
Loading index.shtml. Click <a href="index.shtml">here</a> if not automatically redirected.
|
||||||
|
</font>
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeRTOS.org uIP WEB server demo</title>
|
||||||
|
</head>
|
||||||
|
<BODY onLoad="window.setTimeout("location.href='index.shtml'",2000)">
|
||||||
|
<font face="arial">
|
||||||
|
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
|
||||||
|
<br><p>
|
||||||
|
<hr>
|
||||||
|
<br><p>
|
||||||
|
<h2>Task statistics</h2>
|
||||||
|
Page will refresh every 2 seconds.<p>
|
||||||
|
<font face="courier"><pre>Task State Priority Stack #<br>************************************************<br>
|
||||||
|
%! rtos-stats
|
||||||
|
</pre></font>
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeRTOS.org uIP WEB server demo</title>
|
||||||
|
</head>
|
||||||
|
<BODY>
|
||||||
|
<font face="arial">
|
||||||
|
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
|
||||||
|
<br><p>
|
||||||
|
<hr>
|
||||||
|
<b>LED and LCD IO</b><br>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
Use the check box to turn on or off LED 4, then click "Update IO".
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<form name="aForm" action="/io.shtml" method="get">
|
||||||
|
%! led-io
|
||||||
|
<p>
|
||||||
|
<input type="submit" value="Update IO">
|
||||||
|
</form>
|
||||||
|
<br><p>
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeRTOS.org uIP WEB server demo</title>
|
||||||
|
</head>
|
||||||
|
<BODY onLoad="window.setTimeout("location.href='runtime.shtml'",2000)">
|
||||||
|
<font face="arial">
|
||||||
|
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
|
||||||
|
<br><p>
|
||||||
|
<hr>
|
||||||
|
<br><p>
|
||||||
|
<h2>Run-time statistics</h2>
|
||||||
|
Page will refresh every 2 seconds.<p>
|
||||||
|
<font face="courier"><pre>Task Abs Time % Time<br>****************************************<br>
|
||||||
|
%! run-time
|
||||||
|
</pre></font>
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeRTOS.org uIP WEB server demo</title>
|
||||||
|
</head>
|
||||||
|
<BODY>
|
||||||
|
<font face="arial">
|
||||||
|
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
|
||||||
|
<br><p>
|
||||||
|
<hr>
|
||||||
|
<br><p>
|
||||||
|
<h2>Network statistics</h2>
|
||||||
|
<table width="300" border="0">
|
||||||
|
<tr><td align="left"><font face="courier"><pre>
|
||||||
|
IP Packets received
|
||||||
|
Packets sent
|
||||||
|
Forwaded
|
||||||
|
Dropped
|
||||||
|
IP errors IP version/header length
|
||||||
|
IP length, high byte
|
||||||
|
IP length, low byte
|
||||||
|
IP fragments
|
||||||
|
Header checksum
|
||||||
|
Wrong protocol
|
||||||
|
ICMP Packets received
|
||||||
|
Packets sent
|
||||||
|
Packets dropped
|
||||||
|
Type errors
|
||||||
|
Checksum errors
|
||||||
|
TCP Packets received
|
||||||
|
Packets sent
|
||||||
|
Packets dropped
|
||||||
|
Checksum errors
|
||||||
|
Data packets without ACKs
|
||||||
|
Resets
|
||||||
|
Retransmissionsa
|
||||||
|
Syn to closed port
|
||||||
|
UDP Packets dropped
|
||||||
|
Packets received
|
||||||
|
Packets sent
|
||||||
|
Packets chkerr
|
||||||
|
No connection avaliable
|
||||||
|
</pre></font></td><td><font face="courier"><pre>%! net-stats
|
||||||
|
</pre></font></td></table>
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeRTOS.org uIP WEB server demo</title>
|
||||||
|
</head>
|
||||||
|
<BODY>
|
||||||
|
<font face="arial">
|
||||||
|
<a href="index.shtml">Task Stats</a> <b>|</b> <a href="runtime.shtml">Run Time Stats</a> <b>|</b> <a href="stats.shtml">TCP Stats</a> <b>|</b> <a href="tcp.shtml">Connections</a> <b>|</b> <a href="http://www.freertos.org/">FreeRTOS Homepage</a> <b>|</b> <a href="io.shtml">IO</a> <b>|</b> <a href="logo.jpg">37K jpg</a>
|
||||||
|
<br><p>
|
||||||
|
<hr>
|
||||||
|
<br>
|
||||||
|
<h2>Network connections</h2>
|
||||||
|
<p>
|
||||||
|
<table>
|
||||||
|
<tr><th>Local</th><th>Remote</th><th>State</th><th>Retransmissions</th><th>Timer</th><th>Flags</th></tr>
|
||||||
|
%! tcp-connections
|
||||||
|
</pre></font>
|
||||||
|
</font>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
open(OUTPUT, "> httpd-fsdata.c");
|
||||||
|
|
||||||
|
chdir("httpd-fs");
|
||||||
|
|
||||||
|
opendir(DIR, ".");
|
||||||
|
@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
|
||||||
|
closedir(DIR);
|
||||||
|
|
||||||
|
foreach $file (@files) {
|
||||||
|
|
||||||
|
if(-d $file && $file !~ /^\./) {
|
||||||
|
print "Processing directory $file\n";
|
||||||
|
opendir(DIR, $file);
|
||||||
|
@newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR);
|
||||||
|
closedir(DIR);
|
||||||
|
printf "Adding files @newfiles\n";
|
||||||
|
@files = (@files, map { $_ = "$file/$_" } @newfiles);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach $file (@files) {
|
||||||
|
if(-f $file) {
|
||||||
|
|
||||||
|
print "Adding file $file\n";
|
||||||
|
|
||||||
|
open(FILE, $file) || die "Could not open file $file\n";
|
||||||
|
binmode FILE;
|
||||||
|
|
||||||
|
$file =~ s-^-/-;
|
||||||
|
$fvar = $file;
|
||||||
|
$fvar =~ s-/-_-g;
|
||||||
|
$fvar =~ s-\.-_-g;
|
||||||
|
# for AVR, add PROGMEM here
|
||||||
|
print(OUTPUT "static const char data".$fvar."[] = {\n");
|
||||||
|
print(OUTPUT "\t/* $file */\n\t");
|
||||||
|
for($j = 0; $j < length($file); $j++) {
|
||||||
|
printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1)));
|
||||||
|
}
|
||||||
|
printf(OUTPUT "0,\n");
|
||||||
|
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while(read(FILE, $data, 1)) {
|
||||||
|
if($i == 0) {
|
||||||
|
print(OUTPUT "\t");
|
||||||
|
}
|
||||||
|
printf(OUTPUT "%#02x, ", unpack("C", $data));
|
||||||
|
$i++;
|
||||||
|
if($i == 10) {
|
||||||
|
print(OUTPUT "\n");
|
||||||
|
$i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(OUTPUT "0};\n\n");
|
||||||
|
close(FILE);
|
||||||
|
push(@fvars, $fvar);
|
||||||
|
push(@pfiles, $file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for($i = 0; $i < @fvars; $i++) {
|
||||||
|
$file = $pfiles[$i];
|
||||||
|
$fvar = $fvars[$i];
|
||||||
|
|
||||||
|
if($i == 0) {
|
||||||
|
$prevfile = "NULL";
|
||||||
|
} else {
|
||||||
|
$prevfile = "file" . $fvars[$i - 1];
|
||||||
|
}
|
||||||
|
print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, ");
|
||||||
|
print(OUTPUT "data$fvar + ". (length($file) + 1) .", ");
|
||||||
|
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n");
|
||||||
|
print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n");
|
@ -0,0 +1,167 @@
|
|||||||
|
/**
|
||||||
|
* \addtogroup uipopt
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \name Project-specific configuration options
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* uIP has a number of configuration options that can be overridden
|
||||||
|
* for each project. These are kept in a project-specific uip-conf.h
|
||||||
|
* file and all configuration names have the prefix UIP_CONF.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the uIP TCP/IP stack
|
||||||
|
*
|
||||||
|
* $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* An example uIP configuration file
|
||||||
|
* \author
|
||||||
|
* Adam Dunkels <adam@sics.se>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UIP_CONF_H__
|
||||||
|
#define __UIP_CONF_H__
|
||||||
|
|
||||||
|
#define UIP_CONF_EXTERNAL_BUFFER
|
||||||
|
#define UIP_CONF_PROCESS_HTTPD_FORMS 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 8 bit datatype
|
||||||
|
*
|
||||||
|
* This typedef defines the 8-bit type used throughout uIP.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
typedef unsigned char u8_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 16 bit datatype
|
||||||
|
*
|
||||||
|
* This typedef defines the 16-bit type used throughout uIP.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
typedef unsigned short u16_t;
|
||||||
|
|
||||||
|
typedef unsigned long u32_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics datatype
|
||||||
|
*
|
||||||
|
* This typedef defines the dataype used for keeping statistics in
|
||||||
|
* uIP.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
typedef unsigned short uip_stats_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of TCP connections.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_MAX_CONNECTIONS 40
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of listening TCP ports.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_MAX_LISTENPORTS 40
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uIP buffer size.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_BUFFER_SIZE 1480
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CPU byte order.
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#if __LITTLE_ENDIAN__ == 1
|
||||||
|
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
||||||
|
#else
|
||||||
|
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logging on or off
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_LOGGING 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UDP support on or off
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_UDP 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UDP checksums on or off
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uIP statistics on or off
|
||||||
|
*
|
||||||
|
* \hideinitializer
|
||||||
|
*/
|
||||||
|
#define UIP_CONF_STATISTICS 1
|
||||||
|
|
||||||
|
/* Here we include the header file for the application(s) we use in
|
||||||
|
our project. */
|
||||||
|
/*#include "smtp.h"*/
|
||||||
|
/*#include "hello-world.h"*/
|
||||||
|
/*#include "telnetd.h"*/
|
||||||
|
#include "webserver.h"
|
||||||
|
/*#include "dhcpc.h"*/
|
||||||
|
/*#include "resolv.h"*/
|
||||||
|
/*#include "webclient.h"*/
|
||||||
|
|
||||||
|
#define CCIF
|
||||||
|
#define CC_REGISTER_ARG
|
||||||
|
|
||||||
|
#endif /* __UIP_CONF_H__ */
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
/** @} */
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2002, Adam Dunkels.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||||
|
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the uIP TCP/IP stack
|
||||||
|
*
|
||||||
|
* $Id: webserver.h,v 1.2 2006/06/11 21:46:38 adam Exp $
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __WEBSERVER_H__
|
||||||
|
#define __WEBSERVER_H__
|
||||||
|
|
||||||
|
#include "apps/httpd/httpd.h"
|
||||||
|
|
||||||
|
typedef struct httpd_state uip_tcp_appstate_t;
|
||||||
|
/* UIP_APPCALL: the name of the application function. This function
|
||||||
|
must return void and take no arguments (i.e., C type "void
|
||||||
|
appfunc(void)"). */
|
||||||
|
#define UIP_APPCALL httpd_appcall
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __WEBSERVER_H__ */
|
Loading…
Reference in New Issue