Ariadne misuses W5100 and W5200
loathingKernel opened this issue · 4 comments
From @loathingKernel on February 1, 2014 12:35
@MarekLew wrote:
Library TFTP wrong use registers REG_S3_RX_RD0, REG_S3_TX_WR0, REG_S3_RX_RSR0.
Trying to modify AriadneBootloader for W5200 and ATmega2560 with progaram> 64KB noticed that the transmission every time it stops at 55KB for the 2K buffer soket.
Analyzed the library and documentation W5100 and W5200.
REG_S3_TX_WR0 is NO PHYSICAL ADDRESS for the third soket and can not be freely modified. Is the number of bytes processed the program. A REG_S3_RX_RSR0 tells you how many bytes have to be read in the buffer.
In a few days try shared corrected code. For now, I have to very modified system and W5200. In the meantime, put 'suggested amendments.
Today I have only smartphone.
When soket is initialized:
spiWriteWord (REG_S3_RX_RD0, 0);
You can not move REG_S3_RX_RD0 of S3_RX_START:
-- If (readPointer == 0) readPointer = S3_RX_START;
or move back
-- If (readPointer == S3_RX_END) readPointer = S3_RX_START;
repleace with like this
++ if ((--packetSize) == 0)break;//end of package
or better
-- for(count = TFTP_PACKET_MAX_SIZE; count--;) {
++ for(count = packetSize; count--;) {
to read the bytes from the physical address, use the mask and shift:
-- SpiWriteWord (REG_S3_RX_RD0, readPointer);
++ SpiWriteWord (REG_S3_RX_RD0, S3_RX_START + (readPointer & 0x7ff));
0x7ff - mask for 2k
And of course analogous not to REG_S3_TX_WR0:
-- writePointer = spiReadWord (REG_S3_TX_WR0 - S3_TX_START);
++ writePointer = spiReadWord (REG_S3_TX_RD0);
-- If (writePointer == S3_TX_END) writePointer = S3_TX_START;
-- SpiWriteWord (REG_S3_TX_WR0, writePointer - S3_TX_START);
++ SpiWriteWord (REG_S3_TX_WR0, S3_TX_START + (writePointer & 0x7ff));
And now at last
uint16_t PacketSize = spiReadWord (REG_S3_RX_RSR0);
contains useful information how much data is left in the buffer.
You can probably remove.
while ((spiReadReg (REG_S3_IR) & IR_RECV)) {
spiWriteReg (REG_S3_IR, IR_RECV);
/ / FIXME: is this right after all? smaller delay but
/ / Still a delay and it still breaks occasionally
delayms (TFTP_PACKET_DELAY);
}
Besides, I've used yet PacketSize I used to check whether the data came in full.
I not use this for W5100 only W5200 and 4K socket.
Sorry for my English, I used a translator.
Copied from original issue: codebndr#11
@MarekLew
I am aware of that misuse and to be honest, this was the way it was being done by the previous developer and I didn't want to change it until I knew what I was doing. My guess is that it was being done because of size concerns.
I have a local branch where I have been making changes to create a proper driver infrastructure so different network controllers can be added with ease, and these bugs have been fixed there.
Nevertheless, i am interested in the changes for the W5200 as I do not have it but I would like to add it.
From @MarekLew on February 2, 2014 12:24
this is "32" package problem. "32" ,"64" package is not analize because packageSize==0
From @davidhaenggi on February 9, 2015 14:40
Hi
I downloaded the Ariadne-Bootloader to use it with a OpenMediaController.
It's based on a Atmega2560 and includes a Wiznet W5100 ethernet chip.
In general the bootloader works great, thanks for the nice work.
While trying to upload bigger firmware files I was running into the "64-Package" Problem.
For me it looks like the arduino is receiving a completely messed up message instead of package number 64. When it tries to read the source IP address of the package it gets some random IP and therefor tries to send a response to this random IP. Thats why the Wiznet chip tries to reach to gateway, because the random IP is not in its IP range.
- The solution to set the gateway address to the same IP as the TFTP client was not satisfying to me, as I would like to send firmwares from different client-IPs.
- As a workaround I did some modification to the code:
-
Don't set return IP address and port if the message is not a valid tftp message. I moved the regarding code to the end of funtion processPacket() and add some validation check.
-
// Set up return IP address and port
uint8_t i;
for(i = 0; i < 6; i++) spiWriteReg(REG_S3_DIPR0 + i, buffer[i]);
+
// only set return address if paket received is wellformed, to avoid sending to random IP address.
if(returnCode != ERROR_INVALID && returnCode != ERROR_UNKNOWN){
// Set up return IP address and port
uint8_t i;
for(i = 0; i < 6; i++) spiWriteReg(REG_S3_DIPR0 + i, buffer[i]);
}
-
And I added the same validation check before sending any response messages in tftpPoll().
+
if(response != ERROR_INVALID && response != ERROR_UNKNOWN)
sendResponse(response);
Like this the arduino does not send any error for packet 64. The client repeats the packet and the transfer continues. With this changes I was able to set the TFTP_PACKET_DELAY to 0 and have a fast tftp transfer without any failures.
I know this is not a proper solution, but it works for me and I thought it may help someone.
Thanks for posting this workaround. It is good to have it here for anyone who is looking for a quick solution on this problem.