rt-thread-official/components/net/lwip-1.3.2/src/netif/skeleton.c

212 lines
4.6 KiB
C

#include <rtthread.h>
#include "skeleton.h"
#include <netif/ethernetif.h>
#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");
}