lab 3

Committer:
mbed_official
Date:
Thu Feb 05 13:45:38 2015 +0000
Revision:
23:1283021a4a74
Parent:
22:fa7e1e2c6eb3
Child:
28:72f8b097fbf3
Synchronized with git revision 3365a1117d8f34a9def10bbceddc1fdc6b1a7835

Full URL: https://github.com/mbedmicro/mbed/commit/3365a1117d8f34a9def10bbceddc1fdc6b1a7835/

RZ_A1H - Fix a bug that Ether Driver there is a case where the transmission

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 22:fa7e1e2c6eb3 1 #include "lwip/opt.h"
mbed_official 22:fa7e1e2c6eb3 2 #include "lwip/tcpip.h"
mbed_official 22:fa7e1e2c6eb3 3 #include "netif/etharp.h"
mbed_official 22:fa7e1e2c6eb3 4 #include "mbed_interface.h"
mbed_official 22:fa7e1e2c6eb3 5 #include "ethernet_api.h"
mbed_official 22:fa7e1e2c6eb3 6 #include "ethernetext_api.h"
mbed_official 22:fa7e1e2c6eb3 7
mbed_official 22:fa7e1e2c6eb3 8 #define RECV_TASK_PRI (osPriorityNormal)
mbed_official 22:fa7e1e2c6eb3 9 #define PHY_TASK_PRI (osPriorityNormal)
mbed_official 22:fa7e1e2c6eb3 10 #define PHY_TASK_WAIT (200)
mbed_official 22:fa7e1e2c6eb3 11
mbed_official 22:fa7e1e2c6eb3 12 /* memory */
mbed_official 22:fa7e1e2c6eb3 13 static sys_sem_t recv_ready_sem; /* receive ready semaphore */
mbed_official 22:fa7e1e2c6eb3 14
mbed_official 22:fa7e1e2c6eb3 15 /* function */
mbed_official 22:fa7e1e2c6eb3 16 static void rza1_recv_task(void *arg);
mbed_official 22:fa7e1e2c6eb3 17 static void rza1_phy_task(void *arg);
mbed_official 22:fa7e1e2c6eb3 18 static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr);
mbed_official 22:fa7e1e2c6eb3 19 static err_t rza1_low_level_output(struct netif *netif, struct pbuf *p);
mbed_official 22:fa7e1e2c6eb3 20 static void rza1_recv_callback(void);
mbed_official 22:fa7e1e2c6eb3 21
mbed_official 22:fa7e1e2c6eb3 22 static void rza1_recv_task(void *arg) {
mbed_official 22:fa7e1e2c6eb3 23 struct netif *netif = (struct netif*)arg;
mbed_official 22:fa7e1e2c6eb3 24 struct eth_hdr *ethhdr;
mbed_official 22:fa7e1e2c6eb3 25 u16_t recv_size;
mbed_official 22:fa7e1e2c6eb3 26 struct pbuf *p;
mbed_official 22:fa7e1e2c6eb3 27 struct pbuf *q;
mbed_official 22:fa7e1e2c6eb3 28
mbed_official 22:fa7e1e2c6eb3 29 while (1) {
mbed_official 22:fa7e1e2c6eb3 30 sys_arch_sem_wait(&recv_ready_sem, 0);
mbed_official 22:fa7e1e2c6eb3 31 recv_size = ethernet_receive();
mbed_official 22:fa7e1e2c6eb3 32 if (recv_size != 0) {
mbed_official 22:fa7e1e2c6eb3 33 p = pbuf_alloc(PBUF_RAW, recv_size, PBUF_POOL);
mbed_official 22:fa7e1e2c6eb3 34 if (p != NULL) {
mbed_official 22:fa7e1e2c6eb3 35 for (q = p; q != NULL; q = q->next) {
mbed_official 22:fa7e1e2c6eb3 36 (void)ethernet_read((char *)q->payload, q->len);
mbed_official 22:fa7e1e2c6eb3 37 }
mbed_official 22:fa7e1e2c6eb3 38 ethhdr = p->payload;
mbed_official 22:fa7e1e2c6eb3 39 switch (htons(ethhdr->type)) {
mbed_official 22:fa7e1e2c6eb3 40 case ETHTYPE_IP:
mbed_official 22:fa7e1e2c6eb3 41 case ETHTYPE_ARP:
mbed_official 22:fa7e1e2c6eb3 42 #if PPPOE_SUPPORT
mbed_official 22:fa7e1e2c6eb3 43 case ETHTYPE_PPPOEDISC:
mbed_official 22:fa7e1e2c6eb3 44 case ETHTYPE_PPPOE:
mbed_official 22:fa7e1e2c6eb3 45 #endif /* PPPOE_SUPPORT */
mbed_official 22:fa7e1e2c6eb3 46 /* full packet send to tcpip_thread to process */
mbed_official 22:fa7e1e2c6eb3 47 if (netif->input(p, netif) != ERR_OK) {
mbed_official 22:fa7e1e2c6eb3 48 /* Free buffer */
mbed_official 22:fa7e1e2c6eb3 49 pbuf_free(p);
mbed_official 22:fa7e1e2c6eb3 50 }
mbed_official 22:fa7e1e2c6eb3 51 break;
mbed_official 22:fa7e1e2c6eb3 52 default:
mbed_official 22:fa7e1e2c6eb3 53 /* Return buffer */
mbed_official 22:fa7e1e2c6eb3 54 pbuf_free(p);
mbed_official 22:fa7e1e2c6eb3 55 break;
mbed_official 22:fa7e1e2c6eb3 56 }
mbed_official 22:fa7e1e2c6eb3 57 }
mbed_official 22:fa7e1e2c6eb3 58 }
mbed_official 22:fa7e1e2c6eb3 59 }
mbed_official 22:fa7e1e2c6eb3 60 }
mbed_official 22:fa7e1e2c6eb3 61
mbed_official 22:fa7e1e2c6eb3 62 static void rza1_phy_task(void *arg) {
mbed_official 22:fa7e1e2c6eb3 63 struct netif *netif = (struct netif*)arg;
mbed_official 22:fa7e1e2c6eb3 64 s32_t connect_sts = 0; /* 0: disconnect, 1:connect */
mbed_official 22:fa7e1e2c6eb3 65 s32_t link_sts;
mbed_official 23:1283021a4a74 66 s32_t link_mode_new = NEGO_FAIL;
mbed_official 22:fa7e1e2c6eb3 67 s32_t link_mode_old = NEGO_FAIL;
mbed_official 22:fa7e1e2c6eb3 68
mbed_official 22:fa7e1e2c6eb3 69 while (1) {
mbed_official 22:fa7e1e2c6eb3 70 link_sts = ethernet_link();
mbed_official 22:fa7e1e2c6eb3 71 if (link_sts == 1) {
mbed_official 22:fa7e1e2c6eb3 72 link_mode_new = ethernetext_chk_link_mode();
mbed_official 22:fa7e1e2c6eb3 73 if (link_mode_new != link_mode_old) {
mbed_official 22:fa7e1e2c6eb3 74 if (connect_sts == 1) {
mbed_official 22:fa7e1e2c6eb3 75 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
mbed_official 22:fa7e1e2c6eb3 76 }
mbed_official 22:fa7e1e2c6eb3 77 if (link_mode_new != NEGO_FAIL) {
mbed_official 22:fa7e1e2c6eb3 78 ethernetext_set_link_mode(link_mode_new);
mbed_official 22:fa7e1e2c6eb3 79 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_up, (void*) netif, 1);
mbed_official 22:fa7e1e2c6eb3 80 connect_sts = 1;
mbed_official 22:fa7e1e2c6eb3 81 }
mbed_official 22:fa7e1e2c6eb3 82 }
mbed_official 22:fa7e1e2c6eb3 83 } else {
mbed_official 22:fa7e1e2c6eb3 84 if (connect_sts != 0) {
mbed_official 22:fa7e1e2c6eb3 85 tcpip_callback_with_block((tcpip_callback_fn)netif_set_link_down, (void*) netif, 1);
mbed_official 22:fa7e1e2c6eb3 86 link_mode_new = NEGO_FAIL;
mbed_official 22:fa7e1e2c6eb3 87 connect_sts = 0;
mbed_official 22:fa7e1e2c6eb3 88 }
mbed_official 22:fa7e1e2c6eb3 89 }
mbed_official 22:fa7e1e2c6eb3 90 link_mode_old = link_mode_new;
mbed_official 22:fa7e1e2c6eb3 91 osDelay(PHY_TASK_WAIT);
mbed_official 22:fa7e1e2c6eb3 92 }
mbed_official 22:fa7e1e2c6eb3 93 }
mbed_official 22:fa7e1e2c6eb3 94
mbed_official 22:fa7e1e2c6eb3 95 static err_t rza1_etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr) {
mbed_official 22:fa7e1e2c6eb3 96 /* Only send packet is link is up */
mbed_official 22:fa7e1e2c6eb3 97 if (netif->flags & NETIF_FLAG_LINK_UP) {
mbed_official 22:fa7e1e2c6eb3 98 return etharp_output(netif, q, ipaddr);
mbed_official 22:fa7e1e2c6eb3 99 }
mbed_official 22:fa7e1e2c6eb3 100
mbed_official 22:fa7e1e2c6eb3 101 return ERR_CONN;
mbed_official 22:fa7e1e2c6eb3 102 }
mbed_official 22:fa7e1e2c6eb3 103
mbed_official 22:fa7e1e2c6eb3 104 static err_t rza1_low_level_output(struct netif *netif, struct pbuf *p) {
mbed_official 22:fa7e1e2c6eb3 105 struct pbuf *q;
mbed_official 22:fa7e1e2c6eb3 106 s32_t cnt;
mbed_official 22:fa7e1e2c6eb3 107 err_t err = ERR_MEM;
mbed_official 22:fa7e1e2c6eb3 108 s32_t write_size = 0;
mbed_official 22:fa7e1e2c6eb3 109
mbed_official 22:fa7e1e2c6eb3 110 if ((p->payload != NULL) && (p->len != 0)) {
mbed_official 22:fa7e1e2c6eb3 111 /* If the first data can't be written, transmit descriptor is full. */
mbed_official 22:fa7e1e2c6eb3 112 for (cnt = 0; cnt < 100; cnt++) {
mbed_official 22:fa7e1e2c6eb3 113 write_size = ethernet_write((char *)p->payload, p->len);
mbed_official 22:fa7e1e2c6eb3 114 if (write_size != 0) {
mbed_official 22:fa7e1e2c6eb3 115 break;
mbed_official 22:fa7e1e2c6eb3 116 }
mbed_official 22:fa7e1e2c6eb3 117 osDelay(1);
mbed_official 22:fa7e1e2c6eb3 118 }
mbed_official 22:fa7e1e2c6eb3 119 if (write_size != 0) {
mbed_official 22:fa7e1e2c6eb3 120 for (q = p->next; q != NULL; q = q->next) {
mbed_official 22:fa7e1e2c6eb3 121 (void)ethernet_write((char *)q->payload, q->len);
mbed_official 22:fa7e1e2c6eb3 122 }
mbed_official 22:fa7e1e2c6eb3 123 if (ethernet_send() == 1) {
mbed_official 22:fa7e1e2c6eb3 124 err = ERR_OK;
mbed_official 22:fa7e1e2c6eb3 125 }
mbed_official 22:fa7e1e2c6eb3 126 }
mbed_official 22:fa7e1e2c6eb3 127 }
mbed_official 22:fa7e1e2c6eb3 128
mbed_official 22:fa7e1e2c6eb3 129 return err;
mbed_official 22:fa7e1e2c6eb3 130 }
mbed_official 22:fa7e1e2c6eb3 131
mbed_official 22:fa7e1e2c6eb3 132 static void rza1_recv_callback(void) {
mbed_official 22:fa7e1e2c6eb3 133 sys_sem_signal(&recv_ready_sem);
mbed_official 22:fa7e1e2c6eb3 134 }
mbed_official 22:fa7e1e2c6eb3 135
mbed_official 22:fa7e1e2c6eb3 136 err_t eth_arch_enetif_init(struct netif *netif)
mbed_official 22:fa7e1e2c6eb3 137 {
mbed_official 22:fa7e1e2c6eb3 138 ethernet_cfg_t ethcfg;
mbed_official 22:fa7e1e2c6eb3 139
mbed_official 22:fa7e1e2c6eb3 140 /* set MAC hardware address */
mbed_official 22:fa7e1e2c6eb3 141 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
mbed_official 22:fa7e1e2c6eb3 142 netif->hwaddr[0] = MBED_MAC_ADDR_0;
mbed_official 22:fa7e1e2c6eb3 143 netif->hwaddr[1] = MBED_MAC_ADDR_1;
mbed_official 22:fa7e1e2c6eb3 144 netif->hwaddr[2] = MBED_MAC_ADDR_2;
mbed_official 22:fa7e1e2c6eb3 145 netif->hwaddr[3] = MBED_MAC_ADDR_3;
mbed_official 22:fa7e1e2c6eb3 146 netif->hwaddr[4] = MBED_MAC_ADDR_4;
mbed_official 22:fa7e1e2c6eb3 147 netif->hwaddr[5] = MBED_MAC_ADDR_5;
mbed_official 22:fa7e1e2c6eb3 148 #else
mbed_official 22:fa7e1e2c6eb3 149 mbed_mac_address((char *)netif->hwaddr);
mbed_official 22:fa7e1e2c6eb3 150 #endif
mbed_official 22:fa7e1e2c6eb3 151 netif->hwaddr_len = ETHARP_HWADDR_LEN;
mbed_official 22:fa7e1e2c6eb3 152
mbed_official 22:fa7e1e2c6eb3 153 /* maximum transfer unit */
mbed_official 22:fa7e1e2c6eb3 154 netif->mtu = 1500;
mbed_official 22:fa7e1e2c6eb3 155
mbed_official 22:fa7e1e2c6eb3 156 /* device capabilities */
mbed_official 22:fa7e1e2c6eb3 157 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
mbed_official 22:fa7e1e2c6eb3 158
mbed_official 22:fa7e1e2c6eb3 159 #if LWIP_NETIF_HOSTNAME
mbed_official 22:fa7e1e2c6eb3 160 /* Initialize interface hostname */
mbed_official 22:fa7e1e2c6eb3 161 netif->hostname = "lwiprza1";
mbed_official 22:fa7e1e2c6eb3 162 #endif /* LWIP_NETIF_HOSTNAME */
mbed_official 22:fa7e1e2c6eb3 163
mbed_official 22:fa7e1e2c6eb3 164 netif->name[0] = 'e';
mbed_official 22:fa7e1e2c6eb3 165 netif->name[1] = 'n';
mbed_official 22:fa7e1e2c6eb3 166
mbed_official 22:fa7e1e2c6eb3 167 netif->output = rza1_etharp_output;
mbed_official 22:fa7e1e2c6eb3 168 netif->linkoutput = rza1_low_level_output;
mbed_official 22:fa7e1e2c6eb3 169
mbed_official 22:fa7e1e2c6eb3 170 /* Initialize the hardware */
mbed_official 22:fa7e1e2c6eb3 171 ethcfg.int_priority = 6;
mbed_official 22:fa7e1e2c6eb3 172 ethcfg.recv_cb = &rza1_recv_callback;
mbed_official 22:fa7e1e2c6eb3 173 ethcfg.ether_mac = (char *)netif->hwaddr;
mbed_official 22:fa7e1e2c6eb3 174 ethernetext_init(&ethcfg);
mbed_official 22:fa7e1e2c6eb3 175
mbed_official 22:fa7e1e2c6eb3 176 /* semaphore */
mbed_official 22:fa7e1e2c6eb3 177 sys_sem_new(&recv_ready_sem, 0);
mbed_official 22:fa7e1e2c6eb3 178
mbed_official 22:fa7e1e2c6eb3 179 /* task */
mbed_official 22:fa7e1e2c6eb3 180 sys_thread_new("rza1_recv_task", rza1_recv_task, netif, DEFAULT_THREAD_STACKSIZE, RECV_TASK_PRI);
mbed_official 22:fa7e1e2c6eb3 181 sys_thread_new("rza1_phy_task", rza1_phy_task, netif, DEFAULT_THREAD_STACKSIZE, PHY_TASK_PRI);
mbed_official 22:fa7e1e2c6eb3 182
mbed_official 22:fa7e1e2c6eb3 183 return ERR_OK;
mbed_official 22:fa7e1e2c6eb3 184 }
mbed_official 22:fa7e1e2c6eb3 185
mbed_official 22:fa7e1e2c6eb3 186 void eth_arch_enable_interrupts(void) {
mbed_official 22:fa7e1e2c6eb3 187 ethernetext_start_stop(1);
mbed_official 22:fa7e1e2c6eb3 188 }
mbed_official 22:fa7e1e2c6eb3 189
mbed_official 22:fa7e1e2c6eb3 190 void eth_arch_disable_interrupts(void) {
mbed_official 22:fa7e1e2c6eb3 191 ethernetext_start_stop(0);
mbed_official 22:fa7e1e2c6eb3 192 }