Porting RCM3315 to RCM3000 code in DC 9.62

I am trying to port code that was developed on RCM3315 into RCM3000.
Downgrading to older module, please don’t ask why!

Most of the code is working, thank G-d!

TCP code is giving me grief.

I have tested with ping sample code and I get pings on RCM3000.

However, when I make the developed code work mostly for both boards, the RCM3315 answers ARPs but the RCM3000 doesn’t while being pinged.

They both show same interactions until I start the pinging but the RCM3000 does not respond to pins.

Any idea where to start looking?

How do I add picture to this post to show Stdio differences?

Please open a support ticket for this issue by emailing tech.support@digi.com.

Are you compiling to the board and testing from the Dynamic C IDE? Can you get some Wireshark captures of the network traffic? Are you using a static IP address? Be sure to use a different static IP for each board, as your test PC might be caching a given IP’s MAC address instead of probing for it again.

If you’re compiling to a .bin file that you install with Rabbit Field Utility (RFU), be sure to select “RCM3000” as the target (Options/Project Options/Targetless menu) first. The RCM3000 used a different Ethernet controller than the RCM3315, so it can’t use a binary targeting the RCM3315.

Tried ping and telnet sample codes on both board and both worked.
Minor difference where the RCM3315 sends Gratuitous ARP on init making sure PC registers.
Back to custom code where I stripped everything and last thing stripped was IO init with WrPortI function and clock doubler for some reason.
The whole section breaks the ARP requests and responses.
Please see below. I will try to isolate the ports tomorrow. Any ideas?

WrPortI (GCDR, &GCDRShadow, 0x07);	// set clock doubler
WrPortI (GOCR, &GOCRShadow, 0x2A);	// disable PCLK out

WrPortI(IB0CR, NULL, 0x08);		//allow external WR~ signal
//WrPortI(GOCR,NULL,0x00);		//enable bufen

WrPortI (PFFR, &PFFRShadow, 0x80);		//set PF7 to PWM output
WrPortI (PFDDR, &PFDDRShadow, 0xFF);	//	parallel Port F = Outputs
WrPortI (PFDR, &PFDRShadow, 0xFF);	//	parallel Port F = Outputs

//set up port I/O
//port A is bi-directional and can be read or written to
WrPortI (SPCR, &SPCRShadow, 0x8C);	//port A is aux data bus

//port B is part of aux address bus;
WrPortI (PBDDR, &PBDRShadow, 0x3F);		//all outputs
WrPortI (PBDR, &PBDRShadow, 0x00);

//port C are the 4 UARTs
WrPortI (PCFR, &PCFRShadow, 0x55);		//drive all duart TX outputs

//port D is bi-directional and can be read or written to
WrPortI (PDDCR, &PDDCRShadow, 0x00);
WrPortI (PDDDR, &PDDDRShadow, 0xEF);	//PD4 input
WrPortI (PDDR, &PDDRShadow, 0x03);		//set PD7 - PD2 low

//PWM setup
WrPortI (PWM3R, &PWM3RShadow, 0x88);		//8 MSB's of 10-bit PWM word
WrPortI (PWL3R, &PWL3RShadow, 0x01);		//bits 7 & 6 are LSBs of 10-bit, bit 0 is spread bit

//port E is bi-directional and can be read or written to
WrPortI (PEDDR, &PEDDRShadow, 0xC1);		//0b11000001
WrPortI (PEDR, &PEDRShadow, 0x01);

//port G is bi-directional and can be read or written to
WrPortI (PGFR, &PGDRShadow, 0x00);
WrPortI (PGDDR, &PGDDRShadow, 0x07);		//0b00000111
WrPortI (PGDR, &PGDRShadow, 0x00);

The RCM3000 runs at 29.4912MHz and the RCM3315 runs at 44.2368MHz, so they use different GCDR values. The BIOS sets that register correctly during startup, so there’s no need to include it in your initialization code.

