Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpu/stm32/periph_eth: Add stm32_eth_tracing #18418

Merged
merged 2 commits into from
Sep 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cpu/stm32/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ ifneq (,$(filter stm32_eth_%,$(USEMODULE)))
USEMODULE += stm32_eth
endif

ifneq (,$(filter stm32_eth_tracing,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio_ll
endif

ifneq (,$(filter stm32_eth_auto,$(USEMODULE)))
USEMODULE += stm32_eth_link_up
endif
Expand Down
114 changes: 109 additions & 5 deletions cpu/stm32/periph/eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
#include <string.h>

#include "bitarithm.h"
#include "board.h"
#include "iolist.h"
#include "mii.h"
#include "mutex.h"
#include "net/ethernet.h"
#include "net/eui_provider.h"
#include "net/netdev/eth.h"
#include "periph/gpio.h"
#include "periph/gpio_ll.h"
#include "timex.h"

#define ENABLE_DEBUG 0
Expand Down Expand Up @@ -91,6 +93,58 @@ static ztimer_t _link_status_timer;

#define MIN(a, b) (((a) <= (b)) ? (a) : (b))

/**
* @name GPIOs to use for tracing STM32 Ethernet state via module
* `stm32_eth_tracing`
* @{
*/
#ifndef STM32_ETH_TRACING_TX_PIN_NUM
# if defined(LED1_PIN_NUM) || defined(DOXYGEN)
/**
* @brief pin to trace TX events
*
* This pin will be set when TX starts and cleared when the corresponding
*/
# define STM32_ETH_TRACING_TX_PIN_NUM LED1_PIN_NUM
# else
# define STM32_ETH_TRACING_TX_PIN_NUM 0
# endif
#endif

#ifndef STM32_ETH_TRACING_TX_PORT_NUM
# if defined(LED1_PORT_NUM) || defined(DOXYGEN)
/**
* @brief port to trace TX events
*/
# define STM32_ETH_TRACING_TX_PORT_NUM LED1_PORT_NUM
# else
# define STM32_ETH_TRACING_TX_PORT_NUM 0
# endif
#endif

#ifndef STM32_ETH_TRACING_RX_PIN_NUM
# if defined(LED2_PIN_NUM) || defined(DOXYGEN)
/**
* @brief pin to trace RX events
*/
# define STM32_ETH_TRACING_RX_PIN_NUM LED2_PIN_NUM
# else
# define STM32_ETH_TRACING_RX_PIN_NUM 0
# endif
#endif

#ifndef STM32_ETH_TRACING_RX_PORT_NUM
# if defined(LED2_PORT_NUM) || defined(DOXYGEN)
/**
* @brief port to trace RX events
*/
# define STM32_ETH_TRACING_RX_PORT_NUM LED2_PORT_NUM
# else
# define STM32_ETH_TRACING_RX_PORT_NUM 0
# endif
#endif
/** @} */

/* Synchronization between IRQ and thread context */
mutex_t stm32_eth_tx_completed = MUTEX_INIT_LOCKED;

Expand All @@ -115,8 +169,17 @@ static void _debug_tx_descriptor_info(unsigned line)
DEBUG("[stm32_eth:%u] TX descriptors:\n", line);
for (unsigned i = 0; i < ETH_TX_DESCRIPTOR_COUNT; i++) {
uint32_t status = tx_desc[i].status;
char next_valid;
if (i < ETH_TX_DESCRIPTOR_COUNT - 1) {
next_valid = (tx_desc[i].desc_next == &tx_desc[i + 1])
? '1' : '0';
}
else {
next_valid = (tx_desc[i].desc_next == &tx_desc[0])
? '1' : '0';
}
DEBUG(" %s %u: OWN=%c, ES=%c, UF=%c, EC=%c, NC=%c, FS=%c, "
"LS=%c\n",
"LS=%c, next valid=%c\n",
(tx_curr == tx_desc + i) ? "-->" : " ",
i,
(status & TX_DESC_STAT_OWN) ? '1' : '0',
Expand All @@ -125,7 +188,8 @@ static void _debug_tx_descriptor_info(unsigned line)
(status & TX_DESC_STAT_EC) ? '1' : '0',
(status & TX_DESC_STAT_NC) ? '1' : '0',
(status & TX_DESC_STAT_FS) ? '1' : '0',
(status & TX_DESC_STAT_LS) ? '1' : '0');
(status & TX_DESC_STAT_LS) ? '1' : '0',
next_valid);
}
}
}
Expand All @@ -142,15 +206,26 @@ static void _debug_rx_descriptor_info(unsigned line)
DEBUG("[stm32_eth:%u] RX descriptors:\n", line);
for (unsigned i = 0; i < ETH_RX_DESCRIPTOR_COUNT; i++) {
uint32_t status = rx_desc[i].status;
DEBUG(" %s %u: OWN=%c, FS=%c, LS=%c, ES=%c, DE=%c, FL=%" PRIu32 "\n",
char next_valid;
if (i < ETH_RX_DESCRIPTOR_COUNT - 1) {
next_valid = (rx_desc[i].desc_next == &rx_desc[i + 1])
? '1' : '0';
}
else {
next_valid = (rx_desc[i].desc_next == &rx_desc[0])
? '1' : '0';
}
DEBUG(" %s %u: OWN=%c, FS=%c, LS=%c, ES=%c, DE=%c, FL=%" PRIu32
", next valid=%c\n",
(rx_curr == rx_desc + i) ? "-->" : " ",
i,
(status & RX_DESC_STAT_OWN) ? '1' : '0',
(status & RX_DESC_STAT_FS) ? '1' : '0',
(status & RX_DESC_STAT_LS) ? '1' : '0',
(status & RX_DESC_STAT_ES) ? '1' : '0',
(status & RX_DESC_STAT_DE) ? '1' : '0',
_len_from_rx_desc_status(status));
_len_from_rx_desc_status(status),
next_valid);
}
}
}
Expand Down Expand Up @@ -249,6 +324,8 @@ static void _init_dma_descriptors(void)

