|
|
View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
SPI halt entire program |
Posted: Tue Sep 11, 2018 9:54 pm |
|
|
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: 19561
|
|
Posted: Wed Sep 12, 2018 1:04 am |
|
|
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
|
|
Posted: Tue Nov 06, 2018 10:55 am |
|
|
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: 19561
|
|
Posted: Tue Nov 06, 2018 11:40 am |
|
|
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
|
|
Posted: Wed Nov 07, 2018 1:24 am |
|
|
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 functionThe 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: 19561
|
|
Posted: Wed Nov 07, 2018 3:33 am |
|
|
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
|
|
Posted: Wed Nov 07, 2018 4:00 am |
|
|
Yes, thanks Ttelmah. Now it works. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19561
|
|
Posted: Wed Nov 07, 2018 4:16 am |
|
|
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.... |
|
|
|
|
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
|