mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 15:01:03 +08:00
Merge pull request #2014 from cesanta/halfnofast
Add support for 10M and half-duplex in STM32 and TM4C drivers
This commit is contained in:
commit
b2a76dba98
@ -29,7 +29,12 @@ static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants
|
||||
enum {
|
||||
PHY_ADDR = 0,
|
||||
PHY_BCR = 0,
|
||||
PHY_BSR = 1,
|
||||
PHY_CSCR = 31
|
||||
}; // PHY constants
|
||||
|
||||
static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
|
||||
ETH->MACMIIAR &= (7 << 2);
|
||||
@ -102,7 +107,8 @@ static int guess_mdc_cr(void) {
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
struct mip_driver_stm32_data *d = (struct mip_driver_stm32_data *) ifp->driver_data;
|
||||
struct mip_driver_stm32_data *d =
|
||||
(struct mip_driver_stm32_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -152,7 +158,8 @@ static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_stm32_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t mip_driver_stm32_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // Frame is too big
|
||||
@ -175,8 +182,17 @@ static size_t mip_driver_stm32_tx(const void *buf, size_t len, struct mip_if *if
|
||||
|
||||
static bool mip_driver_stm32_up(struct mip_if *ifp) {
|
||||
uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
|
||||
(void) ifp;
|
||||
return bsr & BIT(2) ? 1 : 0;
|
||||
bool up = bsr & BIT(2) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR);
|
||||
uint32_t maccr = ETH->MACCR | BIT(14) | BIT(11); // 100M, Full-duplex
|
||||
if ((scsr & BIT(3)) == 0) maccr &= ~BIT(14); // 10M
|
||||
if ((scsr & BIT(4)) == 0) maccr &= ~BIT(11); // Half-duplex
|
||||
ETH->MACCR = maccr; // IRQ handler does not fiddle with this register
|
||||
MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10,
|
||||
maccr & BIT(11) ? "full" : "half"));
|
||||
}
|
||||
return up;
|
||||
}
|
||||
|
||||
void ETH_IRQHandler(void);
|
||||
@ -202,6 +218,7 @@ void ETH_IRQHandler(void) {
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_stm32 = {
|
||||
mip_driver_stm32_init, mip_driver_stm32_tx, mip_driver_rx, mip_driver_stm32_up};
|
||||
struct mip_driver mip_driver_stm32 = {mip_driver_stm32_init,
|
||||
mip_driver_stm32_tx, mip_driver_rx,
|
||||
mip_driver_stm32_up};
|
||||
#endif
|
||||
|
@ -35,7 +35,12 @@ static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
enum { EPHY_ADDR = 0, EPHYBMCR = 0, EPHYBMSR = 1 }; // PHY constants
|
||||
enum {
|
||||
EPHY_ADDR = 0,
|
||||
EPHYBMCR = 0,
|
||||
EPHYBMSR = 1,
|
||||
EPHYSTS = 16
|
||||
}; // PHY constants
|
||||
|
||||
static inline void tm4cspin(volatile uint32_t count) {
|
||||
while (count--) (void) 0;
|
||||
@ -124,7 +129,8 @@ static int guess_mdc_cr(void) {
|
||||
}
|
||||
|
||||
static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
struct mip_driver_tm4c_data *d = (struct mip_driver_tm4c_data *) ifp->driver_data;
|
||||
struct mip_driver_tm4c_data *d =
|
||||
(struct mip_driver_tm4c_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -178,7 +184,8 @@ static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_tm4c_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t mip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // fail
|
||||
@ -203,8 +210,17 @@ static size_t mip_driver_tm4c_tx(const void *buf, size_t len, struct mip_if *ifp
|
||||
|
||||
static bool mip_driver_tm4c_up(struct mip_if *ifp) {
|
||||
uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
|
||||
(void) ifp;
|
||||
return (bmsr & BIT(2)) ? 1 : 0;
|
||||
bool up = (bmsr & BIT(2)) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
uint32_t sts = emac_read_phy(EPHY_ADDR, EPHYSTS);
|
||||
uint32_t emaccfg = EMAC->EMACCFG | BIT(14) | BIT(11); // 100M, Full-duplex
|
||||
if (sts & BIT(1)) emaccfg &= ~BIT(14); // 10M
|
||||
if ((sts & BIT(2)) == 0) emaccfg &= ~BIT(11); // Half-duplex
|
||||
EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register
|
||||
MG_DEBUG(("Link is %uM %s-duplex", emaccfg & BIT(14) ? 100 : 10,
|
||||
emaccfg & BIT(11) ? "full" : "half"));
|
||||
}
|
||||
return up;
|
||||
}
|
||||
|
||||
void EMAC0_IRQHandler(void);
|
||||
|
57
mongoose.c
57
mongoose.c
@ -5988,7 +5988,12 @@ static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants
|
||||
enum {
|
||||
PHY_ADDR = 0,
|
||||
PHY_BCR = 0,
|
||||
PHY_BSR = 1,
|
||||
PHY_CSCR = 31
|
||||
}; // PHY constants
|
||||
|
||||
static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
|
||||
ETH->MACMIIAR &= (7 << 2);
|
||||
@ -6061,7 +6066,8 @@ static int guess_mdc_cr(void) {
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
struct mip_driver_stm32_data *d = (struct mip_driver_stm32_data *) ifp->driver_data;
|
||||
struct mip_driver_stm32_data *d =
|
||||
(struct mip_driver_stm32_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -6111,7 +6117,8 @@ static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_stm32_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t mip_driver_stm32_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // Frame is too big
|
||||
@ -6134,8 +6141,17 @@ static size_t mip_driver_stm32_tx(const void *buf, size_t len, struct mip_if *if
|
||||
|
||||
static bool mip_driver_stm32_up(struct mip_if *ifp) {
|
||||
uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
|
||||
(void) ifp;
|
||||
return bsr & BIT(2) ? 1 : 0;
|
||||
bool up = bsr & BIT(2) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
uint32_t scsr = eth_read_phy(PHY_ADDR, PHY_CSCR);
|
||||
uint32_t maccr = ETH->MACCR | BIT(14) | BIT(11); // 100M, Full-duplex
|
||||
if ((scsr & BIT(3)) == 0) maccr &= ~BIT(14); // 10M
|
||||
if ((scsr & BIT(4)) == 0) maccr &= ~BIT(11); // Half-duplex
|
||||
ETH->MACCR = maccr; // IRQ handler does not fiddle with this register
|
||||
MG_DEBUG(("Link is %uM %s-duplex", maccr & BIT(14) ? 100 : 10,
|
||||
maccr & BIT(11) ? "full" : "half"));
|
||||
}
|
||||
return up;
|
||||
}
|
||||
|
||||
void ETH_IRQHandler(void);
|
||||
@ -6161,8 +6177,9 @@ void ETH_IRQHandler(void) {
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_stm32 = {
|
||||
mip_driver_stm32_init, mip_driver_stm32_tx, mip_driver_rx, mip_driver_stm32_up};
|
||||
struct mip_driver mip_driver_stm32 = {mip_driver_stm32_init,
|
||||
mip_driver_stm32_tx, mip_driver_rx,
|
||||
mip_driver_stm32_up};
|
||||
#endif
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
@ -6205,7 +6222,12 @@ static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
enum { EPHY_ADDR = 0, EPHYBMCR = 0, EPHYBMSR = 1 }; // PHY constants
|
||||
enum {
|
||||
EPHY_ADDR = 0,
|
||||
EPHYBMCR = 0,
|
||||
EPHYBMSR = 1,
|
||||
EPHYSTS = 16
|
||||
}; // PHY constants
|
||||
|
||||
static inline void tm4cspin(volatile uint32_t count) {
|
||||
while (count--) (void) 0;
|
||||
@ -6294,7 +6316,8 @@ static int guess_mdc_cr(void) {
|
||||
}
|
||||
|
||||
static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
struct mip_driver_tm4c_data *d = (struct mip_driver_tm4c_data *) ifp->driver_data;
|
||||
struct mip_driver_tm4c_data *d =
|
||||
(struct mip_driver_tm4c_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -6348,7 +6371,8 @@ static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_tm4c_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t mip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // fail
|
||||
@ -6373,8 +6397,17 @@ static size_t mip_driver_tm4c_tx(const void *buf, size_t len, struct mip_if *ifp
|
||||
|
||||
static bool mip_driver_tm4c_up(struct mip_if *ifp) {
|
||||
uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
|
||||
(void) ifp;
|
||||
return (bmsr & BIT(2)) ? 1 : 0;
|
||||
bool up = (bmsr & BIT(2)) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
uint32_t sts = emac_read_phy(EPHY_ADDR, EPHYSTS);
|
||||
uint32_t emaccfg = EMAC->EMACCFG | BIT(14) | BIT(11); // 100M, Full-duplex
|
||||
if (sts & BIT(1)) emaccfg &= ~BIT(14); // 10M
|
||||
if ((sts & BIT(2)) == 0) emaccfg &= ~BIT(11); // Half-duplex
|
||||
EMAC->EMACCFG = emaccfg; // IRQ handler does not fiddle with this register
|
||||
MG_DEBUG(("Link is %uM %s-duplex", emaccfg & BIT(14) ? 100 : 10,
|
||||
emaccfg & BIT(11) ? "full" : "half"));
|
||||
}
|
||||
return up;
|
||||
}
|
||||
|
||||
void EMAC0_IRQHandler(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user