|
|
View previous topic :: View next topic |
Author |
Message |
ressas
Joined: 15 Nov 2019 Posts: 135
|
W5500 Library |
Posted: Wed Jul 15, 2020 6:11 am |
|
|
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: 19506
|
|
Posted: Wed Jul 15, 2020 6:43 am |
|
|
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
|
|
Posted: Wed Jul 15, 2020 8:00 am |
|
|
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: 19506
|
|
Posted: Wed Jul 15, 2020 9:20 am |
|
|
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
|
|
Posted: Thu Jul 16, 2020 2:01 am |
|
|
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: 19506
|
|
Posted: Thu Jul 16, 2020 3:04 am |
|
|
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...
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
|
|
Posted: Thu Jul 16, 2020 4:09 am |
|
|
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: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Jul 16, 2020 5:06 am |
|
|
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: 19506
|
|
Posted: Thu Jul 16, 2020 5:59 am |
|
|
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
|
|
Posted: Thu Jul 16, 2020 6:47 am |
|
|
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: 19506
|
|
Posted: Thu Jul 16, 2020 7:00 am |
|
|
What compiler version are you running?.
Obvious possibility is that there is an issue with your version.... |
|
|
ressas
Joined: 15 Nov 2019 Posts: 135
|
|
Posted: Thu Jul 16, 2020 7:18 am |
|
|
Version 5.015 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Thu Jul 16, 2020 7:43 am |
|
|
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
|
|
Posted: Tue Jul 21, 2020 8:08 am |
|
|
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: 9225 Location: Greensville,Ontario
|
|
Posted: Tue Jul 21, 2020 9:12 am |
|
|
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 |
|
|
|
|
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
|