Your GOCR initialization actually turns the PCLK output on. Note that when you’re using WrPortI(), you should use the shadow variable as a starting value and then mask off bits you want to set to 0 (using &) and then set new bits (using |). If you’re setting all of the bits, you can just use the value directly. But in many cases, you just want to set specific bits of the register without changing bits that other code may have set.

So, if you just want to change just the PCLK bits of GOCR, you should use GOCRShadow & 0x3F, which sets the top 2 bits to 00. If you wanted some other value, you could use (GOCRShadow & 0x3F) | 0x80 (which sets the CLK output low).

Looking at the schematic of the RCM3000, you should update your WrPortI() calls so they don’t modify the following pins (they’re used by the Ethernet interface): PD0, PD1, PE2

At the very least, you want to call your board init routine before initializing the TCP/IP stack, since it will likely fix the I/O configuration for those pins.

So far I got down to Port A initialization.

If I skip that, the ARPs are working.

Any idea why Port A?

What in RCM3000 different from RCM3315 that has to do with Port A?

My socket init was run after this so not sure why that didn’t repurposed Port A if it needed to as suggested in a post.

//set up port I/O

//port A is bi-directional and can be read or written to

WrPortI (SPCR, &SPCRShadow, 0x8C); //port A is aux data bus

The RCM3000 runs at 29.4912MHz and the RCM3315 runs at 44.2368MHz, so they use different GCDR values. The BIOS sets that register correctly during startup, so there’s no need to include it in your initialization code.

No action.

Your GOCR initialization actually turns the PCLK output on. Note that when you’re using WrPortI(), you should use the shadow variable as a starting value and then mask off bits you want to set to 0 (using &) and then set new bits (using |). If you’re setting all of the bits, you can just use the value directly. But in many cases, you just want to set specific bits of the register without changing bits that other code may have set.

Understood. Assuming no action needed.

So, if you just want to change just the PCLK bits of GOCR, you should use GOCRShadow & 0x3F, which sets the top 2 bits to 00. If you wanted some other value, you could use (GOCRShadow & 0x3F) | 0x80 (which sets the CLK output low).

Understood. Assuming no action needed not to deviate too much from original code.

Looking at the schematic of the RCM3000, you should update your WrPortI() calls so they don’t modify the following pins (they’re used by the Ethernet interface): PD0, PD1, PE2

Port A is causing my issue. What is on Port A that could break Ethernet?

PD2, PD3, PD6, and PD7 are mentioned on the user’s manual for Ethernet but not connected

At the very least, you want to call your board init routine before initializing the TCP/IP stack, since it will likely fix the I/O configuration for those pins.

I call Socket Init after IO init. Does socket init, initialize the TCP stack and necessary IO?

You can review the RCM3000 schematic and see that the Ethernet chip on page 3 uses Port A.

I have verified that sock_init() calls pkt_init() which is the function that configures the hardware registers.

Regarding GOCR: the Ethernet driver is using the lower two bits to set /BUFEN. You definitely don’t want to modify those bits after you start making TCP/IP calls.

For Port A, it looks like the driver and hardware are designed to work whether Port A is configured as an auxiliary data bus, or the board is using the regular data bus. If you need to use Port A for aux data (per your WrPortI() call above), you must define PORTA_AUX_IO at the start of your program so it uses the correct configuration from BOARD_DEPS.LIB.

I believe the missing PORTA_AUX_IO macro is causing your failures. And note that if you’ve defined the macro, premain() (which is the code that ultimately calls your main()) will automatically configure SPCR for you.

I recommend adding the macro to the start of your program and skipping over the SPCR initialization in your code. Ethernet should be working correctly, and whatever hardware you have that uses port A as the alternate data bus should still work correctly.

Thank you for the schematic, thorough explanation, and suggested fixes.
I will add the macro and see if all still works.
We do not use the data bus anymore so I will not be able to verify the aux use.
Thank you!

If you aren’t actually using the auxiliary databus, you could should just remove the SPCR initialization and rely on the PORTA_AUX_IO macro to configure both SPCR and the Ethernet driver.

Good luck.