Offline
Sr. Member
Karma: 23
Posts: 446
|
 |
« Reply #15 on: November 02, 2012, 06:55:05 am » |
The other way of doing direct port manipulation looks like this: PIOx->register=value; long r = PIOx->register; where x is A,B,C or D and register is as in the data sheet For example: PIOB->PIO_SODR=1<<27; //lights the LED PIOB->PIO_CODR=1<<27; //clears it boolean p12=!!(PIOD->PIO_PDSR & (1<<8)); //read pin 12
I had a go at writing some digitalReadDirect/digitalWriteDirect functions but you might want to give them some more thorough testing as I only checked if it worked with the LED  inline void digitalWriteDirect(int pin, boolean val){ if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin; else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin; }
inline int digitalReadDirect(int pin){ return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin); }
void setup() { pinMode(13, OUTPUT); pinMode(12, INPUT); Serial.begin(9600); }
void loop() { digitalWriteDirect(13, HIGH); delay(1000); digitalWriteDirect(13, LOW); delay(1000); Serial.println(digitalReadDirect(12)); }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 1
Posts: 83
Arduino rocks
|
 |
« Reply #16 on: November 02, 2012, 07:27:19 am » |
Hummm, you're using the"."!
g_APinDescription[pin].pPort
but it doesn't work if I put the dot in this line anyway:
#define digitalPinToPort(P) ( g_APinDescription[P]->pPort )
I'll test your code later, maybe I can implement it directly in lib.
Thank you
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5454
Strongly opinionated, but not official!
|
 |
« Reply #17 on: November 02, 2012, 12:32:01 pm » |
Now I'm stuck in the control pins of the TFT. Can't you just use digitalWrite() for the control pins, as a first effort?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 20
|
 |
« Reply #18 on: November 02, 2012, 02:10:48 pm » |
The other way of doing direct port manipulation looks like this: PIOx->register=value; long r = PIOx->register; where x is A,B,C or D and register is as in the data sheet For example: PIOB->PIO_SODR=1<<27; //lights the LED PIOB->PIO_CODR=1<<27; //clears it boolean p12=!!(PIOD->PIO_PDSR & (1<<8)); //read pin 12
I had a go at writing some digitalReadDirect/digitalWriteDirect functions but you might want to give them some more thorough testing as I only checked if it worked with the LED  inline void digitalWriteDirect(int pin, boolean val){ if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin; else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin; }
inline int digitalReadDirect(int pin){ return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin); }
void setup() { pinMode(13, OUTPUT); pinMode(12, INPUT); Serial.begin(9600); }
void loop() { digitalWriteDirect(13, HIGH); delay(1000); digitalWriteDirect(13, LOW); delay(1000); Serial.println(digitalReadDirect(12)); }
your code is working pretty well man, thank you a lot... i gained about almost 40% speed in my parallel flash memory writer 
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 1
Posts: 83
Arduino rocks
|
 |
