Ethernet working in the Kinetis K60 demo.

This commit is contained in:
Richard Barry 2011-07-10 12:16:13 +00:00
parent 9d181af847
commit 326b6a2c95
29 changed files with 7166 additions and 17 deletions

View File

@ -155,5 +155,7 @@ to exclude the API function. */
#define configNET_MASK2 255
#define configNET_MASK3 0
#define configPHY_ADDRESS 1
#endif /* FREERTOS_CONFIG_H */

View File

@ -19,6 +19,11 @@ extern void SysTick_Handler( void );
/* The button interrupt. */
extern void vPort_E_ISRHandler( void );
/* Ethernet interrupt handlers. */
void vEMAC_TxISRHandler( void );
void vEMAC_RxISRHandler( void );
void vEMAC_ErrorISRHandler( void );
void vEMAC_ISRHandler( void );
// function prototype for default_isr in vectors.c
void default_isr(void);
@ -126,9 +131,9 @@ extern void __iar_program_start(void);
#define VECTOR_089 default_isr // 0x0000_0164 89 73 USB OTG
#define VECTOR_090 default_isr // 0x0000_0168 90 74 USB Charger Detect
#define VECTOR_091 default_isr // 0x0000_016C 91 75 ENET IEEE 1588 Timer interrupt
#define VECTOR_092 default_isr // 0x0000_0170 92 76 ENET Transmit interrupt
#define VECTOR_093 default_isr // 0x0000_0174 93 77 ENET Receive interrupt
#define VECTOR_094 default_isr // 0x0000_0178 94 78 ENET Error and miscellaneous interrupt
#define VECTOR_092 vEMAC_ISRHandler // 0x0000_0170 92 76 ENET Transmit interrupt
#define VECTOR_093 vEMAC_ISRHandler // 0x0000_0174 93 77 ENET Receive interrupt
#define VECTOR_094 vEMAC_ISRHandler // 0x0000_0178 94 78 ENET Error and miscellaneous interrupt
#define VECTOR_095 default_isr // 0x0000_017C 95 79 I2S
#define VECTOR_096 default_isr // 0x0000_0180 96 80 SDHC
#define VECTOR_097 default_isr // 0x0000_0184 97 81 DAC0

View File

@ -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;
}
/********************************************************************/

View File

@ -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_ */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}
/********************************************************************/

View File

@ -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_ */

View File

@ -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_ */

View File

@ -89,9 +89,9 @@ void vParTestInitialise( void )
}
/*-----------------------------------------------------------*/
void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
void vParTestSetLED( unsigned long ulLED, signed portBASE_TYPE xValue )
{
if( uxLED < partstMAX_LEDS )
if( ulLED < partstMAX_LEDS )
{
/* A critical section is used as the LEDs are also accessed from an
interrupt. */
@ -99,11 +99,11 @@ void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
{
if( xValue == pdTRUE )
{
GPIOA_PDOR &= ~GPIO_PDOR_PDO( ulLEDs[ uxLED ] );
GPIOA_PDOR &= ~GPIO_PDOR_PDO( ulLEDs[ ulLED ] );
}
else
{
GPIOA_PDOR |= GPIO_PDOR_PDO( ulLEDs[ uxLED ] );
GPIOA_PDOR |= GPIO_PDOR_PDO( ulLEDs[ ulLED ] );
}
}
taskEXIT_CRITICAL();
@ -111,36 +111,36 @@ void vParTestSetLED( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
}
/*-----------------------------------------------------------*/
void vParTestToggleLED( unsigned portBASE_TYPE uxLED )
void vParTestToggleLED( unsigned long ulLED )
{
if( uxLED < partstMAX_LEDS )
if( ulLED < partstMAX_LEDS )
{
/* A critical section is used as the LEDs are also accessed from an
interrupt. */
taskENTER_CRITICAL();
{
GPIOA_PTOR |= GPIO_PDOR_PDO( ulLEDs[ uxLED ] );
GPIOA_PTOR |= GPIO_PDOR_PDO( ulLEDs[ ulLED ] );
}
taskEXIT_CRITICAL();
}
}
/*-----------------------------------------------------------*/
void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue )
void vParTestSetLEDFromISR( unsigned long ulLED, signed portBASE_TYPE xValue )
{
unsigned portBASE_TYPE uxInterruptFlags;
if( uxLED < partstMAX_LEDS )
if( ulLED < partstMAX_LEDS )
{
uxInterruptFlags = portSET_INTERRUPT_MASK_FROM_ISR();
{
if( xValue == pdTRUE )
{
GPIOA_PDOR &= ~GPIO_PDOR_PDO( ulLEDs[ uxLED ] );
GPIOA_PDOR &= ~GPIO_PDOR_PDO( ulLEDs[ ulLED ] );
}
else
{
GPIOA_PDOR |= GPIO_PDOR_PDO( ulLEDs[ uxLED ] );
GPIOA_PDOR |= GPIO_PDOR_PDO( ulLEDs[ ulLED ] );
}
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxInterruptFlags );
@ -148,3 +148,29 @@ unsigned portBASE_TYPE uxInterruptFlags;
}
/*-----------------------------------------------------------*/
long lParTestGetLEDState( unsigned long ulLED )
{
long lReturn = pdFALSE;
if( ulLED < partstMAX_LEDS )
{
/* A critical section is used as the LEDs are also accessed from an
interrupt. */
taskENTER_CRITICAL();
{
lReturn = GPIO_PDOR_PDO( ulLEDs[ ulLED ] );
if( lReturn == 0 )
{
lReturn = pdTRUE;
}
else
{
lReturn = pdFALSE;
}
}
taskEXIT_CRITICAL();
}
return lReturn;
}

View File

@ -205,7 +205,7 @@
</option>
<option>
<name>CCDiagSuppress</name>
<state>Pa082</state>
<state>Pa082, Pe1644, Pa039, Pa050, pe191</state>
</option>
<option>
<name>CCDiagRemark</name>
@ -304,6 +304,9 @@
<state>$PROJ_DIR$\Freescale_Code\drivers\mcg</state>
<state>$PROJ_DIR$\Freescale_Code\drivers\wdog</state>
<state>$PROJ_DIR$\Freescale_Code\drivers\adc16</state>
<state>$PROJ_DIR$\Freescale_Code\drivers\enet</state>
<state>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP</state>
<state>$PROJ_DIR$\webserver</state>
</option>
<option>
<name>CCStdIncCheck</name>
@ -1910,6 +1913,21 @@
</group>
<group>
<name>drivers</name>
<group>
<name>enet</name>
<excluded>
<configuration>Blinky</configuration>
</excluded>
<file>
<name>$PROJ_DIR$\Freescale_Code\drivers\enet\enet.c</name>
</file>
<file>
<name>$PROJ_DIR$\Freescale_Code\drivers\enet\eth_phy.c</name>
</file>
<file>
<name>$PROJ_DIR$\Freescale_Code\drivers\enet\mii.c</name>
</file>
</group>
<group>
<name>mcg</name>
<file>
@ -1930,6 +1948,48 @@
</group>
</group>
</group>
<group>
<name>FreeTCPIP (based on uIP)</name>
<excluded>
<configuration>Blinky</configuration>
</excluded>
<group>
<name>webserver</name>
<group>
<name>Common</name>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\apps\httpd\http-strings.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\apps\httpd\httpd-fs.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\apps\httpd\httpd.c</name>
</file>
</group>
<group>
<name>Port specific</name>
<file>
<name>$PROJ_DIR$\webserver\EMAC.c</name>
</file>
<file>
<name>$PROJ_DIR$\webserver\httpd-cgi.c</name>
</file>
</group>
</group>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\psock.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\timer.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\uip.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\Common\ethernet\FreeTCPIP\uip_arp.c</name>
</file>
</group>
<file>
<name>$PROJ_DIR$\FreeRTOSConfig.h</name>
</file>
@ -1951,6 +2011,12 @@
<configuration>Blinky</configuration>
</excluded>
</file>
<file>
<name>$PROJ_DIR$\uIP_Task.c</name>
<excluded>
<configuration>Blinky</configuration>
</excluded>
</file>
</project>

View File

@ -175,6 +175,11 @@ all the available LEDs are already used by other tasks and timers. */
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
/* The WEB server uses string handling functions, which in turn use a bit more
stack than most of the other tasks. */
#define mainuIP_STACK_SIZE ( configMINIMAL_STACK_SIZE * 3 )
/* Priorities defined in this main-full.c file. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
@ -245,6 +250,11 @@ static void prvCheckTimerCallback( xTimerHandle xTimer );
*/
void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE xValue );
/*
* Contains the implementation of the WEB server.
*/
extern void vuIP_Task( void *pvParameters );
/*-----------------------------------------------------------*/
/* The queue used by both application specific demo tasks defined in this file. */
@ -297,6 +307,9 @@ void main( void )
vStartCountingSemaphoreTasks();
vStartDynamicPriorityTasks();
/* The web server task. */
xTaskCreate( vuIP_Task, "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL );
/* The suicide tasks must be created last, as they need to know how many
tasks were running prior to their creation in order to ascertain whether
or not the correct/expected number of tasks are running at any given
@ -435,7 +448,7 @@ portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
/* The button was pushed, so ensure the LED is on before resetting the
LED timer. The LED timer will turn the LED off if the button is not
pushed within 5000ms. */
vParTestToggleLED( mainTIMER_CONTROLLED_LED );
vParTestSetLED( mainTIMER_CONTROLLED_LED, pdTRUE );
/* This interrupt safe FreeRTOS function can be called from this interrupt
because the interrupt priority is below the
@ -461,6 +474,7 @@ static void prvSetupHardware( void )
taskDISABLE_INTERRUPTS();
PORTE_PCR26 = PORT_PCR_MUX( 1 ) | PORT_PCR_IRQC( 0xA ) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
enable_irq( mainGPIO_E_VECTOR );
set_irq_priority( mainGPIO_E_VECTOR, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
/* Configure the LED outputs. */
vParTestInitialise();
@ -561,7 +575,7 @@ volatile size_t xFreeHeapSpace;
xTimerStart( xLED2Timer, portMAX_DELAY );
xFreeHeapSpace = xPortGetFreeHeapSize();
printf( "%d bytes of FreeRTOS heap remain unused - configTOTAL_HEAP_SIZE can be reduced\n", xFreeHeapSpace );
printf( "%d bytes of FreeRTOS heap remain unused\nconfigTOTAL_HEAP_SIZE can be reduced\n", xFreeHeapSpace );
if( xFreeHeapSpace > 100 )
{
@ -582,3 +596,18 @@ void vApplicationTickHook( void )
}
/*-----------------------------------------------------------*/
char *pcGetTaskStatusMessage( void )
{
/* Not bothered about a critical section here although technically because
of the task priorities the pointer could change it will be atomic if not
near atomic and its not critical. */
if( pcStatusMessage == NULL )
{
return "All tasks running without error";
}
else
{
return ( char * ) pcStatusMessage;
}
}
/*-----------------------------------------------------------*/

View File

@ -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 );
}
}
}
/*-----------------------------------------------------------*/

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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 );
}
/** @} */

View File

@ -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>

View File

@ -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(&quot;location.href='index.shtml'&quot;,100)">
<font face="arial">
Loading index.shtml. Click <a href="index.shtml">here</a> if not automatically redirected.
</font>
</font>
</body>
</html>

View File

@ -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(&quot;location.href='index.shtml'&quot;,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>

View File

@ -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

View File

@ -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(&quot;location.href='runtime.shtml'&quot;,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>

View File

@ -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>

View File

@ -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

View File

@ -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");

View File

@ -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__ */
/** @} */
/** @} */

View File

@ -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__ */