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@188:bcfe06ba3d64, 2018-11-08 (annotated)
- Committer:
- AnnaBridge
- Date:
- Thu Nov 08 11:46:34 2018 +0000
- Revision:
- 188:bcfe06ba3d64
- Parent:
- 187:0387e8f68319
- Child:
- 189:f392fc9709a3
mbed-dev library. Release version 164
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 | 167:e84263d55307 | 22 | |
Anna Bridge |
186:707f6e361f3e | 23 | #include "rtw_emac.h" |
Anna Bridge |
186:707f6e361f3e | 24 | #include "EMACMemoryManager.h" |
Anna Bridge |
186:707f6e361f3e | 25 | |
AnnaBridge | 167:e84263d55307 | 26 | #include "rtos.h" |
AnnaBridge | 167:e84263d55307 | 27 | #include "lwip/pbuf.h" |
AnnaBridge | 167:e84263d55307 | 28 | #include "netif/etharp.h" |
AnnaBridge | 167:e84263d55307 | 29 | |
AnnaBridge | 167:e84263d55307 | 30 | #include "lwip_intf.h" |
AnnaBridge | 167:e84263d55307 | 31 | #include "wifi_constants.h" |
AnnaBridge | 167:e84263d55307 | 32 | #include "wifi_conf.h" |
AnnaBridge | 167:e84263d55307 | 33 | |
AnnaBridge | 167:e84263d55307 | 34 | #define RTW_EMAC_MTU_SIZE (1500U) |
AnnaBridge | 167:e84263d55307 | 35 | |
Anna Bridge |
186:707f6e361f3e | 36 | RTW_EMAC::RTW_EMAC() |
Anna Bridge |
186:707f6e361f3e | 37 | { |
Anna Bridge |
186:707f6e361f3e | 38 | set_callback_func((emac_callback)(&RTW_EMAC::wlan_emac_recv), this); |
Anna Bridge |
186:707f6e361f3e | 39 | } |
AnnaBridge | 167:e84263d55307 | 40 | |
Anna Bridge |
186:707f6e361f3e | 41 | uint32_t RTW_EMAC::get_mtu_size() const |
AnnaBridge | 167:e84263d55307 | 42 | { |
AnnaBridge | 167:e84263d55307 | 43 | return RTW_EMAC_MTU_SIZE; |
AnnaBridge | 167:e84263d55307 | 44 | } |
AnnaBridge | 167:e84263d55307 | 45 | |
Anna Bridge |
186:707f6e361f3e | 46 | uint32_t RTW_EMAC::get_align_preference() const |
Anna Bridge |
186:707f6e361f3e | 47 | { |
Anna Bridge |
186:707f6e361f3e | 48 | return true; |
Anna Bridge |
186:707f6e361f3e | 49 | } |
Anna Bridge |
186:707f6e361f3e | 50 | |
Anna Bridge |
186:707f6e361f3e | 51 | void RTW_EMAC::get_ifname(char *name, uint8_t size) const |
AnnaBridge | 167:e84263d55307 | 52 | { |
AnnaBridge | 167:e84263d55307 | 53 | MBED_ASSERT(name != NULL); |
AnnaBridge | 167:e84263d55307 | 54 | strncpy(name, "r0", size); |
AnnaBridge | 167:e84263d55307 | 55 | } |
AnnaBridge | 167:e84263d55307 | 56 | |
Anna Bridge |
186:707f6e361f3e | 57 | uint8_t RTW_EMAC::get_hwaddr_size() const |
AnnaBridge | 167:e84263d55307 | 58 | { |
AnnaBridge | 188:bcfe06ba3d64 | 59 | return ETH_HWADDR_LEN; |
AnnaBridge | 167:e84263d55307 | 60 | } |
AnnaBridge | 167:e84263d55307 | 61 | |
Anna Bridge |
186:707f6e361f3e | 62 | bool RTW_EMAC::get_hwaddr(uint8_t *addr) const |
AnnaBridge | 167:e84263d55307 | 63 | { |
Anna Bridge |
186:707f6e361f3e | 64 | char mac[20]; |
Anna Bridge |
186:707f6e361f3e | 65 | int val[6]; |
Anna Bridge |
186:707f6e361f3e | 66 | int i; |
Anna Bridge |
186:707f6e361f3e | 67 | |
Anna Bridge |
186:707f6e361f3e | 68 | if (RTW_SUCCESS == wifi_get_mac_address(mac)) { |
Anna Bridge |
186:707f6e361f3e | 69 | if (sscanf(mac, "%x:%x:%x:%x:%x:%x", |
Anna Bridge |
186:707f6e361f3e | 70 | &val[0], &val[1], &val[2], &val[3], &val[4], &val[5]) != 6) { |
AnnaBridge | 167:e84263d55307 | 71 | printf("Get HW address failed\r\n"); |
Anna Bridge |
186:707f6e361f3e | 72 | } |
Anna Bridge |
186:707f6e361f3e | 73 | for (i = 0; i < 6; i++) { |
Anna Bridge |
186:707f6e361f3e | 74 | addr[i] = (unsigned char) val[i]; |
Anna Bridge |
186:707f6e361f3e | 75 | } |
Anna Bridge |
186:707f6e361f3e | 76 | } else { |
Anna Bridge |
186:707f6e361f3e | 77 | printf("Get HW address failed\r\n"); |
AnnaBridge | 167:e84263d55307 | 78 | } |
AnnaBridge | 188:bcfe06ba3d64 | 79 | return true; |
AnnaBridge | 167:e84263d55307 | 80 | } |
AnnaBridge | 167:e84263d55307 | 81 | |
Anna Bridge |
186:707f6e361f3e | 82 | void RTW_EMAC::set_hwaddr(const uint8_t *addr) |
AnnaBridge | 167:e84263d55307 | 83 | { |
AnnaBridge | 167:e84263d55307 | 84 | } |
AnnaBridge | 167:e84263d55307 | 85 | |
Anna Bridge |
186:707f6e361f3e | 86 | bool RTW_EMAC::link_out(emac_mem_buf_t *buf) |
AnnaBridge | 167:e84263d55307 | 87 | { |
Anna Bridge |
186:707f6e361f3e | 88 | struct eth_drv_sg *sg_list; |
AnnaBridge | 167:e84263d55307 | 89 | int sg_len = 0; |
AnnaBridge | 167:e84263d55307 | 90 | int tot_len; |
Anna Bridge |
186:707f6e361f3e | 91 | emac_mem_buf_t *p; |
AnnaBridge | 167:e84263d55307 | 92 | bool ret = true; |
AnnaBridge | 167:e84263d55307 | 93 | if (!rltk_wlan_running(0)) { |
Anna Bridge |
186:707f6e361f3e | 94 | memory_manager->free(buf); |
AnnaBridge | 167:e84263d55307 | 95 | return false; |
AnnaBridge | 167:e84263d55307 | 96 | } |
AnnaBridge | 167:e84263d55307 | 97 | |
AnnaBridge | 167:e84263d55307 | 98 | sg_list = (struct eth_drv_sg *)malloc(sizeof(struct eth_drv_sg)*MAX_ETH_DRV_SG); |
Anna Bridge |
186:707f6e361f3e | 99 | if (sg_list == 0) { |
Anna Bridge |
186:707f6e361f3e | 100 | memory_manager->free(buf); |
AnnaBridge | 167:e84263d55307 | 101 | return false; |
AnnaBridge | 167:e84263d55307 | 102 | } |
AnnaBridge | 167:e84263d55307 | 103 | |
Anna Bridge |
186:707f6e361f3e | 104 | p = buf; |
Anna Bridge |
186:707f6e361f3e | 105 | tot_len = memory_manager->get_total_len(p); |
Anna Bridge |
186:707f6e361f3e | 106 | for (; p != NULL && sg_len < MAX_ETH_DRV_SG; p = memory_manager->get_next(p)) { |
Anna Bridge |
186:707f6e361f3e | 107 | sg_list[sg_len].buf = (unsigned int)(static_cast<uint8_t *>(memory_manager->get_ptr(p))); |
Anna Bridge |
186:707f6e361f3e | 108 | sg_list[sg_len].len = memory_manager->get_len(p); |
Anna Bridge |
186:707f6e361f3e | 109 | sg_len++; |
AnnaBridge | 167:e84263d55307 | 110 | } |
AnnaBridge | 167:e84263d55307 | 111 | if (sg_len) { |
AnnaBridge | 167:e84263d55307 | 112 | if (rltk_wlan_send(0, sg_list, sg_len, tot_len) != 0) { |
AnnaBridge | 167:e84263d55307 | 113 | ret = false; |
AnnaBridge | 167:e84263d55307 | 114 | } |
AnnaBridge | 167:e84263d55307 | 115 | } |
AnnaBridge | 167:e84263d55307 | 116 | |
Anna Bridge |
186:707f6e361f3e | 117 | memory_manager->free(buf); |
AnnaBridge | 167:e84263d55307 | 118 | free(sg_list); |
AnnaBridge | 167:e84263d55307 | 119 | return ret; |
AnnaBridge | 167:e84263d55307 | 120 | } |
AnnaBridge | 167:e84263d55307 | 121 | |
Anna Bridge |
186:707f6e361f3e | 122 | bool RTW_EMAC::power_up() |
AnnaBridge | 167:e84263d55307 | 123 | { |
AnnaBridge | 167:e84263d55307 | 124 | wifi_on(RTW_MODE_STA); |
AnnaBridge | 167:e84263d55307 | 125 | wait_ms(1000); |
Anna Bridge |
186:707f6e361f3e | 126 | wlan_emac_link_change(true); |
AnnaBridge | 167:e84263d55307 | 127 | return true; |
AnnaBridge | 167:e84263d55307 | 128 | } |
AnnaBridge | 167:e84263d55307 | 129 | |
Anna Bridge |
186:707f6e361f3e | 130 | void RTW_EMAC::power_down() |
AnnaBridge | 167:e84263d55307 | 131 | { |
AnnaBridge | 167:e84263d55307 | 132 | wifi_off(); |
AnnaBridge | 167:e84263d55307 | 133 | } |
AnnaBridge | 167:e84263d55307 | 134 | |
Anna Bridge |
186:707f6e361f3e | 135 | void RTW_EMAC::set_link_input_cb(emac_link_input_cb_t input_cb) |
AnnaBridge | 167:e84263d55307 | 136 | { |
Anna Bridge |
186:707f6e361f3e | 137 | emac_link_input_cb = input_cb; |
Anna Bridge |
186:707f6e361f3e | 138 | } |
Anna Bridge |
186:707f6e361f3e | 139 | |
Anna Bridge |
186:707f6e361f3e | 140 | void RTW_EMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb) |
Anna Bridge |
186:707f6e361f3e | 141 | { |
Anna Bridge |
186:707f6e361f3e | 142 | emac_link_state_cb = state_cb; |
Anna Bridge |
186:707f6e361f3e | 143 | } |
Anna Bridge |
186:707f6e361f3e | 144 | |
Anna Bridge |
186:707f6e361f3e | 145 | void RTW_EMAC::add_multicast_group(const uint8_t *addr) |
Anna Bridge |
186:707f6e361f3e | 146 | { |
AnnaBridge | 167:e84263d55307 | 147 | } |
AnnaBridge | 167:e84263d55307 | 148 | |
Anna Bridge |
186:707f6e361f3e | 149 | void RTW_EMAC::remove_multicast_group(const uint8_t *addr) |
AnnaBridge | 167:e84263d55307 | 150 | { |
Anna Bridge |
186:707f6e361f3e | 151 | } |
Anna Bridge |
186:707f6e361f3e | 152 | |
Anna Bridge |
186:707f6e361f3e | 153 | void RTW_EMAC::set_all_multicast(bool all) |
Anna Bridge |
186:707f6e361f3e | 154 | { |
AnnaBridge | 167:e84263d55307 | 155 | } |
AnnaBridge | 167:e84263d55307 | 156 | |
Anna Bridge |
186:707f6e361f3e | 157 | void RTW_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr) |
AnnaBridge | 167:e84263d55307 | 158 | { |
Anna Bridge |
186:707f6e361f3e | 159 | memory_manager = &mem_mngr; |
Anna Bridge |
186:707f6e361f3e | 160 | } |
Anna Bridge |
186:707f6e361f3e | 161 | |
Anna Bridge |
186:707f6e361f3e | 162 | void RTW_EMAC::wlan_emac_recv(void *param, struct netif *netif, uint32_t len) |
Anna Bridge |
186:707f6e361f3e | 163 | { |
Anna Bridge |
186:707f6e361f3e | 164 | struct eth_drv_sg sg_list[MAX_ETH_DRV_SG] = {0}; |
Anna Bridge |
186:707f6e361f3e | 165 | emac_mem_buf_t *buf; |
Anna Bridge |
186:707f6e361f3e | 166 | RTW_EMAC *enet = static_cast<RTW_EMAC *>(param); |
Anna Bridge |
186:707f6e361f3e | 167 | emac_mem_buf_t *p; |
AnnaBridge | 167:e84263d55307 | 168 | int sg_len = 0; |
AnnaBridge | 167:e84263d55307 | 169 | if (!rltk_wlan_running(0)) { |
AnnaBridge | 167:e84263d55307 | 170 | return; |
AnnaBridge | 167:e84263d55307 | 171 | } |
AnnaBridge | 167:e84263d55307 | 172 | |
AnnaBridge | 167:e84263d55307 | 173 | if (len > MAX_ETH_MSG || len < 0) { |
AnnaBridge | 167:e84263d55307 | 174 | len = MAX_ETH_MSG; |
AnnaBridge | 167:e84263d55307 | 175 | } |
AnnaBridge | 167:e84263d55307 | 176 | |
Anna Bridge |
186:707f6e361f3e | 177 | buf = enet->memory_manager->alloc_heap(len, 0); |
AnnaBridge | 167:e84263d55307 | 178 | if (buf == NULL) { |
AnnaBridge | 167:e84263d55307 | 179 | return; |
Anna Bridge |
186:707f6e361f3e | 180 | } |
AnnaBridge | 167:e84263d55307 | 181 | |
Anna Bridge |
186:707f6e361f3e | 182 | enet->memory_manager->set_len(buf, len); |
Anna Bridge |
186:707f6e361f3e | 183 | p = buf; |
Anna Bridge |
186:707f6e361f3e | 184 | for (; p != NULL && sg_len < MAX_ETH_DRV_SG; p = enet->memory_manager->get_next(p)) { |
Anna Bridge |
186:707f6e361f3e | 185 | sg_list[sg_len].buf = (unsigned int)(static_cast<uint8_t *>(enet->memory_manager->get_ptr(p))); |
Anna Bridge |
186:707f6e361f3e | 186 | sg_list[sg_len].len = enet->memory_manager->get_len(p); |
AnnaBridge | 167:e84263d55307 | 187 | sg_len++; |
AnnaBridge | 167:e84263d55307 | 188 | } |
Anna Bridge |
186:707f6e361f3e | 189 | |
AnnaBridge | 167:e84263d55307 | 190 | rltk_wlan_recv(0, sg_list, sg_len); |
Anna Bridge |
186:707f6e361f3e | 191 | if (enet->emac_link_input_cb) { |
Anna Bridge |
186:707f6e361f3e | 192 | enet->emac_link_input_cb(buf); |
AnnaBridge | 167:e84263d55307 | 193 | } |
AnnaBridge | 167:e84263d55307 | 194 | } |
AnnaBridge | 167:e84263d55307 | 195 | |
AnnaBridge | 167:e84263d55307 | 196 | void mbed_default_mac_address(char *mac) { |
AnnaBridge | 167:e84263d55307 | 197 | unsigned char RTK_mac_addr[3] = {0x00, 0xE0, 0x4C}; // default Realtek mac address |
AnnaBridge | 167:e84263d55307 | 198 | mac[0] = RTK_mac_addr[0]; |
AnnaBridge | 167:e84263d55307 | 199 | mac[1] = RTK_mac_addr[1]; |
AnnaBridge | 167:e84263d55307 | 200 | mac[2] = RTK_mac_addr[2]; |
AnnaBridge | 167:e84263d55307 | 201 | mac[3] = 0x87; |
AnnaBridge | 167:e84263d55307 | 202 | mac[4] = 0x00; |
AnnaBridge | 167:e84263d55307 | 203 | mac[5] = 0x01; |
AnnaBridge | 167:e84263d55307 | 204 | return; |
AnnaBridge | 167:e84263d55307 | 205 | } |
AnnaBridge | 167:e84263d55307 | 206 | |
AnnaBridge | 167:e84263d55307 | 207 | void mbed_mac_address(char *mac) |
AnnaBridge | 167:e84263d55307 | 208 | { |
AnnaBridge | 167:e84263d55307 | 209 | char hwaddr[20]; |
Anna Bridge |
186:707f6e361f3e | 210 | int val[6]; |
Anna Bridge |
186:707f6e361f3e | 211 | int i; |
Anna Bridge |
186:707f6e361f3e | 212 | if (RTW_SUCCESS == wifi_get_mac_address(hwaddr)) { |
Anna Bridge |
186:707f6e361f3e | 213 | if (sscanf(hwaddr, "%x:%x:%x:%x:%x:%x", |
Anna Bridge |
186:707f6e361f3e | 214 | &val[0], &val[1], &val[2], &val[3], &val[4], &val[5]) != 6) { |
AnnaBridge | 167:e84263d55307 | 215 | printf("Get HW address failed\r\n"); |
Anna Bridge |
186:707f6e361f3e | 216 | } |
Anna Bridge |
186:707f6e361f3e | 217 | for (i = 0; i < 6; i++) { |
Anna Bridge |
186:707f6e361f3e | 218 | mac[i] = (unsigned char) val[i]; |
Anna Bridge |
186:707f6e361f3e | 219 | } |
Anna Bridge |
186:707f6e361f3e | 220 | } else { |
AnnaBridge | 167:e84263d55307 | 221 | printf("Get HW address failed\r\n"); |
AnnaBridge | 167:e84263d55307 | 222 | mbed_default_mac_address(mac); |
AnnaBridge | 167:e84263d55307 | 223 | } |
AnnaBridge | 167:e84263d55307 | 224 | } |
AnnaBridge | 167:e84263d55307 | 225 | |
Anna Bridge |
186:707f6e361f3e | 226 | void RTW_EMAC::wlan_emac_link_change(bool up) |
AnnaBridge | 167:e84263d55307 | 227 | { |
Anna Bridge |
186:707f6e361f3e | 228 | if (emac_link_state_cb) { |
Anna Bridge |
186:707f6e361f3e | 229 | emac_link_state_cb(up); |
AnnaBridge | 167:e84263d55307 | 230 | } |
AnnaBridge | 167:e84263d55307 | 231 | } |
AnnaBridge | 167:e84263d55307 | 232 | |
Anna Bridge |
186:707f6e361f3e | 233 | RTW_EMAC &RTW_EMAC::get_instance() { |
Anna Bridge |
186:707f6e361f3e | 234 | static RTW_EMAC rtw_emac; |
Anna Bridge |
186:707f6e361f3e | 235 | return rtw_emac; |
Anna Bridge |
186:707f6e361f3e | 236 | } |
Anna Bridge |
186:707f6e361f3e | 237 | // Weak so a module can override |
Anna Bridge |
186:707f6e361f3e | 238 | MBED_WEAK EMAC &EMAC::get_default_instance() { |
Anna Bridge |
186:707f6e361f3e | 239 | return RTW_EMAC::get_instance(); |
AnnaBridge | 167:e84263d55307 | 240 | } |
AnnaBridge | 167:e84263d55307 | 241 | #endif |