git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1193 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
c9bfcaa15e
commit
ea9916ae79
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# Compiler options here.
|
# Compiler options here.
|
||||||
ifeq ($(USE_OPT),)
|
ifeq ($(USE_OPT),)
|
||||||
USE_OPT = -O2 -ggdb -fomit-frame-pointer -mabi=apcs-gnu
|
USE_OPT = -O0 -ggdb -fomit-frame-pointer -mabi=apcs-gnu
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# C++ specific options here (added to USE_OPT).
|
# C++ specific options here (added to USE_OPT).
|
||||||
|
|
|
@ -47,21 +47,18 @@ static const struct uip_eth_addr macaddr = {
|
||||||
*/
|
*/
|
||||||
static void network_device_send(void) {
|
static void network_device_send(void) {
|
||||||
int i;
|
int i;
|
||||||
MACTransmitDescriptor *tdp;
|
MACTransmitDescriptor td;
|
||||||
|
|
||||||
for (i = 0; i < SEND_RETRY_MAX; i++) {
|
for (i = 0; i < SEND_RETRY_MAX; i++) {
|
||||||
if ((tdp = macWaitTransmitDescriptor(&MAC1, uip_len, TIME_IMMEDIATE)) != NULL) {
|
if (macWaitTransmitDescriptor(Ð1, &td, TIME_IMMEDIATE) == RDY_OK) {
|
||||||
uint8_t *bp = macGetTransmitBuffer(tdp);
|
|
||||||
|
|
||||||
if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN)
|
if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN)
|
||||||
memcpy(bp, &uip_buf[0], uip_len);
|
macWriteTransmitDescriptor(&td, uip_buf, uip_len);
|
||||||
else {
|
else {
|
||||||
memcpy(bp, &uip_buf[0], UIP_LLH_LEN + UIP_TCPIP_HLEN);
|
macWriteTransmitDescriptor(&td, uip_buf, UIP_LLH_LEN + UIP_TCPIP_HLEN);
|
||||||
memcpy(bp + UIP_LLH_LEN + UIP_TCPIP_HLEN,
|
macWriteTransmitDescriptor(&td, uip_appdata,
|
||||||
uip_appdata,
|
uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN));
|
||||||
uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN));
|
|
||||||
}
|
}
|
||||||
macReleaseTransmitDescriptor(&MAC1, tdp);
|
macReleaseTransmitDescriptor(&td);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chThdSleep(SEND_RETRY_INTERVAL);
|
chThdSleep(SEND_RETRY_INTERVAL);
|
||||||
|
@ -73,15 +70,14 @@ static void network_device_send(void) {
|
||||||
* uIP receive function wrapping the EMAC function.
|
* uIP receive function wrapping the EMAC function.
|
||||||
*/
|
*/
|
||||||
static size_t network_device_read(void) {
|
static size_t network_device_read(void) {
|
||||||
MACReceiveDescriptor *rdp;
|
MACReceiveDescriptor rd;
|
||||||
size_t size;
|
size_t size;
|
||||||
uint8_t *bp;
|
|
||||||
|
|
||||||
if ((rdp = macWaitReceiveDescriptor(&MAC1, &size, TIME_IMMEDIATE)) == NULL)
|
if (macWaitReceiveDescriptor(Ð1, &rd, TIME_IMMEDIATE) != RDY_OK)
|
||||||
return 0;
|
return 0;
|
||||||
bp = macGetReceiveBuffer(rdp);
|
size = rd.rd_size;
|
||||||
memcpy(&uip_buf[0], bp, size);
|
macReadReceiveDescriptor(&rd, uip_buf, size);
|
||||||
macReleaseReceiveDescriptor(&MAC1, rdp);
|
macReleaseReceiveDescriptor(&rd);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +109,7 @@ static void PeriodicTimerHandler(eventid_t id) {
|
||||||
static void ARPTimerHandler(eventid_t id) {
|
static void ARPTimerHandler(eventid_t id) {
|
||||||
|
|
||||||
uip_arp_timer();
|
uip_arp_timer();
|
||||||
(void)macPollLinkStatus(&MAC1);
|
(void)macPollLinkStatus(Ð1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -156,7 +152,7 @@ msg_t WebThread(void *p) {
|
||||||
/*
|
/*
|
||||||
* Event sources setup.
|
* Event sources setup.
|
||||||
*/
|
*/
|
||||||
chEvtRegister(macGetReceiveEventSource(&MAC1), &el0, FRAME_RECEIVED_ID);
|
chEvtRegister(macGetReceiveEventSource(Ð1), &el0, FRAME_RECEIVED_ID);
|
||||||
chEvtPend(EVENT_MASK(FRAME_RECEIVED_ID)); /* In case some frames are already buffered */
|
chEvtPend(EVENT_MASK(FRAME_RECEIVED_ID)); /* In case some frames are already buffered */
|
||||||
|
|
||||||
evtInit(&evt1, MS2ST(500));
|
evtInit(&evt1, MS2ST(500));
|
||||||
|
@ -170,8 +166,8 @@ msg_t WebThread(void *p) {
|
||||||
/*
|
/*
|
||||||
* EMAC settings.
|
* EMAC settings.
|
||||||
*/
|
*/
|
||||||
macSetAddress(&MAC1, &macaddr.addr[0]);
|
macSetAddress(Ð1, &macaddr.addr[0]);
|
||||||
(void)macPollLinkStatus(&MAC1);
|
(void)macPollLinkStatus(Ð1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* uIP initialization.
|
* uIP initialization.
|
||||||
|
|
58
os/io/mac.c
58
os/io/mac.c
|
@ -77,33 +77,32 @@ void macSetAddress(MACDriver *macp, const uint8_t *p) {
|
||||||
* invoking thread is queued until one is freed.
|
* invoking thread is queued until one is freed.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[in] size size of the frame to be transmitted
|
* @param[out] tdp pointer to a @p MACTransmitDescriptor structure
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
* - @a TIME_IMMEDIATE immediate timeout.
|
* - @a TIME_IMMEDIATE immediate timeout.
|
||||||
* - @a TIME_INFINITE no timeout.
|
* - @a TIME_INFINITE no timeout.
|
||||||
* .
|
* .
|
||||||
* @return A pointer to a @p MACTransmitDescriptor structure or @p NULL if
|
* @return The operation status.
|
||||||
* the operation timed out.
|
* @retval RDY_OK the descriptor was obtained.
|
||||||
|
* @retval RDY_TIMEOUT the operation timed out, descriptor not initialized.
|
||||||
*/
|
*/
|
||||||
MACTransmitDescriptor *macWaitTransmitDescriptor(MACDriver *macp,
|
msg_t macWaitTransmitDescriptor(MACDriver *macp,
|
||||||
size_t size,
|
MACTransmitDescriptor *tdp,
|
||||||
systime_t time) {
|
systime_t time) {
|
||||||
MACTransmitDescriptor *tdp;
|
msg_t msg;
|
||||||
|
|
||||||
while (((tdp = max_lld_get_transmit_descriptor(macp, size)) == NULL) &&
|
while (((msg = max_lld_get_transmit_descriptor(macp, tdp)) != RDY_OK) &&
|
||||||
(time > 0)) {
|
(time > 0)) {
|
||||||
chSysLock();
|
chSysLock();
|
||||||
systime_t now = chTimeNow();
|
systime_t now = chTimeNow();
|
||||||
if (chSemWaitTimeoutS(&tdsem, time) == RDY_TIMEOUT) {
|
if ((msg = chSemWaitTimeoutS(&tdsem, time)) == RDY_TIMEOUT)
|
||||||
tdp = NULL;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (time != TIME_INFINITE)
|
if (time != TIME_INFINITE)
|
||||||
time -= (chTimeNow() - now);
|
time -= (chTimeNow() - now);
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
return tdp;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,10 +112,9 @@ MACTransmitDescriptor *macWaitTransmitDescriptor(MACDriver *macp,
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
||||||
*/
|
*/
|
||||||
void macReleaseTransmitDescriptor(MACDriver *macp,
|
void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) {
|
||||||
MACTransmitDescriptor *tdp) {
|
|
||||||
|
|
||||||
mac_lld_release_transmit_descriptor(macp, tdp);
|
mac_lld_release_transmit_descriptor(tdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,47 +124,45 @@ void macReleaseTransmitDescriptor(MACDriver *macp,
|
||||||
* until one is received.
|
* until one is received.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[out szp size of the received frame
|
* @param[out] rdp pointer to a @p MACReceiveDescriptor structure
|
||||||
* @param[in] time the number of ticks before the operation timeouts,
|
* @param[in] time the number of ticks before the operation timeouts,
|
||||||
* the following special values are allowed:
|
* the following special values are allowed:
|
||||||
* - @a TIME_IMMEDIATE immediate timeout.
|
* - @a TIME_IMMEDIATE immediate timeout.
|
||||||
* - @a TIME_INFINITE no timeout.
|
* - @a TIME_INFINITE no timeout.
|
||||||
* .
|
* .
|
||||||
* @return A pointer to a @p MACReceiveDescriptor structure or @p NULL if
|
* @return The operation status.
|
||||||
* the operation timed out or some transient error happened.
|
* @retval RDY_OK the descriptor was obtained.
|
||||||
|
* @retval RDY_TIMEOUT the operation timed out, descriptor not initialized.
|
||||||
*/
|
*/
|
||||||
MACReceiveDescriptor *macWaitReceiveDescriptor(MACDriver *macp,
|
msg_t macWaitReceiveDescriptor(MACDriver *macp,
|
||||||
size_t *szp,
|
MACReceiveDescriptor *rdp,
|
||||||
systime_t time) {
|
systime_t time) {
|
||||||
MACReceiveDescriptor *rdp;
|
msg_t msg;
|
||||||
|
|
||||||
while (((rdp = max_lld_get_receive_descriptor(macp, szp)) == NULL) &&
|
while (((msg = max_lld_get_receive_descriptor(macp, rdp)) != RDY_OK) &&
|
||||||
(time > 0)) {
|
(time > 0)) {
|
||||||
chSysLock();
|
chSysLock();
|
||||||
systime_t now = chTimeNow();
|
systime_t now = chTimeNow();
|
||||||
if (chSemWaitTimeoutS(&rdsem, time) == RDY_TIMEOUT) {
|
if ((msg = chSemWaitTimeoutS(&rdsem, time)) == RDY_TIMEOUT)
|
||||||
rdp = NULL;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (time != TIME_INFINITE)
|
if (time != TIME_INFINITE)
|
||||||
time -= (chTimeNow() - now);
|
time -= (chTimeNow() - now);
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
return rdp;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a receive descriptor.
|
* @brief Releases a receive descriptor.
|
||||||
* @details The descriptor and its buffer is made available for more incoming
|
* @details The descriptor and its buffer are made available for more incoming
|
||||||
* frames.
|
* frames.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
||||||
*/
|
*/
|
||||||
void macReleaseReceiveDescriptor(MACDriver *macp,
|
void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) {
|
||||||
MACReceiveDescriptor *rdp) {
|
|
||||||
|
|
||||||
mac_lld_release_receive_descriptor(macp, rdp);
|
mac_lld_release_receive_descriptor(rdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
64
os/io/mac.h
64
os/io/mac.h
|
@ -30,23 +30,7 @@
|
||||||
#include "mac_lld.h"
|
#include "mac_lld.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the buffer associated to a @p MACTransmitDescriptor.
|
* @brief Returns the received frames event source.
|
||||||
*
|
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
|
||||||
* @return The pointer to the transmit buffer.
|
|
||||||
*/
|
|
||||||
#define macGetTransmitBuffer(tdp) mac_lld_get_transmit_buffer(tdp)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the buffer associated to a @p MACReceiveDescriptor.
|
|
||||||
*
|
|
||||||
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
|
||||||
* @return The pointer to the receive buffer.
|
|
||||||
*/
|
|
||||||
#define macGetReceiveBuffer(rdp) mac_lld_get_receive_buffer(rdp)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @bief Returns the received frames event source.
|
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @return The pointer to the @p EventSource structure.
|
* @return The pointer to the @p EventSource structure.
|
||||||
|
@ -55,24 +39,46 @@
|
||||||
#define macGetReceiveEventSource(macp) (&(macp)->md_rdevent)
|
#define macGetReceiveEventSource(macp) (&(macp)->md_rdevent)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes to a transmit descriptor's stream.
|
||||||
|
*
|
||||||
|
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
|
||||||
|
* @param[in] buf pointer to the buffer containing the data to be written
|
||||||
|
* @param[in] size number of bytes to be written
|
||||||
|
* @return The number of bytes written into the descriptor's stream, this
|
||||||
|
* value can be less than the amount specified in the parameter
|
||||||
|
* @p size if the maximum frame size is reached.
|
||||||
|
*/
|
||||||
|
#define macWriteTransmitDescriptor(tdp, buf, size) \
|
||||||
|
mac_lld_write_transmit_descriptor(tdp, buf, size)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads from a receive descriptor's stream.
|
||||||
|
*
|
||||||
|
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
|
||||||
|
* @param[in] buf pointer to the buffer that will receive the read data
|
||||||
|
* @param[in] size number of bytes to be read
|
||||||
|
* @return The number of bytes read from the descriptor's stream, this
|
||||||
|
* value can be less than the amount specified in the parameter
|
||||||
|
* @p size if there are no more bytes to read.
|
||||||
|
*/
|
||||||
|
#define macReadReceiveDescriptor(rdp, buf, size) \
|
||||||
|
mac_lld_read_receive_descriptor(rdp, buf, size)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void macInit(void);
|
void macInit(void);
|
||||||
void macObjectInit(MACDriver *macp);
|
void macObjectInit(MACDriver *macp);
|
||||||
void macSetAddress(MACDriver *macp, const uint8_t *p);
|
void macSetAddress(MACDriver *macp, const uint8_t *p);
|
||||||
void macStart(MACDriver *macp);
|
msg_t macWaitTransmitDescriptor(MACDriver *macp,
|
||||||
void macStop(MACDriver *macp);
|
MACTransmitDescriptor *tdp,
|
||||||
MACTransmitDescriptor *macWaitTransmitDescriptor(MACDriver *macp,
|
systime_t time);
|
||||||
size_t size,
|
void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp);
|
||||||
systime_t time);
|
msg_t macWaitReceiveDescriptor(MACDriver *macp,
|
||||||
void macReleaseTransmitDescriptor(MACDriver *macp,
|
MACReceiveDescriptor *rdp,
|
||||||
MACTransmitDescriptor *tdp);
|
systime_t time);
|
||||||
MACReceiveDescriptor *macWaitReceiveDescriptor(MACDriver *macp,
|
void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp);
|
||||||
size_t *szp,
|
|
||||||
systime_t time);
|
|
||||||
void macReleaseReceiveDescriptor(MACDriver *macp,
|
|
||||||
MACReceiveDescriptor *rdp);
|
|
||||||
bool_t macPollLinkStatus(MACDriver *macp);
|
bool_t macPollLinkStatus(MACDriver *macp);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <ch.h>
|
#include <ch.h>
|
||||||
#include <mac.h>
|
#include <mac.h>
|
||||||
#include <phy.h>
|
#include <phy.h>
|
||||||
|
@ -32,9 +34,9 @@
|
||||||
#include "at91lib/aic.h"
|
#include "at91lib/aic.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief EMAC object.
|
* @brief Ethernet driver 1.
|
||||||
*/
|
*/
|
||||||
MACDriver MAC1;
|
MACDriver ETH1;
|
||||||
|
|
||||||
#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | AT91C_PB1_ETXEN | \
|
#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | AT91C_PB1_ETXEN | \
|
||||||
AT91C_PB2_ETX0 | AT91C_PB3_ETX1 | \
|
AT91C_PB2_ETX0 | AT91C_PB3_ETX1 | \
|
||||||
|
@ -56,13 +58,16 @@ static bool_t link_up;
|
||||||
|
|
||||||
static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10};
|
static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10};
|
||||||
|
|
||||||
static MACReceiveDescriptor rd[EMAC_RECEIVE_BUFFERS] __attribute__((aligned(8)));
|
static EMACDescriptor *rxptr;
|
||||||
static uint8_t rb[EMAC_RECEIVE_BUFFERS * EMAC_RECEIVE_BUFFERS_SIZE] __attribute__((aligned(8)));
|
static EMACDescriptor *txptr;
|
||||||
static MACReceiveDescriptor *rxptr;
|
static EMACDescriptor rd[EMAC_RECEIVE_DESCRIPTORS]
|
||||||
|
__attribute__((aligned(8)));
|
||||||
static MACTransmitDescriptor td[EMAC_TRANSMIT_BUFFERS] __attribute__((aligned(8)));
|
static EMACDescriptor td[EMAC_TRANSMIT_DESCRIPTORS]
|
||||||
static uint8_t tb[EMAC_TRANSMIT_BUFFERS * EMAC_TRANSMIT_BUFFERS_SIZE] __attribute__((aligned(8)));
|
__attribute__((aligned(8)));
|
||||||
static MACTransmitDescriptor *txptr;
|
static uint8_t rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE]
|
||||||
|
__attribute__((aligned(8)));
|
||||||
|
static uint8_t tb[EMAC_TRANSMIT_DESCRIPTORS * EMAC_TRANSMIT_BUFFERS_SIZE]
|
||||||
|
__attribute__((aligned(8)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,9 +87,9 @@ static void serve_interrupt(void) {
|
||||||
if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
|
if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
|
||||||
if (rsr & AT91C_EMAC_REC) {
|
if (rsr & AT91C_EMAC_REC) {
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
chSemResetI(&MAC1.md_rdsem, 0);
|
chSemResetI(Ð1.md_rdsem, 0);
|
||||||
#if CH_USE_EVENTS
|
#if CH_USE_EVENTS
|
||||||
chEvtBroadcastI(&MAC1.md_rdevent);
|
chEvtBroadcastI(Ð1.md_rdevent);
|
||||||
#endif
|
#endif
|
||||||
chSysUnlockFromIsr();
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
|
@ -94,7 +99,7 @@ static void serve_interrupt(void) {
|
||||||
if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
|
if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
|
||||||
if (tsr & AT91C_EMAC_COMP) {
|
if (tsr & AT91C_EMAC_COMP) {
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
chSemResetI(&MAC1.md_tdsem, 0);
|
chSemResetI(Ð1.md_tdsem, 0);
|
||||||
chSysUnlockFromIsr();
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
|
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
|
||||||
|
@ -121,28 +126,28 @@ void mac_lld_init(void) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
phyInit();
|
phyInit();
|
||||||
macObjectInit(&MAC1);
|
macObjectInit(Ð1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Buffers initialization.
|
* Buffers initialization.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < EMAC_RECEIVE_BUFFERS; i++) {
|
for (i = 0; i < EMAC_RECEIVE_DESCRIPTORS; i++) {
|
||||||
rd[i].w1 = (uint32_t)&rb[i * EMAC_RECEIVE_BUFFERS_SIZE];
|
rd[i].w1 = (uint32_t)&rb[i * EMAC_RECEIVE_BUFFERS_SIZE];
|
||||||
rd[i].w2 = 0;
|
rd[i].w2 = 0;
|
||||||
}
|
}
|
||||||
rd[EMAC_RECEIVE_BUFFERS - 1].w1 |= W1_R_WRAP;
|
rd[EMAC_RECEIVE_DESCRIPTORS - 1].w1 |= W1_R_WRAP;
|
||||||
rxptr = rd;
|
rxptr = rd;
|
||||||
for (i = 0; i < EMAC_TRANSMIT_BUFFERS; i++) {
|
for (i = 0; i < EMAC_TRANSMIT_DESCRIPTORS; i++) {
|
||||||
td[i].w1 = (uint32_t)&tb[i * EMAC_TRANSMIT_BUFFERS_SIZE];
|
td[i].w1 = (uint32_t)&tb[i * EMAC_TRANSMIT_BUFFERS_SIZE];
|
||||||
td[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_LAST_BUFFER | W2_T_USED;
|
td[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_LAST_BUFFER | W2_T_USED;
|
||||||
}
|
}
|
||||||
td[EMAC_TRANSMIT_BUFFERS - 1].w2 |= W2_T_WRAP;
|
td[EMAC_TRANSMIT_DESCRIPTORS - 1].w2 |= W2_T_WRAP;
|
||||||
txptr = td;
|
txptr = td;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Associated PHY initialization.
|
* Associated PHY initialization.
|
||||||
*/
|
*/
|
||||||
phyReset(&MAC1);
|
phyReset(Ð1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EMAC pins setup and clock enable. Note, PB18 is not included because it is
|
* EMAC pins setup and clock enable. Note, PB18 is not included because it is
|
||||||
|
@ -168,15 +173,15 @@ void mac_lld_init(void) {
|
||||||
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE |
|
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE |
|
||||||
AT91C_EMAC_RE |
|
AT91C_EMAC_RE |
|
||||||
AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/
|
AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/
|
||||||
mac_lld_set_address(&MAC1, default_mac);
|
mac_lld_set_address(Ð1, default_mac);
|
||||||
|
|
||||||
#if PHY_HARDWARE == PHY_MICREL_KS8721
|
#if PHY_HARDWARE == PHY_MICREL_KS8721
|
||||||
/*
|
/*
|
||||||
* PHY device identification.
|
* PHY device identification.
|
||||||
*/
|
*/
|
||||||
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
|
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
|
||||||
if ((phyGet(&MAC1, MII_PHYSID1) != (MII_KS8721_ID >> 16)) ||
|
if ((phyGet(Ð1, MII_PHYSID1) != (MII_KS8721_ID >> 16)) ||
|
||||||
((phyGet(&MAC1, MII_PHYSID2) & 0xFFF0) != (MII_KS8721_ID & 0xFFF0)))
|
((phyGet(Ð1, MII_PHYSID2) & 0xFFF0) != (MII_KS8721_ID & 0xFFF0)))
|
||||||
chSysHalt();
|
chSysHalt();
|
||||||
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
|
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
|
||||||
#endif
|
#endif
|
||||||
|
@ -213,91 +218,104 @@ void mac_lld_set_address(MACDriver *macp, const uint8_t *p) {
|
||||||
* returned.
|
* returned.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[in] size size of the frame to be transmitted
|
* @param[out] tdp pointer to a @p MACTransmitDescriptor structure
|
||||||
* @return A pointer to a @p MACTransmitDescriptor structure or @p NULL if
|
* @return The operation status.
|
||||||
* a descriptor is not available.
|
* @retval RDY_OK the descriptor was obtained.
|
||||||
|
* @retval RDY_TIMEOUT descriptor not available.
|
||||||
*/
|
*/
|
||||||
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp,
|
msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
|
||||||
size_t size) {
|
MACTransmitDescriptor *tdp) {
|
||||||
MACTransmitDescriptor *tdp;
|
EMACDescriptor *edp;
|
||||||
|
|
||||||
chDbgAssert(size <= EMAC_TRANSMIT_BUFFERS_SIZE,
|
|
||||||
"max_lld_get_transmit_descriptor(), #1",
|
|
||||||
"unexpected size");
|
|
||||||
|
|
||||||
if (!link_up)
|
if (!link_up)
|
||||||
return NULL;
|
return RDY_TIMEOUT;
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
tdp = txptr;
|
edp = txptr;
|
||||||
chDbgAssert((tdp->w2 & W2_T_USED) && !(tdp->w2 & W2_T_LOCKED),
|
if (!(edp->w2 & W2_T_USED) || (edp->w2 & W2_T_LOCKED)) {
|
||||||
"max_lld_get_transmit_descriptor(), #2", "buffer not available");
|
|
||||||
if (!(tdp->w2 & W2_T_USED) || (tdp->w2 & W2_T_LOCKED)) {
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return NULL;
|
return RDY_TIMEOUT;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Set the buffer size and configuration, the buffer is also marked
|
* Set the buffer size and configuration, the buffer is also marked
|
||||||
* as locked.
|
* as locked.
|
||||||
*/
|
*/
|
||||||
tdp->w2 = size | W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER;
|
if (++txptr >= &td[EMAC_TRANSMIT_DESCRIPTORS]) {
|
||||||
if (++txptr >= &td[EMAC_TRANSMIT_BUFFERS]) {
|
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER | W2_T_WRAP;
|
||||||
tdp->w2 |= W2_T_WRAP;
|
|
||||||
txptr = td;
|
txptr = td;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return tdp;
|
tdp->td_offset = 0;
|
||||||
|
tdp->td_size = EMAC_TRANSMIT_BUFFERS_SIZE;
|
||||||
|
tdp->td_physdesc = edp;
|
||||||
|
return RDY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes to a transmit descriptor's stream.
|
||||||
|
*
|
||||||
|
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
|
||||||
|
* @param[in] buf pointer to the buffer cointaining the data to be written
|
||||||
|
* @param[in] size number of bytes to be written
|
||||||
|
* @return The number of bytes written into the descriptor's stream, this
|
||||||
|
* value can be less than the amount specified in the parameter
|
||||||
|
* @p size if the maximum frame size is reached.
|
||||||
|
*/
|
||||||
|
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
|
||||||
|
uint8_t *buf,
|
||||||
|
size_t size) {
|
||||||
|
|
||||||
|
if (size > tdp->td_size - tdp->td_offset)
|
||||||
|
size = tdp->td_size - tdp->td_offset;
|
||||||
|
if (size > 0) {
|
||||||
|
memcpy((uint8_t *)(tdp->td_physdesc->w1 & W1_T_ADDRESS_MASK) +
|
||||||
|
tdp->td_offset,
|
||||||
|
buf, size);
|
||||||
|
tdp->td_offset += size;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a transmit descriptor and starts the transmission of the
|
* @brief Releases a transmit descriptor and starts the transmission of the
|
||||||
* enqueued data as a single frame.
|
* enqueued data as a single frame.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
||||||
* @param[in]
|
|
||||||
*/
|
*/
|
||||||
void mac_lld_release_transmit_descriptor(MACDriver *macp,
|
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
|
||||||
MACTransmitDescriptor *tdp) {
|
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
tdp->w2 &= ~(W2_T_LOCKED | W2_T_USED);
|
tdp->td_physdesc->w2 = (tdp->td_physdesc->w2 &
|
||||||
|
~(W2_T_LOCKED | W2_T_USED | W2_T_LENGTH_MASK)) |
|
||||||
|
tdp->td_offset;
|
||||||
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
|
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the buffer associated to a @p MACTransmitDescriptor.
|
* @brief Returns a receive descriptor.
|
||||||
*
|
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
|
||||||
* @return The pointer to the transmit buffer.
|
|
||||||
*/
|
|
||||||
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp) {
|
|
||||||
|
|
||||||
return (uint8_t *)(tdp->w1 & W1_T_ADDRESS_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a received frame.
|
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[out szp size of the received frame
|
* @param[out] rdp pointer to a @p MACReceiveDescriptor structure
|
||||||
* @return A pointer to a @p MACReceiveDescriptor structure or @p NULL if
|
* @return The operation status.
|
||||||
* the operation timed out or some transient error happened.
|
* @retval RDY_OK the descriptor was obtained.
|
||||||
|
* @retval RDY_TIMEOUT descriptor not available.
|
||||||
*/
|
*/
|
||||||
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp,
|
msg_t max_lld_get_receive_descriptor(MACDriver *macp,
|
||||||
size_t *szp) {
|
MACReceiveDescriptor *rdp) {
|
||||||
unsigned n;
|
unsigned n;
|
||||||
MACReceiveDescriptor *rdp;
|
EMACDescriptor *edp;
|
||||||
|
|
||||||
n = EMAC_RECEIVE_BUFFERS;
|
n = EMAC_RECEIVE_DESCRIPTORS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skips unused buffers, if any.
|
* Skips unused buffers, if any.
|
||||||
*/
|
*/
|
||||||
skip:
|
skip:
|
||||||
while ((n > 0) && !(rxptr->w1 & W1_R_OWNERSHIP)) {
|
while ((n > 0) && !(rxptr->w1 & W1_R_OWNERSHIP)) {
|
||||||
if (++rxptr >= &rd[EMAC_RECEIVE_BUFFERS])
|
if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
|
||||||
rxptr = rd;
|
rxptr = rd;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +326,7 @@ skip:
|
||||||
while ((n > 0) && (rxptr->w1 & W1_R_OWNERSHIP) &&
|
while ((n > 0) && (rxptr->w1 & W1_R_OWNERSHIP) &&
|
||||||
!(rxptr->w2 & W2_R_FRAME_START)) {
|
!(rxptr->w2 & W2_R_FRAME_START)) {
|
||||||
rxptr->w1 &= ~W1_R_OWNERSHIP;
|
rxptr->w1 &= ~W1_R_OWNERSHIP;
|
||||||
if (++rxptr >= &rd[EMAC_RECEIVE_BUFFERS])
|
if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
|
||||||
rxptr = rd;
|
rxptr = rd;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
|
@ -318,7 +336,7 @@ skip:
|
||||||
* or holes...
|
* or holes...
|
||||||
*/
|
*/
|
||||||
restart:
|
restart:
|
||||||
rdp = rxptr;
|
edp = rxptr;
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
if (!(rxptr->w1 & W1_R_OWNERSHIP))
|
if (!(rxptr->w1 & W1_R_OWNERSHIP))
|
||||||
goto skip; /* Empty buffer for some reason... */
|
goto skip; /* Empty buffer for some reason... */
|
||||||
|
@ -327,58 +345,88 @@ restart:
|
||||||
* End Of Frame found.
|
* End Of Frame found.
|
||||||
*/
|
*/
|
||||||
if (rxptr->w2 & W2_R_FRAME_END) {
|
if (rxptr->w2 & W2_R_FRAME_END) {
|
||||||
*szp = rxptr->w2 & W2_T_LENGTH_MASK;
|
rdp->rd_offset = 0;
|
||||||
return rdp;
|
rdp->rd_size = rxptr->w2 & W2_T_LENGTH_MASK;
|
||||||
|
rdp->rd_physdesc = edp;
|
||||||
|
return RDY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rdp != rxptr) && (rxptr->w2 & W2_R_FRAME_START)) {
|
if ((edp != rxptr) && (rxptr->w2 & W2_R_FRAME_START)) {
|
||||||
/* Found another start... cleaning up the incomplete frame.*/
|
/* Found another start... cleaning up the incomplete frame.*/
|
||||||
do {
|
do {
|
||||||
rdp->w1 &= ~W1_R_OWNERSHIP;
|
edp->w1 &= ~W1_R_OWNERSHIP;
|
||||||
if (++rdp >= &rd[EMAC_RECEIVE_BUFFERS])
|
if (++edp >= &rd[EMAC_RECEIVE_DESCRIPTORS])
|
||||||
rdp = rd;
|
edp = rd;
|
||||||
}
|
}
|
||||||
while (rdp != rxptr);
|
while (edp != rxptr);
|
||||||
goto restart; /* Another start buffer for some reason... */
|
goto restart; /* Another start buffer for some reason... */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++rxptr >= &rd[EMAC_RECEIVE_BUFFERS])
|
if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
|
||||||
rxptr = rd;
|
rxptr = rd;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
return NULL;
|
return RDY_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads from a receive descriptor's stream.
|
||||||
|
*
|
||||||
|
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
|
||||||
|
* @param[in] buf pointer to the buffer that will receive the read data
|
||||||
|
* @param[in] size number of bytes to be read
|
||||||
|
* @return The number of bytes read from the descriptor's stream, this
|
||||||
|
* value can be less than the amount specified in the parameter
|
||||||
|
* @p size if there are no more bytes to read.
|
||||||
|
*/
|
||||||
|
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
|
||||||
|
uint8_t *buf,
|
||||||
|
size_t size) {
|
||||||
|
if (size > rdp->rd_size - rdp->rd_offset)
|
||||||
|
size = rdp->rd_size - rdp->rd_offset;
|
||||||
|
if (size > 0) {
|
||||||
|
uint8_t *src = (uint8_t *)(rdp->rd_physdesc->w1 & W1_R_ADDRESS_MASK) +
|
||||||
|
rdp->rd_offset;
|
||||||
|
uint8_t *limit = &rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE];
|
||||||
|
if (src + size > limit ) {
|
||||||
|
memcpy(buf, src, (size_t)(limit - src));
|
||||||
|
memcpy(buf, rb, (size_t)(src + size - limit));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy(buf, src, size);
|
||||||
|
rdp->rd_offset += size;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a receive descriptor.
|
* @brief Releases a receive descriptor.
|
||||||
* @details The descriptor and its buffer is made available for more incoming
|
* @details The descriptor and its buffer are made available for more incoming
|
||||||
* frames.
|
* frames.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
|
||||||
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
||||||
*/
|
*/
|
||||||
void mac_lld_release_receive_descriptor(MACDriver *macp,
|
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
|
||||||
MACReceiveDescriptor *rdp) {
|
bool_t done;
|
||||||
|
EMACDescriptor *edp = rdp->rd_physdesc;
|
||||||
|
|
||||||
unsigned n = EMAC_RECEIVE_BUFFERS;
|
unsigned n = EMAC_RECEIVE_DESCRIPTORS;
|
||||||
do {
|
do {
|
||||||
rdp->w1 &= ~W1_R_OWNERSHIP;
|
done = ((edp->w2 & W2_R_FRAME_END) != 0);
|
||||||
if (++rdp >= &rd[EMAC_RECEIVE_BUFFERS])
|
chDbgAssert(edp->w1 & W1_R_OWNERSHIP,
|
||||||
rdp = rd;
|
"mac_lld_release_receive_descriptor(), #1",
|
||||||
|
"found not owned descriptor");
|
||||||
|
edp->w1 &= ~(W1_R_OWNERSHIP | W2_R_FRAME_START | W2_R_FRAME_END);
|
||||||
|
if (++edp >= &rd[EMAC_RECEIVE_DESCRIPTORS])
|
||||||
|
edp = rd;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
while ((n > 0) || !(rxptr->w2 & W2_R_FRAME_END));
|
while ((n > 0) && !done);
|
||||||
}
|
/*
|
||||||
|
* Make rxptr point to the descriptor where the next frame will most
|
||||||
/**
|
* likely appear.
|
||||||
* @brief Returns the buffer associated to a @p MACTransmitDescriptor.
|
*/
|
||||||
*
|
rxptr = edp;
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
|
||||||
* @return The pointer to the transmit buffer.
|
|
||||||
*/
|
|
||||||
uint8_t *mac_lld_get_receive_buffer(MACReceiveDescriptor *rdp) {
|
|
||||||
|
|
||||||
return (uint8_t *)(rdp->w1 & W1_R_ADDRESS_MASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,14 +32,28 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of available descriptors/buffers.
|
* @brief Number of available transmit buffers.
|
||||||
*/
|
*/
|
||||||
#if !defined(MAC_TRANSMIT_DESCRIPTORS) || defined(__DOXYGEN__)
|
#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
|
||||||
#define MAC_TRANSMIT_DESCRIPTORS 2
|
#define MAC_TRANSMIT_BUFFERS 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of available receive buffers.
|
||||||
|
*/
|
||||||
|
#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
|
||||||
|
#define MAC_RECEIVE_BUFFERS 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum supported frame size.
|
||||||
|
*/
|
||||||
|
#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||||
|
#define MAC_BUFFERS_SIZE 1518
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* EMAC specific constants and settings. */
|
/* EMAC specific settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,10 +63,16 @@
|
||||||
#define EMAC_INTERRUPT_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 3)
|
#define EMAC_INTERRUPT_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 3)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EMAC_RECEIVE_BUFFERS 24
|
/*===========================================================================*/
|
||||||
|
/* EMAC specific constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define EMAC_RECEIVE_BUFFERS_SIZE 128 /* Do not modify */
|
#define EMAC_RECEIVE_BUFFERS_SIZE 128 /* Do not modify */
|
||||||
#define EMAC_TRANSMIT_BUFFERS MAC_TRANSMIT_DESCRIPTORS
|
#define EMAC_TRANSMIT_BUFFERS_SIZE MAC_BUFFERS_SIZE
|
||||||
#define EMAC_TRANSMIT_BUFFERS_SIZE 1518
|
#define EMAC_RECEIVE_DESCRIPTORS \
|
||||||
|
(((((MAC_BUFFERS_SIZE - 1) | (EMAC_RECEIVE_BUFFERS_SIZE - 1)) + 1) \
|
||||||
|
/ EMAC_RECEIVE_BUFFERS_SIZE) * MAC_RECEIVE_BUFFERS)
|
||||||
|
#define EMAC_TRANSMIT_DESCRIPTORS MAC_TRANSMIT_BUFFERS
|
||||||
|
|
||||||
#define W1_R_OWNERSHIP 0x00000001
|
#define W1_R_OWNERSHIP 0x00000001
|
||||||
#define W1_R_WRAP 0x00000002
|
#define W1_R_WRAP 0x00000002
|
||||||
|
@ -94,33 +114,47 @@
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Structure representing a buffer physical descriptor.
|
||||||
|
* @note It represents both descriptor types.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t w1;
|
||||||
|
uint32_t w2;
|
||||||
|
} EMACDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a MAC driver.
|
* @brief Structure representing a MAC driver.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Semaphore md_tdsem; /**< Transmit semaphore.*/
|
Semaphore md_tdsem; /**< Transmit semaphore. */
|
||||||
Semaphore md_rdsem; /**< Receive semaphore.*/
|
Semaphore md_rdsem; /**< Receive semaphore. */
|
||||||
#if CH_USE_EVENTS
|
#if CH_USE_EVENTS
|
||||||
EventSource md_rdevent; /**< Receive event source.*/
|
EventSource md_rdevent; /**< Receive event source. */
|
||||||
#endif
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
} MACDriver;
|
} MACDriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a transmission descriptor.
|
* @brief Structure representing a transmit descriptor.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
size_t td_offset; /**< Current write offset. */
|
||||||
uint32_t w1;
|
size_t td_size; /**< Available space size. */
|
||||||
uint32_t w2;
|
/* End of the mandatory fields.*/
|
||||||
|
EMACDescriptor *td_physdesc; /**< Pointer to the physical
|
||||||
|
descriptor. */
|
||||||
} MACTransmitDescriptor;
|
} MACTransmitDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a receive descriptor.
|
* @brief Structure representing a receive descriptor.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
size_t rd_offset; /**< Current read offset. */
|
||||||
uint32_t w1;
|
size_t rd_size; /**< Available data size. */
|
||||||
uint32_t w2;
|
/* End of the mandatory fields.*/
|
||||||
|
EMACDescriptor *rd_physdesc; /**< Pointer to the first descriptor
|
||||||
|
of the buffers chain. */
|
||||||
} MACReceiveDescriptor;
|
} MACReceiveDescriptor;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -128,23 +162,25 @@ typedef struct {
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/** @cond never*/
|
/** @cond never*/
|
||||||
extern MACDriver MAC1;
|
extern MACDriver ETH1;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void mac_lld_init(void);
|
void mac_lld_init(void);
|
||||||
void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
|
void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
|
||||||
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp,
|
msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
|
||||||
size_t size);
|
MACTransmitDescriptor *tdp);
|
||||||
void mac_lld_release_transmit_descriptor(MACDriver *macp,
|
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
|
||||||
MACTransmitDescriptor *tdp);
|
uint8_t *buf,
|
||||||
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp);
|
size_t size);
|
||||||
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp,
|
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
|
||||||
size_t *szp);
|
msg_t max_lld_get_receive_descriptor(MACDriver *macp,
|
||||||
void mac_lld_release_receive_descriptor(MACDriver *macp,
|
MACReceiveDescriptor *rdp);
|
||||||
MACReceiveDescriptor *rdp);
|
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
|
||||||
uint8_t *mac_lld_get_receive_buffer(MACReceiveDescriptor *rdp);
|
uint8_t *buf,
|
||||||
|
size_t size);
|
||||||
|
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
|
||||||
bool_t mac_lld_poll_link_status(MACDriver *macp);
|
bool_t mac_lld_poll_link_status(MACDriver *macp);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,77 +52,87 @@ void mac_lld_set_address(MACDriver *macp, const uint8_t *p) {
|
||||||
* returned.
|
* returned.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @param[in] size size of the frame to be transmitted
|
* @param[out] tdp pointer to a @p MACTransmitDescriptor structure
|
||||||
* @return A pointer to a @p MACTransmitDescriptor structure or @p NULL if
|
* @return The operation status.
|
||||||
* a descriptor is not available.
|
* @retval RDY_OK the descriptor was obtained.
|
||||||
|
* @retval RDY_TIMEOUT descriptor not available.
|
||||||
*/
|
*/
|
||||||
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp,
|
msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
|
||||||
size_t size) {
|
MACTransmitDescriptor *tdp) {
|
||||||
|
|
||||||
return NULL;
|
return RDY_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes to a transmit descriptor's stream.
|
||||||
|
*
|
||||||
|
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
|
||||||
|
* @param[in] buf pointer to the buffer cointaining the data to be written
|
||||||
|
* @param[in] size number of bytes to be written
|
||||||
|
* @return The number of bytes written into the descriptor's stream, this
|
||||||
|
* value can be less than the amount specified in the parameter
|
||||||
|
* @p size if the maximum frame size is reached.
|
||||||
|
*/
|
||||||
|
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
|
||||||
|
uint8_t *buf,
|
||||||
|
size_t size) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a transmit descriptor and starts the transmission of the
|
* @brief Releases a transmit descriptor and starts the transmission of the
|
||||||
* enqueued data as a single frame.
|
* enqueued data as a single frame.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
||||||
*/
|
*/
|
||||||
void mac_lld_release_transmit_descriptor(MACDriver *macp,
|
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
|
||||||
MACTransmitDescriptor *tdp) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the buffer associated to a @p MACTransmitDescriptor.
|
* @brief Returns a receive descriptor.
|
||||||
*
|
*
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
* @param[in] macp pointer to the @p MACDriver object
|
||||||
* @return The pointer to the transmit buffer.
|
* @param[out] rdp pointer to a @p MACReceiveDescriptor structure
|
||||||
|
* @return The operation status.
|
||||||
|
* @retval RDY_OK the descriptor was obtained.
|
||||||
|
* @retval RDY_TIMEOUT descriptor not available.
|
||||||
*/
|
*/
|
||||||
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp) {
|
msg_t max_lld_get_receive_descriptor(MACDriver *macp,
|
||||||
|
MACReceiveDescriptor *rdp) {
|
||||||
|
|
||||||
return NULL;
|
return RDY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns a received frame.
|
* @brief Reads from a receive descriptor's stream.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
|
||||||
* @param[out szp size of the received frame
|
* @param[in] buf pointer to the buffer that will receive the read data
|
||||||
* @return A pointer to a @p MACReceiveDescriptor structure or @p NULL if
|
* @param[in] size number of bytes to be read
|
||||||
* the operation timed out or some transient error happened.
|
* @return The number of bytes read from the descriptor's stream, this
|
||||||
|
* value can be less than the amount specified in the parameter
|
||||||
|
* @p size if there are no more bytes to read.
|
||||||
*/
|
*/
|
||||||
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp,
|
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
|
||||||
size_t *szp) {
|
uint8_t *buf,
|
||||||
|
size_t size) {
|
||||||
|
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Releases a receive descriptor.
|
* @brief Releases a receive descriptor.
|
||||||
* @details The descriptor and its buffer is made available for more incoming
|
* @details The descriptor and its buffer are made available for more incoming
|
||||||
* frames.
|
* frames.
|
||||||
*
|
*
|
||||||
* @param[in] macp pointer to the @p MACDriver object
|
|
||||||
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
|
||||||
*/
|
*/
|
||||||
void mac_lld_release_receive_descriptor(MACDriver *macp,
|
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
|
||||||
MACReceiveDescriptor *rdp) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the buffer associated to a @p MACTransmitDescriptor.
|
|
||||||
*
|
|
||||||
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
|
|
||||||
* @return The pointer to the transmit buffer.
|
|
||||||
*/
|
|
||||||
uint8_t *mac_lld_get_receive_buffer(MACReceiveDescriptor *rdp) {
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Updates and returns the link status.
|
* @brief Updates and returns the link status.
|
||||||
*
|
*
|
||||||
|
|
|
@ -32,10 +32,24 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of available descriptors/buffers.
|
* @brief Number of available transmit buffers.
|
||||||
*/
|
*/
|
||||||
#if !defined(MAC_TRANSMIT_DESCRIPTORS) || defined(__DOXYGEN__)
|
#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
|
||||||
#define MAC_TRANSMIT_DESCRIPTORS 2
|
#define MAC_TRANSMIT_BUFFERS 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of available receive buffers.
|
||||||
|
*/
|
||||||
|
#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
|
||||||
|
#define MAC_RECEIVE_BUFFERS 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum supported frame size.
|
||||||
|
*/
|
||||||
|
#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||||
|
#define MAC_BUFFERS_SIZE 1518
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -46,25 +60,30 @@
|
||||||
* @brief Structure representing a MAC driver.
|
* @brief Structure representing a MAC driver.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Semaphore md_tdsem; /**< Transmit semaphore.*/
|
Semaphore md_tdsem; /**< Transmit semaphore. */
|
||||||
Semaphore md_rdsem; /**< Receive semaphore.*/
|
Semaphore md_rdsem; /**< Receive semaphore. */
|
||||||
#if CH_USE_EVENTS
|
#if CH_USE_EVENTS
|
||||||
EventSource md_rdevent; /**< Receive event source.*/
|
EventSource md_rdevent; /**< Receive event source. */
|
||||||
#endif
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
} MACDriver;
|
} MACDriver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a transmission descriptor.
|
* @brief Structure representing a transmit descriptor.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
size_t td_offset; /**< Current write offset. */
|
||||||
|
size_t td_size; /**< Available space size. */
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
} MACTransmitDescriptor;
|
} MACTransmitDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Structure representing a receive descriptor.
|
* @brief Structure representing a receive descriptor.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
size_t rd_offset; /**< Current read offset. */
|
||||||
|
size_t rd_size; /**< Available data size. */
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
} MACReceiveDescriptor;
|
} MACReceiveDescriptor;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -76,16 +95,18 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void mac_lld_init(void);
|
void mac_lld_init(void);
|
||||||
void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
|
void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
|
||||||
MACTransmitDescriptor *max_lld_get_transmit_descriptor(MACDriver *macp,
|
msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
|
||||||
size_t size);
|
MACTransmitDescriptor *tdp);
|
||||||
void mac_lld_release_transmit_descriptor(MACDriver *macp,
|
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
|
||||||
MACTransmitDescriptor *tdp);
|
uint8_t *buf,
|
||||||
uint8_t *mac_lld_get_transmit_buffer(MACTransmitDescriptor *tdp);
|
size_t size);
|
||||||
MACReceiveDescriptor *max_lld_get_receive_descriptor(MACDriver *macp,
|
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
|
||||||
size_t *szp);
|
msg_t max_lld_get_receive_descriptor(MACDriver *macp,
|
||||||
void mac_lld_release_receive_descriptor(MACDriver *macp,
|
MACReceiveDescriptor *rdp);
|
||||||
MACReceiveDescriptor *rdp);
|
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
|
||||||
uint8_t *mac_lld_get_receive_buffer(MACReceiveDescriptor *rdp);
|
uint8_t *buf,
|
||||||
|
size_t size);
|
||||||
|
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
|
||||||
bool_t mac_lld_poll_link_status(MACDriver *macp);
|
bool_t mac_lld_poll_link_status(MACDriver *macp);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue