mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 15:01:03 +08:00
Merge pull request #2759 from cesanta/synpsys
Move stm32h driver to synopsys
This commit is contained in:
commit
b61575eb2b
124
mongoose.c
124
mongoose.c
@ -16511,9 +16511,11 @@ struct mg_tcpip_driver mg_tcpip_driver_stm32f = {
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
|
||||
MG_ENABLE_DRIVER_STM32H
|
||||
struct stm32h_eth {
|
||||
#if MG_ENABLE_TCPIP && (MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN)
|
||||
// STM32H: vendor modded single-queue Synopsys v4.2
|
||||
// MCXNx4x: dual-queue Synopsys v5.2
|
||||
// RT1170 ENET_QOS: quad-queue Synopsys v5.1
|
||||
struct synopsys_enet_qos {
|
||||
volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
|
||||
RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
|
||||
RESERVED4[2], MACTFCR, RESERVED5[7], MACRFCR, RESERVED6[7], MACISR,
|
||||
@ -16544,8 +16546,13 @@ struct stm32h_eth {
|
||||
DMACMFCR;
|
||||
};
|
||||
#undef ETH
|
||||
#define ETH \
|
||||
((struct stm32h_eth *) (uintptr_t) (0x40000000UL + 0x00020000UL + 0x8000UL))
|
||||
#if MG_ENABLE_DRIVER_STM32H
|
||||
#define ETH \
|
||||
((struct synopsys_enet_qos *) (uintptr_t) (0x40000000UL + 0x00020000UL + \
|
||||
0x8000UL))
|
||||
#elif MG_ENABLE_DRIVER_MCXN
|
||||
#define ETH ((struct synopsys_enet_qos *) (uintptr_t) 0x40100000UL)
|
||||
#endif
|
||||
|
||||
#define ETH_PKT_SIZE 1540 // Max frame size
|
||||
#define ETH_DESC_CNT 4 // Descriptors count
|
||||
@ -16573,82 +16580,6 @@ static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
|
||||
while (ETH->MACMDIOAR & MG_BIT(0)) (void) 0;
|
||||
}
|
||||
|
||||
static uint32_t get_hclk(void) {
|
||||
struct rcc {
|
||||
volatile uint32_t CR, HSICFGR, CRRCR, CSICFGR, CFGR, RESERVED1, D1CFGR,
|
||||
D2CFGR, D3CFGR, RESERVED2, PLLCKSELR, PLLCFGR, PLL1DIVR, PLL1FRACR,
|
||||
PLL2DIVR, PLL2FRACR, PLL3DIVR, PLL3FRACR, RESERVED3, D1CCIPR, D2CCIP1R,
|
||||
D2CCIP2R, D3CCIPR, RESERVED4, CIER, CIFR, CICR, RESERVED5, BDCR, CSR,
|
||||
RESERVED6, AHB3RSTR, AHB1RSTR, AHB2RSTR, AHB4RSTR, APB3RSTR, APB1LRSTR,
|
||||
APB1HRSTR, APB2RSTR, APB4RSTR, GCR, RESERVED8, D3AMR, RESERVED11[9],
|
||||
RSR, AHB3ENR, AHB1ENR, AHB2ENR, AHB4ENR, APB3ENR, APB1LENR, APB1HENR,
|
||||
APB2ENR, APB4ENR, RESERVED12, AHB3LPENR, AHB1LPENR, AHB2LPENR,
|
||||
AHB4LPENR, APB3LPENR, APB1LLPENR, APB1HLPENR, APB2LPENR, APB4LPENR,
|
||||
RESERVED13[4];
|
||||
} *rcc = ((struct rcc *) (0x40000000 + 0x18020000 + 0x4400));
|
||||
uint32_t clk = 0, hsi = 64000000 /* 64 MHz */, hse = 8000000 /* 8MHz */,
|
||||
csi = 4000000 /* 4MHz */;
|
||||
unsigned int sel = (rcc->CFGR & (7 << 3)) >> 3;
|
||||
|
||||
if (sel == 1) {
|
||||
clk = csi;
|
||||
} else if (sel == 2) {
|
||||
clk = hse;
|
||||
} else if (sel == 3) {
|
||||
uint32_t vco, m, n, p;
|
||||
unsigned int src = (rcc->PLLCKSELR & (3 << 0)) >> 0;
|
||||
m = ((rcc->PLLCKSELR & (0x3F << 4)) >> 4);
|
||||
n = ((rcc->PLL1DIVR & (0x1FF << 0)) >> 0) + 1 +
|
||||
((rcc->PLLCFGR & MG_BIT(0)) ? 1 : 0); // round-up in fractional mode
|
||||
p = ((rcc->PLL1DIVR & (0x7F << 9)) >> 9) + 1;
|
||||
if (src == 1) {
|
||||
clk = csi;
|
||||
} else if (src == 2) {
|
||||
clk = hse;
|
||||
} else {
|
||||
clk = hsi;
|
||||
clk >>= ((rcc->CR & 3) >> 3);
|
||||
}
|
||||
vco = (uint32_t) ((uint64_t) clk * n / m);
|
||||
clk = vco / p;
|
||||
} else {
|
||||
clk = hsi;
|
||||
clk >>= ((rcc->CR & 3) >> 3);
|
||||
}
|
||||
const uint8_t cptab[12] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div)
|
||||
uint32_t d1cpre = (rcc->D1CFGR & (0x0F << 8)) >> 8;
|
||||
if (d1cpre >= 8) clk >>= cptab[d1cpre - 8];
|
||||
MG_DEBUG(("D1 CLK: %u", clk));
|
||||
uint32_t hpre = (rcc->D1CFGR & (0x0F << 0)) >> 0;
|
||||
if (hpre < 8) return clk;
|
||||
return ((uint32_t) clk) >> cptab[hpre - 8];
|
||||
}
|
||||
|
||||
// Guess CR from AHB1 clock. MDC clock is generated from the ETH peripheral
|
||||
// clock (AHB1); as per 802.3, it must not exceed 2. As the AHB clock can
|
||||
// be derived from HSI or CSI (internal RC) clocks, and those can go above
|
||||
// specs, the datasheets specify a range of frequencies and activate one of a
|
||||
// series of dividers to keep the MDC clock safely below 2.5MHz. We guess a
|
||||
// divider setting based on HCLK with some drift. If the user uses a different
|
||||
// clock from our defaults, needs to set the macros on top. Valid for
|
||||
// STM32H74xxx/75xxx (58.11.4)(4.5% worst case drift)(CSI clock has a 7.5 %
|
||||
// worst case drift @ max temp)
|
||||
static int guess_mdc_cr(void) {
|
||||
const uint8_t crs[] = {2, 3, 0, 1, 4, 5}; // ETH->MACMDIOAR::CR values
|
||||
const uint8_t div[] = {16, 26, 42, 62, 102, 124}; // Respective HCLK dividers
|
||||
uint32_t hclk = get_hclk(); // Guess system HCLK
|
||||
int result = -1; // Invalid CR value
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
|
||||
result = crs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result < 0) MG_ERROR(("HCLK too high"));
|
||||
MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_stm32h_data *d =
|
||||
(struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
|
||||
@ -16667,11 +16598,13 @@ static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
s_txdesc[i][0] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
|
||||
}
|
||||
|
||||
ETH->DMAMR |= MG_BIT(0); // Software reset
|
||||
ETH->DMAMR |= MG_BIT(0); // Software reset
|
||||
for (int i = 0; i < 4; i++)
|
||||
(void) 0; // wait at least 4 clocks before reading
|
||||
while ((ETH->DMAMR & MG_BIT(0)) != 0) (void) 0; // Wait until done
|
||||
|
||||
// Set MDC clock divider. If user told us the value, use it. Otherwise, guess
|
||||
int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
|
||||
// Set MDC clock divider. Get user value, else, assume max freq
|
||||
int cr = (d == NULL || d->mdc_cr < 0) ? 7 : d->mdc_cr;
|
||||
ETH->MACMDIOAR = ((uint32_t) cr & 0xF) << 8;
|
||||
|
||||
// NOTE(scaprile): We do not use timing facilities so the DMA engine does not
|
||||
@ -16695,13 +16628,23 @@ static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
ETH->DMACTDTPR =
|
||||
(uint32_t) (uintptr_t) s_txdesc; // first available descriptor address
|
||||
ETH->DMACCR = 0; // DSL = 0 (contiguous descriptor table) (reset value)
|
||||
#if !MG_ENABLE_DRIVER_STM32H
|
||||
MG_SET_BITS(ETH->DMACTCR, 0x3F << 16, MG_BIT(16));
|
||||
MG_SET_BITS(ETH->DMACRCR, 0x3F << 16, MG_BIT(16));
|
||||
#endif
|
||||
ETH->DMACIER = MG_BIT(6) | MG_BIT(15); // RIE, NIE
|
||||
ETH->MACCR = MG_BIT(0) | MG_BIT(1) | MG_BIT(13) | MG_BIT(14) |
|
||||
MG_BIT(15); // RE, TE, Duplex, Fast, Reserved
|
||||
MG_BIT(15); // RE, TE, Duplex, Fast, Reserved
|
||||
#if MG_ENABLE_DRIVER_STM32H
|
||||
ETH->MTLTQOMR |= MG_BIT(1); // TSF
|
||||
ETH->MTLRQOMR |= MG_BIT(5); // RSF
|
||||
ETH->DMACTCR |= MG_BIT(0); // ST
|
||||
ETH->DMACRCR |= MG_BIT(0); // SR
|
||||
#else
|
||||
ETH->MTLTQOMR |= (7 << 16) | MG_BIT(3) | MG_BIT(1); // 2KB Q0, TSF
|
||||
ETH->MTLRQOMR |= (7 << 20) | MG_BIT(5); // 2KB Q, RSF
|
||||
MG_SET_BITS(ETH->RESERVED6[3], 3, 2); // Enable RxQ0 (MAC_RXQ_CTRL0)
|
||||
#endif
|
||||
ETH->DMACTCR |= MG_BIT(0); // ST
|
||||
ETH->DMACRCR |= MG_BIT(0); // SR
|
||||
|
||||
// MAC address filtering
|
||||
ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
|
||||
@ -16758,9 +16701,14 @@ static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
|
||||
return up;
|
||||
}
|
||||
|
||||
void ETH_IRQHandler(void);
|
||||
static uint32_t s_rxno;
|
||||
#if MG_ENABLE_DRIVER_MCXN
|
||||
void ETHERNET_IRQHandler(void);
|
||||
void ETHERNET_IRQHandler(void) {
|
||||
#else
|
||||
void ETH_IRQHandler(void);
|
||||
void ETH_IRQHandler(void) {
|
||||
#endif
|
||||
if (ETH->DMACSR & MG_BIT(6)) { // Frame received, loop
|
||||
ETH->DMACSR = MG_BIT(15) | MG_BIT(6); // Clear flag
|
||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||
|
14
mongoose.h
14
mongoose.h
@ -2848,8 +2848,14 @@ struct mg_tcpip_driver_stm32f_data {
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
|
||||
MG_ENABLE_DRIVER_STM32H
|
||||
#if MG_ENABLE_TCPIP
|
||||
#if !defined(MG_ENABLE_DRIVER_STM32H)
|
||||
#define MG_ENABLE_DRIVER_STM32H 0
|
||||
#endif
|
||||
#if !defined(MG_ENABLE_DRIVER_MCXN)
|
||||
#define MG_ENABLE_DRIVER_MCXN 0
|
||||
#endif
|
||||
#if MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN
|
||||
|
||||
struct mg_tcpip_driver_stm32h_data {
|
||||
// MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
|
||||
@ -2862,7 +2868,8 @@ struct mg_tcpip_driver_stm32h_data {
|
||||
// 35-60 MHz HCLK/26 3
|
||||
// 150-250 MHz HCLK/102 4 <-- value for max speed HSI
|
||||
// 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on CSI
|
||||
// 110, 111 Reserved
|
||||
// 300-500 MHz HCLK/204 6
|
||||
// 500-800 MHz HCLK/324 7
|
||||
int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
|
||||
|
||||
uint8_t phy_addr; // PHY address
|
||||
@ -2894,6 +2901,7 @@ struct mg_tcpip_driver_stm32h_data {
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "net_builtin.h"
|
||||
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
|
||||
MG_ENABLE_DRIVER_STM32H
|
||||
struct stm32h_eth {
|
||||
#if MG_ENABLE_TCPIP && (MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN)
|
||||
// STM32H: vendor modded single-queue Synopsys v4.2
|
||||
// MCXNx4x: dual-queue Synopsys v5.2
|
||||
// RT1170 ENET_QOS: quad-queue Synopsys v5.1
|
||||
struct synopsys_enet_qos {
|
||||
volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
|
||||
RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
|
||||
RESERVED4[2], MACTFCR, RESERVED5[7], MACRFCR, RESERVED6[7], MACISR,
|
||||
@ -33,8 +35,13 @@ struct stm32h_eth {
|
||||
DMACMFCR;
|
||||
};
|
||||
#undef ETH
|
||||
#define ETH \
|
||||
((struct stm32h_eth *) (uintptr_t) (0x40000000UL + 0x00020000UL + 0x8000UL))
|
||||
#if MG_ENABLE_DRIVER_STM32H
|
||||
#define ETH \
|
||||
((struct synopsys_enet_qos *) (uintptr_t) (0x40000000UL + 0x00020000UL + \
|
||||
0x8000UL))
|
||||
#elif MG_ENABLE_DRIVER_MCXN
|
||||
#define ETH ((struct synopsys_enet_qos *) (uintptr_t) 0x40100000UL)
|
||||
#endif
|
||||
|
||||
#define ETH_PKT_SIZE 1540 // Max frame size
|
||||
#define ETH_DESC_CNT 4 // Descriptors count
|
||||
@ -62,82 +69,6 @@ static void eth_write_phy(uint8_t addr, uint8_t reg, uint16_t val) {
|
||||
while (ETH->MACMDIOAR & MG_BIT(0)) (void) 0;
|
||||
}
|
||||
|
||||
static uint32_t get_hclk(void) {
|
||||
struct rcc {
|
||||
volatile uint32_t CR, HSICFGR, CRRCR, CSICFGR, CFGR, RESERVED1, D1CFGR,
|
||||
D2CFGR, D3CFGR, RESERVED2, PLLCKSELR, PLLCFGR, PLL1DIVR, PLL1FRACR,
|
||||
PLL2DIVR, PLL2FRACR, PLL3DIVR, PLL3FRACR, RESERVED3, D1CCIPR, D2CCIP1R,
|
||||
D2CCIP2R, D3CCIPR, RESERVED4, CIER, CIFR, CICR, RESERVED5, BDCR, CSR,
|
||||
RESERVED6, AHB3RSTR, AHB1RSTR, AHB2RSTR, AHB4RSTR, APB3RSTR, APB1LRSTR,
|
||||
APB1HRSTR, APB2RSTR, APB4RSTR, GCR, RESERVED8, D3AMR, RESERVED11[9],
|
||||
RSR, AHB3ENR, AHB1ENR, AHB2ENR, AHB4ENR, APB3ENR, APB1LENR, APB1HENR,
|
||||
APB2ENR, APB4ENR, RESERVED12, AHB3LPENR, AHB1LPENR, AHB2LPENR,
|
||||
AHB4LPENR, APB3LPENR, APB1LLPENR, APB1HLPENR, APB2LPENR, APB4LPENR,
|
||||
RESERVED13[4];
|
||||
} *rcc = ((struct rcc *) (0x40000000 + 0x18020000 + 0x4400));
|
||||
uint32_t clk = 0, hsi = 64000000 /* 64 MHz */, hse = 8000000 /* 8MHz */,
|
||||
csi = 4000000 /* 4MHz */;
|
||||
unsigned int sel = (rcc->CFGR & (7 << 3)) >> 3;
|
||||
|
||||
if (sel == 1) {
|
||||
clk = csi;
|
||||
} else if (sel == 2) {
|
||||
clk = hse;
|
||||
} else if (sel == 3) {
|
||||
uint32_t vco, m, n, p;
|
||||
unsigned int src = (rcc->PLLCKSELR & (3 << 0)) >> 0;
|
||||
m = ((rcc->PLLCKSELR & (0x3F << 4)) >> 4);
|
||||
n = ((rcc->PLL1DIVR & (0x1FF << 0)) >> 0) + 1 +
|
||||
((rcc->PLLCFGR & MG_BIT(0)) ? 1 : 0); // round-up in fractional mode
|
||||
p = ((rcc->PLL1DIVR & (0x7F << 9)) >> 9) + 1;
|
||||
if (src == 1) {
|
||||
clk = csi;
|
||||
} else if (src == 2) {
|
||||
clk = hse;
|
||||
} else {
|
||||
clk = hsi;
|
||||
clk >>= ((rcc->CR & 3) >> 3);
|
||||
}
|
||||
vco = (uint32_t) ((uint64_t) clk * n / m);
|
||||
clk = vco / p;
|
||||
} else {
|
||||
clk = hsi;
|
||||
clk >>= ((rcc->CR & 3) >> 3);
|
||||
}
|
||||
const uint8_t cptab[12] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div)
|
||||
uint32_t d1cpre = (rcc->D1CFGR & (0x0F << 8)) >> 8;
|
||||
if (d1cpre >= 8) clk >>= cptab[d1cpre - 8];
|
||||
MG_DEBUG(("D1 CLK: %u", clk));
|
||||
uint32_t hpre = (rcc->D1CFGR & (0x0F << 0)) >> 0;
|
||||
if (hpre < 8) return clk;
|
||||
return ((uint32_t) clk) >> cptab[hpre - 8];
|
||||
}
|
||||
|
||||
// Guess CR from AHB1 clock. MDC clock is generated from the ETH peripheral
|
||||
// clock (AHB1); as per 802.3, it must not exceed 2. As the AHB clock can
|
||||
// be derived from HSI or CSI (internal RC) clocks, and those can go above
|
||||
// specs, the datasheets specify a range of frequencies and activate one of a
|
||||
// series of dividers to keep the MDC clock safely below 2.5MHz. We guess a
|
||||
// divider setting based on HCLK with some drift. If the user uses a different
|
||||
// clock from our defaults, needs to set the macros on top. Valid for
|
||||
// STM32H74xxx/75xxx (58.11.4)(4.5% worst case drift)(CSI clock has a 7.5 %
|
||||
// worst case drift @ max temp)
|
||||
static int guess_mdc_cr(void) {
|
||||
const uint8_t crs[] = {2, 3, 0, 1, 4, 5}; // ETH->MACMDIOAR::CR values
|
||||
const uint8_t div[] = {16, 26, 42, 62, 102, 124}; // Respective HCLK dividers
|
||||
uint32_t hclk = get_hclk(); // Guess system HCLK
|
||||
int result = -1; // Invalid CR value
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (hclk / div[i] <= 2375000UL /* 2.5MHz - 5% */) {
|
||||
result = crs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result < 0) MG_ERROR(("HCLK too high"));
|
||||
MG_DEBUG(("HCLK: %u, CR: %d", hclk, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_stm32h_data *d =
|
||||
(struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
|
||||
@ -156,11 +87,13 @@ static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
s_txdesc[i][0] = (uint32_t) (uintptr_t) s_txbuf[i]; // Buf pointer
|
||||
}
|
||||
|
||||
ETH->DMAMR |= MG_BIT(0); // Software reset
|
||||
ETH->DMAMR |= MG_BIT(0); // Software reset
|
||||
for (int i = 0; i < 4; i++)
|
||||
(void) 0; // wait at least 4 clocks before reading
|
||||
while ((ETH->DMAMR & MG_BIT(0)) != 0) (void) 0; // Wait until done
|
||||
|
||||
// Set MDC clock divider. If user told us the value, use it. Otherwise, guess
|
||||
int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr;
|
||||
// Set MDC clock divider. Get user value, else, assume max freq
|
||||
int cr = (d == NULL || d->mdc_cr < 0) ? 7 : d->mdc_cr;
|
||||
ETH->MACMDIOAR = ((uint32_t) cr & 0xF) << 8;
|
||||
|
||||
// NOTE(scaprile): We do not use timing facilities so the DMA engine does not
|
||||
@ -184,13 +117,23 @@ static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
ETH->DMACTDTPR =
|
||||
(uint32_t) (uintptr_t) s_txdesc; // first available descriptor address
|
||||
ETH->DMACCR = 0; // DSL = 0 (contiguous descriptor table) (reset value)
|
||||
#if !MG_ENABLE_DRIVER_STM32H
|
||||
MG_SET_BITS(ETH->DMACTCR, 0x3F << 16, MG_BIT(16));
|
||||
MG_SET_BITS(ETH->DMACRCR, 0x3F << 16, MG_BIT(16));
|
||||
#endif
|
||||
ETH->DMACIER = MG_BIT(6) | MG_BIT(15); // RIE, NIE
|
||||
ETH->MACCR = MG_BIT(0) | MG_BIT(1) | MG_BIT(13) | MG_BIT(14) |
|
||||
MG_BIT(15); // RE, TE, Duplex, Fast, Reserved
|
||||
MG_BIT(15); // RE, TE, Duplex, Fast, Reserved
|
||||
#if MG_ENABLE_DRIVER_STM32H
|
||||
ETH->MTLTQOMR |= MG_BIT(1); // TSF
|
||||
ETH->MTLRQOMR |= MG_BIT(5); // RSF
|
||||
ETH->DMACTCR |= MG_BIT(0); // ST
|
||||
ETH->DMACRCR |= MG_BIT(0); // SR
|
||||
#else
|
||||
ETH->MTLTQOMR |= (7 << 16) | MG_BIT(3) | MG_BIT(1); // 2KB Q0, TSF
|
||||
ETH->MTLRQOMR |= (7 << 20) | MG_BIT(5); // 2KB Q, RSF
|
||||
MG_SET_BITS(ETH->RESERVED6[3], 3, 2); // Enable RxQ0 (MAC_RXQ_CTRL0)
|
||||
#endif
|
||||
ETH->DMACTCR |= MG_BIT(0); // ST
|
||||
ETH->DMACRCR |= MG_BIT(0); // SR
|
||||
|
||||
// MAC address filtering
|
||||
ETH->MACA0HR = ((uint32_t) ifp->mac[5] << 8U) | ifp->mac[4];
|
||||
@ -247,9 +190,14 @@ static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
|
||||
return up;
|
||||
}
|
||||
|
||||
void ETH_IRQHandler(void);
|
||||
static uint32_t s_rxno;
|
||||
#if MG_ENABLE_DRIVER_MCXN
|
||||
void ETHERNET_IRQHandler(void);
|
||||
void ETHERNET_IRQHandler(void) {
|
||||
#else
|
||||
void ETH_IRQHandler(void);
|
||||
void ETH_IRQHandler(void) {
|
||||
#endif
|
||||
if (ETH->DMACSR & MG_BIT(6)) { // Frame received, loop
|
||||
ETH->DMACSR = MG_BIT(15) | MG_BIT(6); // Clear flag
|
||||
for (uint32_t i = 0; i < 10; i++) { // read as they arrive but not forever
|
||||
|
@ -1,7 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
|
||||
MG_ENABLE_DRIVER_STM32H
|
||||
#if MG_ENABLE_TCPIP
|
||||
#if !defined(MG_ENABLE_DRIVER_STM32H)
|
||||
#define MG_ENABLE_DRIVER_STM32H 0
|
||||
#endif
|
||||
#if !defined(MG_ENABLE_DRIVER_MCXN)
|
||||
#define MG_ENABLE_DRIVER_MCXN 0
|
||||
#endif
|
||||
#if MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN
|
||||
|
||||
struct mg_tcpip_driver_stm32h_data {
|
||||
// MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
|
||||
@ -14,7 +20,8 @@ struct mg_tcpip_driver_stm32h_data {
|
||||
// 35-60 MHz HCLK/26 3
|
||||
// 150-250 MHz HCLK/102 4 <-- value for max speed HSI
|
||||
// 250-300 MHz HCLK/124 5 <-- value for Nucleo-H* on CSI
|
||||
// 110, 111 Reserved
|
||||
// 300-500 MHz HCLK/204 6
|
||||
// 500-800 MHz HCLK/324 7
|
||||
int mdc_cr; // Valid values: -1, 0, 1, 2, 3, 4, 5
|
||||
|
||||
uint8_t phy_addr; // PHY address
|
||||
@ -46,3 +53,4 @@ struct mg_tcpip_driver_stm32h_data {
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user