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 halt entire program

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



Joined: 13 Apr 2011
Posts: 405

View user's profile Send private message

SPI halt entire program
PostPosted: Tue Sep 11, 2018 9:54 pm     Reply with quote

CCS 5.078
uC PIC18F14K50
All the program runs ok until must perform an SPI write.

I checked the analog ANSEL/H registers and are all 0x00
Comparators also disabled.

I don't understand why the SPI doesn't transmit. Any idea?

Code:

#include <18F14K50.h>

#use delay(clock=32M)

#use fast_io(ALL)

#fuses INTRC,PLLEN,NOWDT,NOLVP

void main()
{
       output_a(0);
       output_b(0);
       output_c(0);
   
   set_tris_b(0b00111111);
        set_tris_c(0b00111111);
   

   setup_spi(SPI_CLK_DIV_4|SPI_MASTER|SPI_XMIT_L_TO_H|SPI_SAMPLE_AT_MIDDLE|SPI_SCK_IDLE_LOW);

        spi_write(0b11100000);//<- Halt here
        while(1)
   {
            delay_us(50);
        }   
}
   

_________________
Electric Blue
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Sep 12, 2018 1:04 am     Reply with quote

There is nothing obviously 'wrong' and it should not stop on this. The only thing that might apply is that the recent compilers have changed the default fuse behaviour in some cases, and you should have NOXINST selected, or will get intermittent problems at some parts of the code.
However why not use #use spi?. This is the more modern way to setup and use the SPI, and does improve some parts of the code.
Also honestly why use fast_io?. In 99% of code it is safer, and more reliable to let the compiler contol the TRIS for you.
So:
Code:

#include <18F14K50.h>

#fuses INTRC,PLLEN,NOWDT,NOLVP,NOXINST
//you should have the NOXINST fuse selected
#use delay(internal=32M)

#USE SPI(STREAM=SPIPORT, MODE=0, BAUD=2000000)

void main()
{
   output_a(0);
   output_b(0);
   output_c(0);   
   spi_xfer(SPIPORT, 0b11100000);
   while(1)
   {
      delay_us(50);
   }   
}


It will hang on an SPI write, if there is a hardware issue, and the SCK line is shorted and cannot operate. Check. Write a basic function to toggle this pin (PIN_B6) and check it is working. On these later chips the SCK line is fed out from the SPI port 'write' component, and this then feeds back in to the input shift register. If the line does not operate the register does not get clocked, so will sit waiting....
gian



Joined: 13 Jun 2013
Posts: 3

View user's profile Send private message

PostPosted: Tue Nov 06, 2018 10:55 am     Reply with quote

I have the same problem.

CCS 5.048
dsPIC33ev256gm006

I'm trying to make spi2 work but when I try to write the program stop. This is my code:

Code:
#include <33ev256gm006.h>
#use delay(crystal=20Mhz,clock=80Mhz)
#pin_select SDI2=PIN_G7
#pin_select SDO2=PIN_G8
#pin_select SCK2OUT=PIN_G6
#use spi(SPI2, MASTER, FORCE_HW, BITS=8, MODE=0, STREAM=my_spi, BAUD=4000000)


void  main(void)
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi2(SPI_MODE_8B | SPI_SS_DISABLED);

   for(;;)
   {
      spi_write2(1);

      output_high(PIN_F0);  // led ON
      delay_ms(100);
      output_low(PIN_F0);  // led OFF
      delay_ms(100);
   }
}


The only way to make it work is to change the instruction:

Code:
spi_write2(FALSE, 1)

I also tried using the spi_xfer function but It does not work anyway.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue Nov 06, 2018 11:40 am     Reply with quote

General comment, do not use SPI_write with #USE SPI.

There are two completely separate ways of using SPI with the compiler. The old way was to use setup_spi, and spi_read/spi_write.
The newer way is to use #USE SPI, and spi_xfer.
They are _not_ compatible (always) with each other. If you look in the manual, #use spi, only refers you to spi_xfer, and setup_spi only refers you to spi_read/write.
On some occasions they will work with each other, but on a lot of occasions, the result is incorrect....
You currently have both being used.

So replace:

spi_write2(1);

with

spi_xfer(my_spi, 1);

and get rid of the setup_spi2 line.

Now, this line is probably what is causing the problem, since it is incorrect.
SPI_SS_DISABLED, is for a _slave_ device only. Using it on a master results in invalid configuration....

Code:

#include <33ev256gm006.h>
#use delay(crystal=20Mhz,clock=80Mhz)
#pin_select SDI2=PIN_G7
#pin_select SDO2=PIN_G8
#pin_select SCK2OUT=PIN_G6
#use spi(SPI2, MASTER, BITS=8, MODE=0, STREAM=my_spi, BAUD=4000000)
//using the hardware port number always forces hardware to be used


void  main(void)
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
 
   for(;;)
   {
      spi_xfer(my_spi,1);

      output_high(PIN_F0);  // led ON
      delay_ms(100);
      output_low(PIN_F0);  // led OFF
      delay_ms(100);
   }
}   
gian



Joined: 13 Jun 2013
Posts: 3

View user's profile Send private message

PostPosted: Wed Nov 07, 2018 1:24 am     Reply with quote

I tried in this way but it still does not work. The strange thing is that the spi sends the output data anyway but then it stop the program. I looked at the .lst file to see which assembly instruction crashes. I looked at the difference between the function
Code:
spi_write2(FALSE, 1)
(that works) and the function
Code:
spi_write2(1)
The only difference is that in the second function there are two more instructions
Code:
BTSS.B  260.0
BRA     2AA
I'm almost certain that the program hangs on these instructions.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Nov 07, 2018 3:33 am     Reply with quote

260.0, is SPIRBF. Receive buffer full. This will be set by the hardware, once a byte has shifted into the receive register, which will automatically happen once the byte has been clocked out (since SPI is duplex and always receives a byte as it transmits).

I suspect I know what your issue is. It's one I've met on another chip. Add the following to your PPS setup:

#pin_select SCK2IN=PIN_G6

On some chips, the outgoing SPI clock is not automatically connected to the incoming shift register. So you have to map the signal to an output pin, and then connect it 'back' to the input of the shift register, or this does not get clocked (and so the receive will hang...).
gian



Joined: 13 Jun 2013
Posts: 3

View user's profile Send private message

PostPosted: Wed Nov 07, 2018 4:00 am     Reply with quote

Yes, thanks Ttelmah. Now it works.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Wed Nov 07, 2018 4:16 am     Reply with quote

Yours is quite an interesting problem.
On the other chips where this applies, the data sheet normally shows the two separate signals. The output SCK, and the SCK to the shift register. On yours the sheet shows the clock to the shift register connected internally. Duh....

It's only because I 'know' that quite a few of the newer chips have this separate configuration, and the symptom was 'classic' for this not being connected, that I was able to make the leap to suggest this.... Very Happy
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