I am an arduino newbie so know nothing and am hoping begging for some advice will help me get kick started.....
Basically I have not done anything yet as I want to be sure it is possible before starting coding .
I worry I will look stupid as I maybe ask the impossible or should have done some research first, I show below my pseudocode/thoughts/ideas/system description, but will ask my questions first...
-
How can I setup dma on arduino to handle SPI (does arduino even have dma for SPI as slave??) i have seen this http://arduino.cc/forum/index.php?PHPSESSID=3224079b565191d380db0d82da085c82&topic=147858.0, but no mention of dma..
-
How fast can arduino handle dma and interupts and what are speed considerations?, i.e. what is the shortest usleep in the main loop that can guarantee a constant step rate?
-
Is there any example code of similar projects available?
System definition:
Arduino as SPI slave that works as a digital IO interface (basically constant step rate switching gpio pins dependent on SPI data)
- The arduino must take SPI packets of data (64 bytes I guess) as fast as possible
- store SPI data in memory
- constantly step through memory and switching IO pins
- flag SPI master if it runs out of data
- (possibly in future add some code for config the arduino via SPI e.g change step rate, number of io pins being switched etc..)
I am guessing what I need to do is
allocate 3 64 byte buffers
setup arduino dma to write SPI data to buffers (double buffering)
create interupt to rotate through the buffer when SPI dma completes
write the data output loop
I am assuming arduino has dma for SPI and it can be setup for 64 byte packets, I have not found any information about SPI dma yet??????
outline pseudo code below :
current_buffer = 0; // pointer indexing where we are for comparison purposes
dma_buffer = 0; // pointer to where SPI data is buffered by dma
out_buffer = -1; // pointer to buffer currently being read to output pins
setup_dma(); // function, how do we setup dma to copy 64 bytes from SPI to a memory buffer?????
// I imagine interupt routine should be similar to below:
interupt_service_routine()
{
// update circular buffer index
If (current_buffer == 3) current_buffer = 0 ;
else current_buffer = current_buffer + 1 ;
if(current_buffer==out_buffer) halt_spi_master(); // stop if we are going to over write the current output
if(current_buffer==3 & out_buffer==-1 ){ main_loop(); current_buffer=0; } // start the main loop once 3 buffers full
dma_buffer = current_buffer;
}
// I imagine the output loop should be similar to that below:
out_buffer=0;
main_loop()
{
DDRB = b11111111 ; // set portB output direction
for(;
{
PORTB= out_buffer[index]
index++;
usleep(step_time);
if(index==64) {
index=0;
If (out_buffer == 3) out_buffer = 0 ;
else out_buffer = out_buffer + 1 ;
if(out_buffer==dma_buffer) halt_master_flag_underrun();
}
}