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:
Fri Mar 26 15:58:28 2021 +0000
Revision:
0:b599e748252c
Child:
1:bce04bfc41fe
Mbed OS Ethernet MAC (EMAC) driver for the ENC28J60 Ethernet controller.

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 0:b599e748252c 18 #ifndef ENC28J60_EMAC_H_
hudakz 0:b599e748252c 19 #define ENC28J60_EMAC_H_
hudakz 0:b599e748252c 20
hudakz 0:b599e748252c 21 #include <ctype.h>
hudakz 0:b599e748252c 22 #include <stdio.h>
hudakz 0:b599e748252c 23 #include <string.h>
hudakz 0:b599e748252c 24 #include <stdlib.h>
hudakz 0:b599e748252c 25 #include <stdint.h>
hudakz 0:b599e748252c 26 #include "mbed.h"
hudakz 0:b599e748252c 27 #include "EMAC.h"
hudakz 0:b599e748252c 28 #include "rtos.h"
hudakz 0:b599e748252c 29
hudakz 0:b599e748252c 30 #include "enc28j60_reg.h"
hudakz 0:b599e748252c 31 #include "enc28j60.h"
hudakz 0:b599e748252c 32 #include "enc28j60_emac_config.h"
hudakz 0:b599e748252c 33
hudakz 0:b599e748252c 34 class W5500_EMAC :
hudakz 0:b599e748252c 35 public EMAC
hudakz 0:b599e748252c 36 {
hudakz 0:b599e748252c 37 public:
hudakz 0:b599e748252c 38 W5500_EMAC();
hudakz 0:b599e748252c 39
hudakz 0:b599e748252c 40 /** Return the ENC28J60 EMAC
hudakz 0:b599e748252c 41 *
hudakz 0:b599e748252c 42 * Returns the default on-board EMAC - this will be target-specific, and
hudakz 0:b599e748252c 43 * may not be available on all targets.
hudakz 0:b599e748252c 44 */
hudakz 0:b599e748252c 45 static W5500_EMAC& get_instance(void);
hudakz 0:b599e748252c 46
hudakz 0:b599e748252c 47 /**
hudakz 0:b599e748252c 48 * Return maximum transmission unit
hudakz 0:b599e748252c 49 *
hudakz 0:b599e748252c 50 * @return MTU in bytes
hudakz 0:b599e748252c 51 */
hudakz 0:b599e748252c 52 virtual uint32_t get_mtu_size(void) const;
hudakz 0:b599e748252c 53
hudakz 0:b599e748252c 54 /**
hudakz 0:b599e748252c 55 * Gets memory buffer alignment preference
hudakz 0:b599e748252c 56 *
hudakz 0:b599e748252c 57 * Gets preferred memory buffer alignment of the Emac device. IP stack may
hudakz 0:b599e748252c 58 * or may not align link out memory buffer chains using the alignment.
hudakz 0:b599e748252c 59 *
hudakz 0:b599e748252c 60 * @return Memory alignment requirement in bytes
hudakz 0:b599e748252c 61 */
hudakz 0:b599e748252c 62 virtual uint32_t get_align_preference(void) const;
hudakz 0:b599e748252c 63
hudakz 0:b599e748252c 64 /**
hudakz 0:b599e748252c 65 * Return interface name
hudakz 0:b599e748252c 66 *
hudakz 0:b599e748252c 67 * @param name Pointer to where the name should be written
hudakz 0:b599e748252c 68 * @param size Maximum number of character to copy
hudakz 0:b599e748252c 69 */
hudakz 0:b599e748252c 70 virtual void get_ifname(char* name, uint8_t size) const;
hudakz 0:b599e748252c 71
hudakz 0:b599e748252c 72 /**
hudakz 0:b599e748252c 73 * Returns size of the underlying interface HW address size.
hudakz 0:b599e748252c 74 *
hudakz 0:b599e748252c 75 * @return HW address size in bytes
hudakz 0:b599e748252c 76 */
hudakz 0:b599e748252c 77 virtual uint8_t get_hwaddr_size(void) const;
hudakz 0:b599e748252c 78
hudakz 0:b599e748252c 79 /**
hudakz 0:b599e748252c 80 * Return interface-supplied HW address
hudakz 0:b599e748252c 81 *
hudakz 0:b599e748252c 82 * Copies HW address to provided memory, @param addr has to be of correct
hudakz 0:b599e748252c 83 * size see @a get_hwaddr_size
hudakz 0:b599e748252c 84 *
hudakz 0:b599e748252c 85 * HW address need not be provided if this interface does not have its own
hudakz 0:b599e748252c 86 * HW address configuration; stack will choose address from central system
hudakz 0:b599e748252c 87 * configuration if the function returns false and does not write to addr.
hudakz 0:b599e748252c 88 *
hudakz 0:b599e748252c 89 * @param addr HW address for underlying interface
hudakz 0:b599e748252c 90 * @return true if HW address is available
hudakz 0:b599e748252c 91 */
hudakz 0:b599e748252c 92 virtual bool get_hwaddr(uint8_t* addr) const;
hudakz 0:b599e748252c 93
hudakz 0:b599e748252c 94 /**
hudakz 0:b599e748252c 95 * Set HW address for interface
hudakz 0:b599e748252c 96 *
hudakz 0:b599e748252c 97 * Provided address has to be of correct size, see @a get_hwaddr_size
hudakz 0:b599e748252c 98 *
hudakz 0:b599e748252c 99 * Called to set the MAC address to actually use - if @a get_hwaddr is
hudakz 0:b599e748252c 100 * provided the stack would normally use that, but it could be overridden,
hudakz 0:b599e748252c 101 * eg for test purposes.
hudakz 0:b599e748252c 102 *
hudakz 0:b599e748252c 103 * @param addr Address to be set
hudakz 0:b599e748252c 104 */
hudakz 0:b599e748252c 105 virtual void set_hwaddr(const uint8_t* addr);
hudakz 0:b599e748252c 106
hudakz 0:b599e748252c 107 /**
hudakz 0:b599e748252c 108 * Sends the packet over the link
hudakz 0:b599e748252c 109 *
hudakz 0:b599e748252c 110 * That can not be called from an interrupt context.
hudakz 0:b599e748252c 111 *
hudakz 0:b599e748252c 112 * @param buf Packet to be send
hudakz 0:b599e748252c 113 * @return True if the packet was send successfully, False otherwise
hudakz 0:b599e748252c 114 */
hudakz 0:b599e748252c 115 virtual bool link_out(emac_mem_buf_t* buf);
hudakz 0:b599e748252c 116
hudakz 0:b599e748252c 117 /**
hudakz 0:b599e748252c 118 * Initializes the HW
hudakz 0:b599e748252c 119 *
hudakz 0:b599e748252c 120 * @return True on success, False in case of an error.
hudakz 0:b599e748252c 121 */
hudakz 0:b599e748252c 122 virtual bool power_up(void);
hudakz 0:b599e748252c 123
hudakz 0:b599e748252c 124 /**
hudakz 0:b599e748252c 125 * Deinitializes the HW
hudakz 0:b599e748252c 126 *
hudakz 0:b599e748252c 127 */
hudakz 0:b599e748252c 128 virtual void power_down(void);
hudakz 0:b599e748252c 129
hudakz 0:b599e748252c 130 /**
hudakz 0:b599e748252c 131 * Sets a callback that needs to be called for packets received for that
hudakz 0:b599e748252c 132 * interface
hudakz 0:b599e748252c 133 *
hudakz 0:b599e748252c 134 * @param input_cb Function to be register as a callback
hudakz 0:b599e748252c 135 */
hudakz 0:b599e748252c 136 virtual void set_link_input_cb(emac_link_input_cb_t input_cb);
hudakz 0:b599e748252c 137
hudakz 0:b599e748252c 138 /**
hudakz 0:b599e748252c 139 * Sets a callback that needs to be called on link status changes for given
hudakz 0:b599e748252c 140 * interface
hudakz 0:b599e748252c 141 *
hudakz 0:b599e748252c 142 * @param state_cb Function to be register as a callback
hudakz 0:b599e748252c 143 */
hudakz 0:b599e748252c 144 virtual void set_link_state_cb(emac_link_state_change_cb_t state_cb);
hudakz 0:b599e748252c 145
hudakz 0:b599e748252c 146 /** Add device to a multicast group
hudakz 0:b599e748252c 147 *
hudakz 0:b599e748252c 148 * @param address A multicast group hardware address
hudakz 0:b599e748252c 149 */
hudakz 0:b599e748252c 150 virtual void add_multicast_group(const uint8_t* address);
hudakz 0:b599e748252c 151
hudakz 0:b599e748252c 152 /** Remove device from a multicast group
hudakz 0:b599e748252c 153 *
hudakz 0:b599e748252c 154 * @param address A multicast group hardware address
hudakz 0:b599e748252c 155 */
hudakz 0:b599e748252c 156 virtual void remove_multicast_group(const uint8_t* address);
hudakz 0:b599e748252c 157
hudakz 0:b599e748252c 158 /** Request reception of all multicast packets
hudakz 0:b599e748252c 159 *
hudakz 0:b599e748252c 160 * @param all True to receive all multicasts
hudakz 0:b599e748252c 161 * False to receive only multicasts addressed to specified groups
hudakz 0:b599e748252c 162 */
hudakz 0:b599e748252c 163 virtual void set_all_multicast(bool all);
hudakz 0:b599e748252c 164
hudakz 0:b599e748252c 165 /** Sets memory manager that is used to handle memory buffers
hudakz 0:b599e748252c 166 *
hudakz 0:b599e748252c 167 * @param mem_mngr Pointer to memory manager
hudakz 0:b599e748252c 168 */
hudakz 0:b599e748252c 169 virtual void set_memory_manager(EMACMemoryManager& mem_mngr);
hudakz 0:b599e748252c 170 private:
hudakz 0:b599e748252c 171 void link_status_task();
hudakz 0:b599e748252c 172 void receive_task();
hudakz 0:b599e748252c 173 bool low_level_init_successful();
hudakz 0:b599e748252c 174 emac_mem_buf_t* low_level_input();
hudakz 0:b599e748252c 175
hudakz 0:b599e748252c 176 ENC28J60* _enc28j60;
hudakz 0:b599e748252c 177 bool _prev_link_status_up;
hudakz 0:b599e748252c 178 int _link_status_task_handle;
hudakz 0:b599e748252c 179 int _receive_task_handle;
hudakz 0:b599e748252c 180 EMACMemoryManager* _memory_manager;
hudakz 0:b599e748252c 181 Mutex _ethLockMutex;
hudakz 0:b599e748252c 182 uint8_t _hwaddr[ENC28J60_HWADDR_SIZE];
hudakz 0:b599e748252c 183
hudakz 0:b599e748252c 184 emac_link_input_cb_t _emac_link_input_cb;
hudakz 0:b599e748252c 185 emac_link_state_change_cb_t _emac_link_state_cb;
hudakz 0:b599e748252c 186 };
hudakz 0:b599e748252c 187 #endif /* ENC28J60_EMAC_H_ */