CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

W5500 Library
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

W5500 Library
PostPosted: Wed Jul 15, 2020 6:11 am     Reply with quote

Hello everyone.
I decided to write a c library for the w5500.
But I don't think I will succeed without your help.
I'm working on TCP / IP and MODBUS yet.
First, on page 32; There is a second number next to the register address.
What does it mean;
Quote:
MR (Mode Register) [R/W] [0x0000] [0x00]2

This statement exists next to all register addresses.
Quote:
GAR (Gateway IP Address Register) [R/W] [0x0001 – 0x0004] [0x00]

Second, there is a saying in i2c libraries.


Code:

void write( unSIGNED INT16 address,  unSIGNED INT16 data) {             
  i2c_start();                                                             
  i2c_write(dev_adds);         
  i2c_write(address & 0xff);                                                                           
  i2c_write(data >>8);           /<====/           
  i2c_write(data);                                                                                 
  i2c_stop();                                                               
}



By sliding the data, we can send 16 or 8 bit data.
How to handle 16 or 8 bit transmissions in SPI?
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Wed Jul 15, 2020 6:43 am     Reply with quote

Block address.

The registers are organised in pages. So the GAR registers are
registers 1 to 4, of page 0.

If you look at the SPI description for this, you send a 16bit address, then
a byte that specifies the block address (as it's upper 5 bits), followed by
a R/W flag and a two bit mode value.

Honestly, keep it simple and just use 8 bit transmissions. Use make8, rather
than >>8 to get the upper byte (though the optimiser is efficient, is is
easier to use the tools supplied for the job...).
Use VDM mode, and just raise the CS when the transfer is finished.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Wed Jul 15, 2020 8:00 am     Reply with quote

Hmm. I understood.
As in the Datasheet example;
Quote:

Offset Address = 0x0003
BSB[4:0] = ‘11101’
RWB = ‘0’
OM[1:0] = ‘00’
1st Data = 0x17

But instead of sending 8 bits of information separately, how can I send them all at once?
Code:

#use SPI(MASTER, DI=_pinSDI, DO=_pinSDO,  CLK=_pinSCK/*,ENABLE=_pinSCS*/, baud=1000000, bits=8, MODE=2, Stream= W5500)
         spi_write(0x0003);
         //
         spi_write(0b11101); //spi_write(0xE8);
         spi_write(0b0);     
         spi_write(0b00);
         //
         data_in = spi_read(0x17);
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Wed Jul 15, 2020 9:20 am     Reply with quote

If you use spi_xfer, instead of spi_write, you can specify on the individual
transfers how many bits to send. So:

spi_xfer(W5500, val,8); //send an 8 bit value

spi_xfer(W5500, val16, 16); //sends a 16 bit value

However it gains you nothing. The transfer hardware sends 8 bits at a
time, and if you need to read reply data, you are then faced with
different sized pieces coming back. It is no more efficient than simply
looping yourself....

You should _not_ be using spi_write with #use spi. If you look at the
data sheet you will find that #use spi, refers you to spi_xfer, not spi_read
and spi_write. These refer you to setup_spi instead.

These are two 'generations' of different settings, and should not be used
together. Doing so, can lead to 'issues'....

However honestly, use 8 bit transfers.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 2:01 am     Reply with quote

Did I adapt this expression in datasheet correctly? Page 22:
Quote:

Offset Address = 0x0003
BSB[4:0] = ‘11101’
RWB = ‘0’
OM[1:0] = ‘00’
1st Data = 0x17


Code:

          #use SPI(MASTER, DI=_pinSDI, DO=_pinSDO,  CLK=_pinSCK, baud=1000000, bits=16, MODE=2, Stream= W5500)

         spi_xfer(W5500, 0x0003,16);
         spi_xfer(W5500, 0xE8,8);
         data_in = spi_xfer(W5500, 0x17,8);   
         


For data_in value;
When an Ethernet socket is installed: 1
When not: Should I expect values like 0?
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 3:04 am     Reply with quote

Well, no.

First thing why on earth are you using Mode 2?.
The datasheet specifically says the chip supports Mode 0 or Mode 3.
So you are clocking on the wrong edge. Won't work... Sad

Then consider saving yourself a lot of work, and letting the compiler
do a lot of the 'translation' for you:
Code:


#use SPI(MASTER, DI=pinSDI, DO=pinSDO,  CLK=pinSCK, baud=1000000, bits=16, MODE=2, Stream= W5500)
typedef struct {
   int8 OM : 2;
   int8 RWB : 1;   
   int8 BSB : 5;
} control;



//Then in the code you can access the control register like:

   int8 data_in;
   control cval={0,0,0x1D};
   setup_adc_ports(NO_ANALOGS, VSS_VDD);
   spi_xfer(W5500, 0x0003,16);
   //cval = ;
   spi_xfer(W5500, cval ,8);
   data_in = spi_xfer(W5500, 0x0,8);     
//You don't send '0x17', this is the reply expected from the chip

If you look at the data sheet, you will see that the fourth byte in the
transfer has nothing send by the master (0), and the reply comes from
the slave.

The value you were loading for the control register was wrong. You want:

0b11101 0 00
Which is 0xEB, not 9B. The structure declaration I show calculates this
for you.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 4:09 am     Reply with quote

Quote:
spi_xfer(W5500, cval,8);

this line fails for cval; Error 51 A numeric expression must appear here
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 5:06 am     Reply with quote

Possible reason.

From the code fragment above..
This line of code.....

control cval={0,0,0x1D};

doesn't look correct to me

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 5:59 am     Reply with quote

If you look I have a typedef for 'control' above this.

control is declared as three bitfields, and the three values are written into
these fields. What I posted, compiled and worked for me.
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 6:47 am     Reply with quote

Where is my mistake?
Code:

#include <18F46k22.h>
#device ADC=16
#fuses NOWDT,NOBROWNOUT,PUT,NOWRT,NODEBUG,INTRC_IO, NOMCLR, NOPROTECT, NOWDT, NOLVP,PLLEN                 
                 
#use delay(internal=64000000)
#include "W5500.h"
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//#use i2c(Master,sda=PIN_c4,scl=PIN_c3,slow=400000,FORCE_hw)

#define _pinSCK  pin_C3
#define _pinSDI  pin_C4
#define _pinSDO  pin_C5
#define _pinSCS  pin_D0

#define _pinFSR  pin_A0
#define _pinMOT1 pin_C2
#define _pinROT1 pin_E2
#define _pinROT2 pin_D1

    #use SPI(MASTER, DI=_pinSDI, DO=_pinSDO,  CLK=_pinSCK, baud=1000000, bits=16, MODE=0, Stream= W5500)
   
    typedef struct {
         int8 OM  : 2;
         int8 RWB : 1;   
         int8 BSB : 5;
      } control;
     
   
   
   VOID main()
   {
          int8 data_in;
       control cval={0,0,0x1D};
       setup_adc_ports(NO_ANALOGS, VSS_VDD);

       
       WHILE (TRUE)
       {
     
       spi_xfer(W5500, 0x0003,16);
       //cval = ;
       spi_xfer(W5500, cval ,8);
       data_in = spi_xfer(W5500, 0x0,8);
       printf("Dat: %d\n",data_in);
      }

    }
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 7:00 am     Reply with quote

What compiler version are you running?.
Obvious possibility is that there is an issue with your version....
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 7:18 am     Reply with quote

Version 5.015
Ttelmah



Joined: 11 Mar 2010
Posts: 19516

View user's profile Send private message

PostPosted: Thu Jul 16, 2020 7:43 am     Reply with quote

Ouch....

A very early V5 compiler. Only just after it first started to work. Not
possibly surprising that it doesn't support this.
So in which case do it in a 'compatible' mode using defines. Something
like:
Code:

#define BLOCK(x) (x<<3)
#define WRITE 4
#define READ 0
#define VDMN 0
#define FDL1 1
#define FDL2 2
#define FDL4 3

void main()
{
   int8 data_in;
   setup_adc_ports(NO_ANALOGS, VSS_VDD);
   output_high(CS); //ensure CS starts high
 
   while(TRUE)
   {
      output_low(CS); //You have this missing - essential
      spi_xfer(W5500, 0x0003,16);
      spi_xfer(W5500, BLOCK(0x1D) | READ | VDMN ,8);
      data_in = spi_xfer(W5500, 0x0,8);
      output_high(CS); //same comment...
      printf("Dat: %x\n",data_in); //honestly easier to look at in hex     
   }
}
ressas



Joined: 15 Nov 2019
Posts: 135

View user's profile Send private message

PostPosted: Tue Jul 21, 2020 8:08 am     Reply with quote

Hello mr. T.
I tried both code suggestions. In your first suggestion, I was getting an error due to the version. I downloaded the demo to see if it would work. But it didn't work. I get the value: 1 when the socket is connected or not. Maybe I should first learn SPI and try again later.
Temtronic said:
Quote:

quick comment
You need to download your PIC's datasheet and read the section on MSSP. Yes, I know 30-40-50 pages of dull, dreary reading but once you understand it, you're a far better programmer ! It describes and shows all aspects on how the SSP peripheral can be configured for either SPI or I2C modes. As for the SPI 'modes', those deal with the way data is 'seen' based upon if the clock line is high or low. As for the INT, when the peripheral 'sees' data it can inform the PIC by means of an Interrupt 'flag'. Interrupts are far better to use than 'polling', as they are faster and allow the PIC to be doing 'something' else instead of sending the data out.

But it might be better when you read ccs c user manual. What do you suggest?
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 21, 2020 9:12 am     Reply with quote

hmm.. I d/l a datasheet and that w5500 is a 3 volt device so I have to ask what is the power supply you're using ?? Are both the PIC and W5500 running 3 volt or 5 volt ? If 5 volt, is the W5500 on a 'module' that is 5 volt rated ??

Can you correctly select and write then read back data to several of the W5500 registers ? You should code a simple 'select a register, write to it, pause, then read back the data' program. This would confirm basic hardware are software are probably OK.

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group