|
|
View previous topic :: View next topic |
Author |
Message |
Vorian
Joined: 09 Jul 2010 Posts: 6
|
spi problem with pic24F |
Posted: Fri Jul 09, 2010 4:39 am |
|
|
Hi all.
I have a problem with spi and i can't found a solution.
Almost a year ago, I made a library for use a sd card for a datalogger project. This library that I made was used in different projects with differents micros like pic18f2525, pic18f452. Now I'm starting with a new dattalogger and I need more speed. Because of this, I'm using pic24fj48ga002 because it has two spi. This library works fine with others pics but with the new one is imposible to make it works.
I know there are some problems with the configuration of the spi on some 24f pics but I'm sure that i am configuring the spi correctly. I'm using PCWHD v4.106 and this is the software that I made.
Code: |
#include "C:\IGN\PIC\sismica_ign\main.h"
#include "C:\IGN\PIC\sismica_ign\MMC3.h"
#PIN_SELECT SDI2 = PIN_B9
#PIN_SELECT SDO2 = PIN_B11
#PIN_SELECT SCK2OUT = PIN_B10
#byte SPI2STATH = 0x261
#byte SPI2CON1L = 0x262
#byte SPI2CON1H = 0x263
#byte RPINR22L = 0x6AC
#byte RPOR5L = 0x6CA
#byte RPOR5H = 0x6CB
#define SPI_MODE_0_0 0x0100
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0140
#define SPI_MODE_1_1 0x0040
void main()
{
delay_ms(100);
setup_spi2(SPI_MASTER | SPI_MODE_0_0 | SPI_CLK_DIV_16);
fprintf(data,"SPI2CON1L -> %x\n\r",SPI2CON1L);
fprintf(data,"SPI2CON1H -> %x\n\r",SPI2CON1H);
fprintf(data,"SPI2STATH -> %x\n\r\n\r",SPI2STATH);
fprintf(data,"RPINR22L -> %x\n\r",RPINR22L);
fprintf(data,"RPOR5H -> %x\n\r",RPOR5H);
fprintf(data,"RPOR5L -> %x\n\r\n\r",RPOR5L);
CARD_INI();
while(1){}
}
|
In the code above after "#pin_select" and "setup_spi" I read SPI2CON1, RPINR22L and RPOR5 to verify if all is ok. Then I call the CARD_INI function. In the serial port I can see this.
SPI2CON1L -> 7d
SPI2CON1H -> 00
SPI2STATH -> 80
RPINR22L -> 09
RPOR5H -> 0a
RPOR5L -> 0b
MODO IDLE : OK
INVALID CARD
The registers are ok, mode 0 for spi and sdi2, sdo2 and sck2 are the pins selected by "#PIN_SELECT". The card enters in "idle mode" but then it doesn't respond to CMD8 command.
This is the code for the initialization of the card. It works for others micros
Code: |
void CARD_INI()
{
int8 i,RESPONSE,SD;
int8 OCR[4];
output_high(CS_CARD); //CHIP SELECT HIGH!
//MORE THAN 74 CLOCKS TO INIT BUS
for (i=0;i<10;i++){spi_write2(0xFF);}
output_low(CS_CARD); //CHIP SELECT LOW
//SEND RESET COMMAND
if (SEND_COMMAND(CMD0,0) == 1)
{
fprintf(data,"IDLE MODE : OK\n\r");
RESPONSE = SEND_COMMAND(CMD8,0x01AA); //SEND CMD8 COMMAND
if (RESPONSE == 1)
{
for(i=0;i<4;i++)
{
OCR[i] = spi_read2(0xFF);
}
if (OCR[2] == 0x01 && OCR[3] == 0xAA)
{
fprintf(data,"CARD : SD V.2\n\r");
//SD V.2 INIT
while (1)
{
if (SEND_COMMAND(CMD55,0) < 0x02) //SEND COMMAND CMD55
{
RESPONSE = SEND_COMMAND(CMD41,0x40000000);
if (RESPONSE == 0x00)
{
//READ CCS BIT, 1->HIGH CAPACITY 0->STD CAPACITY
if (SEND_COMMAND(CMD58,0) == 0)
{
for(i=0;i<4;i++)
{
OCR[i] = spi_read2(0xFF);
}
if((OCR[0]&0x40) == 0x40)
{
fprintf(data,"HIGH CAPACITY\n\r");
HIGHCAP = 1; //HIGH CAPACITY CARD
break;
}
else
{
fprintf(data,"STANDARD CAPACITY\n\r");
HIGHCAP = 0; //STANDARD CAPACITY CARD
break;
}
}
else {fprintf(data,"NO RESPONSE FROM COMMAND CMD58");break;}
}
else if (RESPONSE > 1)
{
fprintf(data,"CMD41 ERROR : %x\n\r",RESPONSE);
break;
}
}
else
{
fprintf(data,"CMD55 ERROR : %x\n\r",RESPONSE);
while(1);
break;
}
}
}
else {fprintf(data,"%x%x%x%x\r\n",OCR[0],OCR[1],OCR[2],OCR[3]);}
}
else if (RESPONSE == 5) // ILLEGAL COMMAND
{
SD = 0xFF;
while (1)
{
if (SEND_COMMAND(CMD55,0) <= 1) //COMMAND CMD55
{
RESPONSE = SEND_COMMAND(CMD41,0); //COMMAND CMD41
if (RESPONSE == 0x00)
{
fprintf(data,"CARD : SD V.1.X\n\r");
HIGHCAP = 0; //STANDARD CAPACITY
break;
}
else if (RESPONSE == 0x01){SD--;}
else if (RESPONSE > 1)
{
fprintf(data,"CMD41 ERROR : %x\n\r",RESPONSE);
break;
}
}
else{break;}
}
//IT'S A MMC CARD
if (RESPONSE != 0x00)
{
SD = 0xFF;
while (1)
{
if (SEND_COMMAND(CMD1,0) == 0)
{
fprintf(data,"CARD : MMC\n\r"); //NOT IMPLEMENTED
break;
}
SD--;
if (SD == 0)
{
fprintf(data,"UNKNOWN CARD\n\r");
while(1);
}
}
}
}
else
{
fprintf(data,"INVALID CARD\n\r");
while(1);
}
}
else{fprintf(data,"CARD NOT DETECTED\n\r");while(1);}
|
I have tried with different pins and I can't make it works.
Can you help me?.
Thank you in advance.
Sorry for my English |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jul 09, 2010 6:56 am |
|
|
You may want to review what has been said in previous discussions about spi_write() behaviour with PCD. You should simply try with spi_read () exclusively. And don't use a newer version than 4.107, because a new SPI bug has been introduced in 4.108 or 4.109. |
|
|
Vorian
Joined: 09 Jul 2010 Posts: 6
|
|
Posted: Fri Jul 09, 2010 7:58 am |
|
|
Thank you for your answer.
I have read all discussions about spi in this forum. I have changed spi_write2(0xYY) by spi_read2(0xYY) but in my case is the same, same error.
Any ideas.
Thank you. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Jul 09, 2010 10:17 am |
|
|
It's working perfectly for me. Try a simpler test, check if the SPI pins are actually operating. |
|
|
Vorian
Joined: 09 Jul 2010 Posts: 6
|
|
Posted: Fri Jul 09, 2010 4:35 pm |
|
|
I have made a loop with sdi and sdo and all that I send through sdo is received by sdi, but I don't know if this means that it works.
I don't know what can I do. |
|
|
Vorian
Joined: 09 Jul 2010 Posts: 6
|
|
Posted: Sat Jul 10, 2010 2:11 pm |
|
|
Hi.
I have made a simple spi function to transmit and receive data. This is the function.
Code: |
int8 spixmit2(int8 value)
{
int8 read;
int8 k;
for (k=8;k>0;k--)
{
output_low(CK2);
if (bit_test(valor,k-1))
{
output_high(DO2);
}
else
{
output_low(DO2);
}
delay_us(1);
output_high(CK2);
if (input(DI2))
{
bit_set(read,k-1);
}
else
{
bit_clear(read,k-1);
}
delay_us(1);
}
return read;
}
|
Using this code instead of hardware spi the result is the same. The card respond to reset command but then fail. If I use an MMC card, the software (spi hardware or software) detect it but fail at the end of initialization. I think it could be the hardware but it's too simple to be wrong. I'm using 6K8 pull up resistors like always in SDI and SDO lines, VDD of all circuit is 3.3 Volts and I'm using a PCB (the datalogger) and the same scheme on a protoboard and both fails.
Any suggestion??
Thanks |
|
|
Vorian
Joined: 09 Jul 2010 Posts: 6
|
|
Posted: Sun Jul 11, 2010 10:24 am |
|
|
Hi.
Today I have made a circuit with pic24fj120ga010 wich is part of the Explorer 16 development board. I have used spi software with de function that I made before and the result is the same than 24fj48ga002. Later I have used a pic18f2525 and it works. I think I have a problem with 24F but I don't know what it can be.
Fuses???
Code: |
#include <24FJ128GA010.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES ICSP2 //ICD uses PGC2/PGD2 pins
#FUSES NOWINDIS //Watch Dog Timer in Window mode
#FUSES WPRES128 //Watch Dog Timer PreScalar 1:128
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES PR //Primary Oscillator
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is clock output
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#use delay(clock=8000000)
#define CS_CARD PIN_A0
#define CK2 PIN_A1
#define DI2 PIN_A4
#define DO2 PIN_A5
#use rs232(baud=19200,parity=N,xmit=PIN_F5,rcv=PIN_F4,bits=8,stream=data)
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jul 11, 2010 10:42 am |
|
|
I haven't looked at the rest of your code, but these lines are suspicious: Code: | #define SPI_MODE_0_0 0x0100
#define SPI_MODE_0_1 0x0000
#define SPI_MODE_1_0 0x0140
#define SPI_MODE_1_1 0x0040 |
You are using hard coded values instead of the defines from the header files! It is very likely these defines are different in the PIC16/PIC18/PIC24.
This is how it should be defined for the PIC18: Code: | #define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H) |
I don't have the PCD compiler so you should do this yourself. |
|
|
Vorian
Joined: 09 Jul 2010 Posts: 6
|
|
Posted: Sun Jul 11, 2010 11:38 am |
|
|
Thank you for your answer.
But now, I'm using spi by software, with the previous function. I think is not a spi hardware problem because with two differents 24F series pics I get the same error, but when I use a 18f serie pic it works. output_low and output_high is the same for series 18F and 24F pics. Because of that, I don't know what is happening. |
|
|
|
|
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
|