Setting 2 pins at once
Philldapill
Posts: 1,283
I'm trying to set 2 different pins to 2 different states - at the same time. I'm using a VNH2sp30. It's a full H-bridge that takes 3 inputs. Two inputs are for the direction of each leg(highside or lowside on), and a PWM signal to turn the lowsides on/off. This is the same device used on the HB-25 from Parallax.
However, this question has nothing to do with the device itself. I am using the device as an H-bridge, with control over each leg. I'd like to be able to set each leg's input at the same time. To do this, I would have to set 2 pins on the Prop at once. I was thinking something along the lines of storing the outa register into a new variable, modifying that variable by selecting certain bits and setting them, then setting the outa register to the value of the variable.
The problem that I see to this approach, is the propellers ability to let ANY cog set the logic state of a pin. Since I'm doing this in spin, it takes a lot of clock cycles. While I have outa stored in my variable and I modify my variable, another cog could potentially set some other pins to different states, and my variable will not reflect the changes. When I set outa back to my variable, the pin changes will revert back to the original.
i.e., cog A is my cog I'm running with this synchronous pin change program. Cog B is some other cog messing with pins. Cog A makes a copy of outa. Cog B screws with some pins. Then, Cog A finishes it's logic and psuedo-pin-setting, and rewrites back to outa. The final result will appear that cog B didn't do anything as the other pins that Cog A didn't change, revert back to the original.
How can I do this synchronously without messing with other pins?
However, this question has nothing to do with the device itself. I am using the device as an H-bridge, with control over each leg. I'd like to be able to set each leg's input at the same time. To do this, I would have to set 2 pins on the Prop at once. I was thinking something along the lines of storing the outa register into a new variable, modifying that variable by selecting certain bits and setting them, then setting the outa register to the value of the variable.
The problem that I see to this approach, is the propellers ability to let ANY cog set the logic state of a pin. Since I'm doing this in spin, it takes a lot of clock cycles. While I have outa stored in my variable and I modify my variable, another cog could potentially set some other pins to different states, and my variable will not reflect the changes. When I set outa back to my variable, the pin changes will revert back to the original.
i.e., cog A is my cog I'm running with this synchronous pin change program. Cog B is some other cog messing with pins. Cog A makes a copy of outa. Cog B screws with some pins. Then, Cog A finishes it's logic and psuedo-pin-setting, and rewrites back to outa. The final result will appear that cog B didn't do anything as the other pins that Cog A didn't change, revert back to the original.
How can I do this synchronously without messing with other pins?
Comments
To set I/O pins 3 and 10 as outputs, you only have to do: DIRA |= |<10 | |<3
This makes a bitmask with a one in bit 10 (numbered from zero) and a one in bit 3 and zeroes elsewhere. Then it sets DIRA to the bit OR of its current content and the bitmask making those two pins (and any already set to one in this cog) outputs.
To change I/O pins 3 and 10 to inputs, you do: DIRA &= !(|<10 | |<3)
This makes a bitmask with a one in bit 10 and a one in bit 3, then inverts it so there are ones everywhere except bits 10 and 3. Then it sets DIRA to the bit AND of its current content and the inverted bitmask making those two pins inputs.
The same thing can be done with OUTA to make one or more pins high or low.
Set pins 3 and 7 to low, and high respectively.
Next, set pins 3 and 7 to low and low.
Then, set pins 3 and 7 to high and low.
Again, I want these pins to switch states on the same instruction. I was refering to a probelm arising(from my method), by other cogs changing the output state(high or low) of other pins, while the initial cog is grabbing "outa" and playing with the bits. For example, when cog A grabs outa, pin 20 is low. While cog A is bit shifting or whatever, cog B changes pin 20 to high. However, cog A's variable that outa was copied to, still reflects pin 20 as low. Once cog A finally gets around to setting all of outa to whatever it determined, it sets pin 20 low again, even though cog B set it high. Is that a little more clear? If not, please say so.
-Phil
In the red part the port pins are exclusively set/cleared by one COG. The green part shows the prot pins that reflect the result of an OR of the separate OUTA registers.
What you read in any operation COG1 is doing on OUTA afterwards, is still the 1100001101 it puts into its personal OUTA register.
COG2 will read 1010101011 whenever reading OUTA. Changing OUTA in one COG does not affect the OUTA of any other COG.
Your summary is correct.
-Phil