View previous topic :: View next topic |
Author |
Message |
adi1133
Joined: 30 Dec 2010 Posts: 6
|
Spi write functions return too late |
Posted: Thu Aug 09, 2012 9:52 am |
|
|
I want to use hardware spi, I only need to write, I want to use to dump the data into the write buffer and then go on with the main program without waiting to do the full write before resuming. Is there any way to do this besides inserting ASM ?
This is the test application I made, under an oscilloscope I can see that PIN_A1 toggles only after the transfer is done, I'd like this to happen while transferring.
Code: |
#include <18F2550.h>
#use delay(CLOCK = 48MHZ)
#fuses HSPLL, NOWDT, NOPROTECT, NOLVP, USBDIV, PLL5, CPUDIV1, NOMCLR
void main(void)
{
setup_spi(SPI_MASTER|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);
output_high(PIN_A1);
#USE FAST_IO(A)
int8 i;
i=0;
while(1)
{
spi_write(i);
output_toggle(PIN_A1);
output_toggle(PIN_A1);
output_toggle(PIN_A1);
output_toggle(PIN_A1);
delay_ms(100);
i++;
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Aug 09, 2012 10:07 am |
|
|
Code: |
#byte SSPBUF=getenv("SFR:SSPBUF")
#byte SSPSTAT=getenv("SFR:SSPSTAT")
#bit SSP_BUSY=SSPSTAT.0
while (SSP_BUSY); //Use this to wait for buffer to be empty
SSPBUF=i; //to do the write
|
It is annoying. CCS actually 'switches' in versions for the last couple of years, to just writing to the register directly, if used inside an SSP ISR, so on interrupt driven receive/transmit code, works OK, but for use in 'mainline' code where you want to get on and do other jobs while the byte is transmitting, it is a pity that this is not a selectable option....
Best Wishes |
|
|
adi1133
Joined: 30 Dec 2010 Posts: 6
|
|
Posted: Thu Aug 09, 2012 10:26 am |
|
|
Thank you for the fast response, your response is working as intended ,indeed a selectable option for this would be nice.
I guess this works for i2c too, since it uses the same SSP hardware module.
Does getenv("SFR:xxxxx") work with all the registers found in the datasheet of the device ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Thu Aug 09, 2012 1:45 pm |
|
|
It should do (both for SSP, and the use of getenv).
Only problem sometimes is that the names may not be 100% obvious.....
Years ago, I moaned (both here, and to CCS), about the behaviour of the SSP code, and over time, the change was made for interrupt use.
Might be worth another person pointing this out to them.
The amazing thing (to me), is how few people seem to realise the limitations of the standard approach....
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Aug 09, 2012 3:00 pm |
|
|
Code: |
#use spi(FORCE_HW, MASTER, MODE=2, IDLE=1 )
setup_spi(SPI_MASTER|SPI_H_TO_L);
|
so this declaration and the function are not equivalent? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Aug 09, 2012 11:27 pm |
|
|
Most SPI applications are controlling a CS pin in software and thus need to wait for completion of the frame,
as the present spi_write() implementation does. I fear that creating another configuration parameter for
this feature would promote user confusion.
I think. for those applications with different requirements writing your own code isn't asking too much.
Just my five cents. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Fri Aug 10, 2012 2:06 am |
|
|
I don't see that it needs to be confusing _provided it is properly documented_.... (unfortunately, something that CCS is not 'great' at....).
However look (for example), at the read_adc function. Default behaviour to do everything. trigger the read,wait for it to complete, and return the value.
However one is given the option of adding a parameter like 'ADC_START_ONLY', and it then just starts the ADC.
So something like:
spi_write(val);
Behaves exactly as the current implementation, but:
spi_write(val,DO_NOT_WAIT);
Would be simple to implement (I've actually done it, 'overloading' the existing function, since the compiler allows this now), and would mean that one didn't have to do your own functions.
I synchronise SPI, with a slave select for the whole block, rather than for the individual bytes - this is common for a lot of third party chips, so want to get on with other things while the writing takes place.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Aug 10, 2012 5:53 am |
|
|
Quote: | I don't see that it needs to be confusing _provided it is properly documented_.... (unfortunately, something that CCS is not 'great' at....).
spi_write(val,DO_NOT_WAIT); |
I agree, this way it shouldn't be confusing. |
|
|
|