|
|
View previous topic :: View next topic |
Author |
Message |
rashworth1
Joined: 10 May 2012 Posts: 4 Location: UK
|
PIC18F26K80 SPI_READ Freeze |
Posted: Thu May 10, 2012 2:09 am |
|
|
I found the need to switch from software SPI to Hardware SPI due to the software SPI not quite being fast enough. However the program now stops everytime I do a spi_read. Looking throuth this forum I can see that the only reason the program would wait should be if it though it was a SPI SLAVE, which it isn't as you can see from the code. I've also tried the setup_spi() function with the same result.
Any clues?
Compiler PCH v 4.128
Code: |
#include "18F26K80.h"
//Set the PIC18F26K80 device fuses.
#fuses HSH,PLLEN,NOPROTECT,NOWDT,CANC,NOMCLR,NOBROWNOUT//16Mhz Oscillator - Turn on PLL, and BROWNOUT
//
//Used for calculating delays etc.
#use delay(clock=64000000)
//Configure the SPI bus - Hardware Controller - AD7980
//#use spi(MASTER, MSB_FIRST, DI=PIN_C4, DO=PIN_C5, CLK=PIN_C3, MODE=0,BITS=16, stream=SPI_ADC)
#use spi(FORCE_HW,MASTER,MSB_FIRST,MODE=0,BITS=16, stream=SPI_ADC)
|
...
...
...
...
This is where it freezes...
Code: |
//pulse the Conversion pin
output_high(PIN_C2);
delay_us(2);//allow conversion to take place
output_low(PIN_C2);
//now clock the data in on SPI port
ADCVal[Chan]=spi_xfer(SPI_ADC,Zeros);
// iADCVal.b[0]=spi_read(0);
// iADCVal.b[1]=spi_read(0);
// ADCVal[Chan]=100;
// ADCVal[Chan]=iADCVal.i;
|
Any ideas anyone? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu May 10, 2012 4:09 am |
|
|
I'd switch to trying the setup_spi route, rather that #use_spi.
Remember the hardware only does 8bit transfers, so as soon as you select 16bit, a lot more software is getting involved. My guess is that somewhere in this, it is getting confused.
so simply use setup_spi, and make8/make16, send the two bytes separately, and see what happens. The #use SPI system has never seemed as reliablle as the older system. Since (guessing), you seem to only be sending 'zeros' to clock the SPI, the overall command would be very easy. Something like:
Code: |
int8 temp;
temp=spi_read(0);
ADCVal[chan]=make16(temp,spi_read(0));
|
One thing missing, in your existing code - clock rate. Is it possible it is working, but clocking at some ludicrous rate like 1bps?. Though the default is meant to be 'as fast as possible', I'd not put it past the code to be getting this wrong.....
Other thing, look at the errata for this chip. If I remember correctly, one revision has a fault that the buffer full flag doesn't work when operating as an SPI master. You may need to write the code yourself to avoid this, if your chip is one affected by this issue....
Best Wishes |
|
|
rashworth1
Joined: 10 May 2012 Posts: 4 Location: UK
|
|
Posted: Thu May 10, 2012 4:27 am |
|
|
I've already tried both methods of configuring the SPI port - I tried it again with the same result:
Code: |
setup_spi(spi_master |SPI_L_TO_H | spi_clk_div_64);//configure the spi port
|
and
Code: |
iADCVal.b[0]=spi_read(0);
iADCVal.b[1]=spi_read(0);
ADCVal[Chan]=iADCVal.i;
|
Still locks up.
I'm bginning to suspect it is either that the compiler is not setting the MASTER/SLAVE bit correctly or it is to do with the fact that these pins are also used for I2C operation. I've scowered the datasheet but can't see anything which says how to configure it for SPI or I2C. The datasheet goes on about how the same pins are used for each mode without actually saying how you set it to be SPI or I2C.....
Is it possible to set the SSPCON1 register diectly?
The chip is a new one direct from Microchip. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu May 10, 2012 7:30 am |
|
|
Of course it is:
#byte SSPCON1=getenv("SSR:SSPCON1")
Then you have a byte variable called SSPCON1 talking directly to the register.
However you have the wrong idea about errata. A lot apply even to the latest chips. There are few PICs that don't have some problems somewhere. The errata sheets must be part of your general reading for using any chip.
The MSSP is a pretty standard bit of hardware/code (especially if you use the setup_spi route), and has worked reliably for a lot of compiler versions. The only times I've had problems with it, are:
1) Historical - a long time ago....
2) When working as an interrupt driven SPI slave, some of the CCS functions do a bit 'too much' when all you want are simple reads/writes of things like the buffer register.
3) With chip errata.....
You can see in 10 seconds from the .LST file, what is being sent to the registers for the setup_spi call, and what the spi_read calls do.
Thing is that the SPI read, _will_ wait for the byte to transfer, hence a problem with reading the buffer full bit, would hang the chip here.
Best Wishes |
|
|
rashworth1
Joined: 10 May 2012 Posts: 4 Location: UK
|
|
Posted: Thu May 10, 2012 7:44 am |
|
|
Thanks for that, that makes at least gives be a clear direction to debug the issue.
I'm not able to get to the HW at the moment, but assuming the issue is a reading of the buffer full bit, the workaround would be to wait a few uS then to read the contents directly? Or can you suggest anything a bit more elegant...
Thanks,
Rob |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu May 10, 2012 8:21 am |
|
|
Basically you copy the whole register to a RAM variable, then read the bit in this. It is just the bit read function that fails.
Best Wishes |
|
|
rashworth1
Joined: 10 May 2012 Posts: 4 Location: UK
|
|
Posted: Mon May 14, 2012 3:12 am |
|
|
Thanks for that,
after a bit of jiggery pokery, Its now working fine. I'll post the section of code later in-case anyone has similar issues. |
|
|
|
|
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
|