« Reply #19 on: November 02, 2012, 02:24:24 pm » |
Now I'm stuck in the control pins of the TFT. Can't you just use digitalWrite() for the control pins, as a first effort? Yes, I'll try that also. Regards, Joao
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #20 on: November 02, 2012, 03:11:41 pm » |
Hello! tested reading ports A, B and C syncronously and port reading works OK, but then tried syncronous writing with REG_PIOx_ODSR command did not succeed , although bitwise setting with REG_PIOx_SODR and clearing with REG_PIOx_CODR works OK, I might have something wrong although tried also setting first REG_PIOx_OWER mask bit for those bits I wanted to write syncronously , another test result still: enabled output to several bits with pinmode (xx, OUTPUT) commands but still the REG_PIOx_ODSR does not write to the PIO port , so as a summary so far: input port reading (bytes , words , double words) reading works OK but output does not work (yet  testing continues ....
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 20
|
 |
« Reply #21 on: November 02, 2012, 03:22:48 pm » |
can someone write down the clear way how to manipulate different pins at the same time? i'm quite confused! :S
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #22 on: November 02, 2012, 03:42:44 pm » |
the reading is easy:
eg.
unsigned long int input_data = REG_PIOC_PDSR;
reads the C -port (32 bit wide) and all the bits simultaneously to input_data variable and fast , and I've tested A, B, C and D ports by changing bit states ((work ok with Arduino Due),
but then encountered problems when tried writing in the same way with command eg.
REG_PIOC_ODSR = 0xFF;
which should change all bits 0-15 simultanously to 1, look at my post earlier today, where test results are reported,
BR, Seppo
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 23
Posts: 446
|
 |
« Reply #23 on: November 02, 2012, 03:45:16 pm » |
REG_PIOC_ODSR = 0xFF;
which should change all bits 0-15 simultanously to 1, look at my post earlier today, where test results are reported,
BR, Seppo
No, that will only set bits 0-7 to 1 (0xFF is 11111111 in binary).
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 11
|
 |
« Reply #24 on: November 03, 2012, 03:55:21 am » |
yes , of course 8 bits ,
and it is possible to write simultaneously words and double words (32 bits) but not all the pins of PIO - ports are connected to Due I/O ,
Seppo
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Jr. Member
Karma: 1
Posts: 83
Arduino rocks
|
 |
« Reply #25 on: November 03, 2012, 02:45:30 pm » |
inline void digitalWriteDirect(int pin, boolean val){ if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin; else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin; }
inline int digitalReadDirect(int pin){ return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin); }
Hi. Ok, I've managed to put library working with your functions, Thank you! But it's still very slow running DEMO compared to Chipkit. I know that in chipkit, the entire byte is written to port at once and in due I'm writing bit by bit, but I'm not sure that this is enough for a huge difference in run time for demo. In chipkit it takes around 24s, I'm getting with due 44s. Is there a way to use ODSR in this functions? Can I write to ODSR bit by bit? From datasheet, ODSR should be used for synchronous transfer. I'm thinking, maybe using ODSR i might get bet speed. I was trying to do this without success: //DB00 on PIN37 -> PIO_PC5 REG_PIOC_ODSR=((VL&0x01)<<5) & 0x20; //DB01 on PIN36 -> PIO_PC4 REG_PIOC_ODSR=(VL<<3) & 0x10; //DB02 on PIN35 -> PIO_PC3 REG_PIOC_ODSR=(VL<<1) & 0x08; //DB03 on PIN34 -> PIO_PC2 REG_PIOC_ODSR=(VL>>1) & 0x04; //DB04 on PIN33 -> PIO_PC1 REG_PIOC_ODSR=(VL>>3) & 0x02; //DB05 on PIN32 -> PIO_PD10 REG_PIOD_ODSR=(VL<<5) & 0x400; //DB06 on PIN31 -> PIO_PA7 REG_PIOA_ODSR=(VL<<1) & 0x80; //DB07 on PIN30 -> PIO_PD9 REG_PIOD_ODSR=(VL<<2) & 0x200; //DB08 on PIN22 -> PIO_PB26 REG_PIOB_ODSR=(VH<<26) & 0x4000000; //DB09 on PIN23 -> PIO_PA14 REG_PIOA_ODSR=(VH<<13) & 0x4000; //DB10 on PIN24 -> PIO_PA15 REG_PIOA_ODSR=(VH<<13) & 0x8000; //DB11 on PIN25 -> PIO_PD0 REG_PIOD_ODSR=(VH>>3) & 0x01; //DB12 on PIN26 -> PIO_PD1 REG_PIOD_ODSR=(VH>>3) & 0x02; //DB13 on PIN27 -> PIO_PD2 REG_PIOD_ODSR=(VH>>3) & 0x04; //DB14 on PIN28 -> PIO_PD3 REG_PIOD_ODSR=(VH>>3) & 0x08; //DB15 on PIN29 -> PIO_PD6 REG_PIOD_ODSR=(VH>>1) & 0x40;
The working code is: //DB00 on PIN37 -> PIO_PC5 digitalWriteDirect(37,(VL & 0x01)); //DB01 on PIN36 -> PIO_PC4 digitalWriteDirect(36,(VL & 0x02)); //DB02 on PIN35 -> PIO_PC3 digitalWriteDirect(35,(VL & 0x04)); //DB03 on PIN34 -> PIO_PC2 digitalWriteDirect(34,(VL & 0x08)); //DB04 on PIN33 -> PIO_PC1 digitalWriteDirect(33,(VL & 0x10)); //DB05 on PIN32 -> PIO_PD10 digitalWriteDirect(32,(VL & 0x20)); //DB06 on PIN31 -> PIO_PA7 digitalWriteDirect(31,(VL & 0x40)); //DB07 on PIN30 -> PIO_PD9 digitalWriteDirect(30,(VL & 0x80)); //DB08 on PIN22 -> PIO_PB26 digitalWriteDirect(22,(VH & 0x01)); //DB09 on PIN23 -> PIO_PA14 digitalWriteDirect(23,(VH & 0x02)); //DB10 on PIN24 -> PIO_PA15 digitalWriteDirect(24,(VH & 0x04)); //DB11 on PIN25 -> PIO_PD0 digitalWriteDirect(25,(VH & 0x08)); //DB12 on PIN26 -> PIO_PD1 digitalWriteDirect(26,(VH & 0x10)); //DB13 on PIN27 -> PIO_PD2 digitalWriteDirect(27,(VH & 0x20)); //DB14 on PIN28 -> PIO_PD3 digitalWriteDirect(28,(VH & 0x40)); //DB15 on PIN29 -> PIO_PD6 digitalWriteDirect(29,(VH & 0x80));
|
|
|
|
« Last Edit: November 03, 2012, 03:04:18 pm by alvesjc »
|
Logged
|
|
|
|
|
Samplefinger
Offline
God Member
Karma: 8
Posts: 822
ALWAYS ASK FOR THREE. One to use. One to lose. One to abuse.
|
 |
