|
|
View previous topic :: View next topic |
Author |
Message |
Atarek
Joined: 07 Sep 2017 Posts: 9
|
Hardware SPI |
Posted: Thu Sep 07, 2017 2:57 am |
|
|
Hi everyone,
I need advice in something,
I am trying to interface MFRC522 using hardware SPI. However, I fail every time. I thought to share the code, and maybe someone can help me.
The description from the MFRC522's datasheet states the following:
Quote: | from section 8.1.2,
Data on both MOSI and MISO lines must be stable on the rising edge of
the clock and can be changed on the falling edge,
Data is provided by the MFRC522 on the falling clock edge and is stable
during the rising clock edge, |
Hence we can conclude that data transmission mode is Mode 0, right???
Now i use the following code in the main.h
Code: | #use SPI(MASTER, DO = PIN_C5, DI = PIN_C4, CLK = PIN_C3,MODE = 0, ENABLE = PIN_E2, BITS = 8, FORCE_HW)
#define PIN_CS PIN_E2 //MFRC522 SPI chip select pin (NRSTPD) |
and when i try to write to the MFRC522 i used the following code according to the device instructions:
Code: | /*
section 8.1.2.3
The MSB of the first byte defines the mode used.
To write data to the MFRC522 the MSB must be set to logic 0.
Bits 6 to 1 define the address and LSB is set to logic 0;
/*
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
spi_write(value);
output_bit(PIN_CS, 1); |
I hope someone will be able to help me.
Thank you in advance,
Atarek |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Thu Sep 07, 2017 3:26 am |
|
|
You are mixing two ways of using the SPI.
If you look at the manual for #use spi, you will see no mention of spi_write.
The command to use with #use spi, is spi_xfer.
spi_write is the older command for use with setup_spi. They are two _not mixable_ ways of using the spi.
You also need to read the reply (even when it is not used), otherwise the spi commands will return immediately, when the byte is transferred to the hardware.
Now you don't tell us your chip, but assuming your chip does have the hardware SPI on the pins you are using:
Code: |
#USE SPI (SPI1, MODE=0, BITS=8, STREAM=MFRC)
//Then to send to it:
int8 dummy;
output_low(PIN_CS);
dummy=spi_xfer(MFRC, reg & 0x7E);
dummy=spi_xfer(value);
output_high(PIN_CS);
|
The clock is shown as idling low, so yes this is mode 0.
Reading the returned byte, ensures the actual transfer has completed before you raise the CS.
Selecting the peripheral by name, forces the hardware pins to be used. |
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Thu Sep 07, 2017 6:38 am |
|
|
Thank you Ttelmah for your quick feedback,
but it seems that i have another problem. When i try to use the hardware SPI, the micro controller does not exit any routine that uses hardware SPI.
So that when i use the below code in the main.c
Code: | MFRC522_init(); //function that uses SPI
delay_ms(10);
output_high(LEDB);
output_high(LEDR);
output_high(LEDG);
delay_ms(50);
output_low(LEDB);
output_low(LEDR);
output_low(LEDG);
|
the leds never blink.
By the way i am using 18F452.
Thanks in advance,
Atarek |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Thu Sep 07, 2017 7:16 am |
|
|
You really need to show us your init code. |
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Sun Sep 10, 2017 7:00 am |
|
|
here it is
Code: | void MFRC522_init(void) //MFRC522 chip initialization
{
MFRC522_writeReg(TModeReg, 0x8D);
MFRC522_writeReg(TPrescalerReg, 0x3E);
MFRC522_writeReg(TReloadRegH, 0x00);
MFRC522_writeReg(TReloadRegL, 0x30);
MFRC522_writeReg(TxASKReg, 0x40);
MFRC522_writeReg(ModeReg, 0x3D);
MFRC522_AntennaOn();
} |
I tried Hardware SPI using
Code: | spi_write(); spi_read(); |
The code works, but when i try to monitor the signal bus, it is not sending the same data, (the MRFC522 is not working).
By the way the code is based on the library used in the following link:
http://microcontrolandos.blogspot.com.eg/2014/02/pic-rfid-mfrc522.html
Are there some condititions where one cannot substitute software SPI (bit banging) for Hardware SPI, (maybe MSB first) ?
Regards
Atarek |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sun Sep 10, 2017 7:40 am |
|
|
As far as I know the only 2 things are different between HW vs SW SPI
1) SW doesn't have _normally_ interrupt capabilty
2) speed, SW will be _normally_ slower
How the data gets sent to the SPI device depends upon how the programmer sets up the SPI code. A look at the listing, comparing HW vs SW SPI will show what's going on.
Jay |
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Sun Sep 10, 2017 7:57 am |
|
|
Hi Temtronic,
Thank you for the quick feedback,
the list file of the software SPI
.................... SoftSPI_write(reg & 0x7E);
0052: MOVF 65,W
0054: ANDLW 7E
0056: MOVWF 67
0058: MOVWF 6D
005A: RCALL 000E
.................... SoftSPI_write(value);
005C: MOVFF 66,6D
0060: RCALL 000E
and for the hardware SPI
.................... spi_write(reg & 0x7E);
002E: MOVF 65,W
0030: ANDLW 7E
0032: MOVWF 67
0034: MOVF FC9,W
0036: MOVFF 67,FC9
003A: BTFSS FC7.0
003C: BRA 003A
.................... spi_write(value);
003E: MOVF FC9,W
0040: MOVFF 66,FC9
0044: BTFSS FC7.0
0046: BRA 0044
They are different, how to make it work now?
Thanks in advance,
Atarek |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 10, 2017 9:31 am |
|
|
Of course they are different. The software SPI uses a bit-banging routine
and the hardware SPI talks to the hardware SPI registers.
In the code below, you are doing something wrong. You have specified
a Chip Select signal with the ENABLE parameter in the #use spi() statement,
as shown in bold below:
Quote: | #use SPI(MASTER, DO = PIN_C5, DI = PIN_C4, CLK = PIN_C3,MODE = 0, ENABLE = PIN_E2, BITS = 8, FORCE_HW)
|
This ENABLE (chip select) signal operates on a per byte basis. But that's
not what you want for this driver.
The MFRC522 data sheet says:
Quote: | Remark:
The signal NSS must be LOW to be able to send several bytes in one
data stream. To send more than one data stream NSS must be set
HIGH between the data streams. |
NSS is their name for Slave Select. The 'N' means its active state is
a logic low level.
Delete the 'ENABLE = PIN_E2' setting from your #use spi() statement.
Then your #use spi() statement should look like this:
Code: | #use SPI(MASTER, DO = PIN_C5, DI = PIN_C4, CLK = PIN_C3, MODE = 0, BITS = 8, FORCE_HW) |
In the code below, you are manually handling chip select, and you are
keeping it low for the 2-byte transmission. This is the correct way to do it:
Quote: |
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
spi_write(value);
output_bit(PIN_CS, 1);
|
|
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Mon Sep 11, 2017 12:33 am |
|
|
HI PCM Programmer,
Thank you for the explanation,
but in the last section you mentioned the following
Quote: | In the code below, you are manually handling chip select, and you are
keeping it low for the 2-byte transmission. This is the correct way to do it:
Quote:
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
spi_write(value);
output_bit(PIN_CS, 1); |
Do you mean that this is the correct way to do it?
Thanks in advance,
Atarek |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 11, 2017 12:54 am |
|
|
Atarek wrote: |
Do you mean that this is the correct way to do it?
|
To make sure that you understood, I put that exact statement in my post !
Here is my post again, with that line shown in bold:
Quote: |
In the code below, you are manually handling chip select, and you are
keeping it low for the 2-byte transmission. This is the correct way to do it:
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
spi_write(value);
output_bit(PIN_CS, 1);
|
|
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Mon Sep 11, 2017 1:10 am |
|
|
PCM Programmer,
Thank you for your effort to make sure that i understand the concept,
according to what you said the correct answer is to make NSS logic high between the 2 byte transmission,
Code: |
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
output_bit(PIN_CS, 1);
output_bit(PIN_CS, 0);
spi_write(value);
output_bit(PIN_CS, 1); |
Thanks in advance,
Atarek |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 11, 2017 2:07 am |
|
|
Atarek wrote: |
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
output_bit(PIN_CS, 1);
output_bit(PIN_CS, 0);
spi_write(value);
output_bit(PIN_CS, 1);
|
That is absolutely NOT what I said.
I'm done with this. I cannot talk to someone who does the opposite of
what I say. I'm sorry, I'm done. |
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Mon Sep 11, 2017 4:55 am |
|
|
Maybe this
Code: |
spi_write(reg & 0x7E);
output_bit(PIN_CS, 1);
spi_write(value); |
Regards,
Atarek |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Mon Sep 11, 2017 5:13 am |
|
|
What PCM P has said...
Quote: |
In the code below, you are manually handling chip select, and you are
keeping it low for the 2-byte transmission. This is the correct way to do it:
output_bit(PIN_CS, 0);
spi_write(reg & 0x7E);
spi_write(value);
output_bit(PIN_CS, 1);
|
IS THE WAY TO DO IT !!!
I understand English is not everyone's first language, but the code segment that PCM P has posted for you DOES WORK.
No other code you've shown will work.
Hopefully you've got an oscilloscope to view the data stream. If not, save your coins and buy one. Even a 30 year old, 2 channel analog scope, will work fine for 99% of PIC projects. I know as that's what I use, daily.
PCM P's code works, I've seen it on my scope. Normally I don't take time to code/compile/test but his does work, so please use it as posted.
Something not mentioned is power supply levels. Most peripheral 'devices' are designed for 3 volts, and PICs are rated at 5 volts ,unless the 'L' version. The MFRC522 IS a 3 volt device, so what PIC are you using? It is critical information we need to know!! You cannot directly connect 3 V devices to 5V PICs and have them work !!
Jay |
|
|
Atarek
Joined: 07 Sep 2017 Posts: 9
|
|
Posted: Mon Sep 11, 2017 6:37 am |
|
|
thank you temtronic for clarification,
forgive my igonorance,
I use the scope as you said, and here is the results
soft SPI
[img]https://drive.google.com/file/d/0By2rhMw0TAvNRWM0YmhkV1lKWDA/view[/img]
Hard SPI
[img]https://drive.google.com/file/d/0By2rhMw0TAvNY0ZCZ2E4MUs0Yms/view[/img]
please advise
Regards,
Atarek |
|
|
|
|
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
|