diff --git a/rtl837x_phy.c b/rtl837x_phy.c index 65b9d54..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,12 +69,12 @@ __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_8; - pval <<= 8; - pval |= SFR_DATA_0; + phy_read(RTL8224_PHY_ID, 0x1e, 0xa90); + pval = SFR_DATA_U16; // PHY Initialization: REG_WRITE(0x2f8, 0, 0, pval >> 8, pval); @@ -80,14 +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_8; - pval <<= 8; - pval |= SFR_DATA_0; - + phy_write(RTL8224_PHY_ID, 0x1e, 0xa90, pval); delay(50); + print_string("\r\nrtl8224_phy_enable done\r\n"); } @@ -100,46 +98,36 @@ 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_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 + // 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 + // 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 | 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_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 + // 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 & 0xfff3; phy_write(phy, 0x1f, 0xa442, pval); delay(20); @@ -147,40 +135,31 @@ 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_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 + // 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 & 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_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); @@ -190,29 +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); - pval = SFR_DATA_8; - pval <<= 8; - pval |= SFR_DATA_0; + + // 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); } @@ -228,7 +206,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 +231,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 diff --git a/rtl837x_sfr.h b/rtl837x_sfr.h index 8aa3a8c..314ea33 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(0xa6a7) 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; @@ -17,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; @@ -86,7 +91,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 5075095..1ec02d8 100644 --- a/rtlplayground.c +++ b/rtlplayground.c @@ -284,8 +284,7 @@ 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 +297,7 @@ 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 +314,7 @@ 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 +329,7 @@ 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]; @@ -393,10 +389,8 @@ 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 +404,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 +426,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; @@ -507,8 +500,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; @@ -1088,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_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 { @@ -1110,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 { @@ -1134,8 +1120,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 @@ -1210,9 +1196,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); @@ -1226,9 +1210,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); @@ -1410,15 +1392,11 @@ 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(); @@ -1432,9 +1410,7 @@ 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);