PDA

View Full Version : Trying to shift bits



Chuck Minton
11-21-2010, 05:27 PM
I am missing something here. I am trying to understand how to shift information in a table.
the data reads out... it just won't shift.

appreciate the help.
/Chuck

kwinn
11-21-2010, 05:51 PM
Chuck, you should include the objects along with your code as an archive so we have everything needed to test your program.

At a guess, it seems like you are expecting the "TEST1:= TEST1 >> 8" statement to shift the entire byte array and it is only shifting the data in the first byte. Put a character in the first byte and see if it ends up as 0 to verify this.

MagIO2
11-21-2010, 06:28 PM
As Kwinn already said, it looks like you missunderstood the shift instruction. The shift instruction only works at maximum on one native memory location which for a 32 bit processor is a long.

Maybe you should better tell us what the goal of your program is, what data does it read ...

test1[ 4 ] looks strange as well because the 4th byte of a long has the index 3.

For reading 10 bytes into a buffer you could also use an index-variable and increase or decrease it - depending on the direction you want to use for writing:

idx := 0
repeat 10
test1[ idx++ ] := DISPLAY.WAITBYTE

or

idx := 9
repeat 10
test1[ idx-- ] := DISPLAY.WAITBYTE

Chuck Minton
11-21-2010, 06:49 PM
Chuck, you should include the objects along with your code as an archive so we have everything needed to test your program.

At a guess, it seems like you are expecting the "TEST1:= TEST1 >> 8" statement to shift the entire byte array and it is only shifting the data in the first byte. Put a character in the first byte and see if it ends up as 0 to verify this.

Hi Kwinn,
I did not post all the files 'cause it is a lot and I am not a very eloquent : Just trying to get to the core of my problem. ( I tried your suggestion of putting a value in the table: I put $FF into TEST1[1]. The data you see here in TEST1[4] is being read from a input sending a packet. In the past I have done what I call "Back Stacking" where:
t[5]=t[4]
t[4]:=t[3]
t[3]:=t[2]
t[2]:=t[1].......
this builds data bytes into words or longs.
I am trying to learn how to use tables or arrays instead of the long drawn out method I use now.
You can see the $FF I put into the DAT : TEST[1] AND the read byte at TEST[4].
Here is the data I get at PST: MY COMMENTS TO RIGHT.

THE problem is I don't see a shift. (I also tried it as a VARIABLE TEST[10], with same result.

0 255 0 0 128 0 0 0 0 0 ' FIRST TIME THROUGH : BYTE PLACED AT TEST[4]
0 255 0 0 1 0 0 0 0 0 'SECOND READ: I EXPECT 128 TO SHIFT LEFT AND 1 @ TEST[4]
0 255 0 0 5 0 0 0 0 0
0 255 0 0 85 0 0 0 0 0
0 255 0 0 132 0 0 0 0 0


HERE IS TXT VERSION OF CODE : WITH SOME COMMENTS
REPEAT
REPEAT 10

TEST1[4]:=DISPLAY.WAITBYTE 'READ IN BYTE OF PACKET DATA FROM DISPLAY
REPEAT W FROM 0 TO 9 ' LOOP THROUGH THE TEST[W] ARRAY
DEBUG.DEC(TEST1[W]) ' SEND BYTE OF ARRAY TEST[W] TO DISPLAY
DEBUG.CHAR(32) ' INSERT A SPACE
DEBUG.CHAR(13) ' CR TO DISPLAY

TEST1:= TEST1 >> 8 ' THIS IS WHERE I AM TRYING TO SHIFT DATA

DEBUG.CHAR(13) ' CR TO DISPLAY , THEN GET NEXT BYTE OF PACKET

I can include extra progs if you really need.

thanks
Chuck

Chuck Minton
11-21-2010, 06:55 PM
As Kwinn already said, it looks like you missunderstood the shift instruction. The shift instruction only works at maximum on one native memory location which for a 32 bit processor is a long.

Maybe you should better tell us what the goal of your program is, what data does it read ...

test1[ 4 ] looks strange as well because the 4th byte of a long has the index 3.

For reading 10 bytes into a buffer you could also use an index-variable and increase or decrease it - depending on the direction you want to use for writing:

idx := 0
repeat 10
test1[ idx++ ] := DISPLAY.WAITBYTE

or

idx := 9
repeat 10
test1[ idx-- ] := DISPLAY.WAITBYTE

I will try this.
I think you are right. I thought you could stack up a row of data and then shift the entire stack!
So , what you are saying is , if I wrote bytes into a long, then I could shift them to the extent of the long, but I can not shift bits of bytes stacked up against one-another???

kwinn
11-21-2010, 07:24 PM
I will try this.
So , what you are saying is , if I wrote bytes into a long, then I could shift them to the extent of the long, but I can not shift bits of bytes stacked up against one-another???
Yes, this is correct. The spin program is interpreted by a PASM program running in a cog. When you specify a variable as a byte or an array of bytes the shift instruction operates only on the byte specified.

