EMAC driver for the ENC28J60 Ethernet controller. This is a simplified fork of https://github.com/tobiasjaster/ENC28J60-EMAC-Driver published by Tobias Jaster.

Dependents:   MQTT_Hello MQTT_HelloENC28J60

EMAC driver for the ENC28J60 Ethernet controller

https://os.mbed.com/media/uploads/hudakz/enc28j60_module01.jpg

This is a fork (the INT and RST pins are not used) of the ENC28J60-EMAC driver published by Tobias Jaster at

https://github.com/tobiasjaster/ENC28J60-EMAC-Driver

Usage:

  • Connect the ENC28J60 module to the Mbed board as follows:

https://os.mbed.com/media/uploads/hudakz/enc28j60-emac.png

  • Import (add) this ENC28J60-EMAC library to your program.
  • Add a "mbed_app.json" file with the following content to the root directory of your program:

    {
        "target_overrides": {
            "*": {
                "platform.callback-nontrivial": true,
                "enc28j60-emac.mosi":  "D11",
                "enc28j60-emac.miso":  "D12",
                "enc28j60-emac.sck" :  "D13",
                "enc28j60-emac.cs"  :  "D10"
            }
        }
    }
  • Replace "D11", ..., "D10" with the actual pin names you selected on the Mbed board to be used for the SPI communication.
  • To set the MAC address define an array with the desired address bytes and call the "set_hwaddr(mac)" function before calling the network interface "connect" function.

