View previous topic :: View next topic |
Author |
Message |
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
SPI master problem, spi_read not working PIC16F887 |
Posted: Mon Mar 31, 2008 3:39 pm |
|
|
I am communicating to an RFID reader using SPI. The reader is the Skyetek M9 and it is the SPI slave device. My PIC16F887 is the SPI master. After about a week I finally was able to get the M9 to transmit data back. The M9 starts every packet with a 0x02, and I can see that it is sending it using an Oscope. My problem is that I can not get the bytes coming in to save to memory. Please help, it seems like there should be a really easy solution. Code pasted below
-------------------------
#include <16F887.h>
#FUSES INTRC,NOWDT,NOPUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP
#use delay(internal=4000000)
#use rs232(baud=38400, uart1, parity=N, bits=8, stop=1)
#define SSEL PIN_B0
#define D0 PIN_C5
#define DI PIN_C4
#define CLK PIN_C3
void main(void)
{
int i;
BYTE receive = 0;
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16|SPI_SAMPLE_AT_END);
SET_TRIS_C(0x10); // bit 0 = output, 1 = input
while(1)
{
output_low(SSEL);
spi_write(0x02);
spi_write(0x00);
spi_write(0x0A);
spi_write(0x00);
spi_write(0x20);
spi_write(0x12);
spi_write(0x01);
spi_write(0x00);
spi_write(0x01);
spi_write(0x00);
spi_write(0x04);
spi_write(0xDA);
spi_write(0xE9);
output_high(SSEL); //Pull slave select high to indicate packet is done.
delay_ms( 8 );
for(i = 0; i<13; i++)
{
output_low(SSEL); //Pull Slave Select Low
receive = spi_read(0x00);
output_high(SSEL); //Pull Slave Select High
if (receive == 0x20 || receive == 0x08 || receive == 0x04 || receive == 0x02 || receive == 0x01 || receive == 0x10)
output_high(PIN_B2);
delay_ms( 3 );
}
delay_ms( 1000 );
}
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 31, 2008 3:53 pm |
|
|
I can't find a data sheet for the M9 on their website. They have a
document that they call a "data sheet", but it's really a brochure.
If you know where they have the real data sheet available for download,
then post a link to it. |
|
|
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
|
Posted: Mon Mar 31, 2008 4:12 pm |
|
|
You have to have an account to access the data sheet. Here is all they say about the SPI:
*The M9 SPI interface communicates in Mode 1, which means that the clock polarity is zero and the clock phase is one.
*The host must implement SPI master functionality
*The SCK line should be the master clock controlled by the host.
*The MOSI signal provides data from the host to the SkyeModule M9.
*The MISO signal provides data from SkyeModule M9 to host.
*SSEL (Slave Select) is active low.
*The SPI master host software should keep the SCK pin at steady state low.
*Data is transmitted on the falling edge of SCK.
*The data packet exchange between the host (SPI Master) and the M9 (SPI Slave) uses SkyeTek Protocol v3 (Binary Mode only).
*The SPI connection is capable of a 4 MHz data rate.
*A ready signal indicates the reader has data for the host—in loop or inventory modes.
*Low = 0 to 0.8V; High = 2.0 to 5V |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 31, 2008 4:26 pm |
|
|
Quote: | setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16|SPI_SAMPLE_AT_END);
SET_TRIS_C(0x10); |
Why do you have the SPI_SAMPLE_AT_END parameter in there ?
You don't need the set_tris_c() statement. The compiler will set
the TRIS for you.
Quote: |
My problem is that I can not get the bytes coming in to save to memory. |
You can save the incoming bytes in an array. Example:
Code: |
int8 rxdata[13];
int8 i;
for(i = 0; i<13; i++)
{
rxdata[i] = spi_read(0x00);
delay_ms( 3 );
} |
|
|
|
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
|
Posted: Mon Mar 31, 2008 4:43 pm |
|
|
Ok, I put both of those in after, just to see if they do anything. I have an LED set to light up if a 0x02 is ever received. Once it works i will save the data into an array as you have suggested.
I see the data coming in through the Oscope but it still does not save into memory. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 31, 2008 4:46 pm |
|
|
What is your compiler version ? |
|
|
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
|
Posted: Mon Mar 31, 2008 4:58 pm |
|
|
My compiler is version 4.020b.
Is there a way to ensure that the PIC is reading bits on the falling edge? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Mar 31, 2008 4:58 pm |
|
|
Double check you have 'data out' of the PIC connected to 'data in' of the M9 and vice versa.
What voltage is your PIC running?
What are the voltage levels you see on the scope? |
|
|
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
|
Posted: Mon Mar 31, 2008 5:24 pm |
|
|
Here is the data being received (MISO):
[img][/img]
Here is the data being sent (MOSI):
[img][/img]
The data is TTL and the voltages look ok to me (I have a pull up resistor on the receive pin of the PIC C4) |
|
|
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
|
Posted: Mon Mar 31, 2008 6:07 pm |
|
|
Actually the MISO pin is only showing 0 for low and 2 volts for high. All of my other pins are giving me 0 for low and 5V for high. Could this be the problem? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Mar 31, 2008 6:26 pm |
|
|
Quote: | My compiler is version 4.020b. | This was one of the early v4.0xx releases and unstable. Upgrade to a minimum of release v4.030, or revert to the old but stable v3.249.
derrickbez wrote: | Actually the MISO pin is only showing 0 for low and 2 volts for high. All of my other pins are giving me 0 for low and 5V for high. Could this be the problem? | The SPI receive pin on the PIC, pin C4, is of the Schmitt trigger type (figure 3.15 of the PIC datasheet). According to parameter no. D041 of table 17.5 of the PIC datasheet the minimum high voltage level for a Schmitt trigger input is 0.8Vdd. At 5V that equals to a minimum high input level voltage of 4.0V.
So, no 2Volts for high is not going to work with the hardware SPI module. You have two solutions:
1) Add a voltage level converter.
2) Implement a software SPI driver on a TTL input pin (TTL inputs see a high level at 0.25Vdd+0.8V, this is 1.8V when Vdd==5V).
As another thought: How do you know the receive is not working?
Is this because your output B2 never goes high?
By default all pins that can act as an analog input are designated so. Add to the start of your main() the following code: Code: | setup_adc_ports(NO_ANALOGS | VSS_VDD);
setup_adc(ADC_OFF);
setup_comparator(NC_NC_NC_NC);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF); |
|
|
|
derrickbez
Joined: 31 Mar 2008 Posts: 7 Location: San Diego
|
|
Posted: Mon Mar 31, 2008 6:36 pm |
|
|
I just got it to work. I had an LED that was taking the voltage down.
Thank you for your time and your help.
working Code:
Code: |
#include <16F887.h>
#FUSES INTRC,NOWDT,NOPUT,NOMCLR,NOPROTECT,NOCPD,NOBROWNOUT,NOIESO,NOFCMEN,NOLVP
#use delay(internal=4000000)
#use rs232(baud=38400, uart1, parity=N, bits=8, stop=1)
//#use spi(MASTER, FORCE_HW, BITS=8)
//#include <flex_lcd.c>
#include <input.c>
#define SSEL PIN_B0
#define D0 PIN_C5
#define DI PIN_C4
#define CLK PIN_C3
BYTE read_from_spi(void)
{
BYTE data;
data = spi_read(0x00); //Read Data
return(data); //Return Register Data
}
void main(void)
{
BYTE rxdata[13];
int8 i;
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);
while(1)
{
output_low(PIN_B2);
output_low(SSEL);
spi_write(0x02);
spi_write(0x00);
spi_write(0x0A);
spi_write(0x00);
spi_write(0x20);
spi_write(0x12);
spi_write(0x01);
spi_write(0x00);
spi_write(0x01);
spi_write(0x00);
spi_write(0x04);
spi_write(0xDA);
spi_write(0xE9);
output_high(SSEL); //Pull slave select high to indicate packet is done.
delay_ms( 8 );
for(i = 0; i<13; i++)
{
output_low(SSEL); //Pull Slave Select Low
rxdata[i] = spi_read(0x00);
output_high(SSEL); //Pull Slave Select High
delay_ms( 3 );
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 31, 2008 7:10 pm |
|
|
Quote: | My compiler is version 4.020b. |
Quote: | This was one of the early v4.0xx releases and unstable. Upgrade to a minimum of release v4.030, or revert to the old but stable v3.249. |
I looked at the .LST file for vs. 4.020, and there are problems with the
CCS start-up code. The comparators are not initialized (turned off)
correctly. I didn't see anything wrong with the generated SPI code.
The current version (4.070) has fixed the start-up code problems. |
|
|
|