Merge pull request #6 from vDorst/sfr16

Combine two sfr-pairs into a single sfr16 define, so make it less error prone to use and optimize better.
This commit is contained in:
logicog
2025-09-01 18:10:06 +02:00
committed by GitHub
3 changed files with 71 additions and 110 deletions
+39 -61
View File
@@ -6,6 +6,9 @@
#define REGDBG
// Phy ID of the external RTL8224 PHY.
#define RTL8224_PHY_ID 0x00
#include <stdint.h>
#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
+7
View File
@@ -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;
+25 -49
View File
@@ -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);