diff options
| -rw-r--r-- | ports/stm32/boards/stm32n657_af.csv | 11 | ||||
| -rw-r--r-- | ports/stm32/boards/stm32n6xx_hal_conf_base.h | 1 | ||||
| -rw-r--r-- | ports/stm32/eth.c | 214 | ||||
| -rw-r--r-- | ports/stm32/main.c | 7 | ||||
| -rw-r--r-- | ports/stm32/powerctrlboot.c | 5 |
5 files changed, 203 insertions, 35 deletions
diff --git a/ports/stm32/boards/stm32n657_af.csv b/ports/stm32/boards/stm32n657_af.csv index 220d27b3f..d7af19399 100644 --- a/ports/stm32/boards/stm32n657_af.csv +++ b/ports/stm32/boards/stm32n657_af.csv @@ -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 diff --git a/ports/stm32/boards/stm32n6xx_hal_conf_base.h b/ports/stm32/boards/stm32n6xx_hal_conf_base.h index 641a003d8..87556cf15 100644 --- a/ports/stm32/boards/stm32n6xx_hal_conf_base.h +++ b/ports/stm32/boards/stm32n6xx_hal_conf_base.h @@ -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" diff --git a/ports/stm32/eth.c b/ports/stm32/eth.c index 9f6553068..0f8af5311 100644 --- a/ports/stm32/eth.c +++ b/ports/stm32/eth.c @@ -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; @@ -268,6 +310,13 @@ static int eth_mac_init(eth_t *self) { __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(); #else __HAL_RCC_ETHMAC_RELEASE_RESET(); @@ -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 diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 2d97adb1d..6f7413694 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -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 diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c index a8ef8c34a..7baaa6773 100644 --- a/ports/stm32/powerctrlboot.c +++ b/ports/stm32/powerctrlboot.c @@ -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); |
