[Tutor] [spoiler] Re: Shifting arrays as though they are a 'word'

Chip Wachob wachobc at gmail.com
Tue Oct 9 09:21:31 EDT 2018

I'm sorry that my explanations are obtuse...

Hopefully this will clarify things.  Again, not knowing how much
information is too much...  I know I can be too verbose and that's not
always a good thing.

I have a bank of registers that I read via SPI.   The SPI API is from
the IC manufacturer.

The maximum size of that bank is 512 bits.  Or, 64 bytes.

The register bank can be any valid integer between 1 and 512 long and
changes each time the program is run.  There is nothing that limits it
to byte-sized counts.

To determine the size of the bank, I can saturate the register with
ones, followed by a stream of 0x00's.  When I see the reads from the
bank come back as something other than 0xFF, then I know I've 'pushed'
zeros through the entire length of the registers.  I keep a running
count of bytes that contain 0xFF when I do this and if the last byte
is something other than 0xFF or 0x00 then I add one to my byte count.
This is the byte count for this register until the program is run
again.  The next time, the bit count is likely to be different.

The input to the register array is at the least significant bit.  The
output is connected to the most significant bit.

When I read a register, the SPI pumps out the MSByte first, which goes
into my '0'th location in my list (array).  (The data is read as MSbit
first BTW, which is accurate given this configuration).  When the read
is complete, I have something that looks like this:

data_in[0] = MSByte
data_in[1] = MSByte -1
data_in[n-1] = LSByte -1
data_in[n] = LSByte*

*The data_in[n] (LSByte) is the byte that can have extra '1's in it's
least significant bit positions due to the pull-up on the data line..
Only the LSByte has the 'extra' bits.  The other bytes are 'normal'.

To handle the data in what I'll call a 'normal' order, I use the
list.reverse() function that I discovered somewhere on the web.  That
puts the bytes in what I would call the 'proper' order.  So then I
have :

data_in[0] = LSByte
data_in[1] = LSByte - 1
data_in[2] = LSByte - 2
data_in[n-1] = MSByte -1
data_in[n] = MSByte

I still have the extra bits that were added to the lower bits of
data[0], I need to right shift to remove the 'added' ones.  If this
were only a byte sized register, I would do the shift and that would
be sufficient but that is not likely.

So, in the example of just one additional bit that needs removing:

data_in[0] >>= 1

but, I need the least significant bit from data_in[1] to move into the
most significant bit of the now-shifted data_in[0].  This of course
has a domino affect down the line until I reach data_in[n].  Since I
know the length of the register from my initialization process, I can
ignore / mask the most significant bit of data_in[n] in my other

My initial solution was to take data_in[1] and _left_ shift it by the
amount of 8 - shift_count.

scratch = data_in[n] <<= (8 - #)

This moved the LSbit to the MSbit location of scratch.  I then OR the
data_in[0] shifted result and the scratch result to get my final
data_in[0] value.

data_in[0] = data_in[0] | scratch

I really hope that this makes sense.

The API is providing me with a bytearray-formatted result, but the API
only reads one whole byte, or eight bits, at a time.  So, I've been
using only the [0] of the bytearray for my data.  I hope that this
answers your question about octets.  I'm not entirely sure I follow
the question well enough to answer.

On 10/9/18, Alan Gauld via Tutor <tutor at python.org> wrote:
> On 09/10/18 02:55, Chip Wachob wrote:
>> This bit stream is complicated in that I have to reverse the bytes as
>> well since I'm reading off the 'end' of a bunch of registers.  So, the
>> MSByte comes to me first and goes into the [0] location and the extra
>> bits get added to the '0th' end of the LSByte.  It is a very unhandy
>> hardware setup but one that I don't have any control over.
> I'm not sure I understand this fully.
> Do you mean that each byte has extra
> bits added or that only the last (LSByte)
> has extra bits?
> If it's the latter then it becomes a fairly
> trivial exercise of slicing the data off
> rather than shifting. But then you get left
> with a non-byte.
> If it's the former then I don't understand
> how you can determine "byte" boundaries!
> Also when you say you have to "reverse" the
> bytes do you mean the bits within each byte
> need to be reversed? Or merely that the bytes
> themselves come in the reverse order? If
> its the latter then the bytearray.reverse()
> method should suffice to fix that issue.
> Finally, just to clarify what's happening.
> It sounds like you have an API that delivers
> 8 bits(octets) at a time? (Not necessarily actual
> bytes, just groups of 8 bits, is that correct?
> And that potentially your actual data is not
> an even number of octets long (say 14 bits?)
> and thus you get a few random bits of cruft
> at the end.
> Is that the case? If so, how do you know the
> real length of the actual data?
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor

More information about the Tutor mailing list