NXP LPC1768 Ethernet driver for lwip and CMSIS-RTOS

Dependents:   EthernetInterface EthernetInterface EthernetInterface_RSF EthernetInterface ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed 5, the networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of the NXP LPC port of the Lightweight TCP/IP Stack

Copyright(C) 2011, NXP Semiconductor
All rights reserved.

Software that is described herein is for illustrative purposes only
which provides customers with programming information regarding the
products. This software is supplied "AS IS" without any warranties.
NXP Semiconductors assumes no responsibility or liability for the
use of the software, conveys no license or title under any patent,
copyright, or mask work right to the product. NXP Semiconductors
reserves the right to make changes in the software without
notification. NXP Semiconductors also make no representation or
warranty that such application will be suitable for the specified
use without further testing or modification.
Committer:
mbed_official
Date:
Thu May 26 09:00:26 2016 +0100
Revision:
33:9de8bd8ca1c8
Synchronized with git revision 745ebbf4557f0f3964f73063c1d88ddbcda0ed22

Full URL: https://github.com/mbedmicro/mbed/commit/745ebbf4557f0f3964f73063c1d88ddbcda0ed22/

Synch - fix lwip-eth path

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 33:9de8bd8ca1c8 1 #include "lwip/opt.h"
mbed_official 33:9de8bd8ca1c8 2 #include "lwip/sys.h"
mbed_official 33:9de8bd8ca1c8 3 #include "lwip/def.h"
mbed_official 33:9de8bd8ca1c8 4 #include "lwip/mem.h"
mbed_official 33:9de8bd8ca1c8 5 #include "lwip/pbuf.h"
mbed_official 33:9de8bd8ca1c8 6 #include "lwip/stats.h"
mbed_official 33:9de8bd8ca1c8 7 #include "lwip/snmp.h"
mbed_official 33:9de8bd8ca1c8 8 #include "lwip/tcpip.h"
mbed_official 33:9de8bd8ca1c8 9 #include "netif/etharp.h"
mbed_official 33:9de8bd8ca1c8 10 #include "netif/ppp_oe.h"
mbed_official 33:9de8bd8ca1c8 11
mbed_official 33:9de8bd8ca1c8 12 #include "eth_arch.h"
mbed_official 33:9de8bd8ca1c8 13 #include "sys_arch.h"
mbed_official 33:9de8bd8ca1c8 14
mbed_official 33:9de8bd8ca1c8 15 #include "fsl_phy.h"
mbed_official 33:9de8bd8ca1c8 16 #include "k64f_emac_config.h"
mbed_official 33:9de8bd8ca1c8 17 #include <ctype.h>
mbed_official 33:9de8bd8ca1c8 18 #include <stdio.h>
mbed_official 33:9de8bd8ca1c8 19 #include <string.h>
mbed_official 33:9de8bd8ca1c8 20 #include <stdlib.h>
mbed_official 33:9de8bd8ca1c8 21
mbed_official 33:9de8bd8ca1c8 22 #include "mbed_interface.h"
mbed_official 33:9de8bd8ca1c8 23
mbed_official 33:9de8bd8ca1c8 24 enet_handle_t g_handle;
mbed_official 33:9de8bd8ca1c8 25 // TX Buffer descriptors
mbed_official 33:9de8bd8ca1c8 26 uint8_t *tx_desc_start_addr;
mbed_official 33:9de8bd8ca1c8 27 // RX Buffer descriptors
mbed_official 33:9de8bd8ca1c8 28 uint8_t *rx_desc_start_addr;
mbed_official 33:9de8bd8ca1c8 29 // RX packet buffer pointers
mbed_official 33:9de8bd8ca1c8 30 struct pbuf *rx_buff[ENET_RX_RING_LEN];
mbed_official 33:9de8bd8ca1c8 31 // TX packet buffer pointers
mbed_official 33:9de8bd8ca1c8 32 struct pbuf *tx_buff[ENET_RX_RING_LEN];
mbed_official 33:9de8bd8ca1c8 33 // RX packet payload pointers
mbed_official 33:9de8bd8ca1c8 34 uint32_t *rx_ptr[ENET_RX_RING_LEN];
mbed_official 33:9de8bd8ca1c8 35
mbed_official 33:9de8bd8ca1c8 36 /********************************************************************************
mbed_official 33:9de8bd8ca1c8 37 * Internal data
mbed_official 33:9de8bd8ca1c8 38 ********************************************************************************/
mbed_official 33:9de8bd8ca1c8 39 #define ENET_BuffSizeAlign(n) ENET_ALIGN(n, ENET_BUFF_ALIGNMENT)
mbed_official 33:9de8bd8ca1c8 40 #define ENET_ALIGN(x,align) ((unsigned int)((x) + ((align)-1)) & (unsigned int)(~(unsigned int)((align)- 1)))
mbed_official 33:9de8bd8ca1c8 41 extern void k64f_init_eth_hardware(void);
mbed_official 33:9de8bd8ca1c8 42
mbed_official 33:9de8bd8ca1c8 43 /* K64F EMAC driver data structure */
mbed_official 33:9de8bd8ca1c8 44 struct k64f_enetdata {
mbed_official 33:9de8bd8ca1c8 45 struct netif *netif; /**< Reference back to LWIP parent netif */
mbed_official 33:9de8bd8ca1c8 46 sys_sem_t RxReadySem; /**< RX packet ready semaphore */
mbed_official 33:9de8bd8ca1c8 47 sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
mbed_official 33:9de8bd8ca1c8 48 sys_mutex_t TXLockMutex; /**< TX critical section mutex */
mbed_official 33:9de8bd8ca1c8 49 sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
mbed_official 33:9de8bd8ca1c8 50 uint8_t tx_consume_index, tx_produce_index; /**< TX buffers ring */
mbed_official 33:9de8bd8ca1c8 51 };
mbed_official 33:9de8bd8ca1c8 52
mbed_official 33:9de8bd8ca1c8 53 static struct k64f_enetdata k64f_enetdata;
mbed_official 33:9de8bd8ca1c8 54
mbed_official 33:9de8bd8ca1c8 55 /** \brief Driver transmit and receive thread priorities
mbed_official 33:9de8bd8ca1c8 56 *
mbed_official 33:9de8bd8ca1c8 57 * Thread priorities for receive thread and TX cleanup thread. Alter
mbed_official 33:9de8bd8ca1c8 58 * to prioritize receive or transmit bandwidth. In a heavily loaded
mbed_official 33:9de8bd8ca1c8 59 * system or with LEIP_DEBUG enabled, the priorities might be better
mbed_official 33:9de8bd8ca1c8 60 * the same. */
mbed_official 33:9de8bd8ca1c8 61 #define RX_PRIORITY (osPriorityNormal)
mbed_official 33:9de8bd8ca1c8 62 #define TX_PRIORITY (osPriorityNormal)
mbed_official 33:9de8bd8ca1c8 63 #define PHY_PRIORITY (osPriorityNormal)
mbed_official 33:9de8bd8ca1c8 64
mbed_official 33:9de8bd8ca1c8 65 /********************************************************************************
mbed_official 33:9de8bd8ca1c8 66 * Buffer management
mbed_official 33:9de8bd8ca1c8 67 ********************************************************************************/
mbed_official 33:9de8bd8ca1c8 68 /*
mbed_official 33:9de8bd8ca1c8 69 * This function will queue a new receive buffer
mbed_official 33:9de8bd8ca1c8 70 */
mbed_official 33:9de8bd8ca1c8 71 static void update_read_buffer(uint8_t *buf)
mbed_official 33:9de8bd8ca1c8 72 {
mbed_official 33:9de8bd8ca1c8 73 if (buf != NULL) {
mbed_official 33:9de8bd8ca1c8 74 g_handle.rxBdCurrent->buffer = buf;
mbed_official 33:9de8bd8ca1c8 75 }
mbed_official 33:9de8bd8ca1c8 76
mbed_official 33:9de8bd8ca1c8 77 /* Clears status. */
mbed_official 33:9de8bd8ca1c8 78 g_handle.rxBdCurrent->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
mbed_official 33:9de8bd8ca1c8 79
mbed_official 33:9de8bd8ca1c8 80 /* Sets the receive buffer descriptor with the empty flag. */
mbed_official 33:9de8bd8ca1c8 81 g_handle.rxBdCurrent->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
mbed_official 33:9de8bd8ca1c8 82
mbed_official 33:9de8bd8ca1c8 83 /* Increases the buffer descriptor to the next one. */
mbed_official 33:9de8bd8ca1c8 84 if (g_handle.rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) {
mbed_official 33:9de8bd8ca1c8 85 g_handle.rxBdCurrent = g_handle.rxBdBase;
mbed_official 33:9de8bd8ca1c8 86 g_handle.rxBdDirty = g_handle.rxBdBase;
mbed_official 33:9de8bd8ca1c8 87 } else {
mbed_official 33:9de8bd8ca1c8 88 g_handle.rxBdCurrent++;
mbed_official 33:9de8bd8ca1c8 89 g_handle.rxBdDirty++;
mbed_official 33:9de8bd8ca1c8 90 }
mbed_official 33:9de8bd8ca1c8 91
mbed_official 33:9de8bd8ca1c8 92 /* Actives the receive buffer descriptor. */
mbed_official 33:9de8bd8ca1c8 93 ENET->RDAR = ENET_RDAR_RDAR_MASK;
mbed_official 33:9de8bd8ca1c8 94 }
mbed_official 33:9de8bd8ca1c8 95
mbed_official 33:9de8bd8ca1c8 96 /** \brief Free TX buffers that are complete
mbed_official 33:9de8bd8ca1c8 97 *
mbed_official 33:9de8bd8ca1c8 98 * \param[in] k64f_enet Pointer to driver data structure
mbed_official 33:9de8bd8ca1c8 99 */
mbed_official 33:9de8bd8ca1c8 100 static void k64f_tx_reclaim(struct k64f_enetdata *k64f_enet)
mbed_official 33:9de8bd8ca1c8 101 {
mbed_official 33:9de8bd8ca1c8 102 uint8_t i = 0 ;
mbed_official 33:9de8bd8ca1c8 103
mbed_official 33:9de8bd8ca1c8 104 /* Get exclusive access */
mbed_official 33:9de8bd8ca1c8 105 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 106
mbed_official 33:9de8bd8ca1c8 107 i = k64f_enet->tx_consume_index;
mbed_official 33:9de8bd8ca1c8 108 // Traverse all descriptors, looking for the ones modified by the uDMA
mbed_official 33:9de8bd8ca1c8 109 while((i != k64f_enet->tx_produce_index) && (!(g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))) {
mbed_official 33:9de8bd8ca1c8 110 pbuf_free(tx_buff[i]);
mbed_official 33:9de8bd8ca1c8 111 if (g_handle.txBdDirty->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
mbed_official 33:9de8bd8ca1c8 112 g_handle.txBdDirty = g_handle.txBdBase;
mbed_official 33:9de8bd8ca1c8 113 else
mbed_official 33:9de8bd8ca1c8 114 g_handle.txBdDirty++;
mbed_official 33:9de8bd8ca1c8 115
mbed_official 33:9de8bd8ca1c8 116 i = (i + 1) % ENET_TX_RING_LEN;
mbed_official 33:9de8bd8ca1c8 117 }
mbed_official 33:9de8bd8ca1c8 118
mbed_official 33:9de8bd8ca1c8 119 k64f_enet->tx_consume_index = i;
mbed_official 33:9de8bd8ca1c8 120 /* Restore access */
mbed_official 33:9de8bd8ca1c8 121 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 122 }
mbed_official 33:9de8bd8ca1c8 123
mbed_official 33:9de8bd8ca1c8 124 /** \brief Ethernet receive interrupt handler
mbed_official 33:9de8bd8ca1c8 125 *
mbed_official 33:9de8bd8ca1c8 126 * This function handles the receive interrupt of K64F.
mbed_official 33:9de8bd8ca1c8 127 */
mbed_official 33:9de8bd8ca1c8 128 void enet_mac_rx_isr()
mbed_official 33:9de8bd8ca1c8 129 {
mbed_official 33:9de8bd8ca1c8 130 sys_sem_signal(&k64f_enetdata.RxReadySem);
mbed_official 33:9de8bd8ca1c8 131 }
mbed_official 33:9de8bd8ca1c8 132
mbed_official 33:9de8bd8ca1c8 133 void enet_mac_tx_isr()
mbed_official 33:9de8bd8ca1c8 134 {
mbed_official 33:9de8bd8ca1c8 135 sys_sem_signal(&k64f_enetdata.TxCleanSem);
mbed_official 33:9de8bd8ca1c8 136 }
mbed_official 33:9de8bd8ca1c8 137
mbed_official 33:9de8bd8ca1c8 138 void ethernet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *param)
mbed_official 33:9de8bd8ca1c8 139 {
mbed_official 33:9de8bd8ca1c8 140 switch (event)
mbed_official 33:9de8bd8ca1c8 141 {
mbed_official 33:9de8bd8ca1c8 142 case kENET_RxEvent:
mbed_official 33:9de8bd8ca1c8 143 enet_mac_rx_isr();
mbed_official 33:9de8bd8ca1c8 144 break;
mbed_official 33:9de8bd8ca1c8 145 case kENET_TxEvent:
mbed_official 33:9de8bd8ca1c8 146 enet_mac_tx_isr();
mbed_official 33:9de8bd8ca1c8 147 break;
mbed_official 33:9de8bd8ca1c8 148 default:
mbed_official 33:9de8bd8ca1c8 149 break;
mbed_official 33:9de8bd8ca1c8 150 }
mbed_official 33:9de8bd8ca1c8 151 }
mbed_official 33:9de8bd8ca1c8 152
mbed_official 33:9de8bd8ca1c8 153 /** \brief Low level init of the MAC and PHY.
mbed_official 33:9de8bd8ca1c8 154 *
mbed_official 33:9de8bd8ca1c8 155 * \param[in] netif Pointer to LWIP netif structure
mbed_official 33:9de8bd8ca1c8 156 */
mbed_official 33:9de8bd8ca1c8 157 static err_t low_level_init(struct netif *netif)
mbed_official 33:9de8bd8ca1c8 158 {
mbed_official 33:9de8bd8ca1c8 159 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 33:9de8bd8ca1c8 160 uint8_t i;
mbed_official 33:9de8bd8ca1c8 161 uint32_t sysClock;
mbed_official 33:9de8bd8ca1c8 162 phy_speed_t phy_speed;
mbed_official 33:9de8bd8ca1c8 163 phy_duplex_t phy_duplex;
mbed_official 33:9de8bd8ca1c8 164 uint32_t phyAddr = 0;
mbed_official 33:9de8bd8ca1c8 165 bool link = false;
mbed_official 33:9de8bd8ca1c8 166 enet_config_t config;
mbed_official 33:9de8bd8ca1c8 167
mbed_official 33:9de8bd8ca1c8 168 // Allocate RX descriptors
mbed_official 33:9de8bd8ca1c8 169 rx_desc_start_addr = (uint8_t *)calloc(1, sizeof(enet_rx_bd_struct_t) * ENET_RX_RING_LEN + ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 170 if(!rx_desc_start_addr)
mbed_official 33:9de8bd8ca1c8 171 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 172
mbed_official 33:9de8bd8ca1c8 173 // Allocate TX descriptors
mbed_official 33:9de8bd8ca1c8 174 tx_desc_start_addr = (uint8_t *)calloc(1, sizeof(enet_tx_bd_struct_t) * ENET_TX_RING_LEN + ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 175 if(!tx_desc_start_addr)
mbed_official 33:9de8bd8ca1c8 176 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 177
mbed_official 33:9de8bd8ca1c8 178 rx_desc_start_addr = (uint8_t *)ENET_ALIGN(rx_desc_start_addr, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 179 tx_desc_start_addr = (uint8_t *)ENET_ALIGN(tx_desc_start_addr, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 180
mbed_official 33:9de8bd8ca1c8 181 /* Create buffers for each receive BD */
mbed_official 33:9de8bd8ca1c8 182 for (i = 0; i < ENET_RX_RING_LEN; i++) {
mbed_official 33:9de8bd8ca1c8 183 rx_buff[i] = pbuf_alloc(PBUF_RAW, ENET_ETH_MAX_FLEN + ENET_BUFF_ALIGNMENT, PBUF_RAM);
mbed_official 33:9de8bd8ca1c8 184 if (NULL == rx_buff[i])
mbed_official 33:9de8bd8ca1c8 185 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 186
mbed_official 33:9de8bd8ca1c8 187 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 33:9de8bd8ca1c8 188 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 33:9de8bd8ca1c8 189 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 33:9de8bd8ca1c8 190 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 33:9de8bd8ca1c8 191 rx_buff[i]->payload = (void*)ENET_ALIGN((uint32_t)rx_buff[i]->payload, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 192 rx_ptr[i] = rx_buff[i]->payload;
mbed_official 33:9de8bd8ca1c8 193 }
mbed_official 33:9de8bd8ca1c8 194
mbed_official 33:9de8bd8ca1c8 195 k64f_enet->tx_consume_index = k64f_enet->tx_produce_index = 0;
mbed_official 33:9de8bd8ca1c8 196
mbed_official 33:9de8bd8ca1c8 197 /* prepare the buffer configuration. */
mbed_official 33:9de8bd8ca1c8 198 enet_buffer_config_t buffCfg = {
mbed_official 33:9de8bd8ca1c8 199 ENET_RX_RING_LEN,
mbed_official 33:9de8bd8ca1c8 200 ENET_TX_RING_LEN,
mbed_official 33:9de8bd8ca1c8 201 ENET_ALIGN(ENET_ETH_MAX_FLEN, ENET_BUFF_ALIGNMENT),
mbed_official 33:9de8bd8ca1c8 202 0,
mbed_official 33:9de8bd8ca1c8 203 (volatile enet_rx_bd_struct_t *)rx_desc_start_addr,
mbed_official 33:9de8bd8ca1c8 204 (volatile enet_tx_bd_struct_t *)tx_desc_start_addr,
mbed_official 33:9de8bd8ca1c8 205 (uint8_t *)&rx_ptr,
mbed_official 33:9de8bd8ca1c8 206 NULL,
mbed_official 33:9de8bd8ca1c8 207 };
mbed_official 33:9de8bd8ca1c8 208
mbed_official 33:9de8bd8ca1c8 209 k64f_init_eth_hardware();
mbed_official 33:9de8bd8ca1c8 210
mbed_official 33:9de8bd8ca1c8 211 sysClock = CLOCK_GetFreq(kCLOCK_CoreSysClk);
mbed_official 33:9de8bd8ca1c8 212
mbed_official 33:9de8bd8ca1c8 213 ENET_GetDefaultConfig(&config);
mbed_official 33:9de8bd8ca1c8 214
mbed_official 33:9de8bd8ca1c8 215 PHY_Init(ENET, 0, sysClock);
mbed_official 33:9de8bd8ca1c8 216 PHY_GetLinkStatus(ENET, phyAddr, &link);
mbed_official 33:9de8bd8ca1c8 217 if (link)
mbed_official 33:9de8bd8ca1c8 218 {
mbed_official 33:9de8bd8ca1c8 219 /* Get link information from PHY */
mbed_official 33:9de8bd8ca1c8 220 PHY_GetLinkSpeedDuplex(ENET, phyAddr, &phy_speed, &phy_duplex);
mbed_official 33:9de8bd8ca1c8 221 /* Change the MII speed and duplex for actual link status. */
mbed_official 33:9de8bd8ca1c8 222 config.miiSpeed = (enet_mii_speed_t)phy_speed;
mbed_official 33:9de8bd8ca1c8 223 config.miiDuplex = (enet_mii_duplex_t)phy_duplex;
mbed_official 33:9de8bd8ca1c8 224 config.interrupt = kENET_RxFrameInterrupt | kENET_TxFrameInterrupt;
mbed_official 33:9de8bd8ca1c8 225 }
mbed_official 33:9de8bd8ca1c8 226 config.rxMaxFrameLen = ENET_ETH_MAX_FLEN;
mbed_official 33:9de8bd8ca1c8 227 config.macSpecialConfig = kENET_ControlFlowControlEnable;
mbed_official 33:9de8bd8ca1c8 228 config.txAccelerConfig = kENET_TxAccelIsShift16Enabled;
mbed_official 33:9de8bd8ca1c8 229 config.rxAccelerConfig = kENET_RxAccelisShift16Enabled | kENET_RxAccelMacCheckEnabled;
mbed_official 33:9de8bd8ca1c8 230 ENET_Init(ENET, &g_handle, &config, &buffCfg, netif->hwaddr, sysClock);
mbed_official 33:9de8bd8ca1c8 231 ENET_SetCallback(&g_handle, ethernet_callback, netif);
mbed_official 33:9de8bd8ca1c8 232 ENET_ActiveRead(ENET);
mbed_official 33:9de8bd8ca1c8 233
mbed_official 33:9de8bd8ca1c8 234 return ERR_OK;
mbed_official 33:9de8bd8ca1c8 235 }
mbed_official 33:9de8bd8ca1c8 236
mbed_official 33:9de8bd8ca1c8 237
mbed_official 33:9de8bd8ca1c8 238 /**
mbed_official 33:9de8bd8ca1c8 239 * This function is the ethernet packet send function. It calls
mbed_official 33:9de8bd8ca1c8 240 * etharp_output after checking link status.
mbed_official 33:9de8bd8ca1c8 241 *
mbed_official 33:9de8bd8ca1c8 242 * \param[in] netif the lwip network interface structure for this enetif
mbed_official 33:9de8bd8ca1c8 243 * \param[in] q Pointer to pbug to send
mbed_official 33:9de8bd8ca1c8 244 * \param[in] ipaddr IP address
mbed_official 33:9de8bd8ca1c8 245 * \return ERR_OK or error code
mbed_official 33:9de8bd8ca1c8 246 */
mbed_official 33:9de8bd8ca1c8 247 err_t k64f_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
mbed_official 33:9de8bd8ca1c8 248 {
mbed_official 33:9de8bd8ca1c8 249 /* Only send packet is link is up */
mbed_official 33:9de8bd8ca1c8 250 if (netif->flags & NETIF_FLAG_LINK_UP)
mbed_official 33:9de8bd8ca1c8 251 return etharp_output(netif, q, ipaddr);
mbed_official 33:9de8bd8ca1c8 252
mbed_official 33:9de8bd8ca1c8 253 return ERR_CONN;
mbed_official 33:9de8bd8ca1c8 254 }
mbed_official 33:9de8bd8ca1c8 255
mbed_official 33:9de8bd8ca1c8 256 /** \brief Allocates a pbuf and returns the data from the incoming packet.
mbed_official 33:9de8bd8ca1c8 257 *
mbed_official 33:9de8bd8ca1c8 258 * \param[in] netif the lwip network interface structure
mbed_official 33:9de8bd8ca1c8 259 * \param[in] idx index of packet to be read
mbed_official 33:9de8bd8ca1c8 260 * \return a pbuf filled with the received packet (including MAC header)
mbed_official 33:9de8bd8ca1c8 261 */
mbed_official 33:9de8bd8ca1c8 262 static struct pbuf *k64f_low_level_input(struct netif *netif, int idx)
mbed_official 33:9de8bd8ca1c8 263 {
mbed_official 33:9de8bd8ca1c8 264 volatile enet_rx_bd_struct_t *bdPtr = g_handle.rxBdCurrent;
mbed_official 33:9de8bd8ca1c8 265 struct pbuf *p = NULL;
mbed_official 33:9de8bd8ca1c8 266 struct pbuf *temp_rxbuf = NULL;
mbed_official 33:9de8bd8ca1c8 267 u32_t length = 0;
mbed_official 33:9de8bd8ca1c8 268 const u16_t err_mask = ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK | ENET_BUFFDESCRIPTOR_RX_CRC_MASK |
mbed_official 33:9de8bd8ca1c8 269 ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK | ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK;
mbed_official 33:9de8bd8ca1c8 270
mbed_official 33:9de8bd8ca1c8 271
mbed_official 33:9de8bd8ca1c8 272 #ifdef LOCK_RX_THREAD
mbed_official 33:9de8bd8ca1c8 273 /* Get exclusive access */
mbed_official 33:9de8bd8ca1c8 274 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 275 #endif
mbed_official 33:9de8bd8ca1c8 276
mbed_official 33:9de8bd8ca1c8 277 /* Determine if a frame has been received */
mbed_official 33:9de8bd8ca1c8 278 if ((bdPtr->control & err_mask) != 0) {
mbed_official 33:9de8bd8ca1c8 279 #if LINK_STATS
mbed_official 33:9de8bd8ca1c8 280 if ((bdPtr->control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK) != 0)
mbed_official 33:9de8bd8ca1c8 281 LINK_STATS_INC(link.lenerr);
mbed_official 33:9de8bd8ca1c8 282 else
mbed_official 33:9de8bd8ca1c8 283 LINK_STATS_INC(link.chkerr);
mbed_official 33:9de8bd8ca1c8 284 #endif
mbed_official 33:9de8bd8ca1c8 285 LINK_STATS_INC(link.drop);
mbed_official 33:9de8bd8ca1c8 286 /* Re-use the same buffer in case of error */
mbed_official 33:9de8bd8ca1c8 287 update_read_buffer(NULL);
mbed_official 33:9de8bd8ca1c8 288 } else {
mbed_official 33:9de8bd8ca1c8 289 /* A packet is waiting, get length */
mbed_official 33:9de8bd8ca1c8 290 length = bdPtr->length;
mbed_official 33:9de8bd8ca1c8 291
mbed_official 33:9de8bd8ca1c8 292 /* Zero-copy */
mbed_official 33:9de8bd8ca1c8 293 p = rx_buff[idx];
mbed_official 33:9de8bd8ca1c8 294 p->len = length;
mbed_official 33:9de8bd8ca1c8 295
mbed_official 33:9de8bd8ca1c8 296 /* Attempt to queue new buffer */
mbed_official 33:9de8bd8ca1c8 297 temp_rxbuf = pbuf_alloc(PBUF_RAW, ENET_ETH_MAX_FLEN + ENET_BUFF_ALIGNMENT, PBUF_RAM);
mbed_official 33:9de8bd8ca1c8 298 if (NULL == temp_rxbuf) {
mbed_official 33:9de8bd8ca1c8 299 /* Drop frame (out of memory) */
mbed_official 33:9de8bd8ca1c8 300 LINK_STATS_INC(link.drop);
mbed_official 33:9de8bd8ca1c8 301
mbed_official 33:9de8bd8ca1c8 302 /* Re-queue the same buffer */
mbed_official 33:9de8bd8ca1c8 303 update_read_buffer(NULL);
mbed_official 33:9de8bd8ca1c8 304
mbed_official 33:9de8bd8ca1c8 305 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 33:9de8bd8ca1c8 306 ("k64f_low_level_input: Packet index %d dropped for OOM\n",
mbed_official 33:9de8bd8ca1c8 307 idx));
mbed_official 33:9de8bd8ca1c8 308 #ifdef LOCK_RX_THREAD
mbed_official 33:9de8bd8ca1c8 309 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 310 #endif
mbed_official 33:9de8bd8ca1c8 311
mbed_official 33:9de8bd8ca1c8 312 return NULL;
mbed_official 33:9de8bd8ca1c8 313 }
mbed_official 33:9de8bd8ca1c8 314
mbed_official 33:9de8bd8ca1c8 315 rx_buff[idx] = temp_rxbuf;
mbed_official 33:9de8bd8ca1c8 316 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 33:9de8bd8ca1c8 317 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 33:9de8bd8ca1c8 318 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 33:9de8bd8ca1c8 319 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 33:9de8bd8ca1c8 320 rx_buff[idx]->payload = (void*)ENET_ALIGN((uint32_t)rx_buff[idx]->payload, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 321 rx_ptr[idx] = rx_buff[idx]->payload;
mbed_official 33:9de8bd8ca1c8 322
mbed_official 33:9de8bd8ca1c8 323 update_read_buffer(rx_buff[idx]->payload);
mbed_official 33:9de8bd8ca1c8 324 LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
mbed_official 33:9de8bd8ca1c8 325 ("k64f_low_level_input: Packet received: %p, size %d (index=%d)\n",
mbed_official 33:9de8bd8ca1c8 326 p, length, idx));
mbed_official 33:9de8bd8ca1c8 327
mbed_official 33:9de8bd8ca1c8 328 /* Save size */
mbed_official 33:9de8bd8ca1c8 329 p->tot_len = (u16_t) length;
mbed_official 33:9de8bd8ca1c8 330 LINK_STATS_INC(link.recv);
mbed_official 33:9de8bd8ca1c8 331 }
mbed_official 33:9de8bd8ca1c8 332
mbed_official 33:9de8bd8ca1c8 333 #ifdef LOCK_RX_THREAD
mbed_official 33:9de8bd8ca1c8 334 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 335 #endif
mbed_official 33:9de8bd8ca1c8 336
mbed_official 33:9de8bd8ca1c8 337 return p;
mbed_official 33:9de8bd8ca1c8 338 }
mbed_official 33:9de8bd8ca1c8 339
mbed_official 33:9de8bd8ca1c8 340 /** \brief Attempt to read a packet from the EMAC interface.
mbed_official 33:9de8bd8ca1c8 341 *
mbed_official 33:9de8bd8ca1c8 342 * \param[in] netif the lwip network interface structure
mbed_official 33:9de8bd8ca1c8 343 * \param[in] idx index of packet to be read
mbed_official 33:9de8bd8ca1c8 344 */
mbed_official 33:9de8bd8ca1c8 345 void k64f_enetif_input(struct netif *netif, int idx)
mbed_official 33:9de8bd8ca1c8 346 {
mbed_official 33:9de8bd8ca1c8 347 struct eth_hdr *ethhdr;
mbed_official 33:9de8bd8ca1c8 348 struct pbuf *p;
mbed_official 33:9de8bd8ca1c8 349
mbed_official 33:9de8bd8ca1c8 350 /* move received packet into a new pbuf */
mbed_official 33:9de8bd8ca1c8 351 p = k64f_low_level_input(netif, idx);
mbed_official 33:9de8bd8ca1c8 352 if (p == NULL)
mbed_official 33:9de8bd8ca1c8 353 return;
mbed_official 33:9de8bd8ca1c8 354
mbed_official 33:9de8bd8ca1c8 355 /* points to packet payload, which starts with an Ethernet header */
mbed_official 33:9de8bd8ca1c8 356 ethhdr = (struct eth_hdr*)p->payload;
mbed_official 33:9de8bd8ca1c8 357
mbed_official 33:9de8bd8ca1c8 358 switch (htons(ethhdr->type)) {
mbed_official 33:9de8bd8ca1c8 359 case ETHTYPE_IP:
mbed_official 33:9de8bd8ca1c8 360 case ETHTYPE_ARP:
mbed_official 33:9de8bd8ca1c8 361 #if PPPOE_SUPPORT
mbed_official 33:9de8bd8ca1c8 362 case ETHTYPE_PPPOEDISC:
mbed_official 33:9de8bd8ca1c8 363 case ETHTYPE_PPPOE:
mbed_official 33:9de8bd8ca1c8 364 #endif /* PPPOE_SUPPORT */
mbed_official 33:9de8bd8ca1c8 365 /* full packet send to tcpip_thread to process */
mbed_official 33:9de8bd8ca1c8 366 if (netif->input(p, netif) != ERR_OK) {
mbed_official 33:9de8bd8ca1c8 367 LWIP_DEBUGF(NETIF_DEBUG, ("k64f_enetif_input: IP input error\n"));
mbed_official 33:9de8bd8ca1c8 368 /* Free buffer */
mbed_official 33:9de8bd8ca1c8 369 pbuf_free(p);
mbed_official 33:9de8bd8ca1c8 370 }
mbed_official 33:9de8bd8ca1c8 371 break;
mbed_official 33:9de8bd8ca1c8 372
mbed_official 33:9de8bd8ca1c8 373 default:
mbed_official 33:9de8bd8ca1c8 374 /* Return buffer */
mbed_official 33:9de8bd8ca1c8 375 pbuf_free(p);
mbed_official 33:9de8bd8ca1c8 376 break;
mbed_official 33:9de8bd8ca1c8 377 }
mbed_official 33:9de8bd8ca1c8 378 }
mbed_official 33:9de8bd8ca1c8 379
mbed_official 33:9de8bd8ca1c8 380 /** \brief Packet reception task
mbed_official 33:9de8bd8ca1c8 381 *
mbed_official 33:9de8bd8ca1c8 382 * This task is called when a packet is received. It will
mbed_official 33:9de8bd8ca1c8 383 * pass the packet to the LWIP core.
mbed_official 33:9de8bd8ca1c8 384 *
mbed_official 33:9de8bd8ca1c8 385 * \param[in] pvParameters pointer to the interface data
mbed_official 33:9de8bd8ca1c8 386 */
mbed_official 33:9de8bd8ca1c8 387 static void packet_rx(void* pvParameters) {
mbed_official 33:9de8bd8ca1c8 388 struct k64f_enetdata *k64f_enet = pvParameters;
mbed_official 33:9de8bd8ca1c8 389 int idx = 0;
mbed_official 33:9de8bd8ca1c8 390
mbed_official 33:9de8bd8ca1c8 391 while (1) {
mbed_official 33:9de8bd8ca1c8 392 /* Wait for receive task to wakeup */
mbed_official 33:9de8bd8ca1c8 393 sys_arch_sem_wait(&k64f_enet->RxReadySem, 0);
mbed_official 33:9de8bd8ca1c8 394
mbed_official 33:9de8bd8ca1c8 395 while ((g_handle.rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK) == 0) {
mbed_official 33:9de8bd8ca1c8 396 k64f_enetif_input(k64f_enet->netif, idx);
mbed_official 33:9de8bd8ca1c8 397 idx = (idx + 1) % ENET_RX_RING_LEN;
mbed_official 33:9de8bd8ca1c8 398 }
mbed_official 33:9de8bd8ca1c8 399 }
mbed_official 33:9de8bd8ca1c8 400 }
mbed_official 33:9de8bd8ca1c8 401
mbed_official 33:9de8bd8ca1c8 402 /** \brief Transmit cleanup task
mbed_official 33:9de8bd8ca1c8 403 *
mbed_official 33:9de8bd8ca1c8 404 * This task is called when a transmit interrupt occurs and
mbed_official 33:9de8bd8ca1c8 405 * reclaims the pbuf and descriptor used for the packet once
mbed_official 33:9de8bd8ca1c8 406 * the packet has been transferred.
mbed_official 33:9de8bd8ca1c8 407 *
mbed_official 33:9de8bd8ca1c8 408 * \param[in] pvParameters pointer to the interface data
mbed_official 33:9de8bd8ca1c8 409 */
mbed_official 33:9de8bd8ca1c8 410 static void packet_tx(void* pvParameters) {
mbed_official 33:9de8bd8ca1c8 411 struct k64f_enetdata *k64f_enet = pvParameters;
mbed_official 33:9de8bd8ca1c8 412
mbed_official 33:9de8bd8ca1c8 413 while (1) {
mbed_official 33:9de8bd8ca1c8 414 /* Wait for transmit cleanup task to wakeup */
mbed_official 33:9de8bd8ca1c8 415 sys_arch_sem_wait(&k64f_enet->TxCleanSem, 0);
mbed_official 33:9de8bd8ca1c8 416 k64f_tx_reclaim(k64f_enet);
mbed_official 33:9de8bd8ca1c8 417 }
mbed_official 33:9de8bd8ca1c8 418 }
mbed_official 33:9de8bd8ca1c8 419
mbed_official 33:9de8bd8ca1c8 420 /** \brief Low level output of a packet. Never call this from an
mbed_official 33:9de8bd8ca1c8 421 * interrupt context, as it may block until TX descriptors
mbed_official 33:9de8bd8ca1c8 422 * become available.
mbed_official 33:9de8bd8ca1c8 423 *
mbed_official 33:9de8bd8ca1c8 424 * \param[in] netif the lwip network interface structure for this netif
mbed_official 33:9de8bd8ca1c8 425 * \param[in] p the MAC packet to send (e.g. IP packet including MAC addresses and type)
mbed_official 33:9de8bd8ca1c8 426 * \return ERR_OK if the packet could be sent or an err_t value if the packet couldn't be sent
mbed_official 33:9de8bd8ca1c8 427 */
mbed_official 33:9de8bd8ca1c8 428 static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p)
mbed_official 33:9de8bd8ca1c8 429 {
mbed_official 33:9de8bd8ca1c8 430 struct k64f_enetdata *k64f_enet = netif->state;
mbed_official 33:9de8bd8ca1c8 431 struct pbuf *q;
mbed_official 33:9de8bd8ca1c8 432 struct pbuf *temp_pbuf;
mbed_official 33:9de8bd8ca1c8 433 uint8_t *psend = NULL, *dst;
mbed_official 33:9de8bd8ca1c8 434
mbed_official 33:9de8bd8ca1c8 435
mbed_official 33:9de8bd8ca1c8 436 temp_pbuf = pbuf_alloc(PBUF_RAW, p->tot_len + ENET_BUFF_ALIGNMENT, PBUF_RAM);
mbed_official 33:9de8bd8ca1c8 437 if (NULL == temp_pbuf)
mbed_official 33:9de8bd8ca1c8 438 return ERR_MEM;
mbed_official 33:9de8bd8ca1c8 439
mbed_official 33:9de8bd8ca1c8 440 /* K64F note: the next line ensures that the RX buffer is properly aligned for the K64F
mbed_official 33:9de8bd8ca1c8 441 RX descriptors (16 bytes alignment). However, by doing so, we're effectively changing
mbed_official 33:9de8bd8ca1c8 442 a data structure which is internal to lwIP. This might not prove to be a good idea
mbed_official 33:9de8bd8ca1c8 443 in the long run, but a better fix would probably involve modifying lwIP itself */
mbed_official 33:9de8bd8ca1c8 444 psend = (uint8_t *)ENET_ALIGN((uint32_t)temp_pbuf->payload, ENET_BUFF_ALIGNMENT);
mbed_official 33:9de8bd8ca1c8 445
mbed_official 33:9de8bd8ca1c8 446 for (q = p, dst = psend; q != NULL; q = q->next) {
mbed_official 33:9de8bd8ca1c8 447 MEMCPY(dst, q->payload, q->len);
mbed_official 33:9de8bd8ca1c8 448 dst += q->len;
mbed_official 33:9de8bd8ca1c8 449 }
mbed_official 33:9de8bd8ca1c8 450
mbed_official 33:9de8bd8ca1c8 451 /* Wait until a descriptor is available for the transfer. */
mbed_official 33:9de8bd8ca1c8 452 /* THIS WILL BLOCK UNTIL THERE ARE A DESCRIPTOR AVAILABLE */
mbed_official 33:9de8bd8ca1c8 453 while (g_handle.txBdCurrent->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
mbed_official 33:9de8bd8ca1c8 454 osSemaphoreWait(k64f_enet->xTXDCountSem.id, osWaitForever);
mbed_official 33:9de8bd8ca1c8 455
mbed_official 33:9de8bd8ca1c8 456 /* Get exclusive access */
mbed_official 33:9de8bd8ca1c8 457 sys_mutex_lock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 458
mbed_official 33:9de8bd8ca1c8 459 /* Save the buffer so that it can be freed when transmit is done */
mbed_official 33:9de8bd8ca1c8 460 tx_buff[k64f_enet->tx_produce_index] = temp_pbuf;
mbed_official 33:9de8bd8ca1c8 461 k64f_enet->tx_produce_index = (k64f_enet->tx_produce_index + 1) % ENET_TX_RING_LEN;
mbed_official 33:9de8bd8ca1c8 462
mbed_official 33:9de8bd8ca1c8 463 /* Setup transfers */
mbed_official 33:9de8bd8ca1c8 464 g_handle.txBdCurrent->buffer = psend;
mbed_official 33:9de8bd8ca1c8 465 g_handle.txBdCurrent->length = p->tot_len;
mbed_official 33:9de8bd8ca1c8 466 g_handle.txBdCurrent->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
mbed_official 33:9de8bd8ca1c8 467
mbed_official 33:9de8bd8ca1c8 468 /* Increase the buffer descriptor address. */
mbed_official 33:9de8bd8ca1c8 469 if (g_handle.txBdCurrent->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
mbed_official 33:9de8bd8ca1c8 470 g_handle.txBdCurrent = g_handle.txBdBase;
mbed_official 33:9de8bd8ca1c8 471 else
mbed_official 33:9de8bd8ca1c8 472 g_handle.txBdCurrent++;
mbed_official 33:9de8bd8ca1c8 473
mbed_official 33:9de8bd8ca1c8 474 /* Active the transmit buffer descriptor. */
mbed_official 33:9de8bd8ca1c8 475 ENET->TDAR = ENET_TDAR_TDAR_MASK;
mbed_official 33:9de8bd8ca1c8 476
mbed_official 33:9de8bd8ca1c8 477 LINK_STATS_INC(link.xmit);
mbed_official 33:9de8bd8ca1c8 478
mbed_official 33:9de8bd8ca1c8 479 /* Restore access */
mbed_official 33:9de8bd8ca1c8 480 sys_mutex_unlock(&k64f_enet->TXLockMutex);
mbed_official 33:9de8bd8ca1c8 481
mbed_official 33:9de8bd8ca1c8 482 return ERR_OK;
mbed_official 33:9de8bd8ca1c8 483 }
mbed_official 33:9de8bd8ca1c8 484
mbed_official 33:9de8bd8ca1c8 485 /*******************************************************************************
mbed_official 33:9de8bd8ca1c8 486 * PHY task: monitor link
mbed_official 33:9de8bd8ca1c8 487 *******************************************************************************/
mbed_official 33:9de8bd8ca1c8 488
mbed_official 33:9de8bd8ca1c8 489 #define PHY_TASK_PERIOD_MS 200
mbed_official 33:9de8bd8ca1c8 490 #define STATE_UNKNOWN (-1)
mbed_official 33:9de8bd8ca1c8 491
mbed_official 33:9de8bd8ca1c8 492 typedef struct {
mbed_official 33:9de8bd8ca1c8 493 int connected;
mbed_official 33:9de8bd8ca1c8 494 phy_speed_t speed;
mbed_official 33:9de8bd8ca1c8 495 phy_duplex_t duplex;
mbed_official 33:9de8bd8ca1c8 496 } PHY_STATE;
mbed_official 33:9de8bd8ca1c8 497
mbed_official 33:9de8bd8ca1c8 498 int phy_link_status() {
mbed_official 33:9de8bd8ca1c8 499 bool connection_status;
mbed_official 33:9de8bd8ca1c8 500 uint32_t phyAddr = 0;
mbed_official 33:9de8bd8ca1c8 501
mbed_official 33:9de8bd8ca1c8 502 PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
mbed_official 33:9de8bd8ca1c8 503 return (int)connection_status;
mbed_official 33:9de8bd8ca1c8 504 }
mbed_official 33:9de8bd8ca1c8 505
mbed_official 33:9de8bd8ca1c8 506 static void k64f_phy_task(void *data) {
mbed_official 33:9de8bd8ca1c8 507 struct netif *netif = (struct netif*)data;
mbed_official 33:9de8bd8ca1c8 508 bool connection_status;
mbed_official 33:9de8bd8ca1c8 509 PHY_STATE crt_state = {STATE_UNKNOWN, (phy_speed_t)STATE_UNKNOWN, (phy_duplex_t)STATE_UNKNOWN};
mbed_official 33:9de8bd8ca1c8 510 PHY_STATE prev_state;
mbed_official 33:9de8bd8ca1c8 511 uint32_t phyAddr = 0;
mbed_official 33:9de8bd8ca1c8 512 uint32_t rcr = 0;
mbed_official 33:9de8bd8ca1c8 513
mbed_official 33:9de8bd8ca1c8 514 prev_state = crt_state;
mbed_official 33:9de8bd8ca1c8 515 while (true) {
mbed_official 33:9de8bd8ca1c8 516 // Get current status
mbed_official 33:9de8bd8ca1c8 517 PHY_GetLinkStatus(ENET, phyAddr, &connection_status);
mbed_official 33:9de8bd8ca1c8 518 crt_state.connected = connection_status ? 1 : 0;
mbed_official 33:9de8bd8ca1c8 519 // Get the actual PHY link speed
mbed_official 33:9de8bd8ca1c8 520 PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex);
mbed_official 33:9de8bd8ca1c8 521
mbed_official 33:9de8bd8ca1c8 522 // Compare with previous state
mbed_official 33:9de8bd8ca1c8 523 if (crt_state.connected != prev_state.connected) {
mbed_official 33:9de8bd8ca1c8 524 if (crt_state.connected)
mbed_official 33:9de8bd8ca1c8 525 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1);
mbed_official 33:9de8bd8ca1c8 526 else
mbed_official 33:9de8bd8ca1c8 527 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
mbed_official 33:9de8bd8ca1c8 528 }
mbed_official 33:9de8bd8ca1c8 529
mbed_official 33:9de8bd8ca1c8 530 if (crt_state.speed != prev_state.speed) {
mbed_official 33:9de8bd8ca1c8 531 rcr = ENET->RCR;
mbed_official 33:9de8bd8ca1c8 532 rcr &= ~ENET_RCR_RMII_10T_MASK;
mbed_official 33:9de8bd8ca1c8 533 rcr |= ENET_RCR_RMII_10T(!crt_state.speed);
mbed_official 33:9de8bd8ca1c8 534 ENET->RCR = rcr;
mbed_official 33:9de8bd8ca1c8 535 }
mbed_official 33:9de8bd8ca1c8 536
mbed_official 33:9de8bd8ca1c8 537 prev_state = crt_state;
mbed_official 33:9de8bd8ca1c8 538 osDelay(PHY_TASK_PERIOD_MS);
mbed_official 33:9de8bd8ca1c8 539 }
mbed_official 33:9de8bd8ca1c8 540 }
mbed_official 33:9de8bd8ca1c8 541
mbed_official 33:9de8bd8ca1c8 542 /**
mbed_official 33:9de8bd8ca1c8 543 * Should be called at the beginning of the program to set up the
mbed_official 33:9de8bd8ca1c8 544 * network interface.
mbed_official 33:9de8bd8ca1c8 545 *
mbed_official 33:9de8bd8ca1c8 546 * This function should be passed as a parameter to netif_add().
mbed_official 33:9de8bd8ca1c8 547 *
mbed_official 33:9de8bd8ca1c8 548 * @param[in] netif the lwip network interface structure for this netif
mbed_official 33:9de8bd8ca1c8 549 * @return ERR_OK if the loopif is initialized
mbed_official 33:9de8bd8ca1c8 550 * ERR_MEM if private data couldn't be allocated
mbed_official 33:9de8bd8ca1c8 551 * any other err_t on error
mbed_official 33:9de8bd8ca1c8 552 */
mbed_official 33:9de8bd8ca1c8 553 err_t eth_arch_enetif_init(struct netif *netif)
mbed_official 33:9de8bd8ca1c8 554 {
mbed_official 33:9de8bd8ca1c8 555 err_t err;
mbed_official 33:9de8bd8ca1c8 556
mbed_official 33:9de8bd8ca1c8 557 LWIP_ASSERT("netif != NULL", (netif != NULL));
mbed_official 33:9de8bd8ca1c8 558
mbed_official 33:9de8bd8ca1c8 559 k64f_enetdata.netif = netif;
mbed_official 33:9de8bd8ca1c8 560
mbed_official 33:9de8bd8ca1c8 561 /* set MAC hardware address */
mbed_official 33:9de8bd8ca1c8 562 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
mbed_official 33:9de8bd8ca1c8 563 netif->hwaddr[0] = MBED_MAC_ADDR_0;
mbed_official 33:9de8bd8ca1c8 564 netif->hwaddr[1] = MBED_MAC_ADDR_1;
mbed_official 33:9de8bd8ca1c8 565 netif->hwaddr[2] = MBED_MAC_ADDR_2;
mbed_official 33:9de8bd8ca1c8 566 netif->hwaddr[3] = MBED_MAC_ADDR_3;
mbed_official 33:9de8bd8ca1c8 567 netif->hwaddr[4] = MBED_MAC_ADDR_4;
mbed_official 33:9de8bd8ca1c8 568 netif->hwaddr[5] = MBED_MAC_ADDR_5;
mbed_official 33:9de8bd8ca1c8 569 #else
mbed_official 33:9de8bd8ca1c8 570 mbed_mac_address((char *)netif->hwaddr);
mbed_official 33:9de8bd8ca1c8 571 #endif
mbed_official 33:9de8bd8ca1c8 572 netif->hwaddr_len = ETHARP_HWADDR_LEN;
mbed_official 33:9de8bd8ca1c8 573
mbed_official 33:9de8bd8ca1c8 574 /* maximum transfer unit */
mbed_official 33:9de8bd8ca1c8 575 netif->mtu = 1500;
mbed_official 33:9de8bd8ca1c8 576
mbed_official 33:9de8bd8ca1c8 577 /* device capabilities */
mbed_official 33:9de8bd8ca1c8 578 // TODOETH: check if the flags are correct below
mbed_official 33:9de8bd8ca1c8 579 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
mbed_official 33:9de8bd8ca1c8 580
mbed_official 33:9de8bd8ca1c8 581 /* Initialize the hardware */
mbed_official 33:9de8bd8ca1c8 582 netif->state = &k64f_enetdata;
mbed_official 33:9de8bd8ca1c8 583 err = low_level_init(netif);
mbed_official 33:9de8bd8ca1c8 584 if (err != ERR_OK)
mbed_official 33:9de8bd8ca1c8 585 return err;
mbed_official 33:9de8bd8ca1c8 586
mbed_official 33:9de8bd8ca1c8 587 #if LWIP_NETIF_HOSTNAME
mbed_official 33:9de8bd8ca1c8 588 /* Initialize interface hostname */
mbed_official 33:9de8bd8ca1c8 589 netif->hostname = "lwipk64f";
mbed_official 33:9de8bd8ca1c8 590 #endif /* LWIP_NETIF_HOSTNAME */
mbed_official 33:9de8bd8ca1c8 591
mbed_official 33:9de8bd8ca1c8 592 netif->name[0] = 'e';
mbed_official 33:9de8bd8ca1c8 593 netif->name[1] = 'n';
mbed_official 33:9de8bd8ca1c8 594
mbed_official 33:9de8bd8ca1c8 595 netif->output = k64f_etharp_output;
mbed_official 33:9de8bd8ca1c8 596 netif->linkoutput = k64f_low_level_output;
mbed_official 33:9de8bd8ca1c8 597
mbed_official 33:9de8bd8ca1c8 598 /* CMSIS-RTOS, start tasks */
mbed_official 33:9de8bd8ca1c8 599 #ifdef CMSIS_OS_RTX
mbed_official 33:9de8bd8ca1c8 600 memset(k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data));
mbed_official 33:9de8bd8ca1c8 601 k64f_enetdata.xTXDCountSem.def.semaphore = k64f_enetdata.xTXDCountSem.data;
mbed_official 33:9de8bd8ca1c8 602 #endif
mbed_official 33:9de8bd8ca1c8 603 k64f_enetdata.xTXDCountSem.id = osSemaphoreCreate(&k64f_enetdata.xTXDCountSem.def, ENET_TX_RING_LEN);
mbed_official 33:9de8bd8ca1c8 604
mbed_official 33:9de8bd8ca1c8 605 LWIP_ASSERT("xTXDCountSem creation error", (k64f_enetdata.xTXDCountSem.id != NULL));
mbed_official 33:9de8bd8ca1c8 606
mbed_official 33:9de8bd8ca1c8 607 err = sys_mutex_new(&k64f_enetdata.TXLockMutex);
mbed_official 33:9de8bd8ca1c8 608 LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
mbed_official 33:9de8bd8ca1c8 609
mbed_official 33:9de8bd8ca1c8 610 /* Packet receive task */
mbed_official 33:9de8bd8ca1c8 611 err = sys_sem_new(&k64f_enetdata.RxReadySem, 0);
mbed_official 33:9de8bd8ca1c8 612 LWIP_ASSERT("RxReadySem creation error", (err == ERR_OK));
mbed_official 33:9de8bd8ca1c8 613 sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
mbed_official 33:9de8bd8ca1c8 614
mbed_official 33:9de8bd8ca1c8 615 /* Transmit cleanup task */
mbed_official 33:9de8bd8ca1c8 616 err = sys_sem_new(&k64f_enetdata.TxCleanSem, 0);
mbed_official 33:9de8bd8ca1c8 617 LWIP_ASSERT("TxCleanSem creation error", (err == ERR_OK));
mbed_official 33:9de8bd8ca1c8 618 sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
mbed_official 33:9de8bd8ca1c8 619
mbed_official 33:9de8bd8ca1c8 620 /* PHY monitoring task */
mbed_official 33:9de8bd8ca1c8 621 sys_thread_new("phy_thread", k64f_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_PRIORITY);
mbed_official 33:9de8bd8ca1c8 622
mbed_official 33:9de8bd8ca1c8 623 /* Allow the PHY task to detect the initial link state and set up the proper flags */
mbed_official 33:9de8bd8ca1c8 624 osDelay(10);
mbed_official 33:9de8bd8ca1c8 625
mbed_official 33:9de8bd8ca1c8 626 return ERR_OK;
mbed_official 33:9de8bd8ca1c8 627 }
mbed_official 33:9de8bd8ca1c8 628
mbed_official 33:9de8bd8ca1c8 629 void eth_arch_enable_interrupts(void) {
mbed_official 33:9de8bd8ca1c8 630 //NVIC_SetPriority(ENET_Receive_IRQn, 6U);
mbed_official 33:9de8bd8ca1c8 631 //NVIC_SetPriority(ENET_Transmit_IRQn, 6U);
mbed_official 33:9de8bd8ca1c8 632 }
mbed_official 33:9de8bd8ca1c8 633
mbed_official 33:9de8bd8ca1c8 634 void eth_arch_disable_interrupts(void) {
mbed_official 33:9de8bd8ca1c8 635
mbed_official 33:9de8bd8ca1c8 636 }
mbed_official 33:9de8bd8ca1c8 637
mbed_official 33:9de8bd8ca1c8 638 /**
mbed_official 33:9de8bd8ca1c8 639 * @}
mbed_official 33:9de8bd8ca1c8 640 */
mbed_official 33:9de8bd8ca1c8 641
mbed_official 33:9de8bd8ca1c8 642 /* --------------------------------- End Of File ------------------------------ */
mbed_official 33:9de8bd8ca1c8 643