From af0135bcce97950816236f82dc113fd566357da2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 31 Aug 2025 20:08:24 +0200 Subject: [PATCH 1/9] Add sfr16 SFR_REG_ADDR_U16. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So instead do it manual split a uint16_t in to two uint8_t. The compiler can do it, so reduces user error. Note: compiler writes the lower/LSB part first. When that is importent this can“t be used. Assembly is still the same except note above. --- rtl837x_sfr.h | 4 ++++ rtlplayground.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index 8aa3a8c..927aa70 100644 --- a/rtl837x_sfr.h +++ b/rtl837x_sfr.h @@ -1,8 +1,12 @@ /* SFR control registers for switch register access */ __sfr __at(0xa0) SFR_EXEC_GO; __sfr __at(0xa1) SFR_EXEC_STATUS; +__sfr16 __at(0xa2a3) SFR_REG_ADDR_U16; __sfr __at(0xa2) SFR_REG_ADDRH; __sfr __at(0xa3) SFR_REG_ADDRL; +__sfr16 __at(0xa4a5) SFR_DATA_U16; +__sfr32 __at(0xa4a5a6a7) SFR_DATA_U32; +__sfr32 __at(0xa7a6a5a4) SFR_DATA_U32LE; __sfr __at(0xa4) SFR_DATA_24; __sfr __at(0xa5) SFR_DATA_16; __sfr __at(0xa6) SFR_DATA_8; diff --git a/rtlplayground.c b/rtlplayground.c index 5075095..4e358b5 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -284,8 +284,8 @@ void setup_timer0(void) void reg_read(uint16_t reg_addr) { - SFR_REG_ADDRH = reg_addr >> 8; - SFR_REG_ADDRL = reg_addr; + SFR_REG_ADDR_U16 = reg_addr; + SFR_EXEC_GO = SFR_EXEC_READ_REG; do { } while (SFR_EXEC_STATUS != 0); @@ -298,8 +298,8 @@ void reg_read_m(uint16_t reg_addr) #ifdef REGDBG if (EA) { write_char('r'); print_byte(reg_addr >> 8); print_byte(reg_addr); write_char(':'); } #endif - SFR_REG_ADDRH = reg_addr >> 8; - SFR_REG_ADDRL = reg_addr; + SFR_REG_ADDR_U16 = reg_addr; + SFR_EXEC_GO = SFR_EXEC_READ_REG; do { } while (SFR_EXEC_STATUS != 0); @@ -316,8 +316,8 @@ void reg_read_m(uint16_t reg_addr) void reg_write(uint16_t reg_addr) { /* Data to write must be in SFR A4, A5, A6, A7 */ - SFR_REG_ADDRH = reg_addr >> 8; - SFR_REG_ADDRL = reg_addr; + SFR_REG_ADDR_U16 = reg_addr; + SFR_EXEC_GO = SFR_EXEC_WRITE_REG; do { } while (SFR_EXEC_STATUS != 0); @@ -332,8 +332,8 @@ void reg_write_m(uint16_t reg_addr) print_byte(sfr_data[0]); print_byte(sfr_data[1]); print_byte(sfr_data[2]); print_byte(sfr_data[3]); write_char(' '); } #endif - SFR_REG_ADDRH = reg_addr >> 8; - SFR_REG_ADDRL = reg_addr; + SFR_REG_ADDR_U16 = reg_addr; + SFR_DATA_24 = sfr_data[0] ; SFR_DATA_16 = sfr_data[1]; SFR_DATA_8 = sfr_data[2]; From 9dafeab490223c67101884103299f38f188786a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 31 Aug 2025 20:42:16 +0200 Subject: [PATCH 2/9] Added SFR_NIC_DATA_U16LE and SFR_NIC_RING_U16LE. Let's use sfr16 for NIC data and ring. SFR define can so reordered to it does the BE to LE swap for us. --- rtl837x_sfr.h | 2 ++ rtlplayground.c | 22 ++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index 927aa70..46e5a86 100644 --- a/rtl837x_sfr.h +++ b/rtl837x_sfr.h @@ -90,7 +90,9 @@ __sfr __at(0xa9) SFR_FLASH_ADDR0; * CAREFUL: This is now Little Endian */ __sfr __at(0xb7) SFR_NIC_CTRL; +__sfr16 __at(0xb4b3) SFR_NIC_DATA_U16LE; __sfr __at(0xb3) SFR_NIC_DATA_L; __sfr __at(0xb4) SFR_NIC_DATA_H; +__sfr16 __at(0xb6b5) SFR_NIC_RING_U16LE; __sfr __at(0xb5) SFR_NIC_RING_L; __sfr __at(0xb6) SFR_NIC_RING_H; diff --git a/rtlplayground.c b/rtlplayground.c index 4e358b5..37ac990 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -393,10 +393,9 @@ void sfr_mask_data(uint8_t n, uint8_t mask, uint8_t set) void nic_rx_header(uint16_t ring_ptr) { uint16_t buffer = (uint16_t) &rx_headers[0]; - SFR_NIC_DATA_H = buffer >> 8; - SFR_NIC_DATA_L = buffer; - SFR_NIC_RING_L = ring_ptr; - SFR_NIC_RING_H = ring_ptr >> 8; + SFR_NIC_DATA_U16LE = buffer; + SFR_NIC_RING_U16LE = ring_ptr; + SFR_NIC_CTRL = 1; do { } while (SFR_NIC_CTRL != 0); } @@ -410,10 +409,9 @@ void nic_rx_header(uint16_t ring_ptr) */ void nic_rx_packet(register uint16_t buffer, register uint16_t ring_ptr) { - SFR_NIC_DATA_H = buffer >> 8; - SFR_NIC_DATA_L = buffer; - SFR_NIC_RING_L = ring_ptr; - SFR_NIC_RING_H = ring_ptr >> 8; + SFR_NIC_DATA_U16LE = buffer; + SFR_NIC_RING_U16LE = ring_ptr; + uint16_t len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4]; len += 7; len >>= 3; @@ -433,12 +431,12 @@ void nic_tx_packet(uint16_t ring_ptr) { // uint16_t buffer = (uint16_t) tx_buf; uint16_t buffer = (uint16_t) uip_buf + VLAN_TAG_SIZE; - SFR_NIC_DATA_H = buffer >> 8; - SFR_NIC_DATA_L = buffer; + SFR_NIC_DATA_U16LE = buffer; + ring_ptr <<= 3; ring_ptr |= 0x8000; - SFR_NIC_RING_L = ring_ptr; - SFR_NIC_RING_H = ring_ptr >> 8; + SFR_NIC_RING_U16LE = ring_ptr; + uint16_t len = (((uint16_t)uip_buf[VLAN_TAG_SIZE + 5]) << 8) | uip_buf[VLAN_TAG_SIZE + 4]; len += 0xf; len >>= 3; From b8928a8bcd0bea02072ee98e3c5a002704776b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 31 Aug 2025 21:03:52 +0200 Subject: [PATCH 3/9] Replace manual SFR_DATA_0 and SFR_DATA_8 pair read and write with SFR_DATA_U16. Also added SFR_SMI_REG_U16. Doing pval = reg_h; pval <<= 8; pval |= reg_l; dont always optimized by the compiler a some places, not all. A snipped of the diff between two .asm files. 5414,5424c5414,5416 < ; rtlplayground.c:1382: uint16_t pval = SFR_DATA_8; < ; rtlplayground.c:1383: pval <<= 8; < mov r7,_SFR_DATA_8 < mov r6,#0x00 < ; rtlplayground.c:1384: pval |= SFR_DATA_0; < mov r4,_SFR_DATA_0 < mov r5,#0x00 < mov a,r6 < orl ar4,a < mov a,r7 < orl ar5,a --- > ; rtlplayground.c:1382: uint16_t pval = SFR_DATA_U16; > mov r6,((_SFR_DATA_U16 >> 0) & 0xFF) > mov r7,((_SFR_DATA_U16 >> 8) & 0xFF) --- rtl837x_sfr.h | 1 + rtlplayground.c | 41 ++++++++++++++++++----------------------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index 46e5a86..71fc4ae 100644 --- a/rtl837x_sfr.h +++ b/rtl837x_sfr.h @@ -21,6 +21,7 @@ __sfr __at(0xa7) SFR_DATA_0; #define SFR_EXEC_WRITE_SMI 11 /* SFR control registers for phy access via SMI/MDIO */ +__sfr16 __at(0xc2c3) SFR_SMI_REG_U16; __sfr __at(0xc2) SFR_SMI_REG_H; __sfr __at(0xc3) SFR_SMI_REG_L; __sfr __at(0xc4) SFR_SMI_DEV; diff --git a/rtlplayground.c b/rtlplayground.c index 37ac990..47f83d7 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -505,8 +505,7 @@ void sds_write_v(uint8_t sds_id, uint8_t page, uint8_t reg, uint16_t v) print_string("Q"); print_byte(sds_id); print_byte(page); print_byte(reg); write_char(':'); print_byte(v >> 8); print_byte(v); write_char(' '); #endif - SFR_DATA_8 = v >> 8; - SFR_DATA_0 = v; + SFR_DATA_U16 = v; SFR_93 = reg; SFR_94 = page << 1 | sds_id; SFR_EXEC_GO = SFR_EXEC_WRITE_SDS; @@ -1086,11 +1085,11 @@ void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v) print_string("P"); print_byte(phy_mask>>8); print_byte(phy_mask); print_byte(dev_id); write_char('.'); print_byte(reg>>8); print_byte(reg); write_char(':'); print_byte(v>>8); print_byte(v); write_char(' '); #endif - SFR_DATA_8 = v >> 8; // SFR_A6 - SFR_DATA_0 = v; // SFR_A7 + SFR_DATA_U16 = v ; // SFR_A6, SFR_A7 + SFR_SMI_PHYMASK = phy_mask; // SFR_C5 - SFR_SMI_REG_H = reg >> 8; // SFR_C2 - SFR_SMI_REG_L = reg; // SFR_C3 + SFR_SMI_REG_U16 = reg; // SFR_C2, SFR_C3 + SFR_SMI_DEV = (phy_mask >> 8) | dev_id << 3 | 2; // SFR_C4: bit 2 can also be set for some option SFR_EXEC_GO = SFR_EXEC_WRITE_SMI; do { @@ -1132,8 +1131,8 @@ void phy_read(uint8_t phy_id, uint8_t dev_id, uint16_t reg) #ifdef REGDBG print_string("p"); print_byte(phy_id); print_byte(dev_id); write_char('.'); print_byte(reg>>8); print_byte(reg); write_char(':'); #endif - SFR_SMI_REG_H = reg >> 8; // c3 - SFR_SMI_REG_L = reg; // c2 + SFR_SMI_REG_U16 = reg; // c2, c2 + SFR_SMI_PHY = phy_id; // a5 SFR_SMI_DEV = dev_id << 3 | 2; // c4 @@ -1208,9 +1207,7 @@ void sds_init(void) p001e.000d:0010 p001e.000d:0010 R02f8-00000010 R02f4-00000010 P000001.1e00000d:b7fe */ phy_read(0, 0x1e, 0xd); - uint16_t pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + uint16_t pval = SFR_DATA_U16; // PHY Initialization: REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); @@ -1224,9 +1221,7 @@ void sds_init(void) phy_write_mask(0x1, 0x1e, 0xd, pval); phy_read(0, 0x1e, 0xd); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16; REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); @@ -1408,15 +1403,15 @@ void rtl8373_init(void) // q000601:c800 Q000601:c804 q000601:c804 Q000601:c800 sds_read(0, 0x06, 0x01); - uint16_t pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + uint16_t pval = SFR_DATA_U16; + + sds_write_v(0, 0x06, 0x01, pval | 0x04); delay(50); sds_read(0, 0x06, 0x01); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16; + + sds_write_v(0, 0x06, 0x01, pval & 0xfffb); phy_config_8224(); @@ -1430,9 +1425,9 @@ void rtl8373_init(void) sds_write_v(1, 0x36, 0x05, 0x4000); sds_write_v(1, 0x1f, 0x02, 0x001f); sds_read(1, 0x1f, 0x15); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16; + + // r0a90:000000f3 R0a90-000000fc reg_read_m(0xa90); From 94cf079fcb30608f1be5a37f6b4f25180c2de2f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 31 Aug 2025 21:25:16 +0200 Subject: [PATCH 4/9] PHY: also use SFR_DATA_U16. Again less error prone and easier to read. Also see a lot of better optimalizations. A snipped. 390c390 < ;pval Allocated to registers r3 r4 --- > ;pval Allocated to registers 838,852c838,844 < ; rtl837x_phy.c:181: pval = SFR_DATA_8 & 0xbf; < mov r7,_SFR_DATA_8 < anl ar7,#0xbf < ; rtl837x_phy.c:182: pval <<= 8; < mov ar4,r7 < mov r7,#0x00 < ; rtl837x_phy.c:183: pval |= SFR_DATA_0; < mov r2,_SFR_DATA_0 < mov r3,#0x00 < mov a,r2 < orl a,r7 < mov _phy_write_PARM_4,a < mov a,r3 < orl a,r4 < mov (_phy_write_PARM_4 + 1),a --- > ; rtl837x_phy.c:181: pval = SFR_DATA_U16 & 0xbfff; > mov r4,((_SFR_DATA_U16 >> 0) & 0xFF) > mov a,#0xbf > anl a,((_SFR_DATA_U16 >> 8) & 0xFF) > mov r7,a > mov _phy_write_PARM_4,r4 > mov (_phy_write_PARM_4 + 1),r7 864c856 < mov _phy_write_PARM_3,r7 --- > mov _phy_write_PARM_3,#0x00 --- rtl837x_phy.c | 61 +++++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 65b9d54..fbceb67 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -69,10 +69,11 @@ void rtl8224_phy_enable(void) __banked // p001e.0a90:00f3 R02f8-000000f3 R02f4-000000fc P000001.1e000a90:00fc print_string("\r\nrtl8224_phy_enable called\r\n"); phy_read(0, 0x1e, 0xa90); - uint16_t pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + uint16_t pval = SFR_DATA_U16; + + + // PHY Initialization: REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); @@ -83,9 +84,8 @@ void rtl8224_phy_enable(void) __banked phy_write_mask(0x1, 0x1e, 0xa90, pval); phy_read(0, 0x1e, 0xa90); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16; + delay(50); print_string("\r\nrtl8224_phy_enable done\r\n"); @@ -102,44 +102,34 @@ void phy_config(uint8_t phy) __banked // PHY configuration: External 8221B? // p081e.75f3:ffff P000100.1e0075f3:fffe phy_read(phy, 0x1e, 0x75f3); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0 & 0xfe; + pval = SFR_DATA_U16 & 0xfffe; phy_write(phy, 0x1e, 0x75f3, pval); delay(20); // p081e.697a:ffff P000100.1e00697a:ffc1 / p031e.697a:0003 P000008.1e00697a:0001 // SERDES OPTION 1 Register (MMD 30.0x6) bits 0-5: 0x01: Set HiSGMII+SGMII phy_read(phy, 0x1e, 0x697a); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0 & 0xc0 | 0x01; + pval = SFR_DATA_U16 & 0xffc0 | 0x0001; phy_write(phy, 0x1e, 0x697a, pval); delay(20); // p031f.a432:0811 P000008.1f00a432:0831 // PHYCR2 PHY Specific Control Register 2, MMD 31. 0xA432), set bit 5: enable EEE phy_read(phy, 0x1f, 0xa432); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0 | 0x20; + pval = SFR_DATA_U16 | 0x0021; phy_write(phy, 0x1f, 0xa432, pval); // p0307.003e:0000 P000008.0700003e:0001 // EEE avertisment 2 register MMMD 7.0x003e, set bit 0: 2.5G has EEE capability phy_read(phy, 0x7, 0x3e); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0 | 0x1; + pval = SFR_DATA_U16 | 0x0001; phy_write(phy, 0x7, 0x3e, pval); delay(20); // p031f.a442:043c P000008.1f00a442:0430 // Unknown, but clear bits 2/3 phy_read(phy, 0x1f, 0xa442); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0 & 0xf3; + pval = SFR_DATA_U16 & 0x00f3; phy_write(phy, 0x1f, 0xa442, pval); delay(20); @@ -150,18 +140,14 @@ void phy_config(uint8_t phy) __banked // p031e.75b2:0000 P000008.1e0075b2:0060 // set bits 5/6 phy_read(phy, 0x1e, 0x75b2); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0 | 0x60; + pval = SFR_DATA_U16 | 0x0060; phy_write(phy, 0x1e, 0x75b2, pval); delay(20); // p081f.d040:ffff P000100.1f00d040:feff // LCR6 (LED Control Register 6, MMD 31.D040), set bits 8/9 to 0b10 phy_read(phy, 0x1e, 0xd040); - pval = (SFR_DATA_8 & 0xfc) | 0x02; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16 & 0xfc00 | 0x0002; phy_write(phy, 0x1e, 0xd040, pval); delay(20); @@ -171,16 +157,13 @@ void phy_config(uint8_t phy) __banked // Set bit 14, sleep, then clear again, according to the datasheet these bits are reserved phy_read(phy, 0x1f, 0xa400); - pval = SFR_DATA_8 | 0x40; - pval <<= 8; - pval |= SFR_DATA_0; + + pval = SFR_DATA_U16 | 0x4000; phy_write(phy, 0x1f, 0xa400, pval); delay(20); phy_read(phy, 0x1f, 0xa400); - pval = SFR_DATA_8 & 0xbf; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16 & 0xbfff; phy_write(phy, 0x1f, 0xa400, pval); delay(20); @@ -195,9 +178,9 @@ void phy_config_8224(void) __banked uint16_t pval; print_string("\r\nphy_config_8224 called\r\n"); phy_read(0, 0x1e, 0x7b20); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + pval = SFR_DATA_U16; + + REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); pval &= 0x0fe0; @@ -228,7 +211,7 @@ void phy_set_mode(uint8_t port, uint8_t speed, uint8_t flow_control, uint8_t dup { uint16_t v; phy_read(port, 0x1f, 0xa610); - v = (((uint16_t)SFR_DATA_8) << 8) | SFR_DATA_0; + v = SFR_DATA_U16; if (speed == PHY_OFF) { phy_write(port, 0x1f, 0xa610, v | 0x0800); return; @@ -253,14 +236,14 @@ void phy_set_mode(uint8_t port, uint8_t speed, uint8_t flow_control, uint8_t dup phy_write(port, 0x07, 0x20, 0x6001); // bit 14: SLAVE, bit 13: Multi-Port device, 1: LD Loop timin enableed // GBCR (1000Base-T Control Register, MMD 31.0xA412) phy_read(port, 0x1f, 0xa412); - v = (((uint16_t)SFR_DATA_8) << 8) | SFR_DATA_0; + v = SFR_DATA_U16; phy_write(port, 0x1f, 0xa412, v | 0x0200); } else if (speed == PHY_SPEED_2G5) { // Multi-GBASE-TBASE-T AN Control 1 Register (MMD 7.0x0020) phy_write(port, 0x07, 0x20, 0x6081); // bit 14: SLAVE, bit 13: Multi-Port device, bit 8: 2.5GBit available, 1: LD Loop timin enableed // GBCR (1000Base-T Control Register, MMD 31.0xA412) phy_read(port, 0x1f, 0xa412); - v = (((uint16_t)SFR_DATA_8) << 8) | SFR_DATA_0; + v = SFR_DATA_U16; phy_write(port, 0x1f, 0xa412, v & 0xfdff); } phy_write(port, 0x07, 0x00, 0x3200); // Enable AN From d8658626252daaae3322d3c65af79ea4f45df07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Sun, 31 Aug 2025 22:18:30 +0200 Subject: [PATCH 5/9] phy: fix or/and-opperation conversion errors --- rtl837x_phy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index fbceb67..218a74b 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -116,7 +116,7 @@ void phy_config(uint8_t phy) __banked // p031f.a432:0811 P000008.1f00a432:0831 // PHYCR2 PHY Specific Control Register 2, MMD 31. 0xA432), set bit 5: enable EEE phy_read(phy, 0x1f, 0xa432); - pval = SFR_DATA_U16 | 0x0021; + pval = SFR_DATA_U16 | 0x0020; phy_write(phy, 0x1f, 0xa432, pval); // p0307.003e:0000 P000008.0700003e:0001 @@ -129,7 +129,7 @@ void phy_config(uint8_t phy) __banked // p031f.a442:043c P000008.1f00a442:0430 // Unknown, but clear bits 2/3 phy_read(phy, 0x1f, 0xa442); - pval = SFR_DATA_U16 & 0x00f3; + pval = SFR_DATA_U16 & 0xfff3; phy_write(phy, 0x1f, 0xa442, pval); delay(20); @@ -147,7 +147,7 @@ void phy_config(uint8_t phy) __banked // p081f.d040:ffff P000100.1f00d040:feff // LCR6 (LED Control Register 6, MMD 31.D040), set bits 8/9 to 0b10 phy_read(phy, 0x1e, 0xd040); - pval = SFR_DATA_U16 & 0xfc00 | 0x0002; + pval = SFR_DATA_U16 & 0xfcff | 0x0200; phy_write(phy, 0x1e, 0xd040, pval); delay(20); From 689d208ff1b10de22a95ad6aca613e32c8d1ac4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Mon, 1 Sep 2025 09:51:49 +0200 Subject: [PATCH 6/9] phy: fix whitespace and comments alinement --- rtl837x_phy.c | 27 +++++++++------------------ rtlplayground.c | 6 ------ 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 218a74b..c6f8153 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -70,9 +70,6 @@ void rtl8224_phy_enable(void) __banked print_string("\r\nrtl8224_phy_enable called\r\n"); phy_read(0, 0x1e, 0xa90); uint16_t pval = SFR_DATA_U16; - - - // PHY Initialization: REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); @@ -86,7 +83,6 @@ void rtl8224_phy_enable(void) __banked phy_read(0, 0x1e, 0xa90); pval = SFR_DATA_U16; - delay(50); print_string("\r\nrtl8224_phy_enable done\r\n"); } @@ -100,33 +96,33 @@ void phy_config(uint8_t phy) __banked delay(20); // PHY configuration: External 8221B? -// p081e.75f3:ffff P000100.1e0075f3:fffe + // p081e.75f3:ffff P000100.1e0075f3:fffe phy_read(phy, 0x1e, 0x75f3); pval = SFR_DATA_U16 & 0xfffe; phy_write(phy, 0x1e, 0x75f3, pval); delay(20); -// p081e.697a:ffff P000100.1e00697a:ffc1 / p031e.697a:0003 P000008.1e00697a:0001 + // p081e.697a:ffff P000100.1e00697a:ffc1 / p031e.697a:0003 P000008.1e00697a:0001 // SERDES OPTION 1 Register (MMD 30.0x6) bits 0-5: 0x01: Set HiSGMII+SGMII phy_read(phy, 0x1e, 0x697a); pval = SFR_DATA_U16 & 0xffc0 | 0x0001; phy_write(phy, 0x1e, 0x697a, pval); delay(20); -// p031f.a432:0811 P000008.1f00a432:0831 + // p031f.a432:0811 P000008.1f00a432:0831 // PHYCR2 PHY Specific Control Register 2, MMD 31. 0xA432), set bit 5: enable EEE phy_read(phy, 0x1f, 0xa432); pval = SFR_DATA_U16 | 0x0020; phy_write(phy, 0x1f, 0xa432, pval); -// p0307.003e:0000 P000008.0700003e:0001 + // p0307.003e:0000 P000008.0700003e:0001 // EEE avertisment 2 register MMMD 7.0x003e, set bit 0: 2.5G has EEE capability phy_read(phy, 0x7, 0x3e); pval = SFR_DATA_U16 | 0x0001; phy_write(phy, 0x7, 0x3e, pval); delay(20); -// p031f.a442:043c P000008.1f00a442:0430 + // p031f.a442:043c P000008.1f00a442:0430 // Unknown, but clear bits 2/3 phy_read(phy, 0x1f, 0xa442); pval = SFR_DATA_U16 & 0xfff3; @@ -137,27 +133,25 @@ void phy_config(uint8_t phy) __banked phy_write(phy, 0x1e, 0x75b5, 0xe084); delay(20); -// p031e.75b2:0000 P000008.1e0075b2:0060 + // p031e.75b2:0000 P000008.1e0075b2:0060 // set bits 5/6 phy_read(phy, 0x1e, 0x75b2); pval = SFR_DATA_U16 | 0x0060; phy_write(phy, 0x1e, 0x75b2, pval); delay(20); -// p081f.d040:ffff P000100.1f00d040:feff + // p081f.d040:ffff P000100.1f00d040:feff // LCR6 (LED Control Register 6, MMD 31.D040), set bits 8/9 to 0b10 phy_read(phy, 0x1e, 0xd040); pval = SFR_DATA_U16 & 0xfcff | 0x0200; phy_write(phy, 0x1e, 0xd040, pval); delay(20); -// p081f.a400:ffff P000100.1f00a400:ffff, then: p081f.a400:ffff P000100.1f00a400:bfff -// p031f.a400:1040 P000008.1f00a400:5040, then: p031f.a400:5040 P000008.1f00a400:1040 + // p081f.a400:ffff P000100.1f00a400:ffff, then: p081f.a400:ffff P000100.1f00a400:bfff + // p031f.a400:1040 P000008.1f00a400:5040, then: p031f.a400:5040 P000008.1f00a400:1040 // FEDCR (Fast Ethernet Duplex Control Register, MMD 31.0xA400) // Set bit 14, sleep, then clear again, according to the datasheet these bits are reserved - phy_read(phy, 0x1f, 0xa400); - pval = SFR_DATA_U16 | 0x4000; phy_write(phy, 0x1f, 0xa400, pval); delay(20); @@ -179,9 +173,6 @@ void phy_config_8224(void) __banked print_string("\r\nphy_config_8224 called\r\n"); phy_read(0, 0x1e, 0x7b20); pval = SFR_DATA_U16; - - - REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); pval &= 0x0fe0; pval |= 0x000d; diff --git a/rtlplayground.c b/rtlplayground.c index 47f83d7..682b635 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -1404,14 +1404,10 @@ void rtl8373_init(void) // q000601:c800 Q000601:c804 q000601:c804 Q000601:c800 sds_read(0, 0x06, 0x01); uint16_t pval = SFR_DATA_U16; - - sds_write_v(0, 0x06, 0x01, pval | 0x04); delay(50); sds_read(0, 0x06, 0x01); pval = SFR_DATA_U16; - - sds_write_v(0, 0x06, 0x01, pval & 0xfffb); phy_config_8224(); @@ -1427,8 +1423,6 @@ void rtl8373_init(void) sds_read(1, 0x1f, 0x15); pval = SFR_DATA_U16; - - // r0a90:000000f3 R0a90-000000fc reg_read_m(0xa90); sfr_mask_data(0, 0x0f,0x0c); From cc132a87341f8b5f513a74ccf0f38d954165fe48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Mon, 1 Sep 2025 09:59:41 +0200 Subject: [PATCH 7/9] phy_write(): also use SFR_DATA_U16 and SFR_SMI_REG_U16 Was added by pr#7. --- rtlplayground.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/rtlplayground.c b/rtlplayground.c index 682b635..1ec02d8 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -285,7 +285,6 @@ void setup_timer0(void) void reg_read(uint16_t reg_addr) { SFR_REG_ADDR_U16 = reg_addr; - SFR_EXEC_GO = SFR_EXEC_READ_REG; do { } while (SFR_EXEC_STATUS != 0); @@ -299,7 +298,6 @@ void reg_read_m(uint16_t reg_addr) if (EA) { write_char('r'); print_byte(reg_addr >> 8); print_byte(reg_addr); write_char(':'); } #endif SFR_REG_ADDR_U16 = reg_addr; - SFR_EXEC_GO = SFR_EXEC_READ_REG; do { } while (SFR_EXEC_STATUS != 0); @@ -317,7 +315,6 @@ void reg_write(uint16_t reg_addr) { /* Data to write must be in SFR A4, A5, A6, A7 */ SFR_REG_ADDR_U16 = reg_addr; - SFR_EXEC_GO = SFR_EXEC_WRITE_REG; do { } while (SFR_EXEC_STATUS != 0); @@ -333,7 +330,6 @@ void reg_write_m(uint16_t reg_addr) } #endif SFR_REG_ADDR_U16 = reg_addr; - SFR_DATA_24 = sfr_data[0] ; SFR_DATA_16 = sfr_data[1]; SFR_DATA_8 = sfr_data[2]; @@ -395,7 +391,6 @@ void nic_rx_header(uint16_t ring_ptr) uint16_t buffer = (uint16_t) &rx_headers[0]; SFR_NIC_DATA_U16LE = buffer; SFR_NIC_RING_U16LE = ring_ptr; - SFR_NIC_CTRL = 1; do { } while (SFR_NIC_CTRL != 0); } @@ -1085,11 +1080,9 @@ void phy_write_mask(uint16_t phy_mask, uint8_t dev_id, uint16_t reg, uint16_t v) print_string("P"); print_byte(phy_mask>>8); print_byte(phy_mask); print_byte(dev_id); write_char('.'); print_byte(reg>>8); print_byte(reg); write_char(':'); print_byte(v>>8); print_byte(v); write_char(' '); #endif - SFR_DATA_U16 = v ; // SFR_A6, SFR_A7 - + SFR_DATA_U16 = v; // SFR_A6, SFR_A7 SFR_SMI_PHYMASK = phy_mask; // SFR_C5 SFR_SMI_REG_U16 = reg; // SFR_C2, SFR_C3 - SFR_SMI_DEV = (phy_mask >> 8) | dev_id << 3 | 2; // SFR_C4: bit 2 can also be set for some option SFR_EXEC_GO = SFR_EXEC_WRITE_SMI; do { @@ -1107,13 +1100,9 @@ void phy_write(uint8_t phy_id, uint8_t dev_id, uint16_t reg, uint16_t v) print_string("P"); print_byte(phy_mask>>8); print_byte(phy_mask); print_byte(dev_id); write_char('.'); print_byte(reg>>8); print_byte(reg); write_char(':'); print_byte(v>>8); print_byte(v); write_char(' '); #endif - - SFR_DATA_8 = v >> 8; // SFR_A6 - SFR_DATA_0 = v; // SFR_A7 + SFR_DATA_U16 = v; // SFR_A6, SFR_A7 SFR_SMI_PHYMASK = phy_mask; // SFR_C5 - SFR_SMI_REG_H = reg >> 8; // SFR_C2 - SFR_SMI_REG_L = reg; // SFR_C3 - + SFR_SMI_REG_U16 = reg; // SFR_C2, SFR_C3 SFR_SMI_DEV = (phy_mask >> 8) | dev_id << 3 | 2; // SFR_C4: bit 2 can also be set for some option SFR_EXEC_GO = SFR_EXEC_WRITE_SMI; do { From 22dccbad8c38491a0ab1d7a327506b6307790843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Mon, 1 Sep 2025 12:21:39 +0200 Subject: [PATCH 8/9] Replace phy_write_mask(0x1 with phy_write(0x00. Also added define `RTL8224_PHY_ID` for RTL8224 phy_id. So it is more clear that we want to talk to that phy. Replaced in the function which contains `8224` in the name the `phy_write(0x00, ...)` with `phy_write(RTL8224_PHY_ID, ...)`, same for the `phy_read(0x00, ...)` with `phy_read(RTL8224_PHY_ID, ...)`. Removed the extra `phy_read()` in `rtl8224_phy_enable()`. --- rtl837x_phy.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/rtl837x_phy.c b/rtl837x_phy.c index c6f8153..dc62bb0 100644 --- a/rtl837x_phy.c +++ b/rtl837x_phy.c @@ -6,6 +6,9 @@ #define REGDBG +// Phy ID of the external RTL8224 PHY. +#define RTL8224_PHY_ID 0x00 + #include #include "rtl837x_common.h" #include "rtl837x_sfr.h" @@ -66,11 +69,13 @@ __code uint16_t rtl8224_cb[60] = { void rtl8224_phy_enable(void) __banked { + uint16_t pval; + // p001e.0a90:00f3 R02f8-000000f3 R02f4-000000fc P000001.1e000a90:00fc print_string("\r\nrtl8224_phy_enable called\r\n"); - phy_read(0, 0x1e, 0xa90); - uint16_t pval = SFR_DATA_U16; - + phy_read(RTL8224_PHY_ID, 0x1e, 0xa90); + pval = SFR_DATA_U16; + // PHY Initialization: REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); @@ -78,12 +83,9 @@ void rtl8224_phy_enable(void) __banked pval |= 0x0c; REG_WRITE(0x2f4, 0, 0, pval >> 8, pval); - phy_write_mask(0x1, 0x1e, 0xa90, pval); - - phy_read(0, 0x1e, 0xa90); - pval = SFR_DATA_U16; - + phy_write(RTL8224_PHY_ID, 0x1e, 0xa90, pval); delay(50); + print_string("\r\nrtl8224_phy_enable done\r\n"); } @@ -167,26 +169,28 @@ void phy_config(uint8_t phy) __banked void phy_config_8224(void) __banked { - // p001e.7b20:0bff R02f8-00000bff R02f4-00000bed P000001.1e007b20:0bed - uint16_t pval; print_string("\r\nphy_config_8224 called\r\n"); - phy_read(0, 0x1e, 0x7b20); + + // p001e.7b20:0bff R02f8-00000bff R02f4-00000bed P000001.1e007b20:0bed + phy_read(RTL8224_PHY_ID, 0x1e, 0x7b20); pval = SFR_DATA_U16; + REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); pval &= 0x0fe0; pval |= 0x000d; REG_WRITE(0x2f4, 0, 0, pval >> 8, pval); - phy_write_mask(0x01, 0x1e, 0x7b20, pval); + + phy_write(RTL8224_PHY_ID, 0x1e, 0x7b20, pval); uint8_t i = 0; while (rtl8224_ca[i]) { - phy_write_mask(0x1, 0x1e, 0x400, rtl8224_ca[i]); + phy_write(RTL8224_PHY_ID, 0x1e, 0x400, rtl8224_ca[i]); i++; - phy_write_mask(0x1, 0x1e, 0x3f8, rtl8224_ca[i]); + phy_write(RTL8224_PHY_ID, 0x1e, 0x3f8, rtl8224_ca[i]); i++; do { - phy_read(0, 0x1e, 0x3f8); + phy_read(RTL8224_PHY_ID, 0x1e, 0x3f8); } while (SFR_DATA_8 & 0x80); } From bcf4ae316cb5cd80ef75914a70ac32249866a798 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= Date: Mon, 1 Sep 2025 16:47:57 +0200 Subject: [PATCH 9/9] fix SFR_DATA_U16: must use sfr a6a7 not sfr a4a5! --- rtl837x_sfr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index 71fc4ae..314ea33 100644 --- a/rtl837x_sfr.h +++ b/rtl837x_sfr.h @@ -4,7 +4,7 @@ __sfr __at(0xa1) SFR_EXEC_STATUS; __sfr16 __at(0xa2a3) SFR_REG_ADDR_U16; __sfr __at(0xa2) SFR_REG_ADDRH; __sfr __at(0xa3) SFR_REG_ADDRL; -__sfr16 __at(0xa4a5) SFR_DATA_U16; +__sfr16 __at(0xa6a7) SFR_DATA_U16; __sfr32 __at(0xa4a5a6a7) SFR_DATA_U32; __sfr32 __at(0xa7a6a5a4) SFR_DATA_U32LE; __sfr __at(0xa4) SFR_DATA_24;