mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
Merge pull request #18418 from maribu/cpu/stm32/periph/stm32_eth_tracing
cpu/stm32/periph_eth: Add stm32_eth_tracing
This commit is contained in:
commit
e402f1d885
@ -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
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "bitarithm.h"
|
||||
#include "board.h"
|
||||
#include "iolist.h"
|
||||
#include "mii.h"
|
||||
#include "mutex.h"
|
||||
@ -32,6 +33,7 @@
|
||||
#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
|
||||
@ -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;
|
||||
|
||||
@ -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',
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,7 +206,17 @@ 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',
|
||||
@ -150,7 +224,8 @@ static void _debug_rx_descriptor_info(unsigned line)
|
||||
(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
@ -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;
|
||||
@ -480,6 +565,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;
|
||||
@ -498,6 +584,10 @@ 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 */
|
||||
@ -505,12 +595,15 @@ static int stm32_eth_send(netdev_t *netdev, const struct iolist *iolist)
|
||||
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;
|
||||
@ -540,6 +633,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;
|
||||
@ -673,6 +768,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;
|
||||
@ -706,6 +806,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);
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,11 @@
|
||||
*/
|
||||
#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"
|
||||
@ -31,6 +33,37 @@
|
||||
#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 */
|
||||
@ -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);
|
||||
}
|
||||
@ -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) {
|
||||
@ -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");
|
||||
|
@ -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_%
|
||||
|
Loading…
Reference in New Issue
Block a user