|
|
View previous topic :: View next topic |
Author |
Message |
timk
Joined: 03 Aug 2018 Posts: 11
|
SPI problems with PN512 and dsPIC30F6015 |
Posted: Fri Aug 03, 2018 2:36 am |
|
|
Hello,
I want to use SPI for the communication between my dsPIC30F6015 and my PN512 module.
The Problem is, that the communication over SPI does not work.
I connected the MISO, MOSI, NSS and SCK to the Pins, which are described at page 69 in the datasheet.
When I try to read the Registers via SPI, then I send the following data:
When I want to read Register 0x00 (PageReg), then I send an 0x80.
Bit 7 is set to 1 and all other Bits are set to 0.
When I want to read Register 0x01 (CommandReg), then I send an 0x82.
I try to read the other Registers like that, but the module does not return the expected reset value. (Except for page 0x00 and all other pages where the reset value is 0x00.)
The module does not answer at all.
So I looked at the MOSI, MISO, SCK and NSS Pins with an oscilloscope.
MOSI, SCK and NSS seem to work well.
But the MISO Pin is always on Low.
When I communicate with other SPI-devices on the same SPI-bus, then they work well and I get a signal on the MISO PIN.
This is why I am sure, that the MISO Pin is not shorted to GND.
Also I tried all SPI modes and configurations.
I am using a PN5120A0HN1/C1 in the HVQFN-32 package.
Did anyone have similar Problems with this device, or an idea to help me.
Thanks in advance,
Tim |
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Fri Aug 03, 2018 2:55 am |
|
|
Here is some of the used Code:
Code: | #use spi(MASTER, BAUD=20000, BITS=8, MODE=0,stream=SPI_NFC) |
Code: |
while(1)
{
output_low(CS2);
spi_write2(0x82);
spi2_data[0] = spi_read2();
spi_write2(0x00);
spi2_data[1] = spi_read2();
Output_high(CS2);
delay_ms(1000);
}
|
When I print spi2_data, then it is not the data I expect it has to be.[/code] |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Fri Aug 03, 2018 4:10 am |
|
|
Several things:
If using #use spi, use spi_xfer, not spi_write/read. If you look in the manual, you will find that these two commands do not reference each other. setup_spi, is used with read/write, and #use with spi_xfer. They 'can' work together in some specific combinations, but not always.....
Then you need to read the reply from the write. Problem is that when you write a byte to SPI, a reply is always clocked back 'in'. If you then read, it is the reply from this that you get.
So:
Code: |
while(1)
{
int8 dummy;
output_low(CS2);
dummy=spi_xfer(0x82); //send the command. get rid of dummy return
spi2_data[0] = spi_xfer(1); //This should be address1. Is this right?
spi2_data[1] = spi_xfer(0); //and second byte
output_high(CS2);
delay_ms(1000);
}
|
Now look at table 143. Understand that you have to read the dummy byte that comes back when you send the first address byte, and the byte then actually used to clock in the first data byte should be the address byte required for the second byte. Is '0' correct for this?. I've put '1', assuming you want the next byte?. |
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Fri Aug 03, 2018 4:36 am |
|
|
Thats a good tip with the xfer command.
A colleague of me wrote his spi Drivers in this style and because the Drivers worked I adopted it.
But I think I will use the xfer command in the future.
Quote: | Then you need to read the reply from the write. Problem is that when you write a byte to SPI, a reply is always clocked back 'in'. If you then read, it is the reply from this that you get. |
Thats the reason I have 2 read commands.
Quote: |
dummy=spi_xfer(0x82); //send the command. get rid of dummy return
spi2_data[0] = spi_xfer(1); //This should be address1. Is this right?
spi2_data[1] = spi_xfer(0); //and second byte
|
As I understand you need to send 0x82 to read address 1.
Then you read and get dummy.
Then you send 0x00 for end of reading Bytes of addresses.
Then you read to get value of address 1.
Take a look at table 145.
Bit 7 = 1 for read, Bit 7 = 0 for write.
Bit 0 = 0. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Fri Aug 03, 2018 5:42 am |
|
|
The first big problem is your #use spi, is not saying anywhere to talk to SPI2:
Code: |
#use spi(MASTER, SPI2, BAUD=20000, BITS=8, MODE=0,stream=SPI_NFC)
|
This will then tell it to use the SPI2 hardware....
Now since you have used a stream name, you can use stream names in the spi_xfer commands:
Code: |
while(1)
{
int8 dummy;
output_low(CS2);
dummy=spi_xfer(SPI_NFC, 0x82); //send the command. get rid of dummy return
spi2_data[1] = spi_xfer(SPI_NFC, 0); //This should be address1. Is this right?
output_high(CS2);
delay_ms(1000);
}
|
This is great since you can then have multiple SPI interfaces in use....
The core reason your code was not working was that you were talking to SPI2, without this setup....
The code you pasted seems to be putting the dummy reply from the first command into the first entry of the array. Seems pointless.
You can use spi_xfer, just like spi_write. If you call it without a return variable, it writes the byte and leaves the reply in the register, which is what the old code was relying on. Rather pointless, since you can clock a byte and get the reply as one operation, either as I show with spi_xfer, or with:
spi2_data[1] = spi_read(0); //and second byte
Which clocks out '0', and reads the reply. |
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Fri Aug 03, 2018 6:18 am |
|
|
In the real Code i used "SPI2" in the "use spi...", but i forgot to type it in there, because the Computer i do the programming with is offline.
I can "talk" to other SPI-devices with read/write and xfer.
But not to then PN512.
I want to use SPI2 because SPI1 is already in use.
Quote: |
spi2_data[1] = spi_xfer(SPI_NFC, 0); //This should be address1. Is this right?
|
In spi_data[1] should be what is in address 1.
Quote: |
The core reason your code was not working was that you were talking to SPI2, without this setup....
|
I have to use SPI2 Hardware, because the PN512 is on the SPI2.
Quote: |
The code you pasted seems to be putting the dummy reply from the first command into the first entry of the array. Seems pointless.
|
For the program which I intend to write, this is quite pointless.
But I want to Display everything I get over SPI.
Quote: |
Now since you have used a stream name, you can use stream names in the spi_xfer commands:
|
I already tried to use the xfer command, but it does not work.
There are the same symptms.
Signal on MOSI, SCK, NSS (CS2).
No signal on MISO.
You still can see the Definition of the stream in my "#use spi", because I already tried this with xfer and stream.
But I wasnt sure because my colleague did it with read/write. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Fri Aug 03, 2018 6:45 am |
|
|
Seriously, if you are generating MOSI, and SCK, with CS low, then it is the slave that generates MISO. You have a fault in your slave. Triple check the wiring. Particularly that the NRSTPD line is being taken high (the chip won't run till it is). Also obviously the pin pattern to select SPI.
As a comment, why on earth are you clocking at 20KHz?. 2MHz would be a more typical clock rate. I don't see anywhere in the data sheet a minimum clock rate for SPI, but quite a few devices do have a minimum. I would not take it below 100KHz to be safe on this.
Is it possible something has been sent to the chip to put it into power down mode?. Remember needs 1024 clock cycles to wake from this.
What you are sending, does not make sense to me.
You seem to be sending a command to read address 2. Now this is meant to be a control register for interrupts, with 0x80 as the reset value. So what are you getting?.
Honestly if the device is not responding, and other devices do, then you have a hardware issue. |
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Fri Aug 03, 2018 7:08 am |
|
|
Quote: |
Seriously, if you are generating MOSI, and SCK, with CS low, then it is the slave that generates MISO.
|
This was my thinking too.
I also thought about it, because there are two versions of the chip, the C1 and C2 (PN5120A0HN1/C1, PN5120A0HN1/C2).
The Datasheet says that there are just minor differences, but maybe SPI is not implemented on the C1 which i am using?
Quote: |
Also obviously the pin pattern to select SPI.
|
Pin pattern is ok too.
A0 on 3,3V and A1 on GND.
Quote: |
As a comment, why on earth are you clocking at 20KHz?
|
First when it did not run i reduced the Speed to 20 kHz, because i thought that my Speed was too fast.
When the System is ok, I want to let it run at 1 MHz.
Quote: |
Is it possible something has been sent to the chip to put it into power down mode?.
|
I already thought about that, but i have three circuit boards with the same chip, which are all behaving the same.
And I havent read about a power down mode in the datasheet.
Quote: |
You seem to be sending a command to read address 2. Now this is meant to be a control register for interrupts, with 0x80 as the reset value. So what are you getting?.
|
Im getting 0x00 all the time.
And there is absolutely no Signal on MISO.
Quote: |
Honestly if the device is not responding, and other devices do, then you have a hardware issue.
|
I earlier thought about a Hardware failure or false Routing.
Maybe that the MISO Pin of PN512 is not connected with MISO on dsPIC, but the Hardware seems to be ok. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Fri Aug 03, 2018 7:26 am |
|
|
Given the horrible register addressing, I'd suggest something like:
Code: |
#use spi(MASTER, SPI2, BAUD=2000000, BITS=8, MODE=0,stream=SPI_NFC)
#define REGISTER(x,y) (x<<1)|y
#define READ 0x80
#define WRITE 0
#define PAGE 0
#define COMMAND 1
#define COMLEN 2
#define DIVLEN 3
#define DIVIRQ 4
#define ERROR 5
#define STATUS1 6
#define STATUS2 7
#define FIFODAT 8
#define FIFOLVL 8
#define WATERLVL 9
#define CONTROL 10
while(1)
{
int8 dummy;
output_low(CS2);
dummy=spi_xfer(SPI_NFC, REGISTER(COMMAND,READ)); //read
spi2_data[1] = spi_xfer(SPI_NFC, 0); //read the command register and finish
output_high(CS2);
delay_ms(1000);
}
|
Honestly looking at everything, this should read the command register. I repeat if it doesn't, you have a hardware issue. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Fri Aug 03, 2018 7:37 am |
|
|
From your post, you are using the low pin count version. 32pin. So the other pins needed on the larger version don't apply,
Several chips tried, so we can rule out a simple soldering problem.
Question still applies about the reset pin?. If this was not going high, the chip would not wake.
Er....
Quote: |
Maybe that the MISO Pin of PN512 is not connected with MISO on dsPIC, but the Hardware seems to be ok.
|
You do realise the the MISO pin on the PN512 goes to the SDI pin of the PIC and the MOSI pin of the PM512 goes to the SDO pin of the PIC?. |
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Fri Aug 03, 2018 8:10 am |
|
|
Quote: |
From your post, you are using the low pin count version. 32pin
|
Yes it is 32 Pin.
It is wired like this:
PIC PN512
SDCK2/CN8/RG6 -> SCK -> D5 (SCK)
SDI2/CN9/RG7 <- MISO <- D6 (MOSI)
SDO2/CN10/RG8 -> MOSI -> D7 (MISO) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Fri Aug 03, 2018 8:14 am |
|
|
Well that is wrong....
You have the master serial data in pin (SDI2), connected to the slave 'master out slave in' pin. and the same problem for the serial data out.....
PIC pins SDI is serial data in. This has to go to the MI pin (master in).
SDO is serial data out. This has to go to the MO pin (master out).
No wonder it is not working.
You are misunderstanding how the nomenclature works.
When you have a pin labelled just as 'master out', or SDO, this has to connect to the corresponding 'in' pin on the slave. Similarly the in pin has to connect to the out. A swap.
However when the 'MOSI' nomenclature is used, this already does the swap 'for you'. The pin labelled 'MOSI' on the master is it's 'input'. The pin labelled MOSI on the slave, is it's output. MOSI connects to MOSI, and MISO to MISO. You are swapping these, which means you are connecting two outputs together, and two inputs together... |
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Sun Aug 05, 2018 11:58 pm |
|
|
Sorry
Quote: | You are misunderstanding how the nomenclature works. |
I understood right but wrote it down wrong.
It was MISO - MISO.
and MOSI - MOSI.
Now I think I found the real error:
The NRSTPD Pin is always at low in my circuit.
I think that this is the real reason ist not working. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19485
|
|
Posted: Mon Aug 06, 2018 12:47 am |
|
|
As I said quite early on:
Quote: |
Particularly that the NRSTPD line is being taken high (the chip won't run till it is).
|
|
|
|
timk
Joined: 03 Aug 2018 Posts: 11
|
|
Posted: Mon Aug 06, 2018 2:25 am |
|
|
Quote: |
As I said quite early on:
Quote:
Particularly that the NRSTPD line is being taken high (the chip won't run till it is).
Sad
|
I'm sorry,
I thought I had this pin at a high Level, but it was not.
But thank you for helping me! |
|
|
|
|
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
|