For instance:

TEST1[1] := 255
TEST1[1] := TEST1[1] >> 1 ' TEST1[1] is now 127

Only the eight bits in the byte at TEST1[1] are shifted right one position. A 0 bit is shifted in to the msb and the lsb is dropped.

Specifying a shift for an entire array is not valid.

Duane Degn
11-22-2010, 04:06 PM
Chuck Minton,

You can shift sections of memory (bytes in this case) using bytemove.

bytemove(@test1, @test1 + 1, 9)

will move nine bytes starting at the second element in the array down one byte so they start at the first element.

I just tested to make sure you can move bytes on to the same section of memory you are moving them from.

Duane

MagIO2
11-22-2010, 05:51 PM
Right, using bytemove would do the job, but adding or subtracting 1 ten times from an index-variable and write the byte to the place it belongs to should be faster than moving the buffer 10 times.

pgbpsu
11-22-2010, 08:06 PM
If Chuck Minton is trying to do "Back Stacking" as he indicated in the earlier post, why not move a large chunk of memory all at once, as Degn suggests with a single bytemove command? That would only leave the first or last element (depending on which direction things are moved) to be filled. That should be significantly faster than doing so in a repeat loop, shouldn't it?

bytemove(@test1, @test1 + 1, 9)
test1[9] := newValue

MagIO2
11-22-2010, 09:03 PM
I dont remember for sure, but isn't it bytemove (source, destination...)?
If so you would not want to read into the last byte but into the first.
Anyway, the original post looks like he wants to shift in the other direction.

But still moving pointers is more clever than moving memory-blocks.

pgbpsu
11-23-2010, 12:39 AM
bytemove is (DestAddress, SrcAddress, Count)

I may be reading his post incorrectly, but it looks to me like he wants to move things in his array "down":


t[5]=t[4]
t[4]:=t[3]
t[3]:=t[2]
t[2]:=t[1].......


Rather than loop he can simply move things down:



bytemove(@test[1],@test,length-1)
test[0] := newValue


If that's the wrong direction he can move things "up" by doing:


bytemove(@test,@test[1],length-1)
test[length-1]:= newValue


That should work shouldn't it?

I guess it depends on what he's trying to do. I don't think pointers is what his original post were about. They may be faster, but this seems pretty straight forward.

Duane Degn
11-23-2010, 03:39 AM
pgbpsu,

Now that I reread the original post, I think your first example if correct. I had the buffer moving the wrong direction.

When I needed to shift a buffer like this I had new data going in towards the end of the buffer and old data taken off the beginning. I finally took someone on this forum's advice (I think it was Phil) and learned how to use a circular buffer. I'm glad I took the time to figure out how to make a circular buffer because it has greatly streamlined my code.

I still think it's pretty cool that the bytemove command lets you read and write to the same section of memory at once. I originally thought I'd have to move the data to a second location and then move it back to original location in it new shifted position.

I've been learning PASM lately and really miss all the shortcuts Spin allows.

Duane

pgbpsu
11-23-2010, 02:48 PM
Deng-

I agree with MagIO that pointers are probably fastest. However I think conceptually this is a bit simpler. Once Chuck gets this working and he wants speed he probably should move to a circular buffer. Although, that decision probably depends a bit on what his program's overall purpose is.

Learning circular buffers is very worthwhile. I just think doing things the most straight-forward way has benefits as well, especially when one is just learning how things work.

Using the bytemove was your suggestion and a good one at that. I agree that PASM makes most thing easier than ASM, but it's also worth learning. I'm working on that myself.

Cheers

Chuck Minton
11-23-2010, 09:58 PM
WOW! THAHKS FOR ALL THE INPUT FOLKS!
I will need a little direction and clairification on the concept of a circular buffer in the future, however, for the moment, as Kwinn clairified for me, I can shift the bits within a long: It works great and I am able to set pins when I see certain serial sequences pass through... That was my goal.

Now I have a second problem. I originally was using ParallaxSerialTerminal. Because I was out of cogs, forum suggestions pointed to the PCFullDuplexSerial4FC. I got that going, but now I don't get proper reading from my serial sorces but It sees to transmit well. Most of the time I get the first byte of a long right, then the second and third byte seems to be usually wrong, and the forth byte is always right. I am thinking there must be a timing issue ... why else would PST read right all the time.
The good part is if I can figure this out, I will be more or less to the completion point of my project... getting so close!
I tried swithching baud from 115200 to 19200 ( my only options)... That was worse ... could write but would not read it at all.
So, If any one is up on PCFullDuplexSerial4FC, and what may be causing this how I could tweek it I would appreciate it a whole lot.

Thanks , also like conceptual info on circular buffer and what that means.
Chuck