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 support@ccsinfo.com

SPI #use function

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



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

SPI #use function
PostPosted: Mon Sep 18, 2017 2:51 pm     Reply with quote

Hi All,

I am trying use the SPI2 on dsPIC33FJ256GP710A with v5 CCS. Its not working properly, sometimes its leaving LSB or adding 1 in MSB. Is it a speed issue?


Code:
#use spi(SLAVE, SPI2, MODE=0, BITS=32, stream=SPI_PORT2)


#INT_SPI2

void spi2_slave_isr(void)
{
    SPI_Flag = 1;


}
       


 if(spi_data_is_in2())
         { 
            Set_Point = spi_xfer_in(SPI_PORT2,32);
            SPI_Flag = 0;
         }
PCM programmer



Joined: 06 Sep 2003
Posts: 20400

View user's profile Send private message

PostPosted: Mon Sep 18, 2017 4:39 pm     Reply with quote

Usually it's a mode issue. But if you think it's a speed issue, then look
in the CCS manual and find the setting for the speed (baud rate) and
lower it. Try something really low, like 100000.
Quote:

#use spi

BAUD=n
Target bits per second, default is as fast as possible.


CCS PCD manual:
http://www.ccsinfo.com/downloads/PCDReferenceManual.pdf
See page 179, at the bottom of the page.
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 7:04 am     Reply with quote

Thanks PCM.
dsPIC is in slave mode, and master is sending data with 100 Khz clock. I tried with spi_speed(100000), but it's the same problem. And could you explain what could be the mode issue.
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 9:06 am     Reply with quote

I am trying to communicate with Analog discovery 2 and dsPIC33FJ256GP710A on SPI. AD2 is working in Master mode and dsPIC33 is slave. I am trying to read 4 byte data using spi_xfer(). Below is the settings of Analog Discovery.

Freq 100 KHz, First bit MSB, Polarity 0, Phase 0, Active Low, word bits 32.

And CCS settings:
Code:
#use spi(SLAVE, SPI2, MODE=0, BITS = 32,stream=SPI_PORT2),
PCM programmer



Joined: 06 Sep 2003
Posts: 20400

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 10:46 am     Reply with quote

Since your PIC is the SPI slave, you don't need to set the baud rate.
That's controlled by the master.

I searched the internet a little, and I can't find a definitive statement in
the Analog discovery 2 documentation that tells what the default SPI
mode is for that device.

The SPI mode between master and slave must match. ie., if the master
is using mode 0, the slave must be configured for mode 0.

There are some indications on the net that the Analog discovery 2
uses SPI mode 2. On one website, they show an edit screen for
the spi mode for the Analog discovery 2. It shows "active low" and
"sample falling". This is SPI mode 2. So my suggestion is, just try it.
Change the #use spi() statement for the PIC to be "MODE=2".
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Tue Sep 19, 2017 12:01 pm     Reply with quote

Thanks

Its working now, i changed settings to:
Code:
#use spi(SLAVE, SPI2, MODE=2, BITS=32, stream=SPI_PORT2)

and on AD2 changed the phase from 0 to 1.
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Mon Sep 25, 2017 10:56 am     Reply with quote

In the following setup

#use spi(SLAVE, SPI2, MODE = 0, BITS = 8, stream = SPI_2) , is the SS is also configured automatically, cause what is seen in SPI2CON1 bit<7> is 0 not 1.

If i use ENABLE = PIN_G9, SPI doesn't work
PCM programmer



Joined: 06 Sep 2003
Posts: 20400

View user's profile Send private message

PostPosted: Mon Sep 25, 2017 12:32 pm     Reply with quote

I emailed CCS support to ask them about this. I'm waiting for a reply.
PCM programmer



Joined: 06 Sep 2003
Posts: 20400

View user's profile Send private message

PostPosted: Mon Sep 25, 2017 9:07 pm     Reply with quote

CCS support wrote:

The #use spi() statement should enable/disable it automatically based on
your #use spi() settings. It should enable it when you have it setup for
slave mode, the enable=pin set to the SS pin and have enable_active=0,
default if not specified, in your #use spi() statement. Any other
configuration it should disable it or generate an error depending on your
#use spi() statement.

