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 spi_xfer() Vs spi_write [Solved]

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



Joined: 25 Oct 2012
Posts: 51

View user's profile Send private message

SPI spi_xfer() Vs spi_write [Solved]
PostPosted: Fri Feb 24, 2017 8:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 9:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 9:14 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 9:15 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 9:36 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 12:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 24, 2017 3:15 pm     Reply with quote

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. Very Happy
in_nursery



Joined: 25 Oct 2012
Posts: 51

View user's profile Send private message

PostPosted: Mon Feb 27, 2017 8:10 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Feb 27, 2017 11:27 am     Reply with quote

Good. Smile

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

View user's profile Send private message

PostPosted: Tue Feb 28, 2017 8:30 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 28, 2017 8:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 28, 2017 8:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 28, 2017 9:34 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 28, 2017 9:48 am     Reply with quote

Pic
http://www.microchip.com/wwwproducts/en/PIC24EP512GU810

datasheet
http://ww1.microchip.com/downloads/en/DeviceDoc/70616g.pdf
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