|
|
View previous topic :: View next topic |
Author |
Message |
ccsfred
Joined: 15 Jun 2016 Posts: 33
|
SPI MODE 3 DSPIC |
Posted: Wed Jul 13, 2016 2:53 am |
|
|
Hi,
I'm trying to set the hardware SPI up to operate in Mode 3 for a L6470 stepper driver IC, my micro is a dspic33fj256mc710a, and using PCD V4.078. There isn't a header file for the A version so I'm using the dspic33fj256mc710.h
By reading the PCD reference manual NOV 2015, I can see the spi_setup(mode) options:
mode may be:
SPI_MASTER, SPI_SLAVE, SPI_SS_DISABLED
SPI_L_TO_H, SPI_H_TO_L
SPI_CLK_DIV_4, SPI_CLK_DIV_16,
SPI_CLK_DIV_64, SPI_CLK_T2
SPI_SAMPLE_AT_END, SPI_XMIT_L_TO_H
SPI_MODE_16B, SPI_XMIT_L_TO_H
Constants from each group may be or'ed together with |.
and from the header file:
Code: |
#define SPI_MASTER 0x0020
#define SPI_SLAVE 0x1000
#define SPI_L_TO_H 0
#define SPI_H_TO_L 0x0100
#define SPI_CLK_DIV_1 0x001F
#define SPI_CLK_DIV_4 0x001E
#define SPI_CLK_DIV_16 0x001D
#define SPI_CLK_DIV_64 0x001C
#define SPI_SS_DISABLED 0x8000
|
So for mode 3, I want the clock to idle high and read on rising edge, but I can't see how to select clock idle high? How do I do this please?
Thanks! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed Jul 13, 2016 3:36 am |
|
|
Just use:
#USE_SPI (MODE=3,SPI1,BAUD=what_you_want,STREAM=L6470)
Then use spi_xfer for the transfers (remember to specify how many bits you want, either in the setup, or in the transfer).
#USE is the neater and more powerful way now to setup the SPI. |
|
|
ccsfred
Joined: 15 Jun 2016 Posts: 33
|
|
Posted: Wed Jul 13, 2016 5:13 am |
|
|
Hi Ttelmah,
Thanks again for your help!
I've tried as you've suggested but cant see anything on the SPI lines, stripped right down to basic program, and LED flashes once, never again, seems to be getting stuck in the spi_xfer, when I pause debugger the PC is at #use spi.
Code: |
#include <33FJ256MC710.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#fuses HS,NOWDT,NOPROTECT
#define LED PIN_D8
#define LED_ON output_high(LED)
#define LED_OFF output_low(LED)
#use delay(clock=20000000)
#USE SPI (MODE=3,SPI1,BITS=8,BAUD=2000000,FORCE_HW,STREAM=L6470)
void main()
{
LED_ON;
delay_ms(500);
LED_OFF;
delay_ms(500);
spi_xfer(L6470, 0xff);
while(true)
{
LED_ON;
delay_ms(500);
LED_OFF;
delay_ms(500);
spi_xfer(L6470, 0xff);
}
} |
I don't know why it's not working?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed Jul 13, 2016 7:42 am |
|
|
I wouldn't use bits=8, since your target chip wants multi-byte transfers.
Since it wants 1 to 3 byte transmission or replies, use:
spi_xfer(L6470, command8, 8);
Then get the reply, or send the, data for it, with (say)
val32 = spi_xfer(L6470, dummy_val, 24); //to read 24bits
or
spi_xfer(L6470, val32, 24); //to send 24 bits
Also, you don't need 'force_hw' (using the SPI1 port name, forces this already), but this doesn't matter.
An spi_xfer, will normally not hang on write (just clocks the bits out), so you have something wrong.
The only time I have seen a SPI transmit hang, is if something is stopping the clock pin from operating. On these later chips it actually clocks the output pin, and uses the same pin to clock the data 'in' (rather than using an internal connection before the output driver). This makes it easier to handle modes where the clock is generated externally, but means the if the pin is shorted, the input register is not then clocked, and can hang the SPI.
So I would be looking for a hardware problem....
Try setting the port to software SPI (just select the same pins, don't use the hardware port name, & get rid of force_hw). Does it then work?. If not, you have proved there is a hardware problem. If it does then the problem is in the configuration. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 13, 2016 12:23 pm |
|
|
Quote: | when I pause debugger the PC is at #use spi. |
Set the compiler options to make the .LST file in Symbolic mode, compile
and post the .LST file code following the #use spi statement. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed Jul 13, 2016 12:32 pm |
|
|
Also when the debugger stops, tell us what the TRIS is on the pins for the SPI.
Though most 'modern' PIC's have the peripheral override the pin (so when the peripheral is selected, it doesn't care what the TRIS is), I have seen a problem on some chips when the TRIS was not correctly set.... |
|
|
ccsfred
Joined: 15 Jun 2016 Posts: 33
|
|
Posted: Thu Jul 14, 2016 1:10 am |
|
|
Thanks Ttelmah!
The S/W SPI works, but the H/W doesn't.
Here's the .lst file after #use spi:
Code: |
.................... #USE SPI (MODE=3,SPI1,BAUD=2000000,STREAM=L6470) // H/W not working!
00236: BSET.B 243.2
00238: MOV W0,248
0023A: BTSS.B 240.0
0023C: BRA 23A
0023E: BCLR.B 248.6
00240: MOV 248,W0
00242: BCLR.B 243.2
00244: BSET.B 243.2
00246: MOV W1,248
00248: BTSS.B 240.0
0024A: BRA 248
0024C: BCLR.B 248.6
0024E: MOV 248,W1
00250: BCLR.B 243.2
00252: RETURN
|
After debugging the code for a few seconds and nothing happening, I paused and the TRISF was correct for the SPI pins I was using 30BF.
I'm continuing using the S/W SPI at the moment, so I can continue to get my program working, however it's good to learn how to get to the bottom of the cause!
Thanks for your help! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Jul 14, 2016 3:34 am |
|
|
At least the software solution gets you going for now, and proves the hardware.
I must admit, your compiler is scarily 'old' for a DsPIC. This is perhaps reflected by your lack of the version A define file. Also it is just about when V4, started to work at all reasonably.....
The assembler being generated though, although massively different from a modern compiler, does look as if it might work. Suggests therefore, that something in the peripheral setup is wrong. My guess would be that it is perhaps not actually turning the peripheral 'on', or setting it's clock up correctly, and therefore the code hangs since the byte does not get clocked out...
On that basic, I went and compiled code with a 'recent' compiler, and then stopped it in a debugger, and noted the SPI register settings. Then went and did the same for the version I have nearest to yours. Unfortunately I have not kept any of the V4 compilers this old....
With the oldest I have (4.099), there are differences, but everything actually looks as if it ought to work.
However one question. What is your master clock rate?.
There is a warning in the data sheet, not to set both the primary and secondary prescalers to '1:1'. If your CPU clock was low, then this could be happening. Try with a lower baud rate, which would then force these to change.
//Updated.
As a further comment, how are you actually testing this?. A lot of ICD's have hardware limitations, on some peripherals and modes. Have you made sure your's doesn't on this?.... |
|
|
|
|
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
|