software/libbase/mdio: set data before clock, revert two cycle turnaround and test...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 9 Aug 2019 11:26:31 +0000 (13:26 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Fri, 9 Aug 2019 11:26:31 +0000 (13:26 +0200)
litex/soc/software/libbase/mdio.c

index 362e274c4f7d6c96a677f861b7d4c6d0f3d530ae..770c25e99a55b20ceb2e82551ce857382c6f60d6 100644 (file)
@@ -16,15 +16,17 @@ static void raw_write(unsigned int word, int bitcount)
        word <<= 32 - bitcount;
        while(bitcount > 0) {
                if(word & 0x80000000) {
+                       ethphy_mdio_w_write(MDIO_DO|MDIO_OE);
+                       delay();
                        ethphy_mdio_w_write(MDIO_CLK|MDIO_DO|MDIO_OE);
                        delay();
                        ethphy_mdio_w_write(MDIO_DO|MDIO_OE);
-                       delay();
                } else {
+                       ethphy_mdio_w_write(MDIO_OE);
+                       delay();
                        ethphy_mdio_w_write(MDIO_CLK|MDIO_OE);
                        delay();
                        ethphy_mdio_w_write(MDIO_OE);
-                       delay();
                }
                word <<= 1;
                bitcount--;
@@ -39,22 +41,26 @@ static unsigned int raw_read(void)
        word = 0;
        for(i=0;i<16;i++) {
                word <<= 1;
+               if(ethphy_mdio_r_read() & MDIO_DI)
+                       word |= 1;
                ethphy_mdio_w_write(MDIO_CLK);
                delay();
                ethphy_mdio_w_write(0);
                delay();
-               if(ethphy_mdio_r_read() & MDIO_DI)
-                       word |= 1;
        }
        return word;
 }
 
 static void raw_turnaround(void)
 {
+       delay();
        ethphy_mdio_w_write(MDIO_CLK);
        delay();
        ethphy_mdio_w_write(0);
        delay();
+       ethphy_mdio_w_write(MDIO_CLK);
+       delay();
+       ethphy_mdio_w_write(0);
 }
 
 void mdio_write(int phyadr, int reg, int val)