Notes on W5500 Ethernet MAC/PHY
The datasheet is here, although it’s missing some key information, a bit of which I will fill in on this page. Make sure you are working from version 1.1 of the datasheet.
Setting Up RECV Interrupt for MACRAW (Socket 0)
Setup:
- Common register SIMR (0x0018), set S0_IMR=1.
- Socket register Sn_IMR (0x002C), set RECV=1.
- NOTE: Perform an initializing reset on Sn_IR to get things going (see below).
Normal running:
Whenever an interrupt is received there is some cleanup needed to get ready for the next:
- Common register SIR (0x0017) will indicate which socket had an interrupt. See the S0_INT bit. This doesn’t need to be cleared explicitly, clearing Sn_IR is the place to be cleared (see below).
- Socket register Sn_IR will indicate that type of interrupt that happened on the socket. See the RECV bit. IMPORTANT: In order to clear the Sn_IR bit we need to write a “1”.
IMPORTANT NOTE: Use all of the proper precautions when dealing with ISRs:
- Use a memory barrier (__DSB) around data shared between the ISR and the main program. This ensures that there are no race-conditions related to out-of-sequence execution.
- Use SCB_CleanDCache_by_Addr() on shared buffers between the DMA controllers and the main program to flush the d-cache. This ensures that data written by the DMA system is visible to the main program and vice-versa.
- Is using a flag to determine when a DMA has completed (i.e. completion ISR) make sure to disable interrupts before starting the DMA and clearing the flag to make sure that a race condition doesn’t set the flag again before we expect.
Receive Buffer in MACRAW Mode
The receive buffer is filled with packets made up of a two-byte length header (big endian) followed by the packet contents itself. The length header is inclusive of the length and packet contents.
Send/Receive Buffer Pointers
As far as I can tell, the location of teh RX_RD and TX_WR can be tracked using “shadow pointers” in the application. Assuming they are reset to zero when the chip is reset, there is no need to read back the values of these pointers on every read/write. Just keep track of how much data was read/written and advance the pointers based on the location of the shadow pointers.
The RX_RD and TX_WR pointers are 16-bit regardless of the actual size of the RX and RX buffers. As far as I can tell, the wrapping of the RX_RD and TX_WR pointers (which are the two that we need to manage) can be completely ignored by the application ocde. These pointers just wrap around forever.