BlinkenArea - GitList
Repositories
Blog
Wiki
mips_sys
Code
Commits
Branches
Tags
Search
Tree:
c906a48
Branches
Tags
master
mips_sys
fw
eth.c
implemented ethernet RX busmaster -> packet reception working
Stefan Schuermans
commited
c906a48
at 2012-03-03 23:42:55
eth.c
Blame
History
Raw
#include "eth.h" static volatile unsigned int *const eth_ptr = (volatile unsigned int *)0x80000400; static unsigned int eth_idx_hw; static unsigned int eth_rx_buf[2][256]; static unsigned int *eth_rx_pos; /** * @brief provide new receive buffer * @param[in] ptr pointer to new receive buffer * @param[in] sz size of new receive buffer */ static void eth_rx_new_buf(void *ptr, unsigned int sz) { eth_ptr[4] = (unsigned int)ptr; /* new start */ eth_ptr[5] = (unsigned int)ptr + sz; /* new end */ eth_ptr[6] = 1; /* set flag */ while (eth_ptr[6] == 1); /* wait until processed */ } /** * @brief get buffer position of ethernet receiver * @return current buffer position of ethernet receiver * * eveything before this position can be read */ static void * eth_rx_get_pos(void) { return (void *)eth_ptr[0]; } /** initialize receiver */ void eth_rx_init(void) { // give buffer 0 to HW eth_idx_hw = 0; eth_rx_new_buf(eth_rx_buf[0], sizeof(eth_rx_buf[0])); // buffer 1 owned by SW is empty eth_rx_buf[1][0] = 0; eth_rx_pos = eth_rx_buf[1]; } /** * @brief get next received packet * @param[out] *pptr pointer to packet data * @param[out] *psz size of packet * @return if a packet was received */ int eth_rx(void **pptr, unsigned int *psz) { // current SW buffer is empty and HW buffer contains a packet if (*eth_rx_pos == 0 && eth_rx_get_pos() != eth_rx_buf[eth_idx_hw]) { // swap buffers eth_idx_hw = 1 - eth_idx_hw; // give new HW buffer to HW eth_rx_new_buf(eth_rx_buf[eth_idx_hw], sizeof(eth_rx_buf[eth_idx_hw])); // start reading packet data at begin of new SW buffer eth_rx_pos = eth_rx_buf[1 - eth_idx_hw]; } // SW buffer contains a packet if (*eth_rx_pos > 0) { // return size and pointer, advance position *psz = *eth_rx_pos; eth_rx_pos++; *pptr = eth_rx_pos; eth_rx_pos += *psz >> 2; return 1; } // no packet received return 0; }