What are masks and how do they work?
SciNemo
Posts: 91
I am working on a project that involves a row of 8 led's. I've found this nifty chunk of pasm called "Mother of all LED Sequencers" that should do what I want. The only problem is this:
I know that the hex is called a mask, and I thought I knew how they worked, but it seems I do not. I tried this:
..because I want it to use pins 4 through 11, but it does not work. Is my understanding of masks correct? Aren't they just like a row of switches that show which ports to turn on or off (in this case at least)?
So how do I change the hex to make it use pins 4 through 11, and why doesn't my modified code work?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Not the fish.
sites.google.com/site/bitwinproject/
ledmask long $00FF0000 ' 8 LED's at I/O pins 16 to 23 for the demo board
I know that the hex is called a mask, and I thought I knew how they worked, but it seems I do not. I tried this:
ledmask long %00000000000000000000111111110000
..because I want it to use pins 4 through 11, but it does not work. Is my understanding of masks correct? Aren't they just like a row of switches that show which ports to turn on or off (in this case at least)?
So how do I change the hex to make it use pins 4 through 11, and why doesn't my modified code work?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Not the fish.
sites.google.com/site/bitwinproject/
Comments
The term "mask" has different uses. In this case, you have a 32-bit word where each of the bits has a particular meaning (an I/O pin number). You have a constant "ledmask" where there are bits set to 1 where an I/O pin is used by the program. Typically, this mask is copied to the data direction register or sometimes used for the data output register value.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Not the fish.
sites.google.com/site/bitwinproject/
Update: Fixed it, although i am not really sure how. This part is changed:
And:
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Not the fish.
sites.google.com/site/bitwinproject/
Post Edited (SciNemo) : 10/12/2009 11:31:29 PM GMT
I know how to turn pins on and off. But not how to prevent other pins changing - eg you don't want the vga display going haywire when another pin changes.
Could some kind soul explain (and it may only be a couple of lines of pasm code) how to:
1) set a mask so only pin 1 ever changes when outputting a 32 bit long.
2) turn pin 1 high
3) turn pin 1 low
and then, just to make it explicitly clear, set a new mask that
4) only allows pin 2 to change
5) turns pin 2 high
6) turns pin 2 low
I think I am close to understanding this. Presumably there is something like a logical 'and' with xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0 to set pin 1 low and a logical 'or' with xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1 to set that pin high. What I'm not 100% clear about is whether 'x' matters if you have already set a mask earlier?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
So for what you ask, you'd do something like...
Then, to manipulate bit 2 instead, you'd just change the #1's to #2's (or move them to a mask long that can be changed).
Post Edited (localroger) : 10/12/2009 11:57:07 PM GMT
- 8 contiguous LEDs
- LED block is located at pin 16..23
Point one gives us the mask which is 0xFF (i.e. 8 (contiguous) bits set), point two the bit offset in a long and therefore the final mask value 0xFF << 16 = 0x00FF0000. The data you sent to outa is only loosely related to the mask set in dira. But if you want to see something on your output pins then it should uses the same bit locations [noparse]:)[/noparse] So the 8bit LED data has to be shifted by 16 too (there is no point sending the LED pattern to bits 0..7 in outa, they are set as inputs so it wouldn't have any effect) . If you look at the data table this becomes obvious (0x00--0000).Back to your requirements. You have your LEDs connected to pins 4..11. Therefore the mask for those 8 output pins is 0xFF << 4 = 0x00000FF0. The existing data is pre-shifted by 16. As you need them only shifted by 4 you have to undo the shl #16 and then apply a shl #4. The undo is a shr #16. Combined with your required shl #4 that becomes shr #12.
The shr #8 I mentioned before was to match your mask (0x0000FF00). So for LEDs connected to 4..11 that would (obviously) only light up 4 of them (0x0000FF00 defines pins 8..15 as outputs which only covers pin 8..11 of your requirement).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
http://forums.parallax.com/showthread.php?p=601870
(its under "Assembly Code Examples for the beginner - Many contributors" in the getting started sticky)
James
Since last post, some boards I designed have arrived and I'm happily testing things. Got text on a vga screen from a keyboard. But I still don't understand it all. I keep thinking in 8 bit and with instructions like 'rotate' that rotate just one place per instruction. I'm still not used to rotating a variable number of places in one instruction.
But I worked out how instructions work that mask a certain pin. Nothing new for veterans, but I think it is cunning. You set a variable equal to the pin number, eg 14 (decimal). In a binary long that is 00000000000000000000000000001110. You then convert that to a mask with just two machine code instructions:
Ok, 4 instructions really as I think mymask needs some space reserved and pinnumber needs to be set to 14. Still getting my head around setting variables at the end of a program rather than the beginning.
But it is cunning nevertheless as it replaces multiple instructions in a loop in 8 bit assembly with a rotate left by n.
I *think* I understand the next bit. My understanding from the documentation is that you can set the status of a bit and mask it all with one instruction. I thought I understood that. But now I don't.
Ok, I'm looking at the code in the standard keyboard.spin object. There is this line:
But how does that pull a line low?
Ok, earlier I think it set cmask as something like 0000001000000 ie one bit set high. (not 100% sure though) But if you OR that, isn't that setting the bit high, not low. The xor bit under this makes sense as that flips the bit, but I don't understand how an OR pulls a pin low. There is something I don't understand here as I would have thought that definitely setting a pin high would be an OR with 1 (and definitely setting it low is an AND with 0).
Even though I am very confused, I think I am working out enough to write some raw pasm now rather than just do the script kiddie thing.
Help with the above would be most appreciated.
Addit: Hmm - is this right? or dira,mymask sets the mask of that pin only (that is the OR) bit. But it also defaults to setting the pin low to start with? Is that right? Then you xor it to make it high?
This is theoretical as I can't seem to be able to put assembly instructions in the PUB main. I take it you can't do that.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
Post Edited (Dr_Acula) : 10/13/2009 12:07:32 PM GMT
I'm working with spin at the moment sending pins high and low. All working very nicely. Lots of pauses to test things and the logic probe is getting a workout. Down the track I'll translate to pasm. One cool thing I have found is that HCT logic works fine at 3V. I knew HC did, but I wasn't sure about HCT.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build
The andn instruction (which has been around in Parallax languages since the BASIC Stamp 1) is really useful -- it allows us to use one mask for setting (with or) and clearing (andn) desired bits.