Anyway to simplify this PASM code snip? ... Golf challenge?
Beau Schwabe
Posts: 6,568
weekend code project...
Does anyone see how this can be shortened? Not code wise, instruction wise... The section below "if_nz jmp #BitNotReady" needs to be deterministic. I would like to check for #%0110_0000 and #%0000_0110 also to determine the transition, but it's not a show stopper if that doesn't happen.
Prior to this block the raw Manchester data is read at 8 times the bit rate and rolled into a BYTE variable called "ManchesterBit" based on the result of the C flag. If the Bit transition is within the valid window, the "BitFlag" remains zero, otherwise an Error occurred and it is set to 1 where the 'BitSync' is dynamically incremented and eventually locks on to the data.
Does anyone see how this can be shortened? Not code wise, instruction wise... The section below "if_nz jmp #BitNotReady" needs to be deterministic. I would like to check for #%0110_0000 and #%0000_0110 also to determine the transition, but it's not a show stopper if that doesn't happen.
Prior to this block the raw Manchester data is read at 8 times the bit rate and rolled into a BYTE variable called "ManchesterBit" based on the result of the C flag. If the Bit transition is within the valid window, the "BitFlag" remains zero, otherwise an Error occurred and it is set to 1 where the 'BitSync' is dynamically incremented and eventually locks on to the data.
rcl ManchesterBit, #1 'Move the 'C' flag into a BYTE 'that represents 1 Manchester Bit add BitSync, #1 and BitSync, #%111 wz 'Keep value between 0 and 7 if_nz jmp #BitNotReady 'Check if Manchester Bit is ready mov BitFlag, #0 'Valid Flag mov t1, ManchesterBit 'Test for bit transition (leading mis-alignment) and t1, #%0011_0000 cmp t1, #16 wz if_nz cmp t1, #32 wz if_nz mov t1, ManchesterBit 'Test for bit transition (ideal alignment) if_nz and t1, #%0001_1000 if_nz cmp t1, #8 wz if_nz cmp t1, #16 wz if_nz mov t1, ManchesterBit 'Test for bit transition (laging mis-alignment) if_nz and t1, #%0000_1100 if_nz cmp t1, #4 wz if_nz cmp t1, #8 wz if_nz mov BitFlag, #1 'Error Flag if_nz add BitSync, #1 'dynamically adjust bit alignment PossiblyValid {Process ManchesterBit here} BitNotReady
Comments
BTW, I've found that, for Manchester decoding, it's simpler to decode an entire string of bits both ways, then pick the result with the most decoded bits after you're done. It has the additional advantage of not discarding any data due to starting out of sync.
-Phil
"BTW, I've found that, for Manchester decoding, it's simpler to decode an entire string of bits both ways, then pick the result with the most decoded bits after you're done." - Right but I wanted to decode on the fly without a buffer except for the final result.
Hmm.. to start with you can replace the BitFlag ops with a single muxz instruction.
Or even better:
-Phil
I knew there was a better way.... The last iteration you provided shaves 8 instructions from my original ... I'll have to look at it in closer detail later.
TEST of course... I changed the bit pattern to #%0011_1100
Thanks
Now we just have to wait for Kuroneko to wake up in Japan to shave off a few more instructions.
-Phil
pedward,
WOW! ... but I'm not sure the C bit in the RCR works like you would think... "...C flag is set to Value's original bit 0." ... anyway I tried it and there was some jitter on the BitFlag.
The nature of the source of Manchester has a little jitter, so I need to be able to track or encompass the small movements.
It could be reduced to andn BitFlag, # % 0011_1100 as long as you are just checking if Bitflag is non zero. Then it's 2 instructions.
What he's looking for is a transition (in either direction) between bits 3 and 2, 4 and 3, or 5 and 4: IOW any of the following six values:
where the stars represent "don't care" conditions.
-Phil
Here's a thought, in an ideal sample you will always have 2 high bits, there should be ideally 2 low bits surrounding the high bits, but you are willing to accept a single low bit at each end.
The test instruction struck me as interesting because it stores parity in in the C flag and the test in Z.
So, if the possible values you are sampling are:
0110_0000
0011_0000
0001_1000
0000_1100
0000_0110
Then a mask of 0111_1110 would cover all of the valid high bits. Then if you do an AND on a valid result, you get 2 high bits and a match in Z.
The mask above would produce Z = 0 if a match was encountered and C = 0 if there were an even number of bits.
If you combine these you have TEST data, #%0111_1110 wz wc. If you have an even number of bits in the window, c = 0, so there are 2 high bits in the window. If z = then you know there was a match in the window.
If you match a single high bit in the window, c = 1. If there is 1 bit at the beginning of the window and 1 outside, it matches, but c = 1
So:
This code gives you diagnostics to tune the rest of the code. If ErrFlag = 0 then a match was encountered. If OneBitErr is 1, you had only 1 bit in the window, if NoDataErr is set, then you had zero bits in the window.
Does this help?
-Phil
I re-read his original request and based on the code posted and his request (including the "wouldn't it be nice"), I produced the above test.
-Phil
{ some stuff about visualizing data, blah blah, I missed the original point }
If the code I wrote is changed to check for an odd number of bits, then a bit transition happened in the window.
Further, you can make it a call and tune the window as such:
test bits, 0111_1110 'test for transition in window
test bits, 1000_0000 'test for transition at MSB
if first test false and second test true, data is at MSB of sample, else data is at LSB of sample
repeat the tests with smaller windows after each clock adjustment:
test bits, 0011_1100 'test window
test bits, 1100_0000 'test for bits at MSB of sample
test bits, 0001_1000 'test window
test bits, 1110_0000 'test MSB
if in 3 rounds of clock adjustment you haven't gotten a true result, then something isn't right. a correct result is z = 0 and c = 1 for a test with 1 transition within the test window.
Further, this test works to test if you have 2 samples in the window, because z = 0 and c = 0, which tells you your clocking is too slow. This test should give all sorts of diagnostics with only a few instructions.
Cheers.
--0011-- = even
--0111-- = odd
--1110-- = odd
--1100-- = even
--1000-- = odd
All valid transitions.
-Phil
When he says he's 8x oversampling the data, I take that to mean there is 1 potential symbol in the 8 bits, is this incorrect? If there is 1 symbol in 8 bits then my algorithm works correctly. If there are multiple symbols in the 8 bits, then it doesn't work.
When the edge occurs in the center (boldface portion) of the byte, the code is in sync with the incoming signal. Otherwise the sampling phase has to be advanced for another try.
-Phil
So:
This code looks for a solid high bit pattern outside the sync window, then looks for a transition inside the window. You could make the window wider, per Beau's request, and the code would still work with the new values. This code would break if not using 8x oversampling.
EDIT: remove test for flag, crazy editor keeps inserting empty code tags!
Your diagram is correct, as far as my understanding of the problem goes. Beau is oversampling the input so he can adjust synchronization to get the transitions in the center of the bit window. The use of the word "symbol" rather than "bit window" is probably what made things confusing.
-Phil