#include #include "skeleton.h" #include #define MAX_ADDR_LEN 6 struct rt_skeleton_eth { /* inherit from ethernet device */ struct eth_device parent; /* interface address info. */ rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ }; static struct rt_skeleton_eth _skeleton_device; void rt_skeleton_isr(int irqno) { rt_uint32_t status; /* read status */ /* Received the coming packet */ if (status) { /* disable receive interrupt */ /* a frame has been received */ eth_device_ready(&(_skeleton_device.parent)); } /* Transmit Interrupt check */ if (status) { } } static rt_err_t rt_skeleton_init(rt_device_t dev) { return RT_EOK; } static rt_err_t rt_skeleton_open(rt_device_t dev, rt_uint16_t oflag) { return RT_EOK; } static rt_err_t rt_skeleton_close(rt_device_t dev) { return RT_EOK; } static rt_size_t rt_skeleton_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { rt_set_errno(-RT_ENOSYS); return 0; } static rt_size_t rt_skeleton_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { rt_set_errno(-RT_ENOSYS); return 0; } static rt_err_t rt_skeleton_control(rt_device_t dev, int cmd, void *args) { struct rt_skeleton_eth *eth; eth = (struct rt_skeleton_eth*)dev; RT_ASSERT(eth != RT_NULL); switch (cmd) { case NIOCTL_GADDR: /* get mac address */ if (args) rt_memcpy(args, _skeleton_device.dev_addr, 6); else return -RT_ERROR; break; default : break; } return RT_EOK; } rt_err_t rt_skeleton_tx( rt_device_t dev, struct pbuf* p) { { /* q traverses through linked list of pbuf's * This list MUST consist of a single packet ONLY */ struct pbuf *q; rt_uint16_t pbuf_index = 0; rt_uint8_t word[2], word_index = 0; q = p; /* Write data into hardware, two bytes at a time * Handling pbuf's with odd number of bytes correctly * No attempt to optimize for speed has been made */ while (q) { if (pbuf_index < q->len) { word[word_index++] = ((u8_t*)q->payload)[pbuf_index++]; if (word_index == 2) { /* write data to hardware */ word_index = 0; } } else { q = q->next; pbuf_index = 0; } } /* One byte could still be unsent */ if (word_index == 1) { /* write data to hardware */ } } return RT_EOK; } struct pbuf *rt_skeleton_rx(rt_device_t dev) { struct pbuf* p; rt_uint32_t rxbyte; /* init p pointer */ p = RT_NULL; rxbyte = 0; /* get eth status */ if (rxbyte) /* there is data received */ { rt_uint16_t rx_len; rt_uint16_t* data; /* get recieved packet length */ rx_len = 0; /* allocate buffer */ p = pbuf_alloc(PBUF_LINK, rx_len, PBUF_RAM); if (p != RT_NULL) { struct pbuf* q; rt_int32_t len; for (q = p; q != RT_NULL; q= q->next) { data = (rt_uint16_t*)q->payload; len = q->len; while (len > 0) { *data = 0; /* read data from hardware */ data ++; len -= 2; } } } else { rt_uint16_t dummy; rt_int32_t len; /* no pbuf, discard data from EMAC */ data = &dummy; len = rx_len; while (len > 0) { *data = 0; /* read from hardware */ len -= 2; } } } else { /* restore receive interrupt */ } return p; } void rt_hw_skeleton_init() { /* set default MAC address */ _skeleton_device.dev_addr[0] = 0x00; _skeleton_device.dev_addr[1] = 0x60; _skeleton_device.dev_addr[2] = 0x6E; _skeleton_device.dev_addr[3] = 0x11; _skeleton_device.dev_addr[4] = 0x22; _skeleton_device.dev_addr[5] = 0x33; /* set RT-Thread device interface */ _skeleton_device.parent.parent.init = rt_skeleton_init; _skeleton_device.parent.parent.open = rt_skeleton_open; _skeleton_device.parent.parent.close = rt_skeleton_close; _skeleton_device.parent.parent.read = rt_skeleton_read; _skeleton_device.parent.parent.write = rt_skeleton_write; _skeleton_device.parent.parent.control = rt_skeleton_control; _skeleton_device.parent.parent.user_data = RT_NULL; /* set ethernet interface */ _skeleton_device.parent.eth_rx = rt_skeleton_rx; _skeleton_device.parent.eth_tx = rt_skeleton_tx; eth_device_init(&(_skeleton_device.parent), "e0"); }