1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/cpu/stm32/periph/eth_common.c
Marian Buschsieweke 650559276f
cpu/stm32/periph_ptp: bugfix & better debug output
- Clear the PTP timer interrupt *after* the user callback is executed
    - Otherwise it would be possible that the ISR sets another super
      short timeout that triggers during ISR, which also gets cleared
    - This is a pretty nasty race condition :-/
- The debug output was a bit too verbose to be generally useful. Some
  noise is now silenced unless `DEBUG_VERBOSE` is `#define`d to 1
2021-03-23 22:58:10 +01:00

103 lines
2.6 KiB
C

/*
* Copyright (C) 2016 TriaGnoSys GmbH
* 2020 Otto-von-Guericke-Universität Magdeburg
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_stm32
* @{
*
* @file
* @brief Common code for the ETH and PTP driver
*
* @author Víctor Ariño <victor.arino@triagnosys.com>
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*
* @}
*/
#include <string.h>
#include "mutex.h"
#include "net/netdev/eth.h"
#include "periph/gpio.h"
#include "periph/ptp.h"
#include "periph_conf.h"
#include "periph_cpu.h"
#define ENABLE_DEBUG 0
#include "debug.h"
void stm32_eth_common_init(void)
{
/* enable APB2 clock */
RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
/* select RMII if necessary */
if (eth_config.mode == RMII) {
SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
}
/* initialize GPIO */
for (int i = 0; i < (int) eth_config.mode; i++) {
gpio_init(eth_config.pins[i], GPIO_OUT);
gpio_init_af(eth_config.pins[i], GPIO_AF11);
}
/* enable all clocks */
RCC->AHB1ENR |= (RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN |
RCC_AHB1ENR_ETHMACRXEN | RCC_AHB1ENR_ETHMACPTPEN);
/* reset the peripheral */
RCC->AHB1RSTR |= RCC_AHB1RSTR_ETHMACRST;
RCC->AHB1RSTR &= ~RCC_AHB1RSTR_ETHMACRST;
/* software reset */
ETH->DMABMR |= ETH_DMABMR_SR;
while (ETH->DMABMR & ETH_DMABMR_SR) {}
if (IS_USED(MODULE_PERIPH_ETH) || IS_USED(MODULE_PERIPH_PTP_TIMER)) {
NVIC_EnableIRQ(ETH_IRQn);
}
}
#if IS_USED(MODULE_STM32_ETH) || IS_USED(MODULE_PERIPH_PTP_TIMER)
void isr_eth(void)
{
DEBUG("[periph_eth_common] isr_eth()\n");
if (IS_USED(MODULE_PERIPH_PTP_TIMER)) {
if (ETH->MACSR & ETH_MACSR_TSTS) {
/* clear interrupt by reading PTPTSSR */
(void)ETH->PTPTSSR;
ptp_timer_cb();
}
}
if (IS_USED(MODULE_STM32_ETH)) {
extern netdev_t *stm32_eth_netdev;
extern mutex_t stm32_eth_tx_completed;
unsigned tmp = ETH->DMASR;
if ((tmp & ETH_DMASR_TS)) {
ETH->DMASR = ETH_DMASR_NIS | ETH_DMASR_TS;
DEBUG("isr_eth: TX completed\n");
mutex_unlock(&stm32_eth_tx_completed);
}
if ((tmp & ETH_DMASR_RS)) {
ETH->DMASR = ETH_DMASR_NIS | ETH_DMASR_RS;
DEBUG("isr_eth: RX completed\n");
if (stm32_eth_netdev) {
netdev_trigger_event_isr(stm32_eth_netdev);
}
}
}
cortexm_isr_end();
}
#endif