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

SPI2 on 18F67K22
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

SPI2 on 18F67K22
PostPosted: Wed Dec 19, 2018 10:14 am     Reply with quote

I'm using v5.081 PCWHD with a PIC18F67K22, and trying unsuccessfully to use the SPI2 interface.

In another thread about using SPI, I read that you can't use spi_write with a #use spi declaration, nor can you use spi_xfer with the setup_spi function. That spi_write can only be used with setup_spi, and spi_xfer can only be used with #use spi. If that's true, the compiler manual should say so.

In any case, when I try to use SPI2, a call to spi_write, or a call to spi_xfer hangs the cpu forever. It never returns from those calls.
For example:
Code:

#use delay( clock=64000000, internal=16000000 )
#use spi (MASTER, SPI2, MODE=1, BITS=8, STREAM=SPI_2, FORCE_HW)

spi_xfer( SPI_2, value );


or
Code:

#use delay( clock=64000000, internal=16000000 )
setup_spi2(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_64);

spi_write2( value );


In both cases, the program crashes as the spi_xxx call. Am I missing something?
newguy



Joined: 24 Jun 2004
Posts: 1900

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 10:33 am     Reply with quote

It's quite possible and very likely that the compiler is accessing the wrong registers for SPI2.

Options -> Project -> Output Files, select Symbolic for the List File. Recompile. Have a look at the list file and see if spi_xfer() is accessing the proper register when you attempt to transfer something over SPI2. It's a safe bet that it isn't. From memory the standard driver waits on the state of a bit before commencing (or at some point during the procedure). If it's addressing the wrong register(s), then that would explain the hanging you're seeing.
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 11:22 am     Reply with quote

This is from the listing. I don't think I have access to the source code of spi_xfer.

.................... spi_xfer( SPI_2, val[0] );
004D4: MOVFF val,??65535
004D8: CALL @SPI_XFER_1_8
.................... spi_xfer( SPI_2, val[1] );
004DC: MOVFF val+1,??65535
004E0: CALL @SPI_XFER_1_8
newguy



Joined: 24 Jun 2004
Posts: 1900

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 11:34 am     Reply with quote

Near the very top of the processor.h file is a #nolist. Comment it out, then recompile.

Also, in your test program, put in a #use SPI for SPI1, and also put in a spi_xfer(SPI1, whatever) into your program.

You know that SPI1 accesses work properly so you can see the disassembly for that and compare to SPI2.
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 12:50 pm     Reply with quote

The source code from the CCS libraries still does not show up in the list file. But I think you're right, the wrong register(s) is being used.

I changed the #use spi declaration to add FORCE_SW, and now SPI2 works. It's fast enough for my purposes.

I also sent an email to tech support informing of the problem.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 12:52 pm     Reply with quote

It correctly loads the byte into SSPBUF2.

Then loops rotating SSP2STAT right into carry, and since 'BF' is the bottom
bit, should exit the loop, when BF goes off.
The code is right!...

Are you sure the SCK2 pin is not shorted?. It'll lock if this pin is stuck,
since it is the actual signal going 'out' of the chip, that is looped back to
operate the shift register. If this pin is shorted, the SPI will hang as
you describe.
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 12:59 pm     Reply with quote

Yes, I'm sure SCL2 is not shorted. I'm using the same SPI2 pins for the FORCE_SW configuration, and it's all working fine.

#use spi (MASTER, SPI2, MODE=1, BITS=8, BAUD=38400, DI=PIN_D5, DO=PIN_D4, CLK=PIN_D6, STREAM=SPI_2, FORCE_SW)
newguy



Joined: 24 Jun 2004
Posts: 1900

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 1:01 pm     Reply with quote

SeeCwriter wrote:
Yes, I'm sure SCL2 is not shorted. I'm using the same SPI2 pins for the FORCE_SW configuration, and it's all working fine.

#use spi (MASTER, SPI2, MODE=1, BITS=8, BAUD=38400, DI=PIN_D5, DO=PIN_D4, CLK=PIN_D6, STREAM=SPI_2, FORCE_SW)


BAUD=38400

Question

Are you sure about that? The SPI clock speed is very, very limited in terms of what it can provide, and 38,400 is pretty "weird". Usually on the order of several MHz.
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 1:32 pm     Reply with quote

I tried 9600, and the compiler complained it was too slow. So I tried 38400. A 3-byte write is 1ms. The clock is 16.45kHz.

What would you suggest as a better value?
newguy



