![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Bill Legge
Joined: 07 Sep 2010 Posts: 24 Location: West Australia
|
Hardware SPI |
Posted: Sun Sep 26, 2010 9:37 pm |
|
|
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' |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Sep 26, 2010 11:22 pm |
|
|
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);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Owais
Joined: 23 Sep 2010 Posts: 3
|
|
Posted: Mon Sep 27, 2010 5:01 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Bill Legge
Joined: 07 Sep 2010 Posts: 24 Location: West Australia
|
Hardware SPI times 2 |
Posted: Mon Sep 27, 2010 5:53 am |
|
|
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' |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 27, 2010 10:17 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|