Go Down

Topic: Accelerator - How to deal with (Read 453 times) previous topic - next topic

alirazaviarduino

Aug 19, 2019, 09:50 am Last Edit: Aug 19, 2019, 10:02 am by alirazaviarduino
Hi

In conventional processors an microcontrollers, one can precisely determine the clock cycles required
to execute a piece of code.

I am using Arduino Due and want to read a high speed data, with the frequency of 14MHz, 10 bit parallel.

I write a code to simply read PIO_PDSR register and write it into an integer array, and increment the index, and continue. It is important that each read-write-increment takes exactly 6 clock cycles, but the accelerator speeds it up, which is not desired for me.

I get confused because I have not any control on the time of execution of the instructions. The accelerator dynamically changes the execution time.

Is it possible to somehow disable the accelerator feature, or Is there a special type of variables - or special way of coding - not affected by the accelerator?

My code (the important part)

Code: [Select]


REG_PIOD_SODR = PIO_SODR_P0; // Set PD.0

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;

MyArray[ArrayIndex] = REG_PIOC_PDSR;
ArrayIndex++;


REG_PIOD_CODR = PIO_CODR_P0; // Clear PD.0





Thanks.

alirazaviarduino

#1
Aug 19, 2019, 10:02 am Last Edit: Aug 19, 2019, 12:42 pm by alirazaviarduino
I copied two instructions 10 times to make a measurable time between PD.0 set and clear moments.
In addition, placing the instructions in a loop (executed 10 times) takes very higher clock cycles, because it involves a jump + comparison in each execution of the loop.

I test various methods (Interrupt, Polling, Direct checking of PIO_ISR register) and none of them are able to capture the 14MHz incoming data. The only way I think may solve my problem is reading PIO_PDSR register, writing it into an array, and incrementing the index.

westfw

You can copy code into RAM and run it from there.  That should make it both faster (no wait states) and more deterministic.  Except perhaps data access and instruction access might collide...

Then there is DMA...


ard_newbie


Theoretically with a SAM3 or SAM4 when you choose to use an AHB DMA to copy PIO_PDSR into an SRAM array, you can't specify any frequency unless you have a SAMS7 uc. If the targeted frequency is 14 MHz, this is no more than 6 clock cycles to copy PIO_PDSR into an SRAM address: I don't know if this is reallistic target.

Try first the DMA code I provided in a previous thread to copy PIO_PDSR and test the highest frequency achievable.

There may be a workaround to specify a frequency to copy PIO_PDSR with an AHB DMA, but IMO this is a bit tricky....

alirazaviarduino

Exactly as you said, I have 6 clock cycles for both edge detection and reading PIO_PDSR and then writing it into an array.

It seems I have to put a time to study and learn DMA...

Thanks westfw and ard_newbie.

alirazaviarduino

#5
Aug 21, 2019, 08:30 am Last Edit: Aug 21, 2019, 08:31 am by alirazaviarduino
You can copy code into RAM and run it from there.  That should make it both faster (no wait states) and more deterministic.  Except perhaps data access and instruction access might collide...

Then there is DMA...


Thanks.

I dont know how to copy my code into RAM and run it from there. Can you provide me some information or a thread about it?

alirazaviarduino

Is this the related thread?

https://forum.arduino.cc/index.php?topic=425962.0

westfw

It looks like the infrastructure will do the 'copy into RAM' for you, and you just need to declare your function like:
Code: [Select]
__attribute__ ((section(".ramfunc"))) int MyRAMFunction(int x) {
  // blah blah blah
}


And then you can just call the function normally:
Quote
z = MyRAMFunction(1234);
The (generated) code for getting into the function looks a bit funky for reasons that aren't immediately obvious, but that shouldn't matter...


Go Up