For example:

    const uint8_t       MAC[6] = { 0, 1, 2, 3, 4, 5 };
    EthernetInterface   net;
 
    int main()
    {
        net.get_emac().set_hwaddr(MAC);             // set MAC address
        if (net.connect() != 0) {
            printf("Error: Unable to connect to the network.\n");
            return -1;
        }
     ...
Committer:
hudakz
Date:
Mon Mar 29 08:37:01 2021 +0000
Revision:
3:aa88808326b9
Parent:
2:19d290369c66
Mbed OS Ethernet MAC (EMAC) driver for the ENC28J60 Ethernet controller. This a simplified fork of https://github.com/tobiasjaster/ENC28J60-EMAC-Driver published by Tobias Jaster.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:b599e748252c 1 /*
hudakz 0:b599e748252c 2 * Copyright (c) 2019 Tobias Jaster
hudakz 0:b599e748252c 3 *
hudakz 0:b599e748252c 4 * Modified by Zoltan Hudak
hudakz 0:b599e748252c 5 *
hudakz 0:b599e748252c 6 * Licensed under the Apache License, Version 2.0 (the "License");
hudakz 0:b599e748252c 7 * you may not use this file except in compliance with the License.
hudakz 0:b599e748252c 8 * You may obtain a copy of the License at
hudakz 0:b599e748252c 9 *
hudakz 0:b599e748252c 10 * http://www.apache.org/licenses/LICENSE-2.0
hudakz 0:b599e748252c 11 *
hudakz 0:b599e748252c 12 * Unless required by applicable law or agreed to in writing, software
hudakz 0:b599e748252c 13 * distributed under the License is distributed on an "AS IS" BASIS,
hudakz 0:b599e748252c 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
hudakz 0:b599e748252c 15 * See the License for the specific language governing permissions and
hudakz 0:b599e748252c 16 * limitations under the License.
hudakz 0:b599e748252c 17 */
hudakz 2:19d290369c66 18 #include "mbed_interface.h"
hudakz 2:19d290369c66 19 #include "mbed_wait_api.h"
hudakz 2:19d290369c66 20 #include "mbed_assert.h"
hudakz 2:19d290369c66 21 #include "netsocket/nsapi_types.h"
hudakz 2:19d290369c66 22 #include "mbed_shared_queues.h"
hudakz 2:19d290369c66 23 #include "enc28j60_emac.h"
hudakz 0:b599e748252c 24
hudakz 0:b599e748252c 25 /**
hudakz 0:b599e748252c 26 * @brief
hudakz 0:b599e748252c 27 * @note
hudakz 0:b599e748252c 28 * @param
hudakz 0:b599e748252c 29 * @retval
hudakz 0:b599e748252c 30 */
hudakz 2:19d290369c66 31 ENC28J60_EMAC::ENC28J60_EMAC() :
hudakz 2:19d290369c66 32 _enc28j60(new ENC28J60(ENC28J60_MOSI, ENC28J60_MISO, ENC28J60_SCK, ENC28J60_CS)),
hudakz 2:19d290369c66 33 _prev_link_status_up(PHY_STATE_LINK_DOWN),
hudakz 2:19d290369c66 34 _link_status_task_handle(0),
hudakz 2:19d290369c66 35 _receive_task_handle(0),
hudakz 2:19d290369c66 36 _memory_manager(NULL)
hudakz 2:19d290369c66 37 { }
hudakz 0:b599e748252c 38
hudakz 0:b599e748252c 39 /**
hudakz 0:b599e748252c 40 * @brief
hudakz 2:19d290369c66 41 * @note Allocates buffer chain from a pool and filles it with incoming packet.
hudakz 2:19d290369c66 42 * @param
hudakz 2:19d290369c66 43 * @retval Data from incoming packet
hudakz 2:19d290369c66 44 */
hudakz 2:19d290369c66 45 emac_mem_buf_t* ENC28J60_EMAC::low_level_input()
hudakz 2:19d290369c66 46 {
hudakz 2:19d290369c66 47 emac_mem_buf_t* chain;
hudakz 2:19d290369c66 48 emac_mem_buf_t* buf;
hudakz 2:19d290369c66 49 packet_t packet;
hudakz 2:19d290369c66 50
hudakz 2:19d290369c66 51 if (_enc28j60->getPacketInfo(&packet) != ENC28J60_ERROR_OK) {
hudakz 2:19d290369c66 52 return NULL;
hudakz 2:19d290369c66 53 }
hudakz 2:19d290369c66 54
hudakz 2:19d290369c66 55 if (packet.payload.len == 0) {
hudakz 2:19d290369c66 56 return NULL;
hudakz 2:19d290369c66 57 }
hudakz 2:19d290369c66 58
hudakz 2:19d290369c66 59 // Allocate a buffer chain from the memory pool.
hudakz 2:19d290369c66 60 chain = _memory_manager->alloc_pool(packet.payload.len, ENC28J60_BUFF_ALIGNMENT);
hudakz 2:19d290369c66 61 buf = chain;
hudakz 2:19d290369c66 62
hudakz 2:19d290369c66 63 // Iterate through the buffer chain and fill it with packet payload.
hudakz 2:19d290369c66 64 while (buf != NULL) {
hudakz 2:19d290369c66 65 packet.payload.buf = (uint8_t*)_memory_manager->get_ptr(buf);
hudakz 2:19d290369c66 66 packet.payload.len = (uint16_t) (_memory_manager->get_len(buf));
hudakz 2:19d290369c66 67
hudakz 2:19d290369c66 68 // Fill the ethernet stack buffer with packet payload received by ENC28J60.
hudakz 2:19d290369c66 69 _enc28j60->readPacket(&packet);
hudakz 2:19d290369c66 70
hudakz 2:19d290369c66 71 buf = _memory_manager->get_next(buf);
hudakz 2:19d290369c66 72 }
hudakz 2:19d290369c66 73
hudakz 2:19d290369c66 74 // Return the buffer chain filled with packet payload.
hudakz 2:19d290369c66 75 return chain;
hudakz 2:19d290369c66 76 }
hudakz 2:19d290369c66 77
hudakz 2:19d290369c66 78 /**
hudakz 2:19d290369c66 79 * @brief Receive task.
hudakz 2:19d290369c66 80 * @note Passes packet payload received by ENC28J60 to the ethernet stack
hudakz 0:b599e748252c 81 * @param
hudakz 0:b599e748252c 82 * @retval
hudakz 0:b599e748252c 83 */
hudakz 2:19d290369c66 84 void ENC28J60_EMAC::receive_task()
hudakz 2:19d290369c66 85 {
hudakz 2:19d290369c66 86 emac_mem_buf_t* payload;
hudakz 2:19d290369c66 87
hudakz 2:19d290369c66 88 _ethLockMutex.lock();
hudakz 2:19d290369c66 89 payload = low_level_input();
hudakz 2:19d290369c66 90 if (payload != NULL) {
hudakz 2:19d290369c66 91 if (_emac_link_input_cb) {
hudakz 2:19d290369c66 92 _emac_link_input_cb(payload); // pass packet payload to the ethernet stack
hudakz 2:19d290369c66 93 _memory_manager->free(payload);
hudakz 2:19d290369c66 94 }
hudakz 2:19d290369c66 95 }
hudakz 2:19d290369c66 96
hudakz 2:19d290369c66 97 _enc28j60->freeRxBuffer(); // make room in ENC28J60 receive buffer for new packets
hudakz 2:19d290369c66 98 _ethLockMutex.unlock();
hudakz 2:19d290369c66 99 }
hudakz 2:19d290369c66 100
hudakz 2:19d290369c66 101
hudakz 2:19d290369c66 102 /**
hudakz 2:19d290369c66 103 * @brief
hudakz 2:19d290369c66 104 * @note Passes a packet payload from the ethernet stack to ENC28J60 for transmittion
hudakz 2:19d290369c66 105 * @param
hudakz 2:19d290369c66 106 * @retval
hudakz 2:19d290369c66 107 */
hudakz 2:19d290369c66 108 bool ENC28J60_EMAC::link_out(emac_mem_buf_t* buf)
hudakz 0:b599e748252c 109 {
hudakz 2:19d290369c66 110 emac_mem_buf_t* chain = buf;
hudakz 2:19d290369c66 111 packet_t packet;
hudakz 2:19d290369c66 112 enc28j60_error_t error;
hudakz 2:19d290369c66 113
hudakz 2:19d290369c66 114 if (buf == NULL) {
hudakz 2:19d290369c66 115 return false;
hudakz 2:19d290369c66 116 }
hudakz 2:19d290369c66 117
hudakz 2:19d290369c66 118 _ethLockMutex.lock();
hudakz 2:19d290369c66 119 // Iterate through the buffer chain and fill the packet with payload.
hudakz 2:19d290369c66 120 while (buf != NULL) {
hudakz 2:19d290369c66 121 packet.payload.buf = (uint8_t *) (_memory_manager->get_ptr(buf));
hudakz 2:19d290369c66 122 packet.payload.len = _memory_manager->get_len(buf);
hudakz 2:19d290369c66 123 error = _enc28j60->loadPacketInTxBuffer(&packet);
hudakz 2:19d290369c66 124 if (error != ENC28J60_ERROR_OK) {
hudakz 2:19d290369c66 125 _memory_manager->free(chain);
hudakz 2:19d290369c66 126 _ethLockMutex.unlock();
hudakz 2:19d290369c66 127 return false;
hudakz 2:19d290369c66 128 }
hudakz 2:19d290369c66 129
hudakz 2:19d290369c66 130 error = _enc28j60->transmitPacket(&packet);
hudakz 2:19d290369c66 131 if (error != ENC28J60_ERROR_OK) {
hudakz 2:19d290369c66 132 _memory_manager->free(chain);
hudakz 2:19d290369c66 133 _ethLockMutex.unlock();
hudakz 2:19d290369c66 134 return false;
hudakz 2:19d290369c66 135 }
hudakz 2:19d290369c66 136
hudakz 2:19d290369c66 137 buf = _memory_manager->get_next(buf);
hudakz 2:19d290369c66 138 }
hudakz 2:19d290369c66 139
hudakz 2:19d290369c66 140 _memory_manager->free(chain);
hudakz 2:19d290369c66 141 _ethLockMutex.unlock();
hudakz 2:19d290369c66 142
hudakz 2:19d290369c66 143 return true;
hudakz 0:b599e748252c 144 }
hudakz 0:b599e748252c 145
hudakz 0:b599e748252c 146 /**
hudakz 0:b599e748252c 147 * @brief
hudakz 0:b599e748252c 148 * @note
hudakz 0:b599e748252c 149 * @param
hudakz 0:b599e748252c 150 * @retval
hudakz 0:b599e748252c 151 */
hudakz 2:19d290369c66 152 void ENC28J60_EMAC::link_status_task()
hudakz 0:b599e748252c 153 {
hudakz 2:19d290369c66 154 uint16_t phy_basic_status_reg_value = 0;
hudakz 2:19d290369c66 155 bool current_link_status_up = false;
hudakz 0:b599e748252c 156
hudakz 2:19d290369c66 157 /* Get current status */
hudakz 0:b599e748252c 158
hudakz 2:19d290369c66 159 _ethLockMutex.lock();
hudakz 2:19d290369c66 160 _enc28j60->phyRead(PHSTAT2, &phy_basic_status_reg_value);
hudakz 0:b599e748252c 161
hudakz 2:19d290369c66 162 current_link_status_up = (bool) ((phy_basic_status_reg_value & PHSTAT2_LSTAT) != 0);
hudakz 0:b599e748252c 163
hudakz 2:19d290369c66 164 /* Compare with previous state */
hudakz 2:19d290369c66 165 if (current_link_status_up != _prev_link_status_up) {
hudakz 2:19d290369c66 166 if (_emac_link_state_cb) {
hudakz 2:19d290369c66 167 _emac_link_state_cb(current_link_status_up);
hudakz 2:19d290369c66 168 }
hudakz 0:b599e748252c 169
hudakz 2:19d290369c66 170 _prev_link_status_up = current_link_status_up;
hudakz 2:19d290369c66 171 }
hudakz 0:b599e748252c 172
hudakz 2:19d290369c66 173 _ethLockMutex.unlock();
hudakz 0:b599e748252c 174 }
hudakz 0:b599e748252c 175
hudakz 0:b599e748252c 176 /**
hudakz 0:b599e748252c 177 * @brief
hudakz 0:b599e748252c 178 * @note
hudakz 0:b599e748252c 179 * @param
hudakz 0:b599e748252c 180 * @retval
hudakz 0:b599e748252c 181 */
hudakz 2:19d290369c66 182 bool ENC28J60_EMAC::power_up()
hudakz 0:b599e748252c 183 {
hudakz 2:19d290369c66 184 volatile uint32_t timeout = 500;
hudakz 2:19d290369c66 185 _enc28j60->writeOp(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);
hudakz 2:19d290369c66 186 while (_enc28j60->readReg(ESTAT_CLKRDY) == 0) {
hudakz 2:19d290369c66 187 ThisThread::sleep_for(1ms);
hudakz 2:19d290369c66 188 timeout--;
hudakz 2:19d290369c66 189 if (timeout == 0) {
hudakz 2:19d290369c66 190 return false;
hudakz 2:19d290369c66 191 }
hudakz 0:b599e748252c 192 }
hudakz 0:b599e748252c 193
hudakz 2:19d290369c66 194 /* Trigger thread to deal with any RX packets that arrived
hudakz 2:19d290369c66 195 * before receiver_thread was started */
hudakz 2:19d290369c66 196 _receive_task_handle = mbed::mbed_event_queue()->call_every
hudakz 2:19d290369c66 197 (
hudakz 2:19d290369c66 198 RECEIVE_TASK_PERIOD_MS,
hudakz 2:19d290369c66 199 mbed::callback(this, &ENC28J60_EMAC::receive_task)
hudakz 2:19d290369c66 200 );
hudakz 0:b599e748252c 201
hudakz 2:19d290369c66 202 _prev_link_status_up = PHY_STATE_LINK_DOWN;
hudakz 2:19d290369c66 203 mbed::mbed_event_queue()->call(mbed::callback(this, &ENC28J60_EMAC::link_status_task));
hudakz 0:b599e748252c 204
hudakz 2:19d290369c66 205 /* Allow the Link Status task to detect the initial link state */
hudakz 2:19d290369c66 206 ThisThread::sleep_for(10ms);
hudakz 2:19d290369c66 207 _link_status_task_handle = mbed::mbed_event_queue()->call_every
hudakz 2:19d290369c66 208 (
hudakz 2:19d290369c66 209 LINK_STATUS_TASK_PERIOD_MS,
hudakz 2:19d290369c66 210 mbed::callback(this, &ENC28J60_EMAC::link_status_task)
hudakz 2:19d290369c66 211 );
hudakz 0:b599e748252c 212
hudakz 2:19d290369c66 213 return true;
hudakz 0:b599e748252c 214 }
hudakz 0:b599e748252c 215
hudakz 0:b599e748252c 216 /**
hudakz 0:b599e748252c 217 * @brief
hudakz 0:b599e748252c 218 * @note
hudakz 0:b599e748252c 219 * @param
hudakz 0:b599e748252c 220 * @retval
hudakz 0:b599e748252c 221 */
hudakz 2:19d290369c66 222 uint32_t ENC28J60_EMAC::get_mtu_size() const
hudakz 0:b599e748252c 223 {
hudakz 2:19d290369c66 224 return ENC28J60_ETH_MTU_SIZE;
hudakz 0:b599e748252c 225 }
hudakz 0:b599e748252c 226
hudakz 0:b599e748252c 227 /**
hudakz 2:19d290369c66 228 * @brief
hudakz 2:19d290369c66 229 * @note
hudakz 0:b599e748252c 230 * @param
hudakz 0:b599e748252c 231 * @retval
hudakz 0:b599e748252c 232 */
hudakz 2:19d290369c66 233 uint32_t ENC28J60_EMAC::get_align_preference() const
hudakz 0:b599e748252c 234 {
hudakz 2:19d290369c66 235 return ENC28J60_BUFF_ALIGNMENT;
hudakz 0:b599e748252c 236 }
hudakz 0:b599e748252c 237
hudakz 0:b599e748252c 238 /**
hudakz 0:b599e748252c 239 * @brief
hudakz 0:b599e748252c 240 * @note
hudakz 0:b599e748252c 241 * @param
hudakz 0:b599e748252c 242 * @retval
hudakz 0:b599e748252c 243 */
hudakz 2:19d290369c66 244 void ENC28J60_EMAC::get_ifname(char* name, uint8_t size) const
hudakz 0:b599e748252c 245 {
hudakz 2:19d290369c66 246 memcpy(name, ENC28J60_ETH_IF_NAME, (size < sizeof(ENC28J60_ETH_IF_NAME)) ? size : sizeof(ENC28J60_ETH_IF_NAME));
hudakz 0:b599e748252c 247 }
hudakz 0:b599e748252c 248
hudakz 0:b599e748252c 249 /**
hudakz 0:b599e748252c 250 * @brief
hudakz 0:b599e748252c 251 * @note
hudakz 0:b599e748252c 252 * @param
hudakz 0:b599e748252c 253 * @retval
hudakz 0:b599e748252c 254 */
hudakz 2:19d290369c66 255 uint8_t ENC28J60_EMAC::get_hwaddr_size() const
hudakz 0:b599e748252c 256 {
hudakz 2:19d290369c66 257 return ENC28J60_HWADDR_SIZE;
hudakz 0:b599e748252c 258 }
hudakz 0:b599e748252c 259
hudakz 0:b599e748252c 260 /**
hudakz 0:b599e748252c 261 * @brief
hudakz 0:b599e748252c 262 * @note
hudakz 0:b599e748252c 263 * @param
hudakz 0:b599e748252c 264 * @retval
hudakz 0:b599e748252c 265 */
hudakz 2:19d290369c66 266 bool ENC28J60_EMAC::get_hwaddr(uint8_t* addr) const
hudakz 0:b599e748252c 267 {
hudakz 2:19d290369c66 268 enc28j60_error_t error = _enc28j60->readMacAddr((char*)addr);
hudakz 2:19d290369c66 269 if (error == ENC28J60_ERROR_OK) {
hudakz 2:19d290369c66 270 return true;
hudakz 2:19d290369c66 271 }
hudakz 2:19d290369c66 272 else {
hudakz 2:19d290369c66 273 return false;
hudakz 0:b599e748252c 274 }
hudakz 0:b599e748252c 275 }
hudakz 0:b599e748252c 276
hudakz 0:b599e748252c 277 /**
hudakz 0:b599e748252c 278 * @brief
hudakz 0:b599e748252c 279 * @note
hudakz 0:b599e748252c 280 * @param
hudakz 0:b599e748252c 281 * @retval
hudakz 0:b599e748252c 282 */
hudakz 2:19d290369c66 283 void ENC28J60_EMAC::set_hwaddr(const uint8_t* addr)
hudakz 0:b599e748252c 284 {
hudakz 2:19d290369c66 285 if (!addr) {
hudakz 2:19d290369c66 286 return;
hudakz 0:b599e748252c 287 }
hudakz 0:b599e748252c 288
hudakz 2:19d290369c66 289 memcpy(_hwaddr, addr, sizeof _hwaddr);
hudakz 2:19d290369c66 290 _ethLockMutex.lock();
hudakz 0:b599e748252c 291
hudakz 2:19d290369c66 292 enc28j60_error_t error = _enc28j60->writeMacAddr((char*)addr);
hudakz 2:19d290369c66 293 _ethLockMutex.unlock();
hudakz 2:19d290369c66 294 if (error) {
hudakz 2:19d290369c66 295 return;
hudakz 0:b599e748252c 296 }
hudakz 0:b599e748252c 297 }
hudakz 0:b599e748252c 298
hudakz 0:b599e748252c 299 /**
hudakz 0:b599e748252c 300 * @brief
hudakz 0:b599e748252c 301 * @note
hudakz 0:b599e748252c 302 * @param
hudakz 0:b599e748252c 303 * @retval
hudakz 0:b599e748252c 304 */
hudakz 2:19d290369c66 305 void ENC28J60_EMAC::set_link_input_cb(emac_link_input_cb_t input_cb)
hudakz 0:b599e748252c 306 {
hudakz 2:19d290369c66 307 _emac_link_input_cb = input_cb;
hudakz 2:19d290369c66 308 }
hudakz 0:b599e748252c 309
hudakz 2:19d290369c66 310 /**
hudakz 2:19d290369c66 311 * @brief
hudakz 2:19d290369c66 312 * @note
hudakz 2:19d290369c66 313 * @param
hudakz 2:19d290369c66 314 * @retval
hudakz 2:19d290369c66 315 */
hudakz 2:19d290369c66 316 void ENC28J60_EMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb)
hudakz 2:19d290369c66 317 {
hudakz 2:19d290369c66 318 _emac_link_state_cb = state_cb;
hudakz 2:19d290369c66 319 }
hudakz 0:b599e748252c 320
hudakz 2:19d290369c66 321 /**
hudakz 2:19d290369c66 322 * @brief
hudakz 2:19d290369c66 323 * @note
hudakz 2:19d290369c66 324 * @param
hudakz 2:19d290369c66 325 * @retval
hudakz 2:19d290369c66 326 */
hudakz 2:19d290369c66 327 void ENC28J60_EMAC::add_multicast_group(const uint8_t* addr)
hudakz 2:19d290369c66 328 {
hudakz 2:19d290369c66 329 // No action for now
hudakz 2:19d290369c66 330 }
hudakz 0:b599e748252c 331
hudakz 2:19d290369c66 332 /**
hudakz 2:19d290369c66 333 * @brief
hudakz 2:19d290369c66 334 * @note
hudakz 2:19d290369c66 335 * @param
hudakz 2:19d290369c66 336 * @retval
hudakz 2:19d290369c66 337 */
hudakz 2:19d290369c66 338 void ENC28J60_EMAC::remove_multicast_group(const uint8_t* addr)
hudakz 2:19d290369c66 339 {
hudakz 2:19d290369c66 340 // No action for now
hudakz 0:b599e748252c 341 }
hudakz 0:b599e748252c 342
hudakz 0:b599e748252c 343 /**
hudakz 0:b599e748252c 344 * @brief
hudakz 0:b599e748252c 345 * @note
hudakz 0:b599e748252c 346 * @param
hudakz 0:b599e748252c 347 * @retval
hudakz 0:b599e748252c 348 */
hudakz 2:19d290369c66 349 void ENC28J60_EMAC::set_all_multicast(bool all)
hudakz 0:b599e748252c 350 {
hudakz 2:19d290369c66 351 // No action for now
hudakz 0:b599e748252c 352 }
hudakz 0:b599e748252c 353
hudakz 0:b599e748252c 354 /**
hudakz 0:b599e748252c 355 * @brief
hudakz 0:b599e748252c 356 * @note
hudakz 0:b599e748252c 357 * @param
hudakz 0:b599e748252c 358 * @retval
hudakz 0:b599e748252c 359 */
hudakz 2:19d290369c66 360 void ENC28J60_EMAC::power_down()
hudakz 0:b599e748252c 361 {
hudakz 2:19d290369c66 362 _enc28j60->disableMacRecv();
hudakz 2:19d290369c66 363 if (_enc28j60->readReg(ESTAT_RXBUSY) != 0) {
hudakz 2:19d290369c66 364 _enc28j60->enableMacRecv();
hudakz 2:19d290369c66 365 return;
hudakz 2:19d290369c66 366 }
hudakz 0:b599e748252c 367
hudakz 2:19d290369c66 368 if (_enc28j60->readReg(ECON1_TXRTS) != 0) {
hudakz 2:19d290369c66 369 _enc28j60->enableMacRecv();
hudakz 2:19d290369c66 370 return;
hudakz 0:b599e748252c 371 }
hudakz 0:b599e748252c 372
hudakz 2:19d290369c66 373 _enc28j60->writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_VRPS);
hudakz 2:19d290369c66 374 _enc28j60->writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV);
hudakz 2:19d290369c66 375 }
hudakz 2:19d290369c66 376
hudakz 2:19d290369c66 377 /**
hudakz 2:19d290369c66 378 * @brief
hudakz 2:19d290369c66 379 * @note
hudakz 2:19d290369c66 380 * @param
hudakz 2:19d290369c66 381 * @retval
hudakz 2:19d290369c66 382 */
hudakz 2:19d290369c66 383 void ENC28J60_EMAC::set_memory_manager(EMACMemoryManager& mem_mngr)
hudakz 2:19d290369c66 384 {
hudakz 2:19d290369c66 385 _memory_manager = &mem_mngr;
hudakz 0:b599e748252c 386 }
hudakz 2:19d290369c66 387
hudakz 2:19d290369c66 388 /**
hudakz 2:19d290369c66 389 * @brief
hudakz 2:19d290369c66 390 * @note
hudakz 2:19d290369c66 391 * @param
hudakz 2:19d290369c66 392 * @retval
hudakz 2:19d290369c66 393 */
hudakz 2:19d290369c66 394 ENC28J60_EMAC& ENC28J60_EMAC::get_instance()
hudakz 2:19d290369c66 395 {
hudakz 2:19d290369c66 396 static ENC28J60_EMAC emac;
hudakz 2:19d290369c66 397 return emac;
hudakz 2:19d290369c66 398 }
hudakz 2:19d290369c66 399
hudakz 2:19d290369c66 400 EMAC& EMAC::get_default_instance()
hudakz 2:19d290369c66 401 {
hudakz 2:19d290369c66 402 return ENC28J60_EMAC::get_instance();
hudakz 2:19d290369c66 403 }