I tested this with an 18F46K22 (since I don't have the PCD compiler)
and it worked with SPI1. However, it failed to compile with SPI2.
It says "Wrong SS pin" even though I specified the correct SS2 pin.

In your case, you are using PCD. I don't have the PCD compiler to test it.
My advice is write directly to the register bit, as shown below:

Put this above main():
Code:

#word SPI2CON1= getenv("SFR:SPI2CON1")
#bit SSEN = SPI2CON1.7

Then put this near the start of main():
Code:
SSEN = 1;  // Enable the \SS pin for slave mode
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Wed Oct 04, 2017 1:34 pm     Reply with quote

Thanks PCM,

I did something like this
Code:

#use spi(SLAVE, SPI2, BITS = 8, MODE = 0, ENABLE = PIN_G9, stream = SPI_2)

And its working. I can read 4 bytes from master, but couldn't send 4 bytes to the master. Below is functions i am using. It does add this information but delayed by 3 bytes.
Code:
int Body_Temperature = 0,Set_Point = 0;

Set_Point = spi_xfer(SPI_2, Body_Temperature, 32);
temtronic



Joined: 01 Jul 2010
Posts: 6284
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Oct 04, 2017 3:29 pm     Reply with quote

Hmm... I'm wondering why you've got the AD2 as the master, and the PIC as the slave. I looked, briefly at the AD2 ref manual and it appears to be some fancy ADC/DAC/DIO 'smart peripheral'.

Since you say the PIC receives 4 bytes from the AD2, that implies the PIC sent 4 bytes to the AD2 as SPI is a 1byte in, 1 byte out protocol. As the PIC got 4 bytes it had to have sent 4.

That would imply the AD2 program or device is not working properly.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 13651

View user's profile Send private message

PostPosted: Thu Oct 05, 2017 1:26 am     Reply with quote

The SD2, is a 'smart peripheral'. Quite a sophisticated FPGA with several support chips. Primary function 'off the shelf', is as a scope/logic analyser. However controlled by the PC, using Python, you can program it to be a SPI master. There are a couple of examples with the software development kit for it, that give SPI master operation, and of course, you can program your own. There is one such at:
<https://github.com/mentaal/DwfSPI>
Alternatively the 'waveforms' software for it does allow you to setup SPI, in a manner rather like a terminal program for async serial. Program all the settings, and perform a transfer. Really neat.

The CPOL/CPHA can be programmed.

I'd guess that there is a fault in the polarity settings somewhere between his master and slave. With CPOL=1, the sampling edge reverses. Possible a problem. However:

The first place always to start of the hardware. Get DS70206, which is the SPI description for this PIC family. Now critical thing to note here, is that the hardware only supports 8bit or 16bit transfers. If you use the hardware SS, then you must do individual transfers this size. Yes (of course) you can send 32bits, but as two 16bit transfers or four 8bit transfers, not as a single 32bit transfer. If you transfer 32bits as a single transfer, you can't use the hardware SS to synchronise the bus. You can use it as a 'select', triggering the routine when it drops (typically by using an interrupt_, but this has to be done in the software, and then the select won't guarantee to re-synchronise the shift register, which is what it is really for....

Honestly better to set the 'word bits' to 8 in the AD2 program, and do 8 bit transfers with the hardware.

You need to step back, look at what you actually want to do, and start with the hardware limitations to see how to do what you want.
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Fri Oct 20, 2017 9:15 am     Reply with quote

Thanks to everyone for sharing there thoughts. I changed the setting to 8 bits,

#use spi(SLAVE, SPI2, BITS = 8, MODE = 1, ENABLE = PIN_G9, stream = SPI_2)

First of all, to use SS ENABLE = PIN_xx has to be used. Secondly, even though you declare it in use, compiler is not gonna make it input, you have to include output_float(PIN_G9); in your main code.
Ttelmah



Joined: 11 Mar 2010
Posts: 13651

View user's profile Send private message

PostPosted: Fri Oct 20, 2017 3:02 pm     Reply with quote

That suggests you have something else in your code setting it up as an output. Pins all default to input at chip wake up.
tripper269



Joined: 06 May 2013
Posts: 31
Location: Toronto

View user's profile Send private message

PostPosted: Wed Oct 25, 2017 6:51 am     Reply with quote

Here is the complete code, Please let me know if i am doing something wrong.

Code:
#include <33FJ256GP710A.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(crystal = 8Mhz, clock = 100Mhz)
#use spi(SLAVE, SPI2, BITS = 8, MODE = 1, ENABLE = PIN_G9, stream = SPI_2)


int8 SPI_Flag = 0, Byte_Count = 0, Rx, Tx, Cmand, ProbeID = 1, count = 0;
int8 Version = 0x77, TempLowDisplay, VoltageLowDisplay, TempSetPointLow, HVSetPointLow, TempHiDisplay;
int8  HVSetPointHi, TempSetPointHi;

#INT_SPI2

void spi2_slave_isr(void)
{
  Rx = spi_xfer_in(SPI_2, 8);
  Byte_Count++;
 
  switch(Byte_Count)
            {
            case 1:
                spi_prewrite(Version);
                if(Cmand == 1)
                   TempSetPointLow = Rx;
                else if(Cmand == 2)
                   HVSetPointLow = Rx;

                break;
     
            case 2:
                Cmand = Rx;
                if(Cmand == 1)
                   spi_prewrite(TempLowDisplay);
                else if(Cmand == 2)
                        spi_prewrite(VoltageLowDisplay);
                else if(Cmand == 3)
                        spi_prewrite(ProbeID);
               
                break;
           
           
            case 3:
                 
                if(Cmand == 1)
                   spi_prewrite(TempHiDisplay);
                else if(Cmand == 2)
                   spi_prewrite(SPI_Flag);
                else if(Cmand == 3)
                   spi_prewrite(SPI_Flag);
                break;     
           
           
            case 4:
                if(Cmand == 1)
                   TempSetPointHi = Rx;
                else if(Cmand == 2)
                    HVSetPointHi = Rx;
               
                Byte_Count = 0;
                break;
             
            }

}




void main()
{   

   enable_interrupts(INT_SPI2);
   enable_interrupts(INTR_GLOBAL);

   output_float(PIN_G9); // SS as an input
   
   TempLowDisplay = 0;
   VoltageLowDisplay = 0;
   TempHiDisplay = 1;
   
   while(1)
    {

    }
}   
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