ETH->DMARDLAR = (uintptr_t)rx_curr;
ETH->DMATDLAR = (uintptr_t)tx_curr;
_debug_rx_descriptor_info(__LINE__);
_debug_tx_descriptor_info(__LINE__);
}

static void _reset_eth_dma(void)
Expand Down Expand Up @@ -408,6 +485,14 @@ static void _setup_phy(void)
static int stm32_eth_init(netdev_t *netdev)
{
(void)netdev;
if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_init(GPIO_PORT(STM32_ETH_TRACING_TX_PORT_NUM),
STM32_ETH_TRACING_TX_PIN_NUM,
&gpio_ll_out);
gpio_ll_init(GPIO_PORT(STM32_ETH_TRACING_RX_PORT_NUM),
STM32_ETH_TRACING_RX_PIN_NUM,
&gpio_ll_out);
}
if (IS_USED(MODULE_STM32_ETH_LINK_UP)) {
_link_status_timer.callback = _timer_cb;
_link_status_timer.arg = netdev;
Expand Down Expand Up @@ -475,6 +560,7 @@ static int stm32_eth_send(netdev_t *netdev, const struct iolist *iolist)
/* We cannot send more chunks than allocated descriptors */
assert(iolist_count(iolist) <= ETH_TX_DESCRIPTOR_COUNT);

_debug_tx_descriptor_info(__LINE__);
edma_desc_t *dma_iter = tx_curr;
for (unsigned i = 0; iolist; iolist = iolist->iol_next, i++) {
dma_iter->control = iolist->iol_len;
Expand All @@ -493,19 +579,26 @@ static int stm32_eth_send(netdev_t *netdev, const struct iolist *iolist)
dma_iter = dma_iter->desc_next;
}

if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_set(GPIO_PORT(STM32_ETH_TRACING_TX_PORT_NUM),
(1U << STM32_ETH_TRACING_TX_PIN_NUM));
}
/* start TX */
ETH->DMATPDR = 0;
/* await completion */
if (IS_ACTIVE(ENABLE_DEBUG_VERBOSE)) {
DEBUG("[stm32_eth] Started to send %u B via DMA\n", bytes_to_send);
}
mutex_lock(&stm32_eth_tx_completed);
if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_clear(GPIO_PORT(STM32_ETH_TRACING_TX_PORT_NUM),
(1U << STM32_ETH_TRACING_TX_PIN_NUM));
}
if (IS_ACTIVE(ENABLE_DEBUG_VERBOSE)) {
DEBUG("[stm32_eth] TX completed\n");
}

/* Error check */
_debug_tx_descriptor_info(__LINE__);
int error = 0;
while (1) {
uint32_t status = tx_curr->status;
Expand Down Expand Up @@ -535,6 +628,8 @@ static int stm32_eth_send(netdev_t *netdev, const struct iolist *iolist)
}
}

_debug_tx_descriptor_info(__LINE__);

netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
if (error) {
return error;
Expand Down Expand Up @@ -668,6 +763,11 @@ static int stm32_eth_recv(netdev_t *netdev, void *_buf, size_t max_len,
rx_curr = rx_curr->desc_next;
}

if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_clear(GPIO_PORT(STM32_ETH_TRACING_RX_PORT_NUM),
(1U << STM32_ETH_TRACING_RX_PIN_NUM));
}

_debug_rx_descriptor_info(__LINE__);
handle_lost_rx_irqs();
return size;
Expand Down Expand Up @@ -701,6 +801,10 @@ static void stm32_eth_isr(netdev_t *netdev)
}
}

if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_set(GPIO_PORT(STM32_ETH_TRACING_RX_PORT_NUM),
(1U << STM32_ETH_TRACING_RX_PIN_NUM));
}
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
}

Expand Down
44 changes: 44 additions & 0 deletions cpu/stm32/periph/eth_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,49 @@
*/
#include <string.h>

#include "board.h"
#include "mutex.h"
#include "net/netdev/eth.h"
#include "periph/gpio.h"
#include "periph/gpio_ll.h"
#include "periph/ptp.h"
#include "periph_conf.h"
#include "periph_cpu.h"

#define ENABLE_DEBUG 0
#include "debug.h"

/**
* @name GPIOs to use for tracing STM32 Ethernet state via module
* `stm32_eth_tracing`
* @{
*/
#ifndef STM32_ETH_TRACING_IRQ_PIN_NUM
# if defined(LED0_PIN_NUM) || defined(DOXYGEN)
/**
* @brief pin to trace IRQs
*
* This GPIO pin will be toggled every time the Ethernet ISR is executed
* (upon entry of the ISR).
*/
# define STM32_ETH_TRACING_IRQ_PIN_NUM LED0_PIN_NUM
# else
# define STM32_ETH_TRACING_IRQ_PIN_NUM 0
# endif
#endif

#ifndef STM32_ETH_TRACING_IRQ_PORT_NUM
# if defined(LED0_PORT_NUM) || defined(DOXYGEN)
/**
* @brief port to trace IRQs
*/
# define STM32_ETH_TRACING_IRQ_PORT_NUM LED0_PORT_NUM
# else
# define STM32_ETH_TRACING_IRQ_PORT_NUM 0
# endif
#endif
/** @} */

void stm32_eth_common_init(void)
{
/* enable APB2 clock */
Expand Down Expand Up @@ -59,6 +92,12 @@ void stm32_eth_common_init(void)
ETH->DMABMR |= ETH_DMABMR_SR;
while (ETH->DMABMR & ETH_DMABMR_SR) {}

if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_init(GPIO_PORT(STM32_ETH_TRACING_IRQ_PORT_NUM),
STM32_ETH_TRACING_IRQ_PIN_NUM,
&gpio_ll_out);
}

if (IS_USED(MODULE_PERIPH_ETH) || IS_USED(MODULE_PERIPH_PTP_TIMER)) {
NVIC_EnableIRQ(ETH_IRQn);
}
Expand All @@ -68,6 +107,10 @@ void stm32_eth_common_init(void)
void isr_eth(void)
{
DEBUG("[periph_eth_common] isr_eth()\n");
if (IS_USED(MODULE_STM32_ETH_TRACING)) {
gpio_ll_toggle(GPIO_PORT(STM32_ETH_TRACING_IRQ_PORT_NUM),
(1U << STM32_ETH_TRACING_IRQ_PIN_NUM));
}

if (IS_USED(MODULE_PERIPH_PTP_TIMER)) {
if (ETH->MACSR & ETH_MACSR_TSTS) {
Expand All @@ -82,6 +125,7 @@ void isr_eth(void)
extern mutex_t stm32_eth_tx_completed;
unsigned tmp = ETH->DMASR;
ETH->DMASR = ETH_DMASR_NIS | ETH_DMASR_TS | ETH_DMASR_RS;
DEBUG("[periph_eth_common] DMASR = 0x%x\n", tmp);

if ((tmp & ETH_DMASR_TS)) {
DEBUG("isr_eth: TX completed\n");
Expand Down
1 change: 1 addition & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ PSEUDOMODULES += stdio_telnet
PSEUDOMODULES += stm32_eth
PSEUDOMODULES += stm32_eth_auto
PSEUDOMODULES += stm32_eth_link_up
PSEUDOMODULES += stm32_eth_tracing
PSEUDOMODULES += stm32mp1_eng_mode
PSEUDOMODULES += suit_transport_%
PSEUDOMODULES += suit_storage_%
Expand Down