Merge pull request #15610 from maribu/stm32-ethernet-rx-timestamp

drivers/stm32_eth: add RX timestamps
This commit is contained in:
Marian Buschsieweke 2021-01-26 13:32:19 +01:00 committed by GitHub
commit 38188017a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 17 deletions

View File

@ -28,6 +28,7 @@ config BOARD_NUCLEO_F767ZI
select HAS_PERIPH_PTP select HAS_PERIPH_PTP
select HAS_PERIPH_PTP_SPEED_ADJUSTMENT select HAS_PERIPH_PTP_SPEED_ADJUSTMENT
select HAS_PERIPH_PTP_TIMER select HAS_PERIPH_PTP_TIMER
select HAS_PERIPH_PTP_TXRX_TIMESTAMPS
# Put other features for this board (in alphabetical order) # Put other features for this board (in alphabetical order)
select HAS_RIOTBOOT select HAS_RIOTBOOT

View File

@ -9,6 +9,7 @@ FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_ptp FEATURES_PROVIDED += periph_ptp
FEATURES_PROVIDED += periph_ptp_speed_adjustment FEATURES_PROVIDED += periph_ptp_speed_adjustment
FEATURES_PROVIDED += periph_ptp_timer FEATURES_PROVIDED += periph_ptp_timer
FEATURES_PROVIDED += periph_ptp_txrx_timestamps
FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_rtc
FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_rtt
FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_spi

View File

@ -32,6 +32,7 @@
#include "net/eui_provider.h" #include "net/eui_provider.h"
#include "net/netdev/eth.h" #include "net/netdev/eth.h"
#include "periph/gpio.h" #include "periph/gpio.h"
#include "timex.h"
#define ENABLE_DEBUG 0 #define ENABLE_DEBUG 0
#define ENABLE_DEBUG_VERBOSE 0 #define ENABLE_DEBUG_VERBOSE 0
@ -618,12 +619,12 @@ static void handle_lost_rx_irqs(void)
} }
} }
static int stm32_eth_recv(netdev_t *netdev, void *buf, size_t max_len, static int stm32_eth_recv(netdev_t *netdev, void *_buf, size_t max_len,
void *info) void *_info)
{ {
(void)info;
(void)netdev; (void)netdev;
char *data = buf; netdev_eth_rx_info_t *info = _info;
char *buf = _buf;
/* Determine the size of received frame. The frame might span multiple /* Determine the size of received frame. The frame might span multiple
* DMA buffers */ * DMA buffers */
int size = get_rx_frame_size(); int size = get_rx_frame_size();
@ -650,20 +651,29 @@ static int stm32_eth_recv(netdev_t *netdev, void *buf, size_t max_len,
return -ENOBUFS; return -ENOBUFS;
} }
/* Fetch payload, collect RX timestamp from last descriptor if module periph_ptp is used, and
* hand DMA descriptors back to the DMA */
size_t remain = size; size_t remain = size;
while (remain) { while (1) {
size_t chunk = MIN(remain, ETH_RX_BUFFER_SIZE); /* there can be one more DMA descriptor than needed for holding the Ethernet
memcpy(data, rx_curr->buffer_addr, chunk); * payload, as the 4 byte FCS will also be stored by DMA */
data += chunk; if (remain) {
remain -= chunk; size_t chunk = MIN(remain, ETH_RX_BUFFER_SIZE);
/* Hand over descriptor to DMA */ memcpy(buf, rx_curr->buffer_addr, chunk);
rx_curr->status = RX_DESC_STAT_OWN; buf += chunk;
rx_curr = rx_curr->desc_next; remain -= chunk;
} }
if (rx_curr->status & RX_DESC_STAT_LS) {
if ((size + ETHERNET_FCS_LEN - 1) % ETH_RX_BUFFER_SIZE < ETHERNET_FCS_LEN) { /* LS bit set --> reached last DMA descriptor of this frame */
/* one additional rx descriptor was needed only for the FCS, hand that if (IS_USED(MODULE_PERIPH_PTP)) {
* back to the DMA as well */ info->timestamp = rx_curr->ts_low;
info->timestamp += (uint64_t)rx_curr->ts_high * NS_PER_SEC;
info->flags |= NETDEV_ETH_RX_INFO_FLAG_TIMESTAMP;
}
rx_curr->status = RX_DESC_STAT_OWN;
rx_curr = rx_curr->desc_next;
break;
}
rx_curr->status = RX_DESC_STAT_OWN; rx_curr->status = RX_DESC_STAT_OWN;
rx_curr = rx_curr->desc_next; rx_curr = rx_curr->desc_next;
} }

View File

@ -220,6 +220,12 @@ config HAS_PERIPH_PTP_TIMER
help help
Indicates that the PTP clock can be used as timer. Indicates that the PTP clock can be used as timer.
config HAS_PERIPH_PTP_TXRX_TIMESTAMPS
bool
help
Indicates that the PTP clock can provide exact time stamps of the
reception and transmission of frames.
config HAS_PERIPH_PWM config HAS_PERIPH_PWM
bool bool
help help