Created Mon, 22 Jul 2013 00:31:00 +0000 by Omnimusha
Mon, 22 Jul 2013 00:31:00 +0000
hello, the maximum speed that can throw is 40 MHz?? as I can put this at full speed? so?
SPI.setClockDivider (SPI_CLOCK_DIV2) / / 40 MHz??
Mon, 23 Dec 2013 23:55:30 +0000
Your best bet is to use the DSPI library instead of the SPI library - it is far more advanced. Setting the speed in the DSPI library is slightly different, but gives better results, as you set the actual speed you want, not the divider:
#include <DSPI.h>
DSPI0 SPI;
void begin() {
SPI.begin();
SPI.setSpeed(40000000UL);
}
You can also do full 32-bit transfers with the DSPI library to get things running even more smoothly:
uint32_t data = 0x12345678;
SPI.setTransferSize(32);
SPI.transfer(data);
Sat, 28 Dec 2013 11:45:56 +0000
I think you cannot set 40MHz SPI clock, however..
The minimum clock period for SCKx is 40 ns. Therefore, the clock generated in Master mode must not violate this specification.
A pity..
Sat, 28 Dec 2013 11:58:50 +0000
You should be able to - the master clock is 80MHz, the peripheral clock is 1:1, so also 80MHz, and with a BRG of 0 you get a /2 of the PB clock, so 40MHz. As is depicted in this table in section 23.3.7 of the PIC32 FRM: [attachment=0]brg.png[/attachment] However, there is a caveat in the '795 data sheet:
The minimum clock period for SCKx is 40 ns. Therefore, the clock generated in Master mode must not violate this specification.
1/0.00000004 = 25000000Hz, so to stay inside the specifications you cannot reliably generate an SCK of more than 25MHz.
It also states:
These parameters are characterized, but not tested in manufacturing.
So it may be possible to do it, but it's not guaranteed, and what may work on one batch of chips may not work on another batch of chips. As with all these characteristics they err on the side of caution so ensure that they are valid for all imprints of a chip, so you may get lucky have have a chip that can do >25MHz, or you may not - who knows?
Sun, 29 Dec 2013 12:18:37 +0000
The max SPI clock you can get in reality with 80MHz peripheral bus speed is 20MHz. The another option is to run pic32mx @120MHz. Maybe you can get 30MHz SPI clock then.
PS: there were fellows who said they saw 40MHz clock at SCLK output, the ?? is whether the internal logic is able to process the data properly when SCLK=Pbus/2, though..
Sun, 29 Dec 2013 12:24:32 +0000
Alternatively slow it down and use a smaller divider to get the higher SPI speeds. Running at 50MHz should let you get at the 25MHz SPI, or 60MHz to push the boundaries and try for 30MHz.
Sun, 29 Dec 2013 12:32:31 +0000
Yes, that may work as well. But there is a ?? of a balance between the cpu mips vs. sdcard r/w speed. Ie. 25% less cpu and 33% more sdcard.. Probably application specific decision.. :)
PS: is the chipkit's sdcard driver as fast as ie. the retrobsd's one? Talking about the enhanced buffering for example.. That gives you 25% speedup easily..
Sun, 29 Dec 2013 12:44:09 +0000
Hell no - it barely functions as it is!
I have a slightly better version in UECIDE that actually allows you to specify the SPI port (and uses HARDWARE SPI!!!) but it doesn't do enhanced buffering yet. Not all the chips (the one on the Uno32 for example) have an enhanced buffer.
Sun, 29 Dec 2013 12:51:14 +0000
Sd2Card.cpp l.352:
// transfer data
for (uint16_t i = 0; i < count; i++) {
dst[i] = spiRec();
}
The above code is MUCH slower than with enhanced buffering - experts may consider the redesign of those 3 lines and you get much better performance.. A few minutes of work :twisted: ..
The code: http://retrobsd.org/viewtopic.php?f=5&t=502
There is a function mips_bswap in the code, search for it in the repo, it reverts the order of the bits in the 32bit word sent (it uses 32bit spi transfer).
You may use enhaced buffering with 8bit transfers:
http://retrobsd.org/viewtopic.php?f=5&t=513
// READ: 8bit mode, 16bytes FIFO buffer:
// Pito 2011
// --------------------------------
static void spi_get_sector (char *data)
{
register struct sdreg *reg = (struct sdreg*) &SD_PORT;
int i,r;
reg->conset = PIC32_SPICON_ENHBUF;
r = 0;
i = SECTSIZE;
while (r < (SECTSIZE))
{
if ((!(reg->stat & PIC32_SPISTAT_SPITBF)) && (i) )
{
reg->buf = ~0;
i--;
}
if (!(reg->stat & PIC32_SPISTAT_SPIRBE))
{
*data++ = reg->buf;
r++;
}
}
reg->conclr = PIC32_SPICON_ENHBUF;
}
// WRITE: 8bit mode, 16bytes FIFO buffer:
// Pito 2011
// --------------------------------
static void spi_put_sector (char *data)
{
register struct sdreg *reg = (struct sdreg*) &SD_PORT;
int i,r;
reg->conset = PIC32_SPICON_ENHBUF;
r = 0;
i = SECTSIZE;
while (r < (SECTSIZE))
{
if ((!(reg->stat & PIC32_SPISTAT_SPITBF)) && (i) )
{
reg->buf = *data++;
i--;
}
if (!(reg->stat & PIC32_SPISTAT_SPIRBE))
{
(void) reg->buf;
r++;
}
}
reg->conclr = PIC32_SPICON_ENHBUF;
}
The difference against 32bit transfers is small, so go with 8bit transfers when 32bit transfers not available on certain chips.. ;)
Sun, 29 Dec 2013 13:20:27 +0000
32 bit transfers are available on all chips (pic32 chips that is, but that's all we care about). The FIFO buffering, however, is not. At the moment it "works" on all chips. To add the enhanced buffering you'd first have to identify which chips have it available an conditionally compile for only those chips. More than a couple of minutes work...
Sun, 29 Dec 2013 13:30:07 +0000
Above are the two 8bit functions (compare them with the 32bit ones pls - as I'm not sure they are the last revs I've found somewhere).. If you have got 30mins time spare :) , you may try with ie fubarino to see whether it is worth of the effort.. My guess is 20-30% speed increase..
PS: it may work without FIFO.. There is no specific setting for FIFO size.. it depends on how the flags will react when fifo=1.. PS1: without fifo the 32bit version could be the faster one..