I’m having such a hard time just comprehending the wiznet 5100 documentation that I just want to solicit help from one place (bear with me).
I am trying to receive data from a socket. I don’t understand the concept. From page 35 in the datasheet [url]https://www.sparkfun.com/datasheets/DevTools/Arduino/W5100_Datasheet_v1_1_6.pdf[/url], they imply that you have to get the amount of data received, and the read pointer. You have to calculate the base address for that socket (e.g. socket 0) from the rx memory size register value. Then you read forward the number of bytes that the read size is to get the data. If you get to the last address, loop back to the beginning and continue reading. I guess because it’s a circular buffer.
The problem is that their documentation and pseudo code make no sense to me. What I gather is this. To get the data for socket 0 you read n bytes begining from read pointer + 0x6000, where 0x6000 is the base address for socket 0, and it never changes for that socket. For socket 1 the base address would be 0x6000 + however much ram was allocated to socket 0 based on the RX memory size register.
Therefore if socket 0 was assigned 2K of ram then Socket 1’s base address would be 0x6000 + 0x07FF (2,047) = 0x67FF.
If socket 0 was assigned 4K then Socket 1’s base would be 0x6000 + 0x0FFF (4095) = 0x6FFF
If socket 1 was then assigned 2K then Socket 2’s base would be 0x6FFF + 0x07FF = 0x77FE
//RX base address setup
int _rxMemorySize = RxMemorySize;
int _oneKB = 0x400;
sockets[0].rxMemoryBaseAddress = 0x6000;
int _size = ((_oneKB * (0x01 << ((_rxMemorySize >> 0) & 0x03)))); // push value down n places. take last 2 bits. push 0x01 by that number. multiply by 0x400.
sockets[0].rxMemorySize = _size;
sockets[1].rxMemoryBaseAddress = sockets[0].rxMemoryBaseAddress + _size - 1; //subtract 1. add value to previous socket's base address
_size = (_oneKB * (0x01 << ((_rxMemorySize >> 2) & 0x03)));
sockets[1].rxMemorySize = _size;
sockets[2].rxMemoryBaseAddress = sockets[1].rxMemoryBaseAddress + _size - 1;
_size = (_oneKB * (0x01 << ((_rxMemorySize >> 4) & 0x03)));
sockets[2].rxMemorySize = _size;
sockets[3].rxMemoryBaseAddress = sockets[2].rxMemoryBaseAddress + _size - 1;
_size = (_oneKB * (0x01 << ((_rxMemorySize >> 6) & 0x03)));
sockets[3].rxMemorySize = _size;
Well, I think and hope that I did this calculation correctly.
The logic is that I take the 2 bit value and use it to push the number 1 << times then I multiply that by 1024 and minus 1. Do this for each socket in succession. RxMemorySize is the value from the RX Memory Size (RMSR) register.
internal void CheckSocketInterrupt() {
if (IsUsable) {
byte _socketInterrupt = Read(INTERRUPT_INDEX);
byte _status = Read(STATUS_INDEX);
if (wiznet.IsBitSet(_socketInterrupt, (byte)SocketInterrupt.SendOK)) {
}
if (wiznet.IsBitSet(_socketInterrupt, (byte)SocketInterrupt.Timeout)) {
}
if (wiznet.IsBitSet(_socketInterrupt, (byte)SocketInterrupt.Receive)) {
int _receivedSize = ReadUInt16(RX_RECEIVED_SIZE_INDEX);
int _rxPointer = ReadUInt16(RX_READ_POINTER_INDEX);
if (Received != null && _receivedSize > 0) {
byte[] _data = new byte[_receivedSize];
for (int i = _rxPointer; i < _receivedSize; i++) {
_data[i] = ReadRegister(rxMemoryBaseAddress + (i % rxMemorySize));
}
Received.Invoke(_data);
}
Write(RX_READ_POINTER_INDEX, (UInt16)(_rxPointer + _receivedSize));
Write(COMMAND_INDEX, (byte)SocketCommand.Receive);
Write(INTERRUPT_INDEX, 0);
}
if (wiznet.IsBitSet(_socketInterrupt, (byte)SocketInterrupt.Disconnected)) {
}
if (lastStatus == (int)SocketStatus.Listen) {
if (_status == (int)SocketStatus.Established) {
if (wiznet.IsBitSet(_socketInterrupt, (byte)SocketInterrupt.Connected)) {
if (Connected != null) {
Connected.Invoke();
}
lastStatus = _status;
}
}
}
}
}
I use the interrupt method to determine when there is connection, when there is data and when the data is sent etc. I can receive the data. I’m using telnet to connect to a port and send 1 char. Works just fine. Problem is I keep getting the interrupt.
This command Write(COMMAND_INDEX, (byte)SocketCommand.Receive); is supposed to clear the interrupt. The documentation (on page 35, 36 and 43, 44) does not make sense. In the case of clearing the Sn_IR (Socket n Interrupt Register) it says
[quote]Sn_IR (Socket n Interrupt Register) [R] [0x0402, 0x0502, 0x0602, 0x0702] [0x00]
This register is used for notifying connection establishment and termination, receiving data and Timeout. The Socket n Interrupt Register must be cleared by writing ‘1’. (pg. 27)[/quote]
Except that the register has [R] on it, which means read only. So how do you clear the interrupt?
By some magic that isn’t in the documentation and I don’t understand
OR the status with the socket interrupt and writing it back to the socket interrupt register seems to clear the interrupt (I think).
[url]http://wizwiki.net/forum/viewtopic.php?t=1915[/url]
This unknown block of code is what Wiznet has in it's w5100.c driver source. Makes no sense to me.
```cpp
/* +200801[bj] interrupt clear */
IINCHIP_WRITE(IR, 0xf0);
/*---*/
if (int_val & IR_SOCK(0))
{
/* +-200801[bj] save interrupt value*/
I_STATUS[0] |= IINCHIP_READ(Sn_IR(0)); // can be come to over two times.
IINCHIP_WRITE(Sn_IR(0), I_STATUS[0]);
/*---*/
}