View previous topic :: View next topic |
Author |
Message |
Skirmitt
Joined: 19 May 2009 Posts: 60
|
Increasing SPI performance |
Posted: Tue Oct 05, 2010 12:19 pm |
|
|
I finally was able to get the SD/FAT16 code running that Douglas posted on this forum. It is now a bit modified that I can 512 bytes from the card and then process each byte separately. To process an 80 KB file it takes my PIC18F2685 about 5 seconds. Is that normal performance ?
It is now running at 8 MHz with the SPI divider at 16 in mode 0.
I ordered some 40 MHz crystals now, can I expect the reading times to be 5 times faster ? |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
Re: Increasing SPI performance |
Posted: Tue Oct 05, 2010 1:10 pm |
|
|
Skirmitt wrote: | I finally was able to get the SD/FAT16 code running that Douglas posted on this forum. It is now a bit modified that I can 512 bytes from the card and then process each byte separately. To process an 80 KB file it takes my PIC18F2685 about 5 seconds. Is that normal performance ?
It is now running at 8 MHz with the SPI divider at 16 in mode 0.
I ordered some 40 MHz crystals now, can I expect the reading times to be 5 times faster ? |
Noooooooooooooo!
40MHz crystals won't work!
you want a 10MHz crystal and then enabling the 4xPLL config fuse!!
READ THE OSCILLATOR section of the datasheet!
Why is the SPI divider at 16? Right now, you could put the divider at Fosc/4 which would get you an instant speed increase.
And if you turn on the 4xPLL right now, Tosc will be 32MHz and w/SPI at Tosc/4, you'll be running your SPI port at 8MHz.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Skirmitt
Joined: 19 May 2009 Posts: 60
|
|
Posted: Tue Oct 05, 2010 1:31 pm |
|
|
So I add #FUSES H4 to my code and the and the internal OSC will run at 32 MHz, nice I didn't know that feature.
With Fosc/4 you mean that I configure my SPI like:
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4); ? |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Tue Oct 05, 2010 2:28 pm |
|
|
Skirmitt wrote: | So I add #FUSES H4 to my code and the and the internal OSC will run at 32 MHz, nice I didn't know that feature.
|
Yep. It's pretty cool - and you can do that on the fly (with a little care) if you ever needed.
I have one application that's power sensitive so as I have various tasks enabled/disabled on the device, it will change clock rates automagically.
It's fun.
Quote: |
With Fosc/4 you mean that I configure my SPI like:
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4); ? |
Yes.
Wasn't that easy. ;)
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Skirmitt
Joined: 19 May 2009 Posts: 60
|
|
Posted: Wed Oct 06, 2010 12:56 am |
|
|
Hope was high when I applied the settings this morning but it was a bit of a disapointment. The code still runs but with no performance gain at all
I add my code below:
Code: |
#include <18F2685.h>
#fuses INTRC_IO, NOWDT, PUT, PROTECT, NOBROWNOUT, H4
#use delay(clock = 32000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include "HDD Driver.c"
#include <40x4lcd.c>
#define SPI_MODE_0 (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1 (SPI_L_TO_H)
#define SPI_MODE_2 (SPI_H_TO_L)
#define SPI_MODE_3 (SPI_H_TO_L | SPI_XMIT_L_TO_H)
void main()
{
lcd_init1();
delay_ms(2);
lcd_init2();
int r1,i,j,error,error0,error1;
int16 rec_no;
int16 index,rec_size;
int32 offset;
char fname[32],buff0[MMC_BUFF_SIZE+1],buff1[MMC_BUFF_SIZE+1];
char c;
int32 i9=0;
char last;
setup_adc_ports(NO_ANALOGS);
output_high(_CS);
printf(lcd_putc1,"SD wordt gelezen");
//Delay_ms(1000);
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_4);
buff0[MMC_BUFF_SIZE]=0;
buff1[MMC_BUFF_SIZE]=0;
rec_no=0;
///////// init MMC ////////////////////////////////////////
error=init_MMC(10);
rec_size=MMC_BUFF_SIZE;
//strcpy(fname,"HOME\\HOME.TXT");
strcpy(fname,"idle.pcm");
rec_size=MMC_BUFF_SIZE;
error0=open_file(0,fname,rec_size);
if (error0>0)
{
goto mmc_exit;
}
int32 sizeRead = 0;
lcd_gotoxy(1,1);
printf(lcd_putc1,"Start ");
do
{
sizeRead = file_read2(0,buff0);
for (i9 = 0; i9 < sizeRead;i9++)
{
last = buff0[i9];
}
rec_no++;
} while (sizeRead == 512);
lcd_gotoxy(1,1);
printf(lcd_putc1,"Last: %c ", last);
mmc_exit:
//printf("\n\r done winhex adj= %lu \n\r",winhex_adj);
while (true);
} |
What could be wrong ? I measure from the time I print Start to the LCD till it shows the last byte I have in the PCM file. |
|
|
Skirmitt
Joined: 19 May 2009 Posts: 60
|
|
Posted: Wed Oct 06, 2010 1:43 am |
|
|
I found the solution in another thread:
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT,NOLVP,INTRC_IO//,NOMCLR
#use delay(clock=32000000)
I had to let the H4 fuse away. As stated in this thread: http://pic-c.ccsinfo.com/forum/viewtopic.php?t=38263
Although it's not clear for me if I need the line
setup_oscillator (osc_8MHZ | OSC_PLL_ON); ?
Without this line performace is already |
|
|
Geps
Joined: 05 Jul 2010 Posts: 129
|
|
Posted: Wed Oct 06, 2010 2:18 am |
|
|
bkamen wrote: | Skirmitt wrote: | So I add #FUSES H4 to my code and the and the internal OSC will run at 32 MHz, nice I didn't know that feature.
|
Yep. It's pretty cool - and you can do that on the fly (with a little care) if you ever needed.
I have one application that's power sensitive so as I have various tasks enabled/disabled on the device, it will change clock rates automagically.
It's fun.
|
I was reading a recent thread (http://pic-c.ccsinfo.com/forum/viewtopic.php?t=43705) and mentioned you had to power cycle the board in order to activate the PLL function. Is this not the case? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1908
|
|
Posted: Wed Oct 06, 2010 7:32 am |
|
|
Geps wrote: |
I was reading a recent thread (http://pic-c.ccsinfo.com/forum/viewtopic.php?t=43705) and mentioned you had to power cycle the board in order to activate the PLL function. Is this not the case? |
That's only for the H4 fuse, not for the s/w controlled PLL. |
|
|
|