CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

spi problem with pic24F

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Vorian



Joined: 09 Jul 2010
Posts: 6

View user's profile Send private message

spi problem with pic24F
PostPosted: Fri Jul 09, 2010 4:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 09, 2010 6:56 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 09, 2010 7:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 09, 2010 10:17 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 09, 2010 4:35 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 10, 2010 2:11 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 11, 2010 10:24 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 11, 2010 10:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Jul 11, 2010 11:38 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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