mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_Realtek/TARGET_AMEBA/rtw_emac.cpp@189:f392fc9709a3, 2019-02-20 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Feb 20 22:31:08 2019 +0000
- Revision:
- 189:f392fc9709a3
- Parent:
- 188:bcfe06ba3d64
mbed library release version 165
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AnnaBridge | 167:e84263d55307 | 1 | /* mbed Microcontroller Library |
AnnaBridge | 167:e84263d55307 | 2 | * Copyright (c) 2016 Realtek Semiconductor Corp. |
AnnaBridge | 167:e84263d55307 | 3 | * |
AnnaBridge | 167:e84263d55307 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
AnnaBridge | 167:e84263d55307 | 5 | * you may not use this file except in compliance with the License. |
AnnaBridge | 167:e84263d55307 | 6 | * You may obtain a copy of the License at |
AnnaBridge | 167:e84263d55307 | 7 | * |
AnnaBridge | 167:e84263d55307 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
AnnaBridge | 167:e84263d55307 | 9 | * |
AnnaBridge | 167:e84263d55307 | 10 | * Unless required by applicable law or agreed to in writing, software |
AnnaBridge | 167:e84263d55307 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
AnnaBridge | 167:e84263d55307 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AnnaBridge | 167:e84263d55307 | 13 | * See the License for the specific language governing permissions and |
AnnaBridge | 167:e84263d55307 | 14 | * limitations under the License. |
AnnaBridge | 167:e84263d55307 | 15 | */ |
AnnaBridge | 167:e84263d55307 | 16 | |
AnnaBridge | 187:0387e8f68319 | 17 | #if defined(CONFIG_MBED_ENABLED) |
AnnaBridge | 167:e84263d55307 | 18 | |
AnnaBridge | 167:e84263d55307 | 19 | #include <stdio.h> |
AnnaBridge | 167:e84263d55307 | 20 | #include "mbed_assert.h" |
AnnaBridge | 167:e84263d55307 | 21 | #include "mbed_events.h" |
AnnaBridge | 189:f392fc9709a3 | 22 | #include "mbed_wait_api.h" |
AnnaBridge | 167:e84263d55307 | 23 | |
Anna Bridge |
186:707f6e361f3e | 24 | #include "rtw_emac.h" |
Anna Bridge |
186:707f6e361f3e | 25 | #include "EMACMemoryManager.h" |
Anna Bridge |
186:707f6e361f3e | 26 | |
AnnaBridge | 167:e84263d55307 | 27 | #include "rtos.h" |
AnnaBridge | 167:e84263d55307 | 28 | #include "lwip/pbuf.h" |
AnnaBridge | 167:e84263d55307 | 29 | #include "netif/etharp.h" |
AnnaBridge | 167:e84263d55307 | 30 | |
AnnaBridge | 167:e84263d55307 | 31 | #include "lwip_intf.h" |
AnnaBridge | 167:e84263d55307 | 32 | #include "wifi_constants.h" |
AnnaBridge | 167:e84263d55307 | 33 | #include "wifi_conf.h" |
AnnaBridge | 167:e84263d55307 | 34 | |
AnnaBridge | 167:e84263d55307 | 35 | #define RTW_EMAC_MTU_SIZE (1500U) |
AnnaBridge | 167:e84263d55307 | 36 | |
AnnaBridge | 189:f392fc9709a3 | 37 | RTW_EMAC::RTW_EMAC() |
Anna Bridge |
186:707f6e361f3e | 38 | { |
Anna Bridge |
186:707f6e361f3e | 39 | set_callback_func((emac_callback)(&RTW_EMAC::wlan_emac_recv), this); |
Anna Bridge |
186:707f6e361f3e | 40 | } |
AnnaBridge | 167:e84263d55307 | 41 | |
Anna Bridge |
186:707f6e361f3e | 42 | uint32_t RTW_EMAC::get_mtu_size() const |
AnnaBridge | 167:e84263d55307 | 43 | { |
AnnaBridge | 167:e84263d55307 | 44 | return RTW_EMAC_MTU_SIZE; |
AnnaBridge | 167:e84263d55307 | 45 | } |
AnnaBridge | 167:e84263d55307 | 46 | |
Anna Bridge |
186:707f6e361f3e | 47 | uint32_t RTW_EMAC::get_align_preference() const |
Anna Bridge |
186:707f6e361f3e | 48 | { |
Anna Bridge |
186:707f6e361f3e | 49 | return true; |
Anna Bridge |
186:707f6e361f3e | 50 | } |
Anna Bridge |
186:707f6e361f3e | 51 | |
Anna Bridge |
186:707f6e361f3e | 52 | void RTW_EMAC::get_ifname(char *name, uint8_t size) const |
AnnaBridge | 167:e84263d55307 | 53 | { |
AnnaBridge | 167:e84263d55307 | 54 | MBED_ASSERT(name != NULL); |
AnnaBridge | 167:e84263d55307 | 55 | strncpy(name, "r0", size); |
AnnaBridge | 167:e84263d55307 | 56 | } |
AnnaBridge | 167:e84263d55307 | 57 | |
Anna Bridge |
186:707f6e361f3e | 58 | uint8_t RTW_EMAC::get_hwaddr_size() const |
AnnaBridge | 167:e84263d55307 | 59 | { |
AnnaBridge | 188:bcfe06ba3d64 | 60 | return ETH_HWADDR_LEN; |
AnnaBridge | 167:e84263d55307 | 61 | } |
AnnaBridge | 167:e84263d55307 | 62 | |
Anna Bridge |
186:707f6e361f3e | 63 | bool RTW_EMAC::get_hwaddr(uint8_t *addr) const |
AnnaBridge | 167:e84263d55307 | 64 | { |
Anna Bridge |
186:707f6e361f3e | 65 | char mac[20]; |
Anna Bridge |
186:707f6e361f3e | 66 | int val[6]; |
Anna Bridge |
186:707f6e361f3e | 67 | int i; |
Anna Bridge |
186:707f6e361f3e | 68 | |
Anna Bridge |
186:707f6e361f3e | 69 | if (RTW_SUCCESS == wifi_get_mac_address(mac)) { |
AnnaBridge | 189:f392fc9709a3 | 70 | if (sscanf(mac, "%x:%x:%x:%x:%x:%x", |
Anna Bridge |
186:707f6e361f3e | 71 | &val[0], &val[1], &val[2], &val[3], &val[4], &val[5]) != 6) { |
AnnaBridge | 167:e84263d55307 | 72 | printf("Get HW address failed\r\n"); |
Anna Bridge |
186:707f6e361f3e | 73 | } |
Anna Bridge |
186:707f6e361f3e | 74 | for (i = 0; i < 6; i++) { |
Anna Bridge |
186:707f6e361f3e | 75 | addr[i] = (unsigned char) val[i]; |
Anna Bridge |
186:707f6e361f3e | 76 | } |
Anna Bridge |
186:707f6e361f3e | 77 | } else { |
Anna Bridge |
186:707f6e361f3e | 78 | printf("Get HW address failed\r\n"); |
AnnaBridge | 167:e84263d55307 | 79 | } |
AnnaBridge | 188:bcfe06ba3d64 | 80 | return true; |
AnnaBridge | 167:e84263d55307 | 81 | } |
AnnaBridge | 167:e84263d55307 | 82 | |
Anna Bridge |
186:707f6e361f3e | 83 | void RTW_EMAC::set_hwaddr(const uint8_t *addr) |
AnnaBridge | 167:e84263d55307 | 84 | { |
AnnaBridge | 167:e84263d55307 | 85 | } |
AnnaBridge | 167:e84263d55307 | 86 | |
Anna Bridge |
186:707f6e361f3e | 87 | bool RTW_EMAC::link_out(emac_mem_buf_t *buf) |
AnnaBridge | 167:e84263d55307 | 88 | { |
Anna Bridge |
186:707f6e361f3e | 89 | struct eth_drv_sg *sg_list; |
AnnaBridge | 167:e84263d55307 | 90 | int sg_len = 0; |
AnnaBridge | 167:e84263d55307 | 91 | int tot_len; |
Anna Bridge |
186:707f6e361f3e | 92 | emac_mem_buf_t *p; |
AnnaBridge | 167:e84263d55307 | 93 | bool ret = true; |
AnnaBridge | 167:e84263d55307 | 94 | if (!rltk_wlan_running(0)) { |
Anna Bridge |
186:707f6e361f3e | 95 | memory_manager->free(buf); |
AnnaBridge | 167:e84263d55307 | 96 | return false; |
AnnaBridge | 167:e84263d55307 | 97 | } |
AnnaBridge | 167:e84263d55307 | 98 | |
AnnaBridge | 167:e84263d55307 | 99 | sg_list = (struct eth_drv_sg *)malloc(sizeof(struct eth_drv_sg)*MAX_ETH_DRV_SG); |
Anna Bridge |
186:707f6e361f3e | 100 | if (sg_list == 0) { |
Anna Bridge |
186:707f6e361f3e | 101 | memory_manager->free(buf); |
AnnaBridge | 167:e84263d55307 | 102 | return false; |
AnnaBridge | 167:e84263d55307 | 103 | } |
AnnaBridge | 167:e84263d55307 | 104 | |
Anna Bridge |
186:707f6e361f3e | 105 | p = buf; |
Anna Bridge |
186:707f6e361f3e | 106 | tot_len = memory_manager->get_total_len(p); |
Anna Bridge |
186:707f6e361f3e | 107 | for (; p != NULL && sg_len < MAX_ETH_DRV_SG; p = memory_manager->get_next(p)) { |
Anna Bridge |
186:707f6e361f3e | 108 | sg_list[sg_len].buf = (unsigned int)(static_cast<uint8_t *>(memory_manager->get_ptr(p))); |
Anna Bridge |
186:707f6e361f3e | 109 | sg_list[sg_len].len = memory_manager->get_len(p); |
Anna Bridge |
186:707f6e361f3e | 110 | sg_len++; |
AnnaBridge | 167:e84263d55307 | 111 | } |
AnnaBridge | 167:e84263d55307 | 112 | if (sg_len) { |
AnnaBridge | 167:e84263d55307 | 113 | if (rltk_wlan_send(0, sg_list, sg_len, tot_len) != 0) { |
AnnaBridge | 167:e84263d55307 | 114 | ret = false; |
AnnaBridge | 167:e84263d55307 | 115 | } |
AnnaBridge | 167:e84263d55307 | 116 | } |
AnnaBridge | 167:e84263d55307 | 117 | |
Anna Bridge |
186:707f6e361f3e | 118 | memory_manager->free(buf); |
AnnaBridge | 167:e84263d55307 | 119 | free(sg_list); |
AnnaBridge | 167:e84263d55307 | 120 | return ret; |
AnnaBridge | 167:e84263d55307 | 121 | } |
AnnaBridge | 167:e84263d55307 | 122 | |
Anna Bridge |
186:707f6e361f3e | 123 | bool RTW_EMAC::power_up() |
AnnaBridge | 167:e84263d55307 | 124 | { |
AnnaBridge | 167:e84263d55307 | 125 | wifi_on(RTW_MODE_STA); |
AnnaBridge | 167:e84263d55307 | 126 | wait_ms(1000); |
Anna Bridge |
186:707f6e361f3e | 127 | wlan_emac_link_change(true); |
AnnaBridge | 167:e84263d55307 | 128 | return true; |
AnnaBridge | 167:e84263d55307 | 129 | } |
AnnaBridge | 167:e84263d55307 | 130 | |
Anna Bridge |
186:707f6e361f3e | 131 | void RTW_EMAC::power_down() |
AnnaBridge | 167:e84263d55307 | 132 | { |
AnnaBridge | 167:e84263d55307 | 133 | wifi_off(); |
AnnaBridge | 167:e84263d55307 | 134 | } |
AnnaBridge | 167:e84263d55307 | 135 | |
Anna Bridge |
186:707f6e361f3e | 136 | void RTW_EMAC::set_link_input_cb(emac_link_input_cb_t input_cb) |
AnnaBridge | 167:e84263d55307 | 137 | { |
Anna Bridge |
186:707f6e361f3e | 138 | emac_link_input_cb = input_cb; |
Anna Bridge |
186:707f6e361f3e | 139 | } |
Anna Bridge |
186:707f6e361f3e | 140 | |
Anna Bridge |
186:707f6e361f3e | 141 | void RTW_EMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb) |
Anna Bridge |
186:707f6e361f3e | 142 | { |
Anna Bridge |
186:707f6e361f3e | 143 | emac_link_state_cb = state_cb; |
Anna Bridge |
186:707f6e361f3e | 144 | } |
Anna Bridge |
186:707f6e361f3e | 145 | |
Anna Bridge |
186:707f6e361f3e | 146 | void RTW_EMAC::add_multicast_group(const uint8_t *addr) |
Anna Bridge |
186:707f6e361f3e | 147 | { |
AnnaBridge | 167:e84263d55307 | 148 | } |
AnnaBridge | 167:e84263d55307 | 149 | |
Anna Bridge |
186:707f6e361f3e | 150 | void RTW_EMAC::remove_multicast_group(const uint8_t *addr) |
AnnaBridge | 167:e84263d55307 | 151 | { |
Anna Bridge |
186:707f6e361f3e | 152 | } |
Anna Bridge |
186:707f6e361f3e | 153 | |
Anna Bridge |
186:707f6e361f3e | 154 | void RTW_EMAC::set_all_multicast(bool all) |
Anna Bridge |
186:707f6e361f3e | 155 | { |
AnnaBridge | 167:e84263d55307 | 156 | } |
AnnaBridge | 167:e84263d55307 | 157 | |
Anna Bridge |
186:707f6e361f3e | 158 | void RTW_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr) |
AnnaBridge | 167:e84263d55307 | 159 | { |
Anna Bridge |
186:707f6e361f3e | 160 | memory_manager = &mem_mngr; |
Anna Bridge |
186:707f6e361f3e | 161 | } |
Anna Bridge |
186:707f6e361f3e | 162 | |
Anna Bridge |
186:707f6e361f3e | 163 | void RTW_EMAC::wlan_emac_recv(void *param, struct netif *netif, uint32_t len) |
Anna Bridge |
186:707f6e361f3e | 164 | { |
Anna Bridge |
186:707f6e361f3e | 165 | struct eth_drv_sg sg_list[MAX_ETH_DRV_SG] = {0}; |
Anna Bridge |
186:707f6e361f3e | 166 | emac_mem_buf_t *buf; |
Anna Bridge |
186:707f6e361f3e | 167 | RTW_EMAC *enet = static_cast<RTW_EMAC *>(param); |
Anna Bridge |
186:707f6e361f3e | 168 | emac_mem_buf_t *p; |
AnnaBridge | 167:e84263d55307 | 169 | int sg_len = 0; |
AnnaBridge | 167:e84263d55307 | 170 | if (!rltk_wlan_running(0)) { |
AnnaBridge | 167:e84263d55307 | 171 | return; |
AnnaBridge | 167:e84263d55307 | 172 | } |
AnnaBridge | 167:e84263d55307 | 173 | |
AnnaBridge | 167:e84263d55307 | 174 | if (len > MAX_ETH_MSG || len < 0) { |
AnnaBridge | 167:e84263d55307 | 175 | len = MAX_ETH_MSG; |
AnnaBridge | 167:e84263d55307 | 176 | } |
AnnaBridge | 167:e84263d55307 | 177 | |
Anna Bridge |
186:707f6e361f3e | 178 | buf = enet->memory_manager->alloc_heap(len, 0); |
AnnaBridge | 167:e84263d55307 | 179 | if (buf == NULL) { |
AnnaBridge | 167:e84263d55307 | 180 | return; |
AnnaBridge | 189:f392fc9709a3 | 181 | } |
AnnaBridge | 167:e84263d55307 | 182 | |
Anna Bridge |
186:707f6e361f3e | 183 | enet->memory_manager->set_len(buf, len); |
Anna Bridge |
186:707f6e361f3e | 184 | p = buf; |
Anna Bridge |
186:707f6e361f3e | 185 | for (; p != NULL && sg_len < MAX_ETH_DRV_SG; p = enet->memory_manager->get_next(p)) { |
Anna Bridge |
186:707f6e361f3e | 186 | sg_list[sg_len].buf = (unsigned int)(static_cast<uint8_t *>(enet->memory_manager->get_ptr(p))); |
Anna Bridge |
186:707f6e361f3e | 187 | sg_list[sg_len].len = enet->memory_manager->get_len(p); |
AnnaBridge | 167:e84263d55307 | 188 | sg_len++; |
AnnaBridge | 167:e84263d55307 | 189 | } |
Anna Bridge |
186:707f6e361f3e | 190 | |
AnnaBridge | 167:e84263d55307 | 191 | rltk_wlan_recv(0, sg_list, sg_len); |
Anna Bridge |
186:707f6e361f3e | 192 | if (enet->emac_link_input_cb) { |
Anna Bridge |
186:707f6e361f3e | 193 | enet->emac_link_input_cb(buf); |
AnnaBridge | 167:e84263d55307 | 194 | } |
AnnaBridge | 167:e84263d55307 | 195 | } |
AnnaBridge | 167:e84263d55307 | 196 | |
AnnaBridge | 167:e84263d55307 | 197 | void mbed_default_mac_address(char *mac) { |
AnnaBridge | 167:e84263d55307 | 198 | unsigned char RTK_mac_addr[3] = {0x00, 0xE0, 0x4C}; // default Realtek mac address |
AnnaBridge | 167:e84263d55307 | 199 | mac[0] = RTK_mac_addr[0]; |
AnnaBridge | 167:e84263d55307 | 200 | mac[1] = RTK_mac_addr[1]; |
AnnaBridge | 167:e84263d55307 | 201 | mac[2] = RTK_mac_addr[2]; |
AnnaBridge | 167:e84263d55307 | 202 | mac[3] = 0x87; |
AnnaBridge | 167:e84263d55307 | 203 | mac[4] = 0x00; |
AnnaBridge | 167:e84263d55307 | 204 | mac[5] = 0x01; |
AnnaBridge | 167:e84263d55307 | 205 | return; |
AnnaBridge | 167:e84263d55307 | 206 | } |
AnnaBridge | 167:e84263d55307 | 207 | |
AnnaBridge | 167:e84263d55307 | 208 | void mbed_mac_address(char *mac) |
AnnaBridge | 167:e84263d55307 | 209 | { |
AnnaBridge | 189:f392fc9709a3 | 210 | char hwaddr[20]; |
Anna Bridge |
186:707f6e361f3e | 211 | int val[6]; |
Anna Bridge |
186:707f6e361f3e | 212 | int i; |
Anna Bridge |
186:707f6e361f3e | 213 | if (RTW_SUCCESS == wifi_get_mac_address(hwaddr)) { |
Anna Bridge |
186:707f6e361f3e | 214 | if (sscanf(hwaddr, "%x:%x:%x:%x:%x:%x", |
Anna Bridge |
186:707f6e361f3e | 215 | &val[0], &val[1], &val[2], &val[3], &val[4], &val[5]) != 6) { |
AnnaBridge | 167:e84263d55307 | 216 | printf("Get HW address failed\r\n"); |
Anna Bridge |
186:707f6e361f3e | 217 | } |
Anna Bridge |
186:707f6e361f3e | 218 | for (i = 0; i < 6; i++) { |
Anna Bridge |
186:707f6e361f3e | 219 | mac[i] = (unsigned char) val[i]; |
Anna Bridge |
186:707f6e361f3e | 220 | } |
Anna Bridge |
186:707f6e361f3e | 221 | } else { |
AnnaBridge | 167:e84263d55307 | 222 | printf("Get HW address failed\r\n"); |
AnnaBridge | 167:e84263d55307 | 223 | mbed_default_mac_address(mac); |
AnnaBridge | 167:e84263d55307 | 224 | } |
AnnaBridge | 167:e84263d55307 | 225 | } |
AnnaBridge | 167:e84263d55307 | 226 | |
Anna Bridge |
186:707f6e361f3e | 227 | void RTW_EMAC::wlan_emac_link_change(bool up) |
AnnaBridge | 167:e84263d55307 | 228 | { |
Anna Bridge |
186:707f6e361f3e | 229 | if (emac_link_state_cb) { |
Anna Bridge |
186:707f6e361f3e | 230 | emac_link_state_cb(up); |
AnnaBridge | 167:e84263d55307 | 231 | } |
AnnaBridge | 167:e84263d55307 | 232 | } |
AnnaBridge | 167:e84263d55307 | 233 | |
Anna Bridge |
186:707f6e361f3e | 234 | RTW_EMAC &RTW_EMAC::get_instance() { |
Anna Bridge |
186:707f6e361f3e | 235 | static RTW_EMAC rtw_emac; |
Anna Bridge |
186:707f6e361f3e | 236 | return rtw_emac; |
Anna Bridge |
186:707f6e361f3e | 237 | } |
Anna Bridge |
186:707f6e361f3e | 238 | // Weak so a module can override |
Anna Bridge |
186:707f6e361f3e | 239 | MBED_WEAK EMAC &EMAC::get_default_instance() { |
Anna Bridge |
186:707f6e361f3e | 240 | return RTW_EMAC::get_instance(); |
AnnaBridge | 167:e84263d55307 | 241 | } |
AnnaBridge | 167:e84263d55307 | 242 | #endif |