« Reply #26 on: November 23, 2012, 11:00:21 pm » |
I had a go at writing some digitalReadDirect/digitalWriteDirect functions but you might want to give them some more thorough testing as I only checked if it worked with the LED  inline void digitalWriteDirect(int pin, boolean val){ if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin; else g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin; }
inline int digitalReadDirect(int pin){ return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin); }
They seem to work fine. I just used it for my first sketch for my Due, a comparison of port switching and square wave generation using DigitalWrite vs. direct writing using your inline function. Big difference, this is what it looks like on my scope (it overshoots the square because I have a long lead which I corrected for the second measurement):   The waves are a whole lot squarer when running at 1% of the maximum speed.  Sorry for the bad smartphone pics, I haven't figured out how to properly screen capture on the scope yet and I can't open the manual right now because Adobe Acrobat is having a weird fit.
|
|
|
|
« Last Edit: November 24, 2012, 02:12:14 am by JoeN »
|
Logged
|
Latest Sampling Scores: ATXMEGA64A3U-MH x3, ATXMEGA256A3U-MH x3, SST38VF6404-90-5C-EKE x3, SST38VF6402-90-5C-EKE x3, PGA870 x3, THS770006 x3
|
|
|
|
0
Offline
Newbie
Karma: 1
Posts: 10
Arduino rocks
|
 |
« Reply #27 on: December 31, 2012, 07:27:32 pm » |
To use REG_PIOD_ODSR use must first enable the bits with REG_PIOD_OWER (the output write enable). For instance:
void setup() { pinMode(12, OUTPUT); pinMode(14, OUTPUT); pinMode(15, OUTPUT); REG_PIOD_OWER = 0xFFFF; }
void loop() { REG_PIOD_ODSR = 0x0130; REG_PIOD_ODSR = 0x0000; REG_PIOD_ODSR = 0x0130; } Will produce a ~23ns low going pulse on pin 12, 14 and 15. For some reason you need to set the pinModes to make this work.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 1
Posts: 10
Arduino rocks
|
 |
« Reply #28 on: December 31, 2012, 08:10:07 pm » |
I don't know if any one has posted on this yet, fastest update rate for a DAC(?). Here is some code:
int j = 0, topcount = 5;
void setup() { // this is a cheat - enable the DAC analogWrite(DAC0,0); }
void loop() { // write directly dacc_write_conversion_data(DACC_INTERFACE, 0x0000); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0400); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0800); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0C00); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0FFF); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0C00); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0800); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0400); for (j = 0;j < topcount;j++); // delayMicroseconds(1); dacc_write_conversion_data(DACC_INTERFACE, 0x0000); for (j = 0;j < topcount;j++);
}
This code produces a triangular four steps up, four steps down ramp that goes from about 480mV to 2.32V. Each step is about 680ns wide. The waveform becomes unstable below topcount = 5. Is this the fastest DAC step rate?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #29 on: April 15, 2013, 08:10:30 pm » |
the reading is easy:
eg.
unsigned long int input_data = REG_PIOC_PDSR;
reads the C -port (32 bit wide) and all the bits simultaneously to input_data variable and fast , and I've tested A, B, C and D ports by changing bit states ((work ok with Arduino Due),
but then encountered problems when tried writing in the same way with command eg.
REG_PIOC_ODSR = 0xFF;
which should change all bits 0-15 simultanously to 1, look at my post earlier today, where test results are reported,
BR, Seppo
How did you read port C? I tried this but it does not work: REG_PIOC_ODR = 0x3fc; REG_PIOC_PER = 0x3fc; int pixelData = REG_PIOC_PDSR >> 2;
|
|
|
|
|
Logged
|
|
|
|
|
|