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

Hardware SPI

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



Joined: 07 Sep 2010
Posts: 24
Location: West Australia

View user's profile Send private message

Hardware SPI
PostPosted: Sun Sep 26, 2010 9:37 pm     Reply with quote

I'm trying to get a PIC18F8722 to generate two hardware SPI streams:

Code:

/////////////////////////////////////////////////////////////////////////////
// Project:    8722 Sure_03\main.c                                         //
// Author:     WVL                                                         //
// Date:       September 2010                                              //
// Outline:    Drive display using SPI and HPWM:                           //
//             Sure 6432 LED display                                       //
//             ETT PIC18F8722                                              //
//             Heartbeat portH.0                                           //
//             10Mhz Xtal run at 10Mhz using HS                            //
/////////////////////////////////////////////////////////////////////////////

#include <main.h>

// SPI,MSB first(default), data on rising clock edge, 32 bits
// SPI1 drives top half of display using R1
// SPI2 drives bottom half using R2
#use spi(SPI1,SAMPLE_RISE,BITS=32,DO=PIN_C5,STREAM=COM_A) //DO:C5, DI:C4, CLK:C3
#use spi(SPI2,SAMPLE_RISE,BITS=32,DO=PIN_D4,STREAM=COM_B) //DO:D4, DI:D5, CLK:D6


// function to write two 32bit ints to top display using SPI1
void load_A(int32 long_1, int32 long_2)
   {   
   spi_xfer(COM_A,long_1,32); // spi1 write to R1 on C5
   delay_us(10);              // used for scope display but not necessary
   spi_xfer(COM_A,long_2,32); // spi1 write to R1 on C5
   }
   
// function to write two 32bit ints to bottom display using SPI1
void load_B(int32 long_1, int32 long_2)
   {   
   spi_xfer(COM_B,long_1,32); // spi1 write to R2 on D4
   delay_us(10);              // used for scope display but not necessary
   spi_xfer(COM_B,long_2,32); // spi1 write to R2 on D4
   }   
   
void main()
{
   // setups for SPI1 and SPI2 data out
   set_tris_C(0x00);  // all outputs C5 is SSPI1 DO
   set_tris_D(0x00);  // all outputs D4 is SSPI2 DO     
   // setups general
   setup_wdt (WDT_OFF);
   setup_timer_0 (RTCC_INTERNAL);
   setup_timer_1 (T1_DISABLED);     
   setup_timer_4 (T4_DISABLED, 0, 1) ;     
   setup_comparator (NC_NC_NC_NC);
   
   int32 display[32][2];
       
   WHILE (1)
      {             
      // load data into display array
      display[0][0]=0x80000001;   // 32 bits
      display[0][1]=0x80000001;   // 32 bits
     
      // send data to the top display by SPI1
      load_A(display[0][0],display[0][1]);

      // send data to the bottom display by SPI2
      load_B(display[0][0],display[0][1]);     
     
      // latch  shift registers to display
      output_low (LAT); // latch display
      output_high (LAT);     
      }
}


I have stripped out quite a lot of code that just confuses the issue - and left the relevant lines.

SPI1/STREAM=COM_A works OK but SPI2/STREAM=COM_B does not.

Any ideas please.

Regards Bill Legge
_________________
Denmark in West Australia
'Where the forest meets the sea'
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 11:22 pm     Reply with quote

That's not really a test program and it's overly complex.

It appears that the order of the #use spi() statements is important.
To get the compiler to generate code for SPI2, I had to put the SPI2
statement first. Otherwise, all the code was generated for SPI1.
(Including code that should be talking to SPI2). With SPI2 first, it
looks like it will work for both of them.

There is also a problem with the TRIS. It looks like the compiler only
sets up the TRIS for whichever #use spi() statement it sees first.
To fix that, I've added the correct TRIS setup for the SCLK and SDO pins
for SPI1.

Your TRIS statements are incorrect. They set the SDI pins are outputs.
They should be inputs. The compiler is supposed to set the TRIS for you
if you don't use #fast_io mode. Due to the bug I mentioned above, it
does need a fix. All these bugs should be reported to CCS.

This was compiled with vs. 4.112. It will probably produce some output.
If this works, you can expand it and try adding the features that are in
your code.
Code:

#include <18F8722.H>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)

#use spi(SPI2, MODE=0, BAUD=1000000, STREAM=COM_B)   
#use spi(SPI1, MODE=0, BAUD=1000000, STREAM=COM_A)

//=================================
void main()
{
int8 value;
int8 result;

// Setup the TRIS for SPI1.
output_low(PIN_C3);  // SCLK for SPI1
output_low(PIN_C5);  //  SDO for SPI1

while(1)
  {
   result = spi_xfer(COM_A, value);
   result = spi_xfer(COM_B, value);
  }
}
Owais



Joined: 23 Sep 2010
Posts: 3

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 5:01 am     Reply with quote

Maybe it is better to try using spi_write or spi_read functions for hardware SPI peripheral. I am not sure if spi_xfer is for hardware SPI.
Bill Legge



Joined: 07 Sep 2010
Posts: 24
Location: West Australia

View user's profile Send private message

Hardware SPI times 2
PostPosted: Mon Sep 27, 2010 5:53 am     Reply with quote

I've tried:

1. Altering the order of the #use_spi
2. spi_write

And no luck so far. Looking at the .lst file to see what the compiler does to the source code shows that only the SSP1CON registers are affected - not any of the SSP2CON?

I'm sure that it's an error on my part - the reference manual seems quite definate that if an MCU has two spi 'lumps' they can both be driven separately?

Regards Bill Legge
_________________
Denmark in West Australia
'Where the forest meets the sea'
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 10:17 am     Reply with quote

My advice is, don't use the #use spi() library. Use setup_spi() with
spi_write() and spi_read(). It doesn't have as many features but it's
more likely to work. (It's the traditional method for CCS. #use spi()
is new). Implement your desired features with code. For example, to
send 32 bits, just call spi_write() four times.

For the 2nd spi channel, use setup_spi2(), spi_write2(), and spi_read2().
This is in the manual.
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