|
|
View previous topic :: View next topic |
Author |
Message |
tripper269
Joined: 06 May 2013 Posts: 33 Location: Toronto
|
SPI #use function |
Posted: Mon Sep 18, 2017 2:51 pm |
|
|
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: 21708
|
|
Posted: Mon Sep 18, 2017 4:39 pm |
|
|
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: 33 Location: Toronto
|
|
Posted: Tue Sep 19, 2017 7:04 am |
|
|
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: 33 Location: Toronto
|
|
Posted: Tue Sep 19, 2017 9:06 am |
|
|
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: 21708
|
|
Posted: Tue Sep 19, 2017 10:46 am |
|
|
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: 33 Location: Toronto
|
|
Posted: Tue Sep 19, 2017 12:01 pm |
|
|
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: 33 Location: Toronto
|
|
Posted: Mon Sep 25, 2017 10:56 am |
|
|
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: 21708
|
|
Posted: Mon Sep 25, 2017 12:32 pm |
|
|
I emailed CCS support to ask them about this. I'm waiting for a reply. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 25, 2017 9:07 pm |
|
|
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: 33 Location: Toronto
|
|
Posted: Wed Oct 04, 2017 1:34 pm |
|
|
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: 9232 Location: Greensville,Ontario
|
|
Posted: Wed Oct 04, 2017 3:29 pm |
|
|
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: 19529
|
|
Posted: Thu Oct 05, 2017 1:26 am |
|
|
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: 33 Location: Toronto
|
|
Posted: Fri Oct 20, 2017 9:15 am |
|
|
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: 19529
|
|
Posted: Fri Oct 20, 2017 3:02 pm |
|
|
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: 33 Location: Toronto
|
|
Posted: Wed Oct 25, 2017 6:51 am |
|
|
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)
{
}
} |
|
|
|
|
|
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
|