Joined: 24 Jun 2004
Posts: 1900

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 1:36 pm     Reply with quote

Oh, okay. Really low speed, low power. I was thinking standard application, tens of MHz clock, so SPI should also be on the order of MHz.

Just for the heck of it, can you leave off the clock specification entirely and revert to the HW SPI module just to see if that makes any difference at all?
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 1:42 pm     Reply with quote

I removed the BAUD setting, and now SCL2 is 833.3KHz. So why is 38400 so unusual?
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 1:44 pm     Reply with quote

No, I can't switch to hardware SPI. It doesn't work. Only with FORCE_SW set does SPI2 work.
newguy



Joined: 24 Jun 2004
Posts: 1900

View user's profile Send private message

PostPosted: Wed Dec 19, 2018 2:16 pm     Reply with quote

I guess the value isn't unusual, the relatively slow speed is. SPI clocks usually run "on the order" of a few MHz. For example, 5 MHz or 1 MHz or perhaps even 20 MHz. The SPI hardware clock divisor for most PICs usually has options for /2, /4, /8, /16. There may be one or two additional division factors, but the choices are pretty limited.

I saw the 38,400 and given my erroneous assumption that your PIC's clock was "on the order of several tens of MHz", my first impression was that wow, that's a really weird SPI clock. In fact, it's also slower than IIC on the slow setting. Given that SPI is a faster bus/protocol than IIC, it really struck me as weird. However, given your very low processor clock, no it's not unusual I suppose.

Something else just leapt to mind, however. On a relatively recent project a member of my team discovered that the SPI EEPROM he was interfacing with behaved properly if clocked "quickly" but not "slowly". This is a battery powered application, so very low power, very low clock speed. The application can also derive external power from a running vehicle, and when it detects external power, extra functionality is "unlocked" and the processor runs as fast as it will go. He found when the system had external power, everything behaved, but when the application reverted solely to battery power that the EEPROM's data seemed to get scrambled. He eventually tried upping the processor's speed during SPI transactions with the EEPROM, and the problem went away.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Dec 20, 2018 1:51 am     Reply with quote

OK.

Now have triple checked, and spi_xfer, is doing exactly what it should.
The TRIS is setup correctly, the SSP2CON1 register has the port enabled.
It defaults to selecting Fosc/4 (without a baud rate). The slowest baud
rate the hardware can produce is Fosc/32768, by using the TMR2 output
(assuming this is not being used for something else...).
Now, I remember another 'nearby' chip, has an erratum, where the BF
bit does not set correctly. Just starting to wonder if this chip actually has
the same problem on SPI2, and nobody has noticed!...
On that basis I've written a quick 'replacement' for spi_xfer (actually
more like spi_write), setup to use the interrupt bit instead. Replace the
spi_xfer line with this (doesn't use the stream name just talks directly
to the hardware), and see if anything changes. If it does then the chip
has a bug....

Code:

#BYTE SSP2STAT=getenv("SFR:SSP2STAT")
#BIT BF2=SSP2STAT.0
#BYTE SSP2BUF=getenv("SFR:SSP2BUF")
//#define USE_BF  //Leave this enabled to use the BF bit as CCS does

//Simple send and receive from SPI2, using BF or SSP2IF to detect
//transmission complete
unsigned int8 send_spi2(unsigned int8 value)
{
   unsigned int8 val;
   val=SSP2BUF; //read buffer to clear BF
#IFNDEF USE_BF
   clear_interrupt(INT_SSP2); //Clear SSP2 interupt
#ENDIF
   SSP2BUF=val; //write data - shold start sending at once
#IFDEF USE_BF
   while (BF2==0)
      ; //wait for transmission using BF
#ELSE
   while (!interrupt_active(INT_SSP2))
      ; //or wait using SSP2IF
#ENDIF
   return SSP2BUF; //and return value received
}
SeeCwriter



Joined: 18 Nov 2013
Posts: 159

View user's profile Send private message

PostPosted: Thu Dec 20, 2018 8:59 am     Reply with quote

You're absolutely right, the spi_xfer code is correct. The problem is in my code. I am using port D for different things, and have a #use FIXED_IO declaration that sets the various pins of port D accordingly. But I didn't include the SPI2 pins because I was expecting the #use spi to configure the SPI2 pins as needed. Well, that doesn't happen. As soon as I write to any of the pins of port D, the SPI2 quits working. Once I added the SPI2 pins to the FIXED_IO declaration SPI2 worked.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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