Go Down

Topic: Synchronous Port Manipulation on Due (Read 4046 times) previous topic - next topic

jiblets

Coming from this thread on port manipulation:

http://arduino.cc/forum/index.php/topic,129868.15.html

I was able to put together the following sketch:

Code: [Select]

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?

Gericom


Coming from this thread on port manipulation:

http://arduino.cc/forum/index.php/topic,129868.15.html

I was able to put together the following sketch:

Code: [Select]

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:
Code: [Select]

REGISTER &= ~1<<bit;
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

jiblets


If you want to clear a bit, you can do it like this:
Code: [Select]

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.

Gericom



If you want to clear a bit, you can do it like this:
Code: [Select]

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
Code: [Select]

REGISTER = 8bitvalue << firstbitnr;
Subscribe my youtube channel: http://www.youtube.com/user/MKDS3

jiblets


Code: [Select]

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.

stimmer

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
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

Grumpy_Mike

Quote
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.

jiblets

Awesome! Got it working. Thanks a lot everyone.

dishimwe


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
Code: [Select]

    REG_PIOC_ODR = 0x3fc;
    REG_PIOC_PER = 0x3fc;
    int pixelData = REG_PIOC_PDSR >> 2;

ssclark88



Code: [Select]


    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?

Markus_L811




Code: [Select]


    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

ssclark88

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.

Code: [Select]

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



Go Up