Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)


Closed Thread
Results 1 to 40 of 63

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    Hi,
    I don't know what the "best" way to aproach this actually is. I don't think me posting hundreds or thousands of lines of code is going to actually help others that much and I don't think I'll get much out of it either.

    Instead I think I'll post snippets and routines, explaining what they do (or at least intend to do) and why. This way I think it's easier to tag along, one step at the time and, which is important, we can discuss suggestions on improvements and alternative ways of doing the same thing. In the end we will hopefully have a set of routines which can be used to build a working application.

    Before we go on I just have to point out that this is new territory for me too. I don't know much about ethernet, UDP, TCP, sockets, HTTP, HTML etc so this is very much a learning experience for me as well. Please feel free to correct any statements I make in error and please do bring suggestions on how to do things differently and, hopefully, better.


    Right, the Wiznet W5100 ethernet chip (which is used on the Ethernet shield) is controlled by reading and writing to its internal registers. There are quite a few registers and instead of using a bunch of 'magic numbers' (ie the adress of the register in the W5100's memory) I've put together a file (W5100_defs.pbp) containing the name and memory adress for the registers as well as a couple of other constants we might need. Attached to this post is v1.0 of that file (remove .txt extenstion), there might be newer versions in the posts to come.

    I've set up my AMICUS18 board to use the hardware USART at 115200 baud for debugging purposes. Then I set up the TRISB and TRISC registers to match the pinout of the modified Ethernet shield:
    Code:
    ' By default the AMICUS18 board uses the PIC18F25K20, make sure to
    ' set up MCSP or whatever IDE is being used to compile for the
    ' correct device.
     
    DEFINE OSC 64
    DEFINE LOADER_USED 1            ' We're using a bootloader.
    DEFINE HSER_RCSTA 90h           ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h           ' Enable transmit, BRGH = 1
    DEFINE HSER_CLROERR 1           ' Clear overflow automatically
    DEFINE HSER_SPBRG 138           ' 115200 Baud @ 64MHz, -0,08%
     
    SPBRGH = 0
    BAUDCON.3 = 1                   ' Enable 16 bit baudrate generator
     
    TRISC = %10010111
    ' RC7: USART RX
    ' RC6: USART TX
    ' RC5: ETHERNET SPI Data out (SDO/MOSI)
    ' RC4: ETHERNET SPI Data in (SDI/MISO)
    ' RC3: ETHERNET SPI clock (SCK) set to INPUT according to datasheet....
    ' RC2: N/U - currently
    ' RC2: N/U - currently
    ' RC1: N/U - currently
     
    TRISB = %11011011
    ' RB7: N/U - currently
    ' RB6: N/U - currently
    ' RB5: ETHERNET Chip select line to W5100
    ' RB4: N/U - currently
    ' RB3: N/U - currently
    ' RB2: ETHERNET Chip select line to SD-Card
    ' RB1: N/U and can not be used with the Ethernet shield
    ' RB0: ETHERNET Interrupt pin from W5100

    Then I pretty much cut'n'pasted the register definition/aliases for the MSSP module from the SPI master example on MELABS web site. However, I had to change the CKE bit from 0 to 1 in order to get reliable communications with the W5100. This feels a bit awkward but since doing that it has been rock solid so it must be right - right?
    Code:
    ' Aliases for the MSSP module status and control bits.
    SSPEN   VAR     SSPCON1.5   ' SSP Enable bit  
    CKP     VAR     SSPCON1.4   ' Clock Polarity Select  
    SMP     VAR     SSPSTAT.7   ' Data input sample phase  
    CKE     VAR     SSPSTAT.6   ' Clock Edge Select bit  
    SSPIF   VAR     PIR1.3      ' SPI interrupt flag
     
    'Set up the MSSP module.
    CKP = 0                     ' Clock idles low  
    CKE = 1                     ' Transmit on active to idle transition.  
    SSPIF = 0                   ' Clear buffer full status  
    SMP = 0                     ' Sample in middle of data 
    SSPEN = 1                   ' Enable SPI pins
    SSPCON1.0 = 1              'Slow down SPI clock to Fosc/16 for now.
    I also had to slow down the SPI clock from the default (Fosc/4) to Fosc/16 in order to get reliable communication. The AMICUS18 defaults to 64MHz so with Fosc/16 the SPI clock is running at 4Mhz which isn't directly slow but well below what the W5100 is capable of (if I read the datasheet correctly that would be ~14Mhz). However, the modification done to the shield and the fact that W5100 is on a separate board from the 18F25K20 may have an impact on the maximum speed achievable. Anyway, I'll leave it at Fosc/16 for now.

    Finally I included the file with all the register definitions for the W5100:
    Code:
    INCLUDE "W5100_defs.pbp"        ' Register definitions and constants for the W5100.
    That's all for this post.

    /Henrik.
    Attached Files Attached Files

  2. #2
    Join Date
    Sep 2009
    Posts
    755

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    I am interested in this project. For now, I have no hardware, no time to make it. So for now I'll watch and learn

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    Hi,
    In todays post I'll try to cover the basic input and output routines I use to communicate with the W5100.

    The W5100 can communicate with the main controller either over a parallel data bus featuring 14 adress lines, 8 data lines and a couple of control lines or it can use a serial interface, SPI. On the Ethernet shield the W5100 is setup to use the SPI interface which is fortunate because we simply don't have enough I/O lines on the AMICUS18.

    Every transaction to and from the W5100, when using SPI, requires 4 bytes. First an OP code telling the W5100 if we're doing a read or a write operation, then two bytes containing the adress we are writing or reading and finally the actual data. When writing to the W5100 WE put the data in the forth byte, when reading from the W5100 IT puts the data in the forth byte - basically. So for each transaction we pull the Chip Select line of the W5100, send 4 bytes and release the Chip Select line (pull high). Here's the code for my read and write subroutines:

    Code:
    WizAdress           VAR WORD       ' Adress in the W5100 to be read or written
    WizData             VAR BYTE       ' Data to be written or data read from the W5100
    WizResponse         VAR BYTE[4]    ' Respose to the four bytes in each SPI transaction. Should be 0,1,2,3 or 0,1,2,data
     
    W5100_Select        VAR PortB.5    ' Chip select line of W5100 connected to RB.5
    W5100_Select = 1
     
    '******************************************************************************************
    Read_W5100:
        WizResponse[0] = SSPBUF         ' Dummy read 
     
        W5100_Select = 0                ' Select W5100
     
        SSPBUF = W5100_READ_OP          ' Send OP code for read operation
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[0] = SSPBUF         ' Store result, should be 0
     
        SSPBUF = WizAdress.HighByte     ' Send high byte of adress
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[1] = SSPBUF         ' Store result, should be 1
        SSPBUF = WizAdress.LowByte      ' Send low byte of adress
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[2] = SSPBUF         ' Store result, should be 2
     
        SSPBUF = 0                      ' Send data
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[3] = SSPBUF         ' Store result, will be the actual data read at the specified adress
     
        WizData = WizResponse[3]        ' Copy databyte from array to WizData.
        W5100_Select = 1                ' Deselect the W5100
    RETURN
    '******************************************************************************************
     
    '******************************************************************************************
    Write_W5100:
        WizResponse[0] = SSPBUF         ' Dummy read.
     
        W5100_Select = 0                ' Pull chip select line low to select W5100
     
        SSPBUF = W5100_WRITE_OP         ' Send OP code for write operation
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[0] = SSPBUF         ' Store result, should be 0
     
        SSPBUF = WizAdress.HighByte     ' Send high byte of adress
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[1] = SSPBUF         ' Store result, should be 1
     
        SSPBUF = WizAdress.LowByte      ' Send low byte of adress
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[2] = SSPBUF         ' Store result, should be 2
     
        SSPBUF = WizData                ' Send the data byte
        While SSPSTAT.0 = 0 : WEND      ' Wait for operation to complete
        WizResponse[3] = SSPBUF         ' Store the result, should be 3
     
        W5100_Select = 1                ' Deselect the W5100
     
    RETURN
    '******************************************************************************************
    I've declared two variables of specific interest here, WizAdress and WizData. WizAdress is the adress in the W5100 we want to access and WizData is, in the case of a write operation, the data we want to write to that adress OR, in the case of a read operation, the data read FROM that adress. In the W5100_defs.pbp file attached to an earlier post the OP-codes for read and write operation as well as the names and adresses of all the registers are defined. Looking at the datasheet for the W5100 we can see that setting bit 7 of the Mode register will perform a reset of the device after which bit 7 is automatically cleared again. Doing this with help from the above subroutines is as simple as:
    Code:
    WizAdress = W5100_Mode : WizData = %10000000 : GOSUB Write_W5100
    In a similar manner we can read, for example, the interrupt register at location $0015 and output its content over the USART like this:
    Code:
    WizAdress = W5100_IR : GOSUB Read_W5100
    HSEROUT ["The status of the Interrupt register is: ", BIN8 WizData, 13]
    As ilustrated here, when writing TO the W5100 WE put the data in the WizData variable and when reading FROM the W5100 we GET the data in the WizData variable.


    To get the Ethernet shield to respond to a Ping all we need to do is set its MAC-adress, IP-adress and NetMask. Doing that is just a series of write operations:

    Code:
    SetUp:
        HSEROUT["W5100_Init",13]
     
        'Send Reset command to W5100.
        WizAdress = W5100_Mode  : WizData = 128 : Gosub Write_W5100
     
        ' Set MAC-adress, see sticker on the back of the Ethernet shield. 
        WizAdress = W5100_SHAR0 : WizData = $05 : GOSUB Write_W5100
        WizAdress = W5100_SHAR1 : WizData = $06 : GOSUB Write_W5100
        WizAdress = W5100_SHAR2 : WizData = $07 : GOSUB Write_W5100
        WizAdress = W5100_SHAR3 : WizData = $08 : GOSUB Write_W5100
        WizAdress = W5100_SHAR4 : WizData = $09 : GOSUB Write_W5100
        WizAdress = W5100_SHAR5 : WizData = $0A : GOSUB Write_W5100
     
        'Set IP adress of W5100    
        WizAdress = W5100_SIPR0 : WizData = 192 : GOSUB Write_W5100
        WizAdress = W5100_SIPR1 : WizData = 168 : GOSUB Write_W5100
        WizAdress = W5100_SIPR2 : WizData = 1   : GOSUB Write_W5100
        WizAdress = W5100_SIPR3 : WizData = 50  : GOSUB Write_W5100
        'Set net-mask
        WizAdress = W5100_SUBR0 : WizData = 255 : GOSUB Write_W5100
        WizAdress = W5100_SUBR1 : WizData = 255 : GOSUB Write_W5100    
        WizAdress = W5100_SUBR2 : WizData = 255 : GOSUB Write_W5100
        WizAdress = W5100_SUBR3 : WizData = 0   : GOSUB Write_W5100
        HSEROUT ["Basic setup done",13]
     
    Main:
    @ NOP
    GOTO MAIN
    Name:  Ping.jpg
Views: 7748
Size:  49.9 KB
    (Sorry about the Swedish screenshot but you'll get the idea...it works...)

    Without the HSEROUT statements we're looking at a just above 400 bytes (out of the 18F25K20's 16k) worth of program memory. Granted, only being able to respond to a ping isn't really worth much from a practical standpoint but it IS a start.


    Finally a word or two about the WizResponse array. When using SPI, data is shifted in and out of the PIC at the same time. Basically as one bit goes out at the "low end" of the MSSP modules shift register one bit goes at the "high end" so after 8 clock cycles the byte we loaded into SSPBUF have been exchanged with a byte from the W5100.

    When writing data to the W5100 it responds with 0, 1, 2, 3 for the four bytes it receives and I'm storing this response in the array WizResponse in order to potentionally use it to verify that the operation was successfull. When reading from the W5100 it responds with 0, 1, 2 and then the actual data in the 4th byte so all I'm doing is copying the data from the 4th byte of the array to the WizData variable before returning from the subroutine.

    /Henrik.

  4. #4
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    Hi,
    In todays post(s) I thought I'd try demonstrate how to set up one of the W5100's four sockets in TCP mode and how to read data that is received. In the end we'll be able to see the data that a web browser sends when it tries to reach the W5100.

    The W5100 can have four connections, or sockets as it called, open simultanously. What this means is that you can have one socket setup to listen for TCP trafic on port 80 (which is the standard port for HTTP) thus acting as a webserver. At the same time you can have another socket connect TO a server and send an email while a third socket connects to a NTP server and retrieves the correct time.

    For now we'll concentrate on a single socket though.

    First order of business is to initialize the W5100, like before this is done by performing a soft reset and then write to its SHAR, SIPR, SUBR and GAR registers to set the MAC-adress, IP-adress, net-mask and gateway adress. Setting the gateway adress isn't strictly needed for this to work but I did that anyway. For now I kept all the settings "hardcoded" but in a real device these would obviously have to be changable thru some kind of userinterface and stored in EEPROM or whatever.
    Code:
    '******************************************************************************************
    Init_W5100:
     
        'Perform a soft reset of the W5100
        WizAdress = W5100_Mode : WizData = 128 : Gosub Write_W5100
     
        ' Set W5100 MAC adress
        WizAdress = W5100_SHAR0 : WizData = $90 : GOSUB Write_W5100
        WizAdress = W5100_SHAR1 : WizData = $A2 : GOSUB Write_W5100
        WizAdress = W5100_SHAR2 : WizData = $DA : GOSUB Write_W5100
        WizAdress = W5100_SHAR3 : WizData = $00 : GOSUB Write_W5100
        WizAdress = W5100_SHAR4 : WizData = $48 : GOSUB Write_W5100
        WizAdress = W5100_SHAR5 : WizData = $03 : GOSUB Write_W5100
     
        ' Set W5100 IP adress
        WizAdress = W5100_SIPR0 : WizData = 192 : Gosub Write_W5100
        WizAdress = W5100_SIPR1 : WizData = 168 : Gosub Write_W5100
        WizAdress = W5100_SIPR2 : WizData = 1   : Gosub Write_W5100
        WizAdress = W5100_SIPR3 : WizData = 50  : Gosub Write_W5100
     
        ' Set W5100 Net mask
        WizAdress = W5100_SUBR0 : WizData = 255 : GOSUB Write_W5100
        WizAdress = W5100_SUBR1 : WizData = 255 : GOSUB Write_W5100
        WizAdress = W5100_SUBR2 : WizData = 255 : GOSUB Write_W5100
        WizAdress = W5100_SUBR3 : WizData = 0   : GOSUB Write_W5100
     
        ' Set W5100 gateway adress
        WizAdress = W5100_GAR0 : WizData = 192 : GOSUB Write_W5100
        WizAdress = W5100_GAR1 : WizData = 168 : GOSUB Write_W5100
        WizAdress = W5100_GAR2 : WizData = 1   : GOSUB Write_W5100
        WizAdress = W5100_GAR3 : WizData = 254 : GOSUB Write_W5100
    RETURN
    '******************************************************************************************
    Next task is to setup socket 0 to listen for TCP trafic on port 80. To do this we first write the value 1 to the sockets Mode register, this sets the protocol for the socket to TCP. Then we write the value 80 to the sockets Source Port register and then tell the W5100 to open the socket. Once the socket is open we can finally switch it into Listen mode which is what we want when acting as a server.
    Code:
    '******************************************************************************************
    Init_Socket_0:
        ' Set socket 0 protocol to TCP by assigning the sockets mode register the value 1.
        WizAdress = W5100_S0_MR       : WizData = 1  : GOSUB Write_W5100
     
        ' Set the port register of socket 0.
        WizAdress = W5100_S0_PORT0    : WizData = 0  : Gosub Write_W5100
        WizAdress = W5100_S0_PORT1    : WizData = 80 : GOSUB Write_W5100
     
    Open_Socket_0:
        ' Set the Command Register of socket 0 to OPEN - this inits the socket.
        WizAdress = W5100_S0_CR     : WizData = W5100_Sn_OPEN : GOSUB Write_W5100
     
        ' Now switch Socket 0 into Listen Mode.
        WizAdress = W5100_S0_CR  : WizData = W5100_Sn_LISTEN : GOSUB Write_W5100
    RETURN
    '******************************************************************************************
    Once the socket is in Listen mode it will automatically switch to Established mode when it receives a connection request from a client. We can check in which mode the socket is by reading the sockets Status register.
    Code:
    HSEROUT ["Program Start", 13]
    Main:
        WizAdress = W5100_S0_SR : GOSUB Read_W5100
        HSEROUT["Socket 0 status = $", HEX WizData,13]
        Pause 500
    Goto Main
    If you run this code with a serial terminal open and type in the W5100's IP-adress in a browser you should see the sockets status register changing from $14 (Listen) to $17 (Established):

    Name:  Socket status output.jpg
Views: 8904
Size:  49.3 KB

    ...to be continued in the next post.

    /Henrik.

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    ...continued from previous post...

    In the W5100 there's a total of 8k of RAM reserved for the sockets receive memory buffer as well as 8k for the sockets transmit memory buffer. The memory can be assigned to each socket in various configuration by writing to the RMSR and TMSR registers. By default both these registers are set to $55 which assigns 2k of RX and TX memory to each of the four sockets. Since we're only about to use one socket we COULD assign then full 8k of each buffer to socket 0 but for this exercise we'll just leave it at the default.

    Once we've established a connection with the client we can determine if any data has been received by reading the sockets Received Size register. The value returned tells us the number of "new" bytes in the sockets receive buffer. What it doesn't tell us is where in the buffer these bytes are....

    The sockets receive (and transmit) buffers are circular buffers meaning once they hit the highest memory adress they wrap around and start over at the beginning. The first byte we're interested in might be somewhere in the middle of the buffer and the last byte might be just before it even though it intuitively should be after the first byte. And, because all four sockets are assigned a "segment" of memory out of a total of 8k the actual start and end adresses of each sockets buffer can "move around" depending on the amount of memory assigned to each socket. If we take a look at the bottom of the W5100_defs.pbp file posted earlier we'll find this:
    Code:
    '**************************************************************************************
    ' ----------- THESE VALUES MAY NEED TO BE CHANGED BY THE USER OF THIS FILE ------------
    '**************************************************************************************
    ' Socket 0-3 RX memory START & END adresses and MASK values for calculating pointer.
    ' Make sure to change these if the RMSR value is changed from its default value of $55
     
    W5100_S0_RX_START        CON $6000  'Start adress of Socket 0 (not changeable)
    W5100_S0_RX_END          CON $67FF
    W5100_S0_RX_MASK         CON $07FF  'Mask value for 2k
     
    W5100_S1_RX_START        CON $6800  'Start adress of Socket 1 (depends on the size of socket 0)
    W5100_S1_RX_END          CON $6FFF
    W5100_S1_RX_MASK         CON $07FF  'Mask value for 2k
     
    W5100_S2_RX_START        CON $7000  'Start adress of socket 2 (depends on the size of sockets 0 & 1)
    W5100_S2_RX_END          CON $77FF
    W5100_S2_RX_MASK         CON $07FF  'Mask value for 2k
     
    W5100_S3_RX_START        CON $8000  'Start adress of socket 3 (depends on the size of sockets 0, 1 & 2)
    W5100_S3_RX_END          CON $8FFF
    W5100_S3_RX_MASK         CON $07FF  'Mask value for 2k
    '**************************************************************************************
    These are the physical start and end adresses for each sockets RX memory buffer when they are each assigned 2k of memory. If the memory allocation between sockets are changed these constants must be updated to reflect the start and end adress of each sockets memory area.

    OK, so how do we know where in the buffer our new data is? This is done by reading the sockets RX Read Pointer register but unfortunately this doesn't give us the real adress of the data, instead it gives us an offset into the sockets memory area. If the value of the pointer is 0 then the first byte of our new data is located at the start-adress of the sockets RX memory ($6000 in this case), if the value is $123 then the first byte is located at adress $6123. Not to bad.... But to make it a bit more complicated this pointer doesn't wrap around "in sync" with the circular buffer. The Rx Read Pointer register is a 16bit register meaning it counts from 0 to 65535 even though we only have 2048 bytes assigned to our buffer - so where is our data when the pointer value is $1234?

    This is where the sockets RX_MASK constant defined in the W5100_defs.pbp file comes in. When the raw pointer value is bitwise AND'ed with the RX_MASK value we'll get the correct offset into the sockets buffer. If we then add this offset to the physical start adress of sockets buffer we finally have the physical adress of the first byte of new data in the buffer.

    So now we know where the first byte of our new data is as well as how many byte there is to read, now we only need to figure out where the last byte is. Given the above this shouldn't be too hard to do... If the adress of the first byte plus the total number of bytes does not "extend" beyond the end of the buffer (no buffer wrap-around) we're done - just read from first byte to first byte + number of bytes. But if it does "extend" beyond the end of the buffer we need to first read up to the end of the buffer, then start over at the beginning, subtracting the number of bytes already accounted for and continue reading. I've wrapped all of this into, yet another, subroutine:
    Code:
    '******************************************************************************************
    ' Variables WizPtr, WizStart, WizEnd and WizSize (all WORDs) declared elsewhere.
     
    CheckBufferForData:
     
        ' Read the sockets receive size register.
        WizAdress = W5100_S0_RX_RSR0 : GOSUB Read_W5100 : WizSize.HighByte = WizData
        WizAdress = W5100_S0_RX_RSR1 : GOSUB Read_W5100 : WizSize.LowByte = WizData
     
        ' If received size is more than 0 we do indeed have new data in the buffer.
        ' In that case we read the socket 0 receive pointer register.
        IF WizSize > 0 THEN
     
            WizAdress = W5100_S0_RX_RD0 : Gosub Read_W5100 : WizPtr.HighByte = WizData
            WizAdress = W5100_S0_RX_RD1 : GOSUB Read_W5100 : WizPtr.LowByte = WizData
     
            ' Calculate the physical adress of the first "fresh" byte in the buffer.
            WizStart = W5100_S0_RX_START + (WizPtr & W5100_S0_RX_MASK)
     
            ' Is the buffer about to wrap around?
            IF WizStart + WizSize > W5100_S0_RX_END THEN
                WizEnd = W5100_S0_RX_START + ((WizStart + WizSize) - W5100_S0_RX_END)
                WizEnd = WizEnd - 2         ' Account for the "zero indexing"
     
            ELSE                                  'No wrap around.
     
                WizEnd = WizStart + WizSize - 1
            ENDIF
     
        ENDIF
    RETURN
    '******************************************************************************************
    When returning from this subroutine the physical adress of the first byte as well as that of the last byte of new data are available to us in the WizStart and WizEnd variables. If WizEnd is less than WizStart the buffer has wrapped around and we need to account for that when actually "extracting" the data. If WizEnd is bigger than [/i]WizStart[/i] then it's as simple as reading from the WizStart to WizEnd.
    Code:
    '*****************************************************************************************************
    GetData:
        HSEROUT [REP "-"\20, " Data read from Rx buffer follows ", REP "-"\20, 13]
     
        Counter = 0                                 ' Temporary as a dubug aid
     
        ' Do we have a buffer wrap around condition?
        If WizEnd < WizStart THEN
     
           ' When that happends we need to start reading at the first byte in the received
           ' package and go on until the end of the sockets RX memory....
            For WizAdress = WizStart to W5100_S0_RX_END
                Gosub Read_W5100
                HSEROUT[WizData]
                Counter = Counter + 1                ' Keep count
            NEXT
     
            ' ...then we need to start over at the beginning of the buffer and keep reading
            ' until we've got all the bytes in the buffer.
            For WizAdress = W5100_S0_RX_START to WizEnd
                Gosub Read_W5100
                HSEROUT[WizData]
                Counter = Counter + 1                ' Keep count
            Next
     
        ELSE       ' There's no buffer wrap-around.
     
            ' WizStart now contains the physical adress of the first byte to read.
            For WizAdress = WizStart to WizEnd
                Gosub Read_W5100
                HSEROUT[WizData]
                Counter = Counter + 1                ' Keep count
            NEXT
     
        ENDIF
     
        HSEROUT [REP "-"\23, " End of data from Rx buffer ", REP "-"\23, 13]
        HSEROUT ["Total number of bytes read:", #Counter,13]
        HSEROUT [REP "-"\76, 13, 13]
    When all data have been "extracted" from the buffer we have to tell the W5100 that we're done so it can recycle that memory for new data that comes in. This is done by first updating the RX Read pointer register so it points to where we left off and finally issuing the RECV command to the sockets command register. Issuing the RECV command tells the W5100 that we're done with the recevied data up to the "adress" of the newly written RX Read pointer register.

    Finally, since we're currently not responding to the request from the client, we simply disconnect and switch back into Listen mode. Not very polite but it'll look the browser as if no one is at the other end so it's OK for now.
    Code:
        WizPtr = WizPtr + WizSize
     
        WizAdress = W5100_S0_RX_RD0 : WizData = WizPtr.HighByte : GOSUB Write_W5100
        WizAdress = W5100_S0_RX_RD1 : WizData = WizPtr.LowByte  : GOSUB Write_W5100
     
        WizAdress = W5100_S0_CR : WizData = W5100_Sn_RECV : GOSUB Write_W5100
        WizAdress = W5100_S0_CR : WizData = W5100_Sn_LISTEN : GOSUB Write_W5100
    Using the above code you'll be able to "see" the HTTP GET request issued by a web-browser pointing at the W5100's IP-adress:

    Name:  HTTP Get request.jpg
Views: 8123
Size:  84.7 KB

    To this post I've attached the exact file I compiled to arrive at the screenshot above (remove .txt extension), you'll also need the W5100_defs.pbp posted earlier in the thread.

    /Henrik.
    Attached Files Attached Files

  6. #6
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    Hi,
    Anyone knows what needs to be done to have a device listen to a "name" as well as its IP-adress?
    For example, I have a SOHO server which has a web-interface, I can access that by either typing in its IP-adress or its name in the adress field of the browser.

    I don't know if it's even possible to do with the W5100 but without knowing how the name is mapped to the IP-adress I don't know how to find out if it can be done. I'm guessing the W5100 needs to "present itself" to the network somehow but how does that mechanism work? Anyone knows or have a reference you can point me at?

    /Henrik.

  7. #7
    Join Date
    Dec 2005
    Posts
    1,073

    Default Re: Using the Arduino Ethernet shield with AMICUS18 (Joint forum project?)

    Quote Originally Posted by HenrikOlsson View Post
    Anyone knows what needs to be done to have a device listen to a "name" as well as its IP-adress?
    For example, I have a SOHO server which has a web-interface, I can access that by either typing in its IP-adress or its name in the adress field of the browser.
    I think your SOHO server (or router) has a DNS/DHCP server which maintains a list of names and corresponding IP addresses. This page might help.
    Last edited by dhouston; - 5th June 2011 at 16:11.

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts