Offline
Newbie
Karma: 0
Posts: 24
|
 |
« on: March 20, 2013, 02:46:19 pm » |
Coming from this thread on port manipulation: http://arduino.cc/forum/index.php/topic,129868.15.htmlI was able to put together the following sketch: void setup() { int k ; for( k = 44 ; k <= 51 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C12-C19 to output pins. Necessary or no data is written. for( k = 34 ; k <= 41 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C2-C9 to output pins // Set the output pins in the Output Write Enable Register REG_PIOC_OWER = 0x000FF3FC ; // Disable writing to all other pins on the same port REG_PIOC_OWDR = 0xFFF00C03 ; }
void loop() { int i ; // Writes data to pins 44-51 (PortC 12-19) for( i = 0 ; i <= 128 ; i++ ) REG_PIOC_ODSR = i << 12 ;
// Writes data to pins 34-41 (PortC 2-9) for( i = 0 ; i <= 128 ; i++ ) REG_PIOC_ODSR = i << 2 ; }
What I can't figure out, is how to write data to a specific 8 pins without modifying all of the other pins on the port. In the sketch above, the value 128 should remain present on PortC19 until I start writing to that block again, but what actually happens is it gets set to zero as soon as I start the next loop. I realize that I could OR the port with the new value but then if the pin was already high and I need to write a 0 to it it won't change. Has anyone been able to solve this problem?
|
|
|
|
|
Logged
|
|
|
|
|
The Netherlands
Offline
Jr. Member
Karma: 1
Posts: 63
MKDS hacker and Programmer
|
 |
« Reply #1 on: March 20, 2013, 02:50:12 pm » |
Coming from this thread on port manipulation: http://arduino.cc/forum/index.php/topic,129868.15.htmlI was able to put together the following sketch: void setup() { int k ; for( k = 44 ; k <= 51 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C12-C19 to output pins. Necessary or no data is written. for( k = 34 ; k <= 41 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C2-C9 to output pins // Set the output pins in the Output Write Enable Register REG_PIOC_OWER = 0x000FF3FC ; // Disable writing to all other pins on the same port REG_PIOC_OWDR = 0xFFF00C03 ; }
void loop() { int i ; // Writes data to pins 44-51 (PortC 12-19) for( i = 0 ; i <= 128 ; i++ ) REG_PIOC_ODSR = i << 12 ;
// Writes data to pins 34-41 (PortC 2-9) for( i = 0 ; i <= 128 ; i++ ) REG_PIOC_ODSR = i << 2 ; }
What I can't figure out, is how to write data to a specific 8 pins without modifying all of the other pins on the port. In the sketch above, the value 128 should remain present on PortC19 until I start writing to that block again, but what actually happens is it gets set to zero as soon as I start the next loop. I realize that I could OR the port with the new value but then if the pin was already high and I need to write a 0 to it it won't change. Has anyone been able to solve this problem? If you want to clear a bit, you can do it like this: REGISTER &= ~1<<bit;
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 24
|
 |
« Reply #2 on: March 20, 2013, 03:02:40 pm » |
If you want to clear a bit, you can do it like this: REGISTER &= ~1<<bit;
Thanks, I will remember that, but it doesnt quite solve the problem. I still need to be able to write all values synchronously. I suppose I could clear that block on the port and then OR it with the new value, but its an extra step that would need to be performed each time and I would like to avoid it.
|
|
|
|
|
Logged
|
|
|
|
|
The Netherlands
Offline
Jr. Member
Karma: 1
Posts: 63
MKDS hacker and Programmer
|
 |
« Reply #3 on: March 20, 2013, 03:07:24 pm » |
If you want to clear a bit, you can do it like this: REGISTER &= ~1<<bit;
Thanks, I will remember that, but it doesnt quite solve the problem. I still need to be able to write all values synchronously. I suppose I could clear that block on the port and then OR it with the new value, but its an extra step that would need to be performed each time and I would like to avoid it. I don't think that's possible. The registers are 32 bit. But if you don't use the remaining pins, you can just use REGISTER = 8bitvalue << firstbitnr;
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 24
|
 |
« Reply #4 on: March 20, 2013, 03:14:24 pm » |
REGISTER = 8bitvalue << firstbitnr;
Yea, that's what I was using before but the problem is that I do need to use the other pins on the port, and it's important that they stay at the same level while the data is being written.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Sr. Member
Karma: 23
Posts: 446
|
 |
« Reply #5 on: March 20, 2013, 03:22:07 pm » |
You're almost there - what you have to do is use REG_PIOC_OWER and REG_PIOC_OWDR to mask off which pins you want to alter before writing REG_PIOC_ODSR to change them - the other bits will stay as outputs and stay unchanged. REG_PIOC_OWER = 0x000003FC ; REG_PIOC_OWDR = 0x000FF000 ; lets you change 2-9 leaving 12-19 unchanged REG_PIOC_OWER = 0x000FF000 ; REG_PIOC_OWDR = 0x000003FC ; lets you change 12-19 leaving 2-9 unchanged
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25517
Solder is electric glue
|
 |
« Reply #6 on: March 21, 2013, 03:06:55 am » |
I suppose I could clear that block on the port and then OR it with the new value, but its an extra step that would need to be performed each time and I would like to avoid it. That is what you have to do in order to write any value you want. Mask AND to clear and OR to set.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 24
|
 |
« Reply #7 on: March 21, 2013, 09:39:53 am » |
Awesome! Got it working. Thanks a lot everyone.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 15
|
 |
« Reply #8 on: April 15, 2013, 07:44:52 pm » |
You're almost there - what you have to do is use REG_PIOC_OWER and REG_PIOC_OWDR to mask off which pins you want to alter before writing REG_PIOC_ODSR to change them - the other bits will stay as outputs and stay unchanged. REG_PIOC_OWER = 0x000003FC ; REG_PIOC_OWDR = 0x000FF000 ; lets you change 2-9 leaving 12-19 unchanged REG_PIOC_OWER = 0x000FF000 ; REG_PIOC_OWDR = 0x000003FC ; lets you change 12-19 leaving 2-9 unchanged
how can i do the same thing but instead of setting them as output, use them as input? I have tried this but it does not seem to work REG_PIOC_ODR = 0x3fc; REG_PIOC_PER = 0x3fc; int pixelData = REG_PIOC_PDSR >> 2;
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #9 on: April 16, 2013, 12:43:17 pm » |
for( k = 44 ; k <= 51 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C12-C19 to output pins. Necessary or no data is written. for( k = 34 ; k <= 41 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C2-C9 to output pins
Is there a list of which due pins correspond to which port registers?
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Full Member
Karma: 10
Posts: 181
|
 |
« Reply #10 on: April 16, 2013, 02:50:48 pm » |
for( k = 44 ; k <= 51 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C12-C19 to output pins. Necessary or no data is written. for( k = 34 ; k <= 41 ; k++ ) pinMode( k, OUTPUT ) ; // Sets Port C2-C9 to output pins
Is there a list of which due pins correspond to which port registers? May a little bit inconvenient but you can put it yourself together from the Pinout http://arduino.cc/forum/index.php/topic,132130.0.html
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 5
|
 |
« Reply #11 on: April 16, 2013, 05:52:54 pm » |
I was looking everywhere for that, and it was right there the whole time! I put it into a table for reference if it's useful to anyone. Due Pin Port Channel 0 A 8 1 A 9 2 B 25 3 C 28 4 C 26 5 C 25 6 C 24 7 C 23 8 C 22 9 C 21 10 C 29 11 D 7 12 D 8 13 B 27 14 D 4 15 D 5 16 A 13 17 A 12 18 A 11 19 A 10 20 A 12 21 A 13 22 B 26 23 A 14 24 A 15 25 D 0 26 D 1 27 D 2 28 D 3 29 D 6 30 D 9 31 A 7 32 D 10 33 C 1 34 C 2 35 C 3 36 C 4 37 C 5 38 C 6 39 C 7 40 C 8 41 C 9 42 A 19 43 A 20 44 C 19 45 C 18 46 C 17 47 C 16 48 C 15 49 C 14 50 C 13 51 C 12 52 B 21 53 B 14
|
|
|
|
|
Logged
|
|
|
|
|
|