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 on 18F16Q41

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



Joined: 03 Jun 2020
Posts: 37
Location: UK

View user's profile Send private message

SPI on 18F16Q41
PostPosted: Thu Jan 25, 2024 8:35 am     Reply with quote

Using Workshop compiler v5.105 on Windows 10
Several attempts to use SPI have failed,what am I doing wrong?

Latest code in entirety:
#include <18F16Q41.h>

#fuses NOWDT
#use delay(clock=16M)
#include <stdlib.h>

#pin_select SDO1=PIN_A2 // chip pin 17
#use spi(MODE=0, BITS=8)

int8 i = 0;
void main() {
output_high(PIN_C2); // enable SPI
while(TRUE){
spi_write(i++);
output_toggle(PIN_A4); // check activity
}
}

code compiles with no errors or warnings, PinA4 toggles, but nothing
from SPI pins (or any other pin)
Replacing #use line with:
#use spi(SPI1, MODE=0, BITS=8)
results in an error: Option invalid Not valid for H/W
BUT SPI1 is listed as a valid option in the help file.
gaugeguy



Joined: 05 Apr 2011
Posts: 289

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 9:01 am     Reply with quote

SPI requires CLOCK, DATA OUT, and DATA IN.
You did not set a pin for the clock.
temtronic



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

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 9:34 am     Reply with quote

have a look in the CCS manual as well as examples that they supply !
lots of 'need to know info' there .
colin382



Joined: 03 Jun 2020
Posts: 37
Location: UK

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 9:42 am     Reply with quote

Thanks for the advice,

I replaced the #use spi line with
#use spi(MODE=0, BITS=8, CLK=PIN_B6, DI=PIN_B4, DO=PIN_A2)
// chip pin 11 13 17

but still no clock or data seen. The hardware is good, other test code that
just toggles these pins works.

I also tried spi_init(100000); just after main(), but the compiler
complains, wanting a comma. So I think this means I have to define a stream
Adding stream = flash to the options in #use spi and in spi_init is OK but now I get error "undefined identifier"

Other forum topics suggest that compiler versions around 5.1xx have problems with the PPS pins in some PICs, maybe I should upgrade.
Ttelmah



Joined: 11 Mar 2010
Posts: 19231

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 10:47 am     Reply with quote

Several things:

First you need to setup #PIN_SELECT for all three pins. Then just use
SPI1 in the #use spi.
Then add bits=8 to the #use spi.
Then use spi_xfer, not xpi_write.
If you look at the manual, you will find that #use spi, refers you to spi_xfer
not to spi_read or spi_write. Spi_read and spi_write are the old commands
for use with the setrup_spi command. Mixing the two sets of commands is
a 'may not work, and certainly will not work properly' way of working.
Code:

#include <18F16Q41.h>

#fuses NOWDT
#use delay(clock=16M)
#include <stdlib.h>

#pin_select SDO1=PIN_A2 // chip pin 17
#pin_select SDI1=PIN_B4
#pin_select SCK1=PIN_B6
#use spi(SPI1, MODE=0, BITS=8)

int8 i = 0;
void main()
{
   output_high(PIN_C2); // enable SPI
   while(TRUE)
   {
      spi_xfer(i++);
      output_toggle(PIN_A4); // check activity
   }
}
colin382



Joined: 03 Jun 2020
Posts: 37
Location: UK

View user's profile Send private message

Solved!
PostPosted: Thu Jan 25, 2024 11:55 am     Reply with quote

@temtronic: RTFM is always good advice, but in this case the FM was in conflict with the compiler. Having read the manual and the help file I reached the conclusion that if I stayed with the hardware it would not be necessary to define the pins to be used. That didn't work, and because I have plans for the SPI1 hardware pins, I chose to go to SPI2 and then define the pins much as Ttelmah described. That didnt work either!

Then I came back to find Ttelmah's solution which worked straight off the bat. Kudos Ttelmah. BUT when I translated across by changing "SPI1"to "SPI2" with no other changes it still didn't work!

I'll rework my other pin assignments to use SPI1

Thanks to all who offered advice. This forum is BRILLIANT.
temtronic



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

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 12:00 pm     Reply with quote

the other little 'gotcha' ...
...is that not all pins are remappable to all peripherals on PPS PICs.

these 'new' PICs have loads of nice features but, yes, kinda helps to 'look over' the datasheet.
gaugeguy



Joined: 05 Apr 2011
Posts: 289

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 12:36 pm     Reply with quote

Please post your code for SPI2.

Keep in mind you have to do all of the changes, not just SPI1 -> SPI2:
SPI1 -> SPI2
SCK1 -> SCK2
SDO1 -> SDO2
SDI1 -> SDI2
colin382



Joined: 03 Jun 2020
Posts: 37
Location: UK

View user's profile Send private message

PostPosted: Thu Jan 25, 2024 4:37 pm     Reply with quote

@guageguy
Here you go:
#include <18F16Q41.h>

#fuses NOWDT
#use delay(clock=16M)
#include <stdlib.h>

#pin_select SDO2=PIN_A2 // chip pin 17
#pin_select SDI2=PIN_B4
#pin_select SCK2=PIN_B6
#use spi(SPI2, MODE=0, BITS=8)

int8 i = 0;
void main()
{
output_high(PIN_C2); // enable SPI
while(TRUE)
{
spi_write(i++);
output_toggle(PIN_A4); // check activity
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19231

View user's profile Send private message

PostPosted: Fri Jan 26, 2024 2:52 am     Reply with quote

I've already told you exactly why this will not work.

You are using spi_write. spi_write is _NOT_ repeat _NOT_ the command
for use with #USE SPI.
Look at the manual. Select the entry for #use spi. Now look at the bottom
of the page, where it lists the commands 'related' to this. It shows:

Quote:

See Also:
spi_xfer(), spi_transfer(), spi_transfer_write(), spi_transfer_read(), spi_transfer_done(), spi_transfer_clear()


No mention at all of spi_write.

As I said before "Mixing the two sets of commands is a 'may not work,
and certainly will not work properly' way of working."
Code:

#include <18F16Q41.h>

#fuses NOWDT
#use delay(internal=16M)
#include <stdlib.h>

#pin_select SDO2=PIN_A2 // chip pin 17
#pin_select SDI2=PIN_B4
#pin_select SCK2=PIN_B6
#use spi(SPI2, MODE=0, BITS=8)

int8 i = 0;
void main()
{
   output_high(PIN_C2); // enable SPI
   while(TRUE)
   {
       spi_xfer(i++);
       output_toggle(PIN_A4); // check activity
   }
}


Also learn to use the code buttons, and be explicit on how the 'clock' is
to be generated.

You do not use spi_write, with #use spi.
colin382



Joined: 03 Jun 2020
Posts: 37
Location: UK

View user's profile Send private message

PostPosted: Fri Jan 26, 2024 5:20 am     Reply with quote

@Ttelmah
OK, sorry to miss the sublties of your code. Clearly one has to not only RTFM, but read what is NOT in the FM.
Taking on board your observations re spi_xfer() vs spi_write(), out of curiosity I checked out SPI1 and SPI2 with both instructions.
SPI1 works with either, SPI2 only works with spi_xfer(). Good to know.

Thanks for your help.
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