Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51_Vdd TextLCD BME280
NanostackEMACInterface.cpp
00001 /* 00002 * Copyright (c) 2017 ARM Limited. All rights reserved. 00003 */ 00004 00005 #include "NanostackEthernetInterface.h" 00006 #include "NanostackEthernetPhy.h" 00007 #include "nsdynmemLIB.h" 00008 #include "arm_hal_phy.h" 00009 #include "EMAC.h" 00010 00011 class EMACPhy : public NanostackEthernetPhy 00012 { 00013 public: 00014 EMACPhy(NanostackMemoryManager &mem, EMAC &m); 00015 virtual int8_t phy_register(); 00016 virtual void get_mac_address(uint8_t *mac); 00017 virtual void set_mac_address(uint8_t *mac); 00018 00019 int8_t address_write(phy_address_type_e , uint8_t *); 00020 int8_t tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle,data_protocol_e data_flow); 00021 00022 void emac_phy_rx(emac_mem_buf_t *mem); 00023 00024 private: 00025 NanostackMemoryManager &memory_manager; 00026 EMAC &emac; 00027 uint8_t mac_addr[6]; 00028 int8_t device_id; 00029 phy_device_driver_s phy; 00030 }; 00031 00032 // GAH! no handles on the callback. Force a single interface 00033 static EMACPhy *single_phy; 00034 00035 extern "C" 00036 { 00037 static int8_t emac_phy_address_write(phy_address_type_e address_type, uint8_t *address_ptr) 00038 { 00039 return single_phy->address_write(address_type, address_ptr); 00040 } 00041 00042 static int8_t emac_phy_interface_state_control(phy_interface_state_e, uint8_t) 00043 { 00044 return -1; 00045 } 00046 00047 static int8_t emac_phy_tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle,data_protocol_e data_flow) 00048 { 00049 return single_phy->tx(data_ptr, data_len, tx_handle, data_flow); 00050 } 00051 00052 EMACPhy::EMACPhy(NanostackMemoryManager &mem, EMAC &m) : memory_manager(mem), emac(m), device_id(-1) 00053 { 00054 /* Same default address logic as lwIP glue uses */ 00055 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) 00056 mac_addr[0] = MBED_MAC_ADDR_0; 00057 mac_addr[1] = MBED_MAC_ADDR_1; 00058 mac_addr[2] = MBED_MAC_ADDR_2; 00059 mac_addr[3] = MBED_MAC_ADDR_3; 00060 mac_addr[4] = MBED_MAC_ADDR_4; 00061 mac_addr[5] = MBED_MAC_ADDR_5; 00062 #else 00063 mbed_mac_address((char *) mac_addr); 00064 #endif 00065 /* We have a default MAC address, so do don't force them to supply one */ 00066 /* They may or may not update hwaddr with their address */ 00067 emac.get_hwaddr(mac_addr); 00068 } 00069 00070 00071 void EMACPhy::emac_phy_rx(emac_mem_buf_t *mem) 00072 { 00073 const uint8_t *ptr = NULL; 00074 uint8_t *tmpbuf = NULL; 00075 uint32_t total_len; 00076 00077 if (memory_manager.get_next(mem) == NULL) { 00078 // Easy contiguous case 00079 ptr = static_cast<const uint8_t*>(memory_manager.get_ptr(mem)); 00080 total_len = memory_manager.get_len(mem); 00081 } else { 00082 // Nanostack can't accept chunked data - make temporary contiguous copy 00083 total_len = memory_manager.get_total_len(mem); 00084 ptr = tmpbuf = static_cast<uint8_t *>(ns_dyn_mem_temporary_alloc(total_len)); 00085 if (tmpbuf) { 00086 memory_manager.copy_from_buf(tmpbuf, total_len, mem); 00087 } 00088 } 00089 00090 if (ptr && phy.phy_rx_cb) { 00091 phy.phy_rx_cb(ptr, total_len, 0xff, 0, device_id); 00092 } 00093 ns_dyn_mem_free(tmpbuf); 00094 memory_manager.free(mem); 00095 } 00096 00097 } // extern "C" 00098 00099 int8_t EMACPhy::address_write(phy_address_type_e address_type, uint8_t *address_ptr) 00100 { 00101 if (address_type != PHY_MAC_48BIT) { 00102 return -1; 00103 } 00104 memcpy(mac_addr, address_ptr, 6); 00105 emac.set_hwaddr(address_ptr); 00106 return 0; 00107 } 00108 00109 int8_t EMACPhy::tx(uint8_t *data_ptr, uint16_t data_len, uint8_t tx_handle,data_protocol_e data_flow) 00110 { 00111 emac_mem_buf_t *mem = memory_manager.alloc_pool(data_len, 0); 00112 if (!mem) { 00113 return -1; 00114 } 00115 memory_manager.copy_to_buf(mem, data_ptr, data_len); 00116 00117 // They take ownership - their responsibility to free 00118 emac.link_out(mem); 00119 00120 return 0; 00121 } 00122 00123 int8_t EMACPhy::phy_register() 00124 { 00125 if (device_id < 0) { 00126 00127 phy.PHY_MAC = mac_addr; 00128 phy.address_write = emac_phy_address_write; 00129 phy.driver_description = const_cast<char*>("ETH"); 00130 phy.link_type = PHY_LINK_ETHERNET_TYPE; 00131 phy.phy_MTU = 0; 00132 phy.phy_header_length = 0; 00133 phy.phy_tail_length = 0; 00134 phy.state_control = emac_phy_interface_state_control; 00135 phy.tx = emac_phy_tx; 00136 phy.phy_rx_cb = NULL; 00137 phy.phy_tx_done_cb = NULL; 00138 00139 emac.set_memory_manager(memory_manager); 00140 emac.set_link_input_cb(mbed::callback(this, &EMACPhy::emac_phy_rx)); 00141 00142 if (!emac.power_up()) { 00143 return -1; 00144 } 00145 00146 phy.phy_MTU = emac.get_mtu_size(); 00147 /* Set the address - this could be either board default, what they 00148 * told us with EMAC::get_mac_address, or something manually specified 00149 * with EMACPhy::set_mac_address 00150 */ 00151 emac.set_hwaddr(mac_addr); 00152 00153 emac.set_all_multicast(true); 00154 00155 device_id = arm_net_phy_register(&phy); 00156 // driver_readiness_status_callback = driver_status_cb; 00157 00158 if (device_id < 0){ 00159 //tr_error("Ethernet Driver failed to register with Stack. RetCode=%i", eth_driver_enabled); 00160 //driver_readiness_status_callback(0, eth_interface_id); 00161 emac.power_down(); 00162 return -1; 00163 } 00164 } 00165 00166 return device_id; 00167 } 00168 00169 void EMACPhy::get_mac_address(uint8_t *mac) 00170 { 00171 memcpy(mac, mac_addr, sizeof mac_addr); 00172 } 00173 00174 void EMACPhy::set_mac_address(uint8_t *mac) 00175 { 00176 memcpy(mac_addr, mac, sizeof mac_addr); 00177 } 00178 00179 nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr) 00180 { 00181 if (single_phy) { 00182 return NSAPI_ERROR_DEVICE_ERROR ; 00183 } 00184 00185 single_phy = new (std::nothrow) EMACPhy(this->memory_manager, emac); 00186 if (!single_phy) { 00187 return NSAPI_ERROR_NO_MEMORY ; 00188 } 00189 00190 if (mac_addr) { 00191 single_phy->set_mac_address(const_cast<uint8_t*>(mac_addr)); 00192 } 00193 00194 Nanostack::EthernetInterface *interface; 00195 00196 interface = new (std::nothrow) Nanostack::EthernetInterface(*single_phy); 00197 if (!interface) { 00198 return NSAPI_ERROR_NO_MEMORY ; 00199 } 00200 00201 nsapi_error_t err = interface->initialize(); 00202 if (err) { 00203 delete interface; 00204 return err; 00205 } 00206 00207 *interface_out = interface; 00208 00209 return NSAPI_ERROR_OK ; 00210 00211 } 00212 00213 nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) 00214 { 00215 Nanostack::EthernetInterface *interface; 00216 nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface); 00217 *interface_out = interface; 00218 return err; 00219 }
Generated on Tue Jul 12 2022 15:15:53 by
