From: richardbarry Date: Sun, 10 Jul 2011 12:16:13 +0000 (+0000) Subject: Ethernet working in the Kinetis K60 demo. X-Git-Tag: V7.0.2~121 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=93e335f4b7d1496b470b1489b2e2a12dab5c2dd3;p=freertos Ethernet working in the Kinetis K60 demo. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1489 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/FreeRTOSConfig.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/FreeRTOSConfig.h index 1baa172e2..e086598ce 100644 --- a/Demo/CORTEX_Kinetis_K60_Tower_IAR/FreeRTOSConfig.h +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/FreeRTOSConfig.h @@ -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 */ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/cpu/vectors.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/cpu/vectors.h index 76bf5afdc..2f412088d 100644 --- a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/cpu/vectors.h +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/cpu/vectors.h @@ -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 diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/enet.c b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/enet.c new file mode 100644 index 000000000..50b585920 --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/enet.c @@ -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; +} +/********************************************************************/ + + + diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/enet.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/enet.h new file mode 100644 index 000000000..c0e76ee44 --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/enet.h @@ -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_ */ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth.h new file mode 100644 index 000000000..ea942be7f --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth.h @@ -0,0 +1,58 @@ +/*! + * \file eth.h + * \brief Definitinos for Ethernet Frames + * \version $Revision: 1.1 $ + * \author Michael Norman + */ + +#ifndef _ETH_H +#define _ETH_H + +/*b06862*/ +#include "common.h" + +/*******************************************************************/ + +/* Ethernet standard lengths in bytes*/ +#define ETH_ADDR_LEN (6) +#define ETH_TYPE_LEN (2) +#define ETH_CRC_LEN (4) +#define ETH_MAX_DATA (1500) +#define ETH_MIN_DATA (46) +#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN) + +/* Defined Ethernet Frame Types */ +#define ETH_FRM_IP (0x0800) +#define ETH_FRM_ARP (0x0806) +#define ETH_FRM_RARP (0x8035) +#define ETH_FRM_TEST (0xA5A5) + +/* Maximum and Minimum Ethernet Frame Sizes */ +#define ETH_MAX_FRM (ETH_HDR_LEN + ETH_MAX_DATA + ETH_CRC_LEN) +#define ETH_MIN_FRM (ETH_HDR_LEN + ETH_MIN_DATA + ETH_CRC_LEN) +#define ETH_MTU (ETH_HDR_LEN + ETH_MAX_DATA) + +/* Ethernet Addresses */ +typedef uint8_t ETH_ADDR[ETH_ADDR_LEN]; + +/* 16-bit Ethernet Frame Type, ie. Protocol */ +typedef uint16_t ETH_FRM_TYPE; + +/* Ethernet Frame Header definition */ +typedef struct +{ + ETH_ADDR dest; + ETH_ADDR src; + ETH_FRM_TYPE type; +} ETH_HDR; + +/* Ethernet Frame definition */ +typedef struct +{ + ETH_HDR head; + uint8_t* data; +} ETH_FRAME; + +/*******************************************************************/ + +#endif /* _ETH_H */ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth_phy.c b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth_phy.c new file mode 100644 index 000000000..6183f50ee --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth_phy.c @@ -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; +} diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth_phy.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth_phy.h new file mode 100644 index 000000000..27330c235 --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/eth_phy.h @@ -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 */ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.c b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.c new file mode 100644 index 000000000..8de8dae21 --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.c @@ -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; +} +/********************************************************************/ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.h new file mode 100644 index 000000000..8c94d95f7 --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/mii.h @@ -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_ */ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/nbuf.h b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/nbuf.h new file mode 100644 index 000000000..5e2c98515 --- /dev/null +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/Freescale_Code/drivers/enet/nbuf.h @@ -0,0 +1,233 @@ +// ---------------------------------------------------------------------- +// File: nbuf.h +// Purpose: Definitions for Network Buffer Allocation. +// +// Notes: +// +// ---------------------------------------------------------------------- + +#ifndef _NBUF_H_ +#define _NBUF_H_ + +// Define number of MACs +#define NUM_CHANNELS 1/*b06862*/ + +// Choose Enhanced Buffer Descriptor or Legacy +#define ENHANCED_BD + +//b06862: define Endianess for Little Endian architectures like ARM. +//Motorola/Freescale uses Big Endian or Register-Endianess +#define NBUF_LITTLE_ENDIAN + +// Transmit packet directly or copy to dedicated buffers. If packets +// are not alligned dedicated Tx buffers can be used +//#define USE_DEDICATED_TX_BUFFERS + +// Buffer sizes in bytes (must be divisible by 16) +#define RX_BUFFER_SIZE 256 +#define TX_BUFFER_SIZE 256 + +// Number of Receive and Transmit Buffers and Buffer Descriptors +#define NUM_RXBDS 20//10 +#define NUM_TXBDS 20//10 + +// Buffer Descriptor Format +#ifdef ENHANCED_BD + typedef struct + { + uint16_t status; /* control and status */ + uint16_t length; /* transfer length */ + uint8_t *data; /* buffer address */ + uint32_t ebd_status; + uint16_t length_proto_type; + uint16_t payload_checksum; + uint32_t bdu; + uint32_t timestamp; + uint32_t reserverd_word1; + uint32_t reserverd_word2; + } NBUF; +#else + typedef struct + { + uint16_t status; /* control and status */ + uint16_t length; /* transfer length */ + uint8_t *data; /* buffer address */ + } NBUF; +#endif /* ENHANCED_BD */ + +// ---------------------------------------------------------------------- +// Function Declarations +// ---------------------------------------------------------------------- +void +nbuf_alloc(int ch); + +void +nbuf_init(int); + +void +nbuf_start_rx(int); + +void +nbuf_flush(int); + +//NM - return value +void +enet_get_received_packet(int, NBUF *); + +//NM - return value +void +enet_fill_txbds(int, NBUF *); + +void +enet_transmit_packet(int,NBUF *); + +#ifdef NBUF_LITTLE_ENDIAN + +//For Freescale ARM Architecture + +// ---------------------------------------------------------------------- +// TX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_R 0x0080 +#define TX_BD_TO1 0x0040 +#define TX_BD_W 0x0020 +#define TX_BD_TO2 0x0010 +#define TX_BD_L 0x0008 +#define TX_BD_TC 0x0004 +#define TX_BD_ABC 0x0002 + +// ---------------------------------------------------------------------- +// TX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_INT 0x00000040 +#define TX_BD_TS 0x00000020 +#define TX_BD_PINS 0x00000010 +#define TX_BD_IINS 0x00000008 +#define TX_BD_TXE 0x00800000 +#define TX_BD_UE 0x00200000 +#define TX_BD_EE 0x00100000 +#define TX_BD_FE 0x00080000 +#define TX_BD_LCE 0x00040000 +#define TX_BD_OE 0x00020000 +#define TX_BD_TSE 0x00010000 + +#define TX_BD_BDU 0x00000080 + +// ---------------------------------------------------------------------- +// RX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- + +// Offset 0 flags - status: Big Endian +#define RX_BD_E 0x0080 +#define RX_BD_R01 0x0040 +#define RX_BD_W 0x0020 +#define RX_BD_R02 0x0010 +#define RX_BD_L 0x0008 +#define RX_BD_M 0x0001 +#define RX_BD_BC 0x8000 +#define RX_BD_MC 0x4000 +#define RX_BD_LG 0x2000 +#define RX_BD_NO 0x1000 +#define RX_BD_CR 0x0400 +#define RX_BD_OV 0x0200 +#define RX_BD_TR 0x0100 + +// ---------------------------------------------------------------------- +// RX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define RX_BD_ME 0x00000080 +#define RX_BD_PE 0x00000004 +#define RX_BD_CE 0x00000002 +#define RX_BD_UC 0x00000001 + +#define RX_BD_INT 0x00008000 + +#define RX_BD_ICE 0x20000000 +#define RX_BD_PCR 0x10000000 +#define RX_BD_VLAN 0x04000000 +#define RX_BD_IPV6 0x02000000 +#define RX_BD_FRAG 0x01000000 + +#define RX_BD_BDU 0x00000080 + +#else + +//For Freescale ColdFire Architecture +// ---------------------------------------------------------------------- +// TX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_R 0x8000 +#define TX_BD_TO1 0x4000 +#define TX_BD_W 0x2000 +#define TX_BD_TO2 0x1000 +#define TX_BD_L 0x0800 +#define TX_BD_TC 0x0400 +#define TX_BD_ABC 0x0200 + +// ---------------------------------------------------------------------- +// TX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define TX_BD_INT 0x40000000 +#define TX_BD_TS 0x20000000 +#define TX_BD_PINS 0x10000000 +#define TX_BD_IINS 0x08000000 +#define TX_BD_TXE 0x00008000 +#define TX_BD_UE 0x00002000 +#define TX_BD_EE 0x00001000 +#define TX_BD_FE 0x00000800 +#define TX_BD_LCE 0x00000400 +#define TX_BD_OE 0x00000200 +#define TX_BD_TSE 0x00000100 + +#define TX_BD_BDU 0x80000000 + +// ---------------------------------------------------------------------- +// RX Buffer Descriptor Bit Definitions +// ---------------------------------------------------------------------- + +// Offset 0 flags - status +#define RX_BD_E 0x8000 +#define RX_BD_R01 0x4000 +#define RX_BD_W 0x2000 +#define RX_BD_R02 0x1000 +#define RX_BD_L 0x0800 +#define RX_BD_M 0x0100 +#define RX_BD_BC 0x0080 +#define RX_BD_MC 0x0040 +#define RX_BD_LG 0x0020 +#define RX_BD_NO 0x0010 +#define RX_BD_CR 0x0004 +#define RX_BD_OV 0x0002 +#define RX_BD_TR 0x0001 + +// ---------------------------------------------------------------------- +// RX Enhanced BD Bit Definitions +// ---------------------------------------------------------------------- +#define RX_BD_ME 0x80000000 +#define RX_BD_PE 0x04000000 +#define RX_BD_CE 0x02000000 +#define RX_BD_UC 0x01000000 +#define RX_BD_INT 0x00800000 +#define RX_BD_ICE 0x00000020 +#define RX_BD_PCR 0x00000010 +#define RX_BD_VLAN 0x00000004 +#define RX_BD_IPV6 0x00000002 +#define RX_BD_FRAG 0x00000001 + +#define RX_BD_BDU 0x80000000 + + +#endif + +// ---------------------------------------------------------------------- +// Defines for word offsets of various fields of RX Enhanced BDs +// ---------------------------------------------------------------------- +//#define RX_EBD_HEADER_LENGTH_OFFSET 12 +//#define RX_EBD_PROTOCOL_TYPE_OFFSET 12 +//#define RX_EBD_PAYLOAD_CHKSM_OFFSET 14 +//#define RX_EBD_BDU_OFFSET 16 +//#define RX_EBD_TIMESTAMP_MSB_OFFSET 20 +//#define RX_EBD_TIMESTAMP_LSB_OFFSET 22 + + +#endif /* _NBUF_H_ */ diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/ParTest.c b/Demo/CORTEX_Kinetis_K60_Tower_IAR/ParTest.c index 37e48fe10..86087e5ec 100644 --- a/Demo/CORTEX_Kinetis_K60_Tower_IAR/ParTest.c +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/ParTest.c @@ -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; +} diff --git a/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewp b/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewp index 6ed187b1d..7c5e038e1 100644 --- a/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewp +++ b/Demo/CORTEX_Kinetis_K60_Tower_IAR/RTOSDemo.ewp @@ -205,7 +205,7 @@