|
|
View previous topic :: View next topic |
Author |
Message |
in_nursery
Joined: 25 Oct 2012 Posts: 51
|
SPI spi_xfer() Vs spi_write [Solved] |
Posted: Fri Feb 24, 2017 8:51 am |
|
|
Hi all
I want to port a working code using hardware SPI to another using sofware.
So I first try to use spi_xfer insteed of spi_write with hardware SPI.
I switch from setup spi to use spi
Code: | #USE SPI (FORCE_HW, MASTER, SPI1, MODE=0, BITS=8,DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3,ENABLE=PIN_B1, STREAM=xfer) |
with spi_write() it work fine
Code: | void write_Register_short(int8 address, int8 data_r)
{
output_low(CS); //CS = 0;
address = (((address << 1) & 0b01111111) | 0x01);
SPI_Write(address); // addressing register
SPI_Write(data_r); // write data in register
output_high(CS); //;CS = 1;
} |
But doesn't work with spi_xfer()
Code: | void write_Register_short(int8 address, int8 data_r)
{
output_low(CS); //CS = 0;
address = (((address << 1) & 0b01111111) | 0x01);
spi_xfer(xfer, address); // addressing register
spi_xfer(xfer, data_r); // write data in register
output_high(CS); //;CS = 1;
} |
What did I miss? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Fri Feb 24, 2017 9:12 am |
|
|
quik guess...
#USE SPI (FORCE_HW, MASTER, SPI1, MODE=0, BITS=8,DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3,ENABLE=PIN_B1, STREAM=xfer)
Option 'SPI1 ' says to use the 1st HW SPI pins...
THEN you say
Option 'DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3'...
where you say what pins to use.
So you're sending 'mixed messages' to the compiler. I'm guessing those pins are not the HW pins, though I can't tell as you don't say which PIC you're using.
Now this may not be the problem, but, it's not following the correct way to use the use spi....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Fri Feb 24, 2017 9:14 am |
|
|
Spi_xfer has one critical difference to spi_write. If you just say:
spi_xfer(xfer, data_r); // write data in register
It checks if the SPI is busy, and waits if it is. Then as soon as the SPI is ready, loads the SPI write register, and returns immediately.
So it doesn't wait for the SPI transaction to complete. This is brilliant, since it means you can be getting the next byte 'ready' while one is sending, making it handle the bus much more efficiently.
However if you are operating a CS, then you need to ensure the second transfer has completed, before raising CS. So what you then do is read the returned byte on the second write. A _read_ will always wait for the byte to be available.
So:
Code: |
void write_Register_short(int8 address, int8 data_r)
{
int8 dummy;
output_low(CS); //CS = 0;
address = (((address << 1) & 0b01111111) | 0x01);
spi_xfer(xfer, address); // addressing register
dummy=spi_xfer(xfer, data_r); // write data in register
output_high(CS); //;CS = 1;
}
|
Also you don't need the pin numbers in the #USE. Or FORCE_HW.
The 'SPI1' command is equivalent to all of the following:
FORCE_HW, DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3
Bit puzzled why you are selecting 'enable'. You don't have any equivalent in the setup_spi operation (would be a pin pulsed low for each byte). Are you sure this is right?. Enable is used on some SPI busses, or a latch on some others, but not on most.
So suspect:
#USE SPI (SPI1, MASTER, MODE=0, BITS=8, STREAM=XFER)
(prefer to use upper case for things like stream names and defines)
is probably the correct syntax.
How fast do you want it to clock?. #USE SPI, will clock as fast as possible unless given a baud rate. Might be too fast?. |
|
|
in_nursery
Joined: 25 Oct 2012 Posts: 51
|
|
Posted: Fri Feb 24, 2017 9:15 am |
|
|
I try to update it with
Code: | #USE SPI (MASTER, MODE=0, BITS=8, DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3, ENABLE=PIN_B1, STREAM=XFER) |
and still have the same problem
8Mhz clock.
With
Code: | #USE SPI (SPI1, MASTER, MODE=0, BITS=8, STREAM=XFER) |
it works but not with pin selection. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Fri Feb 24, 2017 9:36 am |
|
|
There isn't 'pin selection'.
The hardware goes to the hardware pins.
You can't select pins on the hardware, except on chips that offer #pin_select (and a few with fuse selections), and on these you have to select the pins with these other methods. As Temtronic says, you are sending mixed messages. Telling the compiler to use the hardware, and then trying to tell it to use specific pins. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Fri Feb 24, 2017 12:59 pm |
|
|
I'm rethinking the original post and _maybe_ what he wants is to create software SPI functionality on I/O pins of his choosing ??
Obviously SW SPI will be slower but is possible.
It'd help if we knew which PIC though....
..as well as what SPI device the PIC is connected to.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Fri Feb 24, 2017 3:15 pm |
|
|
But he has 'FORCE_HW' in his configuration, and setup_spi, only works with hardware SPI.
Agree wholeheartedly (usually do). More data would help massively. |
|
|
in_nursery
Joined: 25 Oct 2012 Posts: 51
|
|
Posted: Mon Feb 27, 2017 8:10 am |
|
|
I use a Pickit demo board with 18F45K20.
My final goal is the make the software SPI work.
I first try to update setup_SPI to use SPI with SPI hardware Pins.
so with
Code: | #USE SPI (SPI1, MASTER, MODE=0, BITS=8, STREAM=XFER) |
and Ttelmah read added
Code: | void write_Register_short(int8 address, int8 data_r)
{
int8 dummy;
output_low(CS); //CS = 0;
spi_xfer(XFER,address); // addressing register
dummy=spi_xfer(XFER, data_r); // read data in register
spi_xfer(XFER,data_r); // write data in register
dummy=spi_xfer(XFER, data_r); // read data in register
output_high(CS); //;CS = 1;
}
|
it works.
then I use the software pins it works too.
Code: |
#USE SPI (MASTER, MODE=0, BITS=8, DI=PIN_D4, DO=PIN_D5, CLK=PIN_D6, STREAM=XFER) |
My master problem was a wrong contact when I moved pins.
By the way thanks for your support and help, it's give more information and comprehension about the use of the #USE SPI. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Mon Feb 27, 2017 11:27 am |
|
|
Good.
One of the problems is the sheer number of things you can actually do with the #use.
You don't need a read on the first write. The second one will wait until the first byte has sent.
However in fact you could do the whole transaction with a single spi_xfer.
If you added your CS pin as the 'enable' pin in the #use SPI, and changed it to say 'bits=16', then if you did the transfer as:
Code: |
spi_xfer(XFER, make16(address, data_r));
|
The transfer will send 16 bits (so both registers), and lower the 'enable' pin before the transfer and raise it afterwards. |
|
|
in_nursery
Joined: 25 Oct 2012 Posts: 51
|
|
Posted: Tue Feb 28, 2017 8:30 am |
|
|
thanks Ttelmah for this information.
My next step is to make it work a PIC24 (first time I use one)
this is what I try with no succes
Code: | #include <24EP512GU810.h>
#fuses NOJTAG //JTAG disabled
#fuses WPOSTS11 //Watch Dog Timer PostScalar 1:1024
#fuses WPRES128 //Watch Dog Timer PreScalar 1:128
#fuses NOWDT //No Watch Dog Timer. can still be enabled with setup_wdt()
#fuses OSCIO //OSC2 is general purpose output
#fuses NOBROWNOUT //No brownout reset
#fuses NOIOL1WAY //Allows multiple reconfigurations of peripheral pins
#fuses NOWRT //Program memory not write protected
#fuses NOPROTECT //Code not protected from reading
#fuses NOGSSK //General segment key bits, use if using both NOWRT and NOPROTECT fuses
#fuses AWRT //Auxiliary program memory is write protected
#fuses NOAPROTECT //Auxiliary program memory is not protected from reading
#fuses APLK //Auxiliary segment key bits, use if using either AWRT or APROTECT fuses
#use delay(oscillator=8MHz)
#USE SPI (MASTER, MODE=0, BITS=8, DI=PIN_B1, DO=PIN_B3, CLK=PIN_B0, STREAM=XFER, BAUD=500000)) |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Tue Feb 28, 2017 8:34 am |
|
|
It'd help a lot if you told us what device you were actually talking to?.
Obvious things to check before anything else are:
1) Have you done a basic 'flash an LED' test and verified your chip is working, and at the correct speed?
2) Any other peripherals on the pins that may need to be disabled?.
3) Are the signalling voltage levels compatible?.
4) What baud rate is actually supported?. |
|
|
in_nursery
Joined: 25 Oct 2012 Posts: 51
|
|
Posted: Tue Feb 28, 2017 8:51 am |
|
|
oups sorry
It's a MRF24JM40A
1) yes I have a flashing led at each send (500 ms)
2) no only the MRF
3) everything running 3.3V
4) The MRF24J40 supports SPI (mode 0,0) which requires that SCK idles in a low state. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Tue Feb 28, 2017 9:34 am |
|
|
I'm talking about other peripherals _inside the PIC_ You often have to turn things off before pins can be used for other functions.
Your part number doesn't give any hits. Sure you have it right? |
|
|
in_nursery
Joined: 25 Oct 2012 Posts: 51
|
|
|
|
|
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
|