mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
stm32/eth: Add support for Ethernet on N6 MCUs.
This adds working support for 100MBit Ethernet on N6 MCUs. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -20,6 +20,7 @@ PortC,PC9 , , , ,
|
||||
PortC,PC10, , , , , , , , , , ,SDMMC1_D2 , , , , , ,
|
||||
PortC,PC11, , , , , , , , , , ,SDMMC1_D3 , , , , , ,
|
||||
PortC,PC12, , , , , , , , , , ,SDMMC1_CK , , , , , ,
|
||||
PortD,PD1 , , , , , , , , , , , ,ETH1_MDC , , , , ,
|
||||
PortD,PD2 , , , , , , , , , , , ,SDMMC2_CK , , , , ,
|
||||
PortD,PD5 , , , , , , , ,USART2_TX , , , , , , , , ,
|
||||
PortD,PD6 , , , , ,TIM15_CH2 , , , , , , , , , , , ,
|
||||
@@ -27,6 +28,7 @@ PortD,PD7 , , , ,
|
||||
PortD,PD8 , , , , , , , ,USART3_TX , , , , , , , , ,
|
||||
PortD,PD9 , , , , , , , ,USART3_RX , , , , , , , , ,
|
||||
PortD,PD11, , , , , ,SPI2_MISO , , , , , , , , , , ,
|
||||
PortD,PD12, , , , , , , , , , , ,ETH1_MDIO , , , , ,
|
||||
PortD,PD13, , ,TIM4_CH2 , , , , , , , , , , , , , ,
|
||||
PortE,PE5 , , , , , , , ,USART1_TX , , , , , , , , ,
|
||||
PortE,PE6 , , , , , , , ,USART1_RX , , , , , , , , ,
|
||||
@@ -38,12 +40,21 @@ PortE,PE13, , , ,
|
||||
PortE,PE14, , , , ,I2C4_SDA , , , , , , , , , , , ,
|
||||
PortE,PE15, , , , , ,SPI5_SCK , , , , , , , , , , ,
|
||||
PortF,PF3 , , , , , , , ,USART2_RTS , , , , , , , , ,ADC1_INP16
|
||||
PortF,PF4 , , , , , , , , , , , ,ETH1_MDIO , , , , ,
|
||||
PortF,PF6 , , , , , , , ,USART2_RX , , , , , , , , ,
|
||||
PortF,PF7 , , , , , , , , , , , ,ETH1_RMII_REF_CLK , , , , ,
|
||||
PortF,PF10, , , , , , , , , , , ,ETH1_RMII_CRS_DV , , , , ,
|
||||
PortF,PF11, , , , , , , , , , , ,ETH1_RMII_TX_EN , , , , ,
|
||||
PortF,PF12, , , , , , , , , , , ,ETH1_RMII_TXD0 , , , , ,
|
||||
PortF,PF13, , , , , , , , , , , ,ETH1_RMII_TXD1 , , , , ,
|
||||
PortF,PF14, , , , , , , , , , , ,ETH1_RMII_RXD0 , , , , ,
|
||||
PortF,PF15, , , , , , , , , , , ,ETH1_RMII_RXD1 , , , , ,
|
||||
PortG,PG0 , , ,TIM12_CH1 , , , , , , , , , , , , , ,
|
||||
PortG,PG1 , , , , , ,SPI5_MISO , , , , , , , , , , ,
|
||||
PortG,PG2 , , , , , ,SPI5_MOSI , , , , , , , , , , ,
|
||||
PortG,PG5 , , , , , , , ,USART2_CTS , , , , , , , , ,
|
||||
PortG,PG8 , , , , , , , , , , , ,SDMMC2_D1 , , , , ,
|
||||
PortG,PG11, , , , , , , , , , , ,ETH1_MDC , , , , ,
|
||||
PortG,PG12, ,TIM17_CH1 , , , , , , , , , , , , , , ,
|
||||
PortG,PG13, , ,TIM4_CH1 , , , , ,USART3_RTS , , , , , , , , ,
|
||||
PortG,PG15, , , , , , , , , , , , , , , , ,ADC12_INP7/ADC12_INN3
|
||||
|
||||
|
@@ -160,7 +160,6 @@
|
||||
#include "stm32n6xx_hal_dcmipp.h"
|
||||
#include "stm32n6xx_hal_dma2d.h"
|
||||
#include "stm32n6xx_hal_dts.h"
|
||||
#include "stm32n6xx_hal_eth.h"
|
||||
#include "stm32n6xx_hal_exti.h"
|
||||
#include "stm32n6xx_hal_fdcan.h"
|
||||
#include "stm32n6xx_hal_gfxmmu.h"
|
||||
|
||||
@@ -41,8 +41,19 @@
|
||||
#include "lwip/dhcp.h"
|
||||
#include "netif/ethernet.h"
|
||||
|
||||
// Register and IRQ compatibility for STM32N6.
|
||||
#if defined(STM32N6)
|
||||
#define ETH ETH1
|
||||
#define ETH_MACMDIOAR_MB (ETH_MACMDIOAR_GB)
|
||||
#define ETH_MACMDIOAR_MOC_Msk (ETH_MACMDIOAR_GOC_Msk)
|
||||
#define ETH_MACMDIOAR_MOC_WR (ETH_MACMDIOAR_GOC_0)
|
||||
#define ETH_MACMDIOAR_MOC_RD (ETH_MACMDIOAR_GOC_1 | ETH_MACMDIOAR_GOC_0)
|
||||
#define ETH_IRQn ETH1_IRQn
|
||||
#define ETH_IRQHandler ETH1_IRQHandler
|
||||
#endif
|
||||
|
||||
// ETH DMA RX and TX descriptor definitions
|
||||
#if defined(STM32H5)
|
||||
#if defined(STM32H5) || defined(STM32N6)
|
||||
#define RX_DESCR_3_OWN_Pos (31)
|
||||
#define RX_DESCR_3_IOC_Pos (30)
|
||||
#define RX_DESCR_3_BUF1V_Pos (24)
|
||||
@@ -85,6 +96,13 @@
|
||||
#define TX_DESCR_1_TBS1_Pos (0)
|
||||
#endif
|
||||
|
||||
// Static alternate function macro.
|
||||
#if defined(STM32N6)
|
||||
#define STATIC_AF_ETH(signal) STATIC_AF_ETH1_##signal
|
||||
#else
|
||||
#define STATIC_AF_ETH(signal) STATIC_AF_ETH_##signal
|
||||
#endif
|
||||
|
||||
// Configuration values
|
||||
|
||||
#define PHY_INIT_TIMEOUT_MS (10000)
|
||||
@@ -95,6 +113,12 @@
|
||||
#define RX_BUF_NUM (5)
|
||||
#define TX_BUF_NUM (5)
|
||||
|
||||
#if defined(STM32N6)
|
||||
// The N6 has two DMA channels, so use one for RX and one for TX.
|
||||
#define RX_DMA_CH (0)
|
||||
#define TX_DMA_CH (1)
|
||||
#endif
|
||||
|
||||
typedef struct _eth_dma_rx_descr_t {
|
||||
volatile uint32_t rdes0, rdes1, rdes2, rdes3;
|
||||
} eth_dma_rx_descr_t;
|
||||
@@ -129,7 +153,7 @@ static void eth_mac_deinit(eth_t *self);
|
||||
static void eth_process_frame(eth_t *self, size_t len, const uint8_t *buf);
|
||||
|
||||
void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
|
||||
}
|
||||
uint32_t ar = ETH->MACMDIOAR;
|
||||
@@ -157,7 +181,7 @@ void eth_phy_write(uint32_t phy_addr, uint32_t reg, uint32_t val) {
|
||||
}
|
||||
|
||||
uint32_t eth_phy_read(uint32_t phy_addr, uint32_t reg) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
while (ETH->MACMDIOAR & ETH_MACMDIOAR_MB) {
|
||||
}
|
||||
uint32_t ar = ETH->MACMDIOAR;
|
||||
@@ -197,15 +221,15 @@ int eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type) {
|
||||
}
|
||||
|
||||
// Configure GPIO
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDC, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_MDC);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDIO, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_MDIO);
|
||||
mp_hal_pin_config_alt_static_speed(MICROPY_HW_ETH_RMII_REF_CLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, MP_HAL_PIN_SPEED_MEDIUM, STATIC_AF_ETH_RMII_REF_CLK);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_CRS_DV, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_CRS_DV);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_RXD0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_RXD0);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_RXD1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_RXD1);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TX_EN, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_TX_EN);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TXD0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_TXD0);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TXD1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH_RMII_TXD1);
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDC, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(MDC));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_MDIO, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(MDIO));
|
||||
mp_hal_pin_config_alt_static_speed(MICROPY_HW_ETH_RMII_REF_CLK, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, MP_HAL_PIN_SPEED_MEDIUM, STATIC_AF_ETH(RMII_REF_CLK));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_CRS_DV, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(RMII_CRS_DV));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_RXD0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(RMII_RXD0));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_RXD1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(RMII_RXD1));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TX_EN, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(RMII_TX_EN));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TXD0, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(RMII_TXD0));
|
||||
mp_hal_pin_config_alt_static(MICROPY_HW_ETH_RMII_TXD1, MP_HAL_PIN_MODE_ALT, MP_HAL_PIN_PULL_NONE, STATIC_AF_ETH(RMII_TXD1));
|
||||
|
||||
// Enable peripheral clock
|
||||
#if defined(STM32H5)
|
||||
@@ -216,6 +240,11 @@ int eth_init(eth_t *self, int mac_idx, uint32_t phy_addr, int phy_type) {
|
||||
__HAL_RCC_ETH1MAC_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1TX_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1RX_CLK_ENABLE();
|
||||
#elif defined(STM32N6)
|
||||
__HAL_RCC_ETH1_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1MAC_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1TX_CLK_ENABLE();
|
||||
__HAL_RCC_ETH1RX_CLK_ENABLE();
|
||||
#else
|
||||
__HAL_RCC_ETH_CLK_ENABLE();
|
||||
#endif
|
||||
@@ -229,7 +258,7 @@ void eth_set_trace(eth_t *self, uint32_t value) {
|
||||
static int eth_mac_init(eth_t *self) {
|
||||
// Configure MPU
|
||||
uint32_t irq_state = mpu_config_start();
|
||||
#if defined(STM32H5)
|
||||
#if defined(STM32H5) || defined(STM32N6)
|
||||
mpu_config_region(MPU_REGION_ETH, (uint32_t)ð_dma, MPU_CONFIG_ETH(16 * 1024));
|
||||
#else
|
||||
mpu_config_region(MPU_REGION_ETH, (uint32_t)ð_dma, MPU_CONFIG_ETH(MPU_REGION_SIZE_16KB));
|
||||
@@ -241,16 +270,29 @@ static int eth_mac_init(eth_t *self) {
|
||||
__HAL_RCC_ETH_FORCE_RESET();
|
||||
#elif defined(STM32H7)
|
||||
__HAL_RCC_ETH1MAC_FORCE_RESET();
|
||||
#elif defined(STM32N6)
|
||||
__HAL_RCC_ETH1_FORCE_RESET();
|
||||
#else
|
||||
__HAL_RCC_ETHMAC_FORCE_RESET();
|
||||
#endif
|
||||
|
||||
// Select clock sources.
|
||||
#if defined(STM32N6)
|
||||
LL_RCC_SetETHREFTXClockSource(LL_RCC_ETH1REFTX_CLKSOURCE_EXT); // max 25MHz
|
||||
LL_RCC_SetETHREFRXClockSource(LL_RCC_ETH1REFRX_CLKSOURCE_EXT); // max 125MHz
|
||||
LL_RCC_SetETHClockSource(LL_RCC_ETH1_CLKSOURCE_IC12); // max 125MHz
|
||||
LL_RCC_SetETH1PTPDivider(LL_RCC_ETH1PTP_DIV_1);
|
||||
LL_RCC_SetETHPTPClockSource(LL_RCC_ETH1PTP_CLKSOURCE_HCLK); // max 200MHz
|
||||
#endif
|
||||
|
||||
// Select RMII interface
|
||||
#if defined(STM32H5)
|
||||
__HAL_RCC_SBS_CLK_ENABLE();
|
||||
SBS->PMCR = (SBS->PMCR & ~SBS_PMCR_ETH_SEL_PHY_Msk) | SBS_PMCR_ETH_SEL_PHY_2;
|
||||
#elif defined(STM32H7)
|
||||
SYSCFG->PMCR = (SYSCFG->PMCR & ~SYSCFG_PMCR_EPIS_SEL_Msk) | SYSCFG_PMCR_EPIS_SEL_2;
|
||||
#elif defined(STM32N6)
|
||||
LL_RCC_SetETHPHYInterface(LL_RCC_ETH1PHY_IF_RMII);
|
||||
#else
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL;
|
||||
@@ -265,6 +307,13 @@ static int eth_mac_init(eth_t *self) {
|
||||
#elif defined(STM32H7)
|
||||
__HAL_RCC_ETH1MAC_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_ETH1MAC_CLK_SLEEP_ENABLE();
|
||||
__HAL_RCC_ETH1TX_CLK_SLEEP_ENABLE();
|
||||
__HAL_RCC_ETH1RX_CLK_SLEEP_ENABLE();
|
||||
#elif defined(STM32N6)
|
||||
__HAL_RCC_ETH1_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_ETH1_CLK_SLEEP_ENABLE();
|
||||
__HAL_RCC_ETH1MAC_CLK_SLEEP_ENABLE();
|
||||
__HAL_RCC_ETH1TX_CLK_SLEEP_ENABLE();
|
||||
__HAL_RCC_ETH1RX_CLK_SLEEP_ENABLE();
|
||||
@@ -277,7 +326,7 @@ static int eth_mac_init(eth_t *self) {
|
||||
#endif
|
||||
|
||||
// Do a soft reset of the MAC core
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
#define ETH_SOFT_RESET(eth) do { eth->DMAMR = ETH_DMAMR_SWR; } while (0)
|
||||
#define ETH_IS_RESET(eth) (eth->DMAMR & ETH_DMAMR_SWR)
|
||||
#else
|
||||
@@ -299,7 +348,7 @@ static int eth_mac_init(eth_t *self) {
|
||||
// Set MII clock range
|
||||
uint32_t hclk = HAL_RCC_GetHCLKFreq();
|
||||
uint32_t cr_div;
|
||||
#if defined(STM32H5)
|
||||
#if defined(STM32H5) || defined(STM32N6)
|
||||
cr_div = ETH->MACMDIOAR & ~ETH_MACMDIOAR_CR;
|
||||
if (hclk < 35000000) {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV16;
|
||||
@@ -311,8 +360,17 @@ static int eth_mac_init(eth_t *self) {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV62;
|
||||
} else if (hclk < 250000000) {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV102;
|
||||
#if defined(STM32H5)
|
||||
} else {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV124;
|
||||
#else
|
||||
} else if (hclk < 300000000) {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV124;
|
||||
} else if (hclk < 500000000) {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV204;
|
||||
} else {
|
||||
cr_div |= ETH_MACMDIOAR_CR_DIV324;
|
||||
#endif
|
||||
}
|
||||
ETH->MACMDIOAR = cr_div;
|
||||
#elif defined(STM32H7)
|
||||
@@ -344,9 +402,17 @@ static int eth_mac_init(eth_t *self) {
|
||||
ETH->MACMIIAR = cr_div;
|
||||
#endif
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
// Configure the MAC 1-us tick counter register.
|
||||
WRITE_REG(ETH->MAC1USTCR, HAL_RCC_GetHCLKFreq() / 1000000U - 1U);
|
||||
#endif
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
// don't skip 32bit words since our descriptors are continuous in memory
|
||||
ETH->DMACCR &= ~(ETH_DMACCR_DSL_Msk);
|
||||
#elif defined(STM32N6)
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACCR &= ~(ETH_DMACxCR_DSL_Msk);
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACCR &= ~(ETH_DMACxCR_DSL_Msk);
|
||||
#endif
|
||||
|
||||
// Reset the PHY
|
||||
@@ -397,7 +463,7 @@ static int eth_mac_init(eth_t *self) {
|
||||
uint16_t phy_scsr = self->phy_get_link_status(self->phy_addr);
|
||||
|
||||
// Burst mode configuration
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
ETH->DMASBMR = ETH->DMASBMR & ~ETH_DMASBMR_AAL & ~ETH_DMASBMR_FB;
|
||||
#else
|
||||
ETH->DMABMR = 0;
|
||||
@@ -410,6 +476,11 @@ static int eth_mac_init(eth_t *self) {
|
||||
| ETH_DMACIER_NIE // enable normal interrupts
|
||||
| ETH_DMACIER_RIE // enable RX interrupt
|
||||
;
|
||||
#elif defined(STM32N6)
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACIER =
|
||||
ETH_DMACxIER_NIE // enable normal interrupts
|
||||
| ETH_DMACxIER_RIE // enable RX interrupt
|
||||
;
|
||||
#else
|
||||
ETH->DMAIER =
|
||||
ETH_DMAIER_NISE // enable normal interrupts
|
||||
@@ -419,7 +490,7 @@ static int eth_mac_init(eth_t *self) {
|
||||
|
||||
// Configure RX descriptor lists
|
||||
for (size_t i = 0; i < RX_BUF_NUM; ++i) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
eth_dma.rx_descr[i].rdes3 =
|
||||
1 << RX_DESCR_3_OWN_Pos
|
||||
| (1 << RX_DESCR_3_BUF1V_Pos) // buf1 address valid
|
||||
@@ -439,6 +510,11 @@ static int eth_mac_init(eth_t *self) {
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
ETH->DMACRDLAR = (uint32_t)ð_dma.rx_descr[0];
|
||||
#elif defined(STM32N6)
|
||||
// Set number of RX descriptors and buffer pointers.
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACRXRLR = RX_BUF_NUM - 1;
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACRXDLAR = (uint32_t)ð_dma.rx_descr[0];
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACRXDTPR = (uint32_t)ð_dma.rx_descr[RX_BUF_NUM - 1];
|
||||
#else
|
||||
ETH->DMARDLAR = (uint32_t)ð_dma.rx_descr[0];
|
||||
#endif
|
||||
@@ -446,7 +522,7 @@ static int eth_mac_init(eth_t *self) {
|
||||
|
||||
// Configure TX descriptor lists
|
||||
for (size_t i = 0; i < TX_BUF_NUM; ++i) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
eth_dma.tx_descr[i].tdes0 = 0;
|
||||
eth_dma.tx_descr[i].tdes1 = 0;
|
||||
eth_dma.tx_descr[i].tdes2 = TX_BUF_SIZE & TX_DESCR_2_B1L_Msk;
|
||||
@@ -465,6 +541,11 @@ static int eth_mac_init(eth_t *self) {
|
||||
ETH->DMACRDRLR = RX_BUF_NUM - 1;
|
||||
|
||||
ETH->DMACTDLAR = (uint32_t)ð_dma.tx_descr[0];
|
||||
#elif defined(STM32N6)
|
||||
// Set number of TX descriptors and buffer pointers.
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACTXRLR = TX_BUF_NUM - 1;
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACTXDLAR = (uint32_t)ð_dma.tx_descr[0];
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACTXDTPR = (uint32_t)ð_dma.tx_descr[0];
|
||||
#else
|
||||
ETH->DMATDLAR = (uint32_t)ð_dma.tx_descr[0];
|
||||
#endif
|
||||
@@ -476,6 +557,11 @@ static int eth_mac_init(eth_t *self) {
|
||||
ETH->MTLRQOMR = ETH_MTLRQOMR_RSF;
|
||||
// transmission starts when a full packet resides in the Tx queue
|
||||
ETH->MTLTQOMR = ETH_MTLTQOMR_TSF;
|
||||
#elif defined(STM32N6)
|
||||
// read from RX FIFO only after a full frame is written
|
||||
ETH->MTL_QUEUE[0].MTLRXQOMR = ETH_MTLRXQxOMR_RSF;
|
||||
// transmission starts when a full packet resides in the Tx queue
|
||||
ETH->MTL_QUEUE[0].MTLTXQOMR = ETH_MTLTXQxOMR_TSF;
|
||||
#else
|
||||
ETH->DMAOMR =
|
||||
ETH_DMAOMR_RSF // read from RX FIFO after a full frame is written
|
||||
@@ -485,7 +571,7 @@ static int eth_mac_init(eth_t *self) {
|
||||
mp_hal_delay_ms(2);
|
||||
|
||||
// Select MAC filtering options
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
ETH->MACPFR = ETH_MACPFR_RA; // pass all frames up
|
||||
#else
|
||||
ETH->MACFFR =
|
||||
@@ -501,15 +587,47 @@ static int eth_mac_init(eth_t *self) {
|
||||
ETH->MACA0LR = mac[3] << 24 | mac[2] << 16 | mac[1] << 8 | mac[0];
|
||||
mp_hal_delay_ms(2);
|
||||
|
||||
// Work out the line speed configuration for MACCR.
|
||||
uint32_t maccr = 0;
|
||||
if (phy_scsr & PHY_SPEED_100HALF) {
|
||||
maccr |= ETH_MACCR_FES;
|
||||
}
|
||||
if (phy_scsr & PHY_DUPLEX) {
|
||||
maccr |= ETH_MACCR_DM;
|
||||
}
|
||||
|
||||
#if defined(STM32N6)
|
||||
|
||||
maccr |=
|
||||
ETH_MACCR_IPG_96BIT
|
||||
| ETH_MACCR_SARC_REPADDR0
|
||||
| ETH_MACCR_IPC
|
||||
| ETH_MACCR_PS
|
||||
| ETH_MACCR_BL_10
|
||||
| ETH_MACCR_PRELEN_7;
|
||||
|
||||
ETH->MACCR = maccr;
|
||||
ETH->MACECR = 0x618U;
|
||||
ETH->MACWTR = ETH_MACWTR_WTO_2KB;
|
||||
ETH->MACQ0TXFCR = ETH_MACQ0TXFCR_PLT_MINUS4;
|
||||
ETH->MACRXFCR = 0;
|
||||
ETH->MACRXQC0R = ETH_MACRXQC0R_RXQ0EN_GT | ETH_MACRXQC0R_RXQ1EN_NOT;
|
||||
|
||||
ETH->MTLOMR = ETH_MTLOMR_SCHALG_SP | ETH_MTLOMR_RAA_SP;
|
||||
ETH->MTLRXQDMAMR = ETH_MTLRXQDMAMR_Q0MDMACH_DMACH0 | ETH_MTLRXQDMAMR_Q1MDMACH_DMACH1;
|
||||
ETH->MTL_QUEUE[0].MTLTXQOMR = ETH_MTLTXQxOMR_TXQEN_EN | ETH_MTLTXQxOMR_TSF | 7 << ETH_MTLTXQxOMR_TQS_Pos;
|
||||
ETH->MTL_QUEUE[1].MTLTXQOMR = ETH_MTLTXQxOMR_TXQEN_EN | ETH_MTLTXQxOMR_TSF | 7 << ETH_MTLTXQxOMR_TQS_Pos;
|
||||
ETH->MTL_QUEUE[0].MTLRXQOMR = ETH_MTLRXQxOMR_RSF | 15 << ETH_MTLRXQxOMR_RQS_Pos;
|
||||
ETH->MTL_QUEUE[1].MTLRXQOMR = ETH_MTLRXQxOMR_RSF | 15 << ETH_MTLRXQxOMR_RQS_Pos;
|
||||
|
||||
#else
|
||||
|
||||
// Set main MAC control register
|
||||
ETH->MACCR =
|
||||
phy_scsr == PHY_SPEED_10FULL ? ETH_MACCR_DM
|
||||
: phy_scsr == PHY_SPEED_100HALF ? ETH_MACCR_FES
|
||||
: phy_scsr == PHY_SPEED_100FULL ? (ETH_MACCR_FES | ETH_MACCR_DM)
|
||||
: 0
|
||||
;
|
||||
ETH->MACCR = maccr;
|
||||
mp_hal_delay_ms(2);
|
||||
|
||||
#endif
|
||||
|
||||
// Start MAC layer
|
||||
ETH->MACCR |=
|
||||
ETH_MACCR_TE // enable TX
|
||||
@@ -521,6 +639,15 @@ static int eth_mac_init(eth_t *self) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
ETH->DMACRCR |= ETH_DMACRCR_SR; // start RX
|
||||
ETH->DMACTCR |= ETH_DMACTCR_ST; // start TX
|
||||
#elif defined(STM32N6)
|
||||
ETH->MTL_QUEUE[0].MTLTXQOMR |= ETH_MTLTXQxOMR_FTQ; // flush TX FIFO
|
||||
ETH->MTL_QUEUE[1].MTLTXQOMR |= ETH_MTLTXQxOMR_FTQ; // flush TX FIFO
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACRXCR = RX_BUF_SIZE << ETH_DMACxRXCR_RBSZ_Pos;
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACRXCR |= ETH_DMACxRXCR_SR; // start RX
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACTXCR = 4 << ETH_DMACxTXCR_TXPBL_Pos;
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACTXCR |= ETH_DMACxTXCR_ST; // start TX
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACSR |= ETH_DMACxSR_TPS | ETH_DMACxSR_RPS; // clear TX/RX process stopped flags
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACSR |= ETH_DMACxSR_TPS | ETH_DMACxSR_RPS; // clear TX/RX process stopped flags
|
||||
#else
|
||||
ETH->DMAOMR |=
|
||||
ETH_DMAOMR_ST // start TX
|
||||
@@ -547,6 +674,10 @@ static void eth_mac_deinit(eth_t *self) {
|
||||
__HAL_RCC_ETH1MAC_FORCE_RESET();
|
||||
__HAL_RCC_ETH1MAC_RELEASE_RESET();
|
||||
__HAL_RCC_ETH1MAC_CLK_DISABLE();
|
||||
#elif defined(STM32N6)
|
||||
__HAL_RCC_ETH1_FORCE_RESET();
|
||||
__HAL_RCC_ETH1_RELEASE_RESET();
|
||||
__HAL_RCC_ETH1_CLK_DISABLE();
|
||||
#else
|
||||
__HAL_RCC_ETHMAC_FORCE_RESET();
|
||||
__HAL_RCC_ETHMAC_RELEASE_RESET();
|
||||
@@ -563,7 +694,7 @@ static int eth_tx_buf_get(size_t len, uint8_t **buf) {
|
||||
eth_dma_tx_descr_t *tx_descr = ð_dma.tx_descr[eth_dma.tx_descr_idx];
|
||||
uint32_t t0 = mp_hal_ticks_ms();
|
||||
for (;;) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
if (!(tx_descr->tdes3 & (1 << TX_DESCR_3_OWN_Pos))) {
|
||||
break;
|
||||
}
|
||||
@@ -577,7 +708,7 @@ static int eth_tx_buf_get(size_t len, uint8_t **buf) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
// Update TX descriptor with length and buffer pointer
|
||||
*buf = ð_dma.tx_buf[eth_dma.tx_descr_idx * TX_BUF_SIZE];
|
||||
tx_descr->tdes2 = len & TX_DESCR_2_B1L_Msk;
|
||||
@@ -599,7 +730,7 @@ static int eth_tx_buf_send(void) {
|
||||
eth_dma.tx_descr_idx = (eth_dma.tx_descr_idx + 1) % TX_BUF_NUM;
|
||||
|
||||
// Schedule to send next outgoing frame
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
tx_descr->tdes3 =
|
||||
1 << TX_DESCR_3_OWN_Pos // owned by DMA
|
||||
| 1 << TX_DESCR_3_LD_Pos // last segment
|
||||
@@ -623,6 +754,11 @@ static int eth_tx_buf_send(void) {
|
||||
ETH->DMACSR = ETH_DMACSR_TBU;
|
||||
}
|
||||
ETH->DMACTDTPR = (uint32_t)ð_dma.tx_descr[eth_dma.tx_descr_idx];
|
||||
#elif defined(STM32N6)
|
||||
if (ETH->DMA_CH[TX_DMA_CH].DMACSR & ETH_DMACxSR_TBU) {
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACSR = ETH_DMACxSR_TBU;
|
||||
}
|
||||
ETH->DMA_CH[TX_DMA_CH].DMACTXDTPR = (uint32_t)ð_dma.tx_descr[eth_dma.tx_descr_idx];
|
||||
#else
|
||||
if (ETH->DMASR & ETH_DMASR_TBUS) {
|
||||
ETH->DMASR = ETH_DMASR_TBUS;
|
||||
@@ -640,7 +776,7 @@ static void eth_dma_rx_free(void) {
|
||||
eth_dma.rx_descr_idx = (eth_dma.rx_descr_idx + 1) % RX_BUF_NUM;
|
||||
|
||||
// Schedule to get next incoming frame
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
rx_descr->rdes0 = (uint32_t)buf;
|
||||
rx_descr->rdes3 = 1 << RX_DESCR_3_OWN_Pos; // owned by DMA
|
||||
rx_descr->rdes3 |= 1 << RX_DESCR_3_BUF1V_Pos; // buf 1 address valid
|
||||
@@ -659,16 +795,24 @@ static void eth_dma_rx_free(void) {
|
||||
__DMB();
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
ETH->DMACRDTPR = (uint32_t)&rx_descr[eth_dma.rx_descr_idx];
|
||||
#elif defined(STM32N6)
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACRXDTPR = (uint32_t)&rx_descr[eth_dma.rx_descr_idx];
|
||||
#else
|
||||
ETH->DMARPDR = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ETH_IRQHandler(void) {
|
||||
MP_STATIC_ASSERT(ETH_IRQn > 0);
|
||||
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
uint32_t sr = ETH->DMACSR;
|
||||
ETH->DMACSR = ETH_DMACSR_NIS;
|
||||
uint32_t rx_interrupt = sr & ETH_DMACSR_RI;
|
||||
#elif defined(STM32N6)
|
||||
uint32_t sr = ETH->DMA_CH[RX_DMA_CH].DMACSR;
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACSR = ETH_DMACxSR_NIS;
|
||||
uint32_t rx_interrupt = sr & ETH_DMACxSR_RI;
|
||||
#else
|
||||
uint32_t sr = ETH->DMASR;
|
||||
ETH->DMASR = ETH_DMASR_NIS;
|
||||
@@ -677,11 +821,13 @@ void ETH_IRQHandler(void) {
|
||||
if (rx_interrupt) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
ETH->DMACSR = ETH_DMACSR_RI;
|
||||
#elif defined(STM32N6)
|
||||
ETH->DMA_CH[RX_DMA_CH].DMACSR = ETH_DMACxSR_RI;
|
||||
#else
|
||||
ETH->DMASR = ETH_DMASR_RS;
|
||||
#endif
|
||||
for (;;) {
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
eth_dma_rx_descr_t *rx_descr_l = ð_dma.rx_descr[eth_dma.rx_descr_idx];
|
||||
if (rx_descr_l->rdes3 & (1 << RX_DESCR_3_OWN_Pos)) {
|
||||
// No more RX descriptors ready to read
|
||||
@@ -696,13 +842,13 @@ void ETH_IRQHandler(void) {
|
||||
#endif
|
||||
|
||||
// Get RX buffer containing new frame
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
size_t len = (rx_descr_l->rdes3 & RX_DESCR_3_PL_Msk);
|
||||
#else
|
||||
size_t len = (rx_descr->rdes0 & RX_DESCR_0_FL_Msk) >> RX_DESCR_0_FL_Pos;
|
||||
#endif
|
||||
len -= 4; // discard CRC at end
|
||||
#if defined(STM32H5) || defined(STM32H7)
|
||||
#if defined(STM32H5) || defined(STM32H7) || defined(STM32N6)
|
||||
uint8_t *buf = ð_dma.rx_buf[eth_dma.rx_descr_idx * RX_BUF_SIZE];
|
||||
#else
|
||||
uint8_t *buf = (uint8_t *)rx_descr->rdes2;
|
||||
@@ -875,6 +1021,8 @@ void eth_low_power_mode(eth_t *self, bool enable) {
|
||||
// Enable eth clock
|
||||
#if defined(STM32H7)
|
||||
__HAL_RCC_ETH1MAC_CLK_ENABLE();
|
||||
#elif defined(STM32N6)
|
||||
__HAL_RCC_ETH1_CLK_ENABLE();
|
||||
#else
|
||||
__HAL_RCC_ETH_CLK_ENABLE();
|
||||
#endif
|
||||
@@ -886,6 +1034,8 @@ void eth_low_power_mode(eth_t *self, bool enable) {
|
||||
// Disable eth clock.
|
||||
#if defined(STM32H7)
|
||||
__HAL_RCC_ETH1MAC_CLK_DISABLE();
|
||||
#elif defined(STM32N6)
|
||||
__HAL_RCC_ETH1_CLK_DISABLE();
|
||||
#else
|
||||
__HAL_RCC_ETH_CLK_DISABLE();
|
||||
#endif
|
||||
|
||||
@@ -318,11 +318,14 @@ static void risaf_init(void) {
|
||||
rimc_master.MasterCID = RIF_CID_1;
|
||||
rimc_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV;
|
||||
|
||||
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_ADC12, RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
|
||||
HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_SDMMC1, &rimc_master);
|
||||
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_SDMMC1, RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
|
||||
HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_SDMMC2, &rimc_master);
|
||||
HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_ETH1, &rimc_master);
|
||||
|
||||
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_ADC12, RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
|
||||
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_SDMMC1, RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
|
||||
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_SDMMC2, RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
|
||||
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_ETH1, RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -482,6 +482,11 @@ void SystemClock_Config(void) {
|
||||
LL_RCC_IC11_SetDivider(1);
|
||||
LL_RCC_IC11_Enable();
|
||||
|
||||
// Configure IC12 at 100MHz for ETH1CLKSEL.
|
||||
LL_RCC_IC12_SetSource(LL_RCC_ICCLKSOURCE_PLL1);
|
||||
LL_RCC_IC12_SetDivider(8);
|
||||
LL_RCC_IC12_Enable();
|
||||
|
||||
// Configure IC14 at 100MHz for slower peripherals.
|
||||
LL_RCC_IC14_SetSource(LL_RCC_ICCLKSOURCE_PLL1);
|
||||
LL_RCC_IC14_SetDivider(8);
|
||||
|
||||
Reference in New Issue
Block a user