I am not sure how the SD library sets/clears the CS pins, however, assuming it does so using a digital write, this operation on its own might take as much or more than the time needed for the data to be sent.
Is there any way to define the CS pin witting directly to the port?
Thanks Nilton. Thats exactly what I do. But in libraries, say for a TFT or an SD card, I cannot define the chipselect as a port number. This means changing the library rather than the code, for every different project
Is there any macro I can use that allows me to write a function say "PORTx |= 1<<bitnumber" instead of having to do this manually each time I want to set up a library on a specific platform?
Why do you think you need to do this? Both the SD and TFT libraries allow you to set the CS pin in the begin function or constructor using the digital pin number.
Is there any macro I can use that allows me to write a function say "PORTx |= 1<<bitnumber" instead of having to do this manually each time I want to set up a library on a specific platform?
I am not sure how the SD library sets/clears the CS pins, however, assuming it does so using a digital write, this operation on its own might take as much or more than the time needed for the data to be sent.
I strongly doubt that. Have you got any figures to back that up? The SD library has to read/write hundreds if not thousands of bytes to the SD card, a few microseconds setting chip select at the start won't make any difference.
#include <digitalWriteFast.h>
void setup ()
{
Serial.begin (115200);
Serial.println ();
} // end of setup
void loop ()
{
unsigned long start;
unsigned long finish;
const unsigned long iterations = 10000;
unsigned long counter;
start = micros ();
for (counter = 0; counter < iterations; counter++)
digitalWrite (10, HIGH);
finish = micros ();
Serial.print ("Using digitalWrite = ");
Serial.print (finish - start);
Serial.println (" uS");
start = micros ();
for (counter = 0; counter < iterations; counter++)
digitalWriteFast (10, HIGH);
finish = micros ();
Serial.print ("Using digitalWriteFast = ");
Serial.print (finish - start);
Serial.println (" uS");
while (true) {}
} // end of loop
Results:
Using digitalWrite = 54708 uS <-- i.e. 5.471 µS each
Using digitalWriteFast = 5784 uS <-- i.e. 0.579 µS each
So yep, you will save 5 µS by direct port manipulation. But compare that to how long it takes to access the SD card, open a file, write to it, and close it, and that will be virtually nothing.
Considering the speed boost I've seen in TFT's I have my doubts the speed increase is insignificant.
Take for example where a JPEG is read from the SD and forwarded to a SPI TFT. How many thousands of operations are required to select both devices, each one reading 1 byte at a time.
Good example timing digitalWritefast.
I timed direct port manipulation using the Atmel registers and that took 0.2uS per toggle, for a maximum output of 500Khz, so close enough
Well, I will have a look at this soon and post back the results.
The digitalWriteFast turns into port manipulation if it can (ie. if the port is a constant and not a variable).
As for the timings, surely you won't read a byte at a time from the SD card? If you are, there is your bottleneck. Read something like 512 bytes. And even the TFT device should be able to be selected once and then a whole lot of SPI sent to it.