STM32H7 MAC status
Moderator: RoccoMarco
STM32H7 MAC status
Hi,
ChibiOS-21.11.4, GCC 9.5.0
I'm trying to get MAC running on a custom STM32H743ZI board with a DP83848I wired as RMII.
First, I started with a STM32H723 nucleo144 devkit (which has a LAN8742A also wired RMII). Starting with the demo project for that board, I managed to start the MAC and initialize LWIP with a static IP. I did have to call SCB_DisableDCache() before it would work.
I then tried the same test on the H743 (different board file to accommodate pins). The first issue I had was getting an assert in mii_find_phy(). After looking at the MDIO/MCK signals on the logic analyzer, and single stepping in the debugger, it seems that the mii_read() function (which returns the contents of MACMDIODR) was failing to match the expected MII_PHYSID1. For some reason the upper 16 bits in that register are not 0x0000 (it contained 0x00012000, instead of 0x00002000). I blindly changed mii_read() to mask only the lower 16bits, which gets it to recognize the LAN chip and read a few other registers, but it still does not respond to ping after initializing LWIP.
I don't like just blindly hacking so I thought I'd ask for advice on how to proceed.
Thanks,
Dave
ChibiOS-21.11.4, GCC 9.5.0
I'm trying to get MAC running on a custom STM32H743ZI board with a DP83848I wired as RMII.
First, I started with a STM32H723 nucleo144 devkit (which has a LAN8742A also wired RMII). Starting with the demo project for that board, I managed to start the MAC and initialize LWIP with a static IP. I did have to call SCB_DisableDCache() before it would work.
I then tried the same test on the H743 (different board file to accommodate pins). The first issue I had was getting an assert in mii_find_phy(). After looking at the MDIO/MCK signals on the logic analyzer, and single stepping in the debugger, it seems that the mii_read() function (which returns the contents of MACMDIODR) was failing to match the expected MII_PHYSID1. For some reason the upper 16 bits in that register are not 0x0000 (it contained 0x00012000, instead of 0x00002000). I blindly changed mii_read() to mask only the lower 16bits, which gets it to recognize the LAN chip and read a few other registers, but it still does not respond to ping after initializing LWIP.
I don't like just blindly hacking so I thought I'd ask for advice on how to proceed.
Thanks,
Dave
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32H7 MAC status
Play with GPIO settings and check the PHY datasheet and board schematic, those often do tricks with pullups/pulldowns to latch the PHY address.
Giovanni
Giovanni
Re: STM32H7 MAC status
OK so a little progress:
I noted that this PHY is strapped to be phyaddr = 1. I think there is a bug in the MACv2 mii_find_phy() function:
The upper 16 bits of ETH->MACMDIODR reg is being set with the phyaddr index, but I don't think that is correct here (it lives in MACMDIOAR, set on the line above). In fact, even setting MACMDIOAR in this function is redundant because the first thing mii_read() does is set those, and several other bits. If I comment out those two lines, the PHYSID is read back from MACMDIODR as expected (without the 0xFFFF hack in my previous post).
I think also that MACMDIODR_CR was meant to be named MACMDIOAR_CR seeing the other ways it is being used.
I still do not get ping yet, but I thought I'd share my progress on this bit. Do you agree with my assessment?
Thanks,
Dave
I noted that this PHY is strapped to be phyaddr = 1. I think there is a bug in the MACv2 mii_find_phy() function:
Code: Select all
for (i = 0U; i <= 31U; i++) {
macp->phyaddr = i << ETH_MACMDIOAR_PA_Pos;
ETH->MACMDIOAR = (i << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR;
ETH->MACMDIODR = (i << ETH_MACMDIODR_RA_Pos) | MACMDIODR_CR;
if (((mii_read(macp, MII_PHYSID1)) == (BOARD_PHY_ID >> 16U)) &&
((mii_read(macp, MII_PHYSID2) & 0xFFF0U) == (BOARD_PHY_ID & 0xFFF0U))) {
return;
}
}
The upper 16 bits of ETH->MACMDIODR reg is being set with the phyaddr index, but I don't think that is correct here (it lives in MACMDIOAR, set on the line above). In fact, even setting MACMDIOAR in this function is redundant because the first thing mii_read() does is set those, and several other bits. If I comment out those two lines, the PHYSID is read back from MACMDIODR as expected (without the 0xFFFF hack in my previous post).
I think also that MACMDIODR_CR was meant to be named MACMDIOAR_CR seeing the other ways it is being used.
I still do not get ping yet, but I thought I'd share my progress on this bit. Do you agree with my assessment?
Thanks,
Dave
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32H7 MAC status
It is possible there is an error, try comparing with MACv1, it is very different.
Giovanni
Giovanni
Re: STM32H7 MAC status
Some more progress:
While probing around the circuits to verify wiring etc., my poor 100MHz scope is not very good at 100BaseT signals. So I programmed the phy (write_mii) to be stuck at 10BaseT/half duplex. After doing that I do get a response to ping, but with about 95% responses lost.
On my scope, I can see the signals come in from the transformer, go through the PHY and out the RX0/RX1 pair of pins to the micro. This happens once a second (ie with every ping received). However, I only seem to get an interrupt once in a while.
This exact same test, running on my H723 nucleo (different PHY) works as expected.
Just wondering if there are any common gotchas when switching PHY around? Clock polarity/phase? I'm quite new to this, so any thoughts are appreciated. Next session, I'll have to borrow a faster logic analyzer and see if it can decode the digital signals coming from the PHY.
Dave
While probing around the circuits to verify wiring etc., my poor 100MHz scope is not very good at 100BaseT signals. So I programmed the phy (write_mii) to be stuck at 10BaseT/half duplex. After doing that I do get a response to ping, but with about 95% responses lost.
On my scope, I can see the signals come in from the transformer, go through the PHY and out the RX0/RX1 pair of pins to the micro. This happens once a second (ie with every ping received). However, I only seem to get an interrupt once in a while.
This exact same test, running on my H723 nucleo (different PHY) works as expected.
Just wondering if there are any common gotchas when switching PHY around? Clock polarity/phase? I'm quite new to this, so any thoughts are appreciated. Next session, I'll have to borrow a faster logic analyzer and see if it can decode the digital signals coming from the PHY.
Dave
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32H7 MAC status
Well, the board was assembled in 2024.
The DBGMCU REV_ID field indicates it is revision 'V' (and the case also has a V). This is the highest hex number in the reference manual (0x2003), but it is also the lowest letter. So now I'm more confused than before as to if it is new or old.
I'll check against the other (working) devkit when I can plug it in next.
Scanning the errata.
Dave
The DBGMCU REV_ID field indicates it is revision 'V' (and the case also has a V). This is the highest hex number in the reference manual (0x2003), but it is also the lowest letter. So now I'm more confused than before as to if it is new or old.
I'll check against the other (working) devkit when I can plug it in next.
Scanning the errata.
Dave
Re: STM32H7 MAC status
Ok, this issue was actually a wiring problem. When using the DP83848 PHY in RMII mode, you are not supposed to use its RX reference clock output, but feed the raw oscillator into the STM32. The phase was off just enough that it was violating the hold time.
I still think my comments in post #3 are valid, namely:
Should be deleted, and MACMDIODR_CR should be renamed to MACMDIOAR_CR. I can provide a patch if you'd like.
Dave
I still think my comments in post #3 are valid, namely:
ETH->MACMDIOAR = (i << ETH_MACMDIOAR_RDA_Pos) | MACMDIODR_CR;
ETH->MACMDIODR = (i << ETH_MACMDIODR_RA_Pos) | MACMDIODR_CR;
Should be deleted, and MACMDIODR_CR should be renamed to MACMDIOAR_CR. I can provide a patch if you'd like.
Dave
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times