... uses "@" with REP, so I guess that's how it's supposed to be. Seems a little strange though...
The D value in the REP instruction is a unsigned 9 bit offset to the end of the REP block.
Only positive offsets are allowed for REP instructions, so a @ instead of a #@ might be Chip's Pnut trick to solve this?
... uses "@" with REP, so I guess that's how it's supposed to be. Seems a little strange though...
The D value in the REP instruction is a unsigned 9 bit offset to the end of the REP block.
Only positive offsets are allowed for REP instructions, so a @ instead of a #@ might be Chip's Pnut trick to solve this?
@ used for D in REP sets the number of instructions to repeat, minus one, based on a forward label after the instructions. REP must be encountered before the instructions to repeat, so a reverse branch is not possible.
notice... the condition (if_c) is wrong and I have an akpin in there, where I don't think I need it anymore.
Also... somewhere I got the idea that the bit period had a new calculation:
cambitper long (sys_clk/cambaud_rate)*$10_000 & $FFFFFC00 | 7 'sys_clk/baud_rate + bits-1
when I use this, I get an extra byte (=128) sent out through tx_pin following the correct byte...
but when I go back to the prior calculation for the bit period:
cambitper long (sys_clk/cambaud_rate)<<16 + 7 'sys_clk/baud_rate + bits-1
everything is as it should be, no extra byte.
I thought maybe I had accidentally used the wrong .rbf file, but I just re-loaded the image and the behavior is the same.
I have included a zip of the full code. The routine starts at line 866.
Still having the same issue. My setup is a serial line between a P1 and P2... using pins: P1 rx=5; tx=4 ......... P2 rx=33 tx=32.
The P2 receiver works exactly as expected... same wc condition on testin and no akpin required.
But to transmit I still have to use the wrong condition and put an akpin in... it works,
but I'm confused as why.
Also... when the P2 starts transmitting for the first time, it seems to throw out one extra byte. I have tried
various ways to get rid of this byte to no avail.... seems to be something at start-up.
Thanks
Rich
edit... on the P1 I have both rx and tx tied to ground.
edit #2... P1 and P2 share common ground. In the P2 code... the delay waitx ##160000 is required because I'm using ser.rxtime(1) on the P1 side.
@rjo__
I see you're using TESTIN on the tx pin -- in this case C is set when the buffer empties.
1. Wait for an output word to be buffered via WYPIN, then set the ‘buffer-full’ and ‘busy’ flags.
2. Move the word into the shifter, clear the ‘buffer-full’ flag, and raise IN.
dtx_char
testin #TX wc ' Wait for tx ready
if_nc jmp #dtx_char
and dtx, #$ff ' Ensure limited to extended ASCII space
wypin dtx, #TX
ret
Edit: is there any speed difference between using TESTIN or RDPIN/RQPIN? I know the latter is two clocks -- is TESTIN the same?
tx_byte testin #tx_pin wc
if_nc jmp #tx_byte
can be replaced with
txbyte jnp #tx_pin,#txbyte
I don't have a problem using rdpin, but when I use the above code, it hangs and I have to throw an akpin to make if_c work:)
Remember... this is going straight to a Prop1.... not sure that it matters, but that is what I'm doing.
The reason I persist is that it just doesn't seem right... and I don't think it is my code.
Altogether I looked at over 20 values and didn't see a 101 pattern, which you would expect if the value was random. The value seen after power cycling the P123 board was variable.
Also... when the P2 starts transmitting for the first time, it seems to throw out one extra byte. I have tried
...
The initial extra byte is still there. It occurs any time I recompile the P2 code.
Here is a consecutive list of the extra first values... each collected after a recompile:
Altogether I looked at over 20 values and didn't see a 101 pattern, which you would expect if the value was random. The value seen after power cycling the P123 board was variable.
Can you clarify - is that extra byte there on any Reset too - you only mention recompile and Power cycling ?
How does it re-boot - from SPI or via serial loader ?
Is this testing a separate smart pin, or sharing the one used for Serial Boot ?
Can anyone else confirm an extra byte when P2 starts transmitting ?
I was just admiring jump table code in garryl's USB code for processing commands and calling whatever subroutine is needed:
mov dtmp, devent ' Save the eventID
min dtmp, #1
max dtmp, #D_END
sub dtmp, #1 ' Jump table is zero-based
add dtmp, #devent_jmp
push #devent_exit ' Event handlers return here
jmp dtmp
devent_jmp
jmp #htx_asciiz ' Host requested string output to terminal
jmp #htx_break ' Send host debug data to terminal, then halt
jmp #htx_dbg_data ' Send host debug data to terminal
jmp #htx_hexdump ' Dump raw data to terminal
jmp #connect_info
jmp #dev_disconnect
jmp #parse_dev_desc ' Parse string data in the device descriptor
jmp #parse_con_desc ' Parse config descriptor to determine if it's a known device class
jmp #get_txn_result ' Get DTX_RESULT event data and jump to IRP result handler routine
jmp #get_tx_hresult ' DTX_HRESULT is a way for the host to route processing results to the terminal
loc ptra, #@sz_jmptbl_err ' DEBUG: Jump table beyond limit
call #dtx_asciiz
devent_exit
wrlut #D_READY, #D_EVENT ' Ready for next event posting
ret
It's very efficient. Like how it pushes the return address so can do a JMP with subroutine doing a RET that is basically tricked into returning to the address that was pushed.
The simple way I was doing it works, but uses much more space:
This would be a good place to use the JMPREL instruction
push #devent_exit ' Event handlers return here
jmprel devent
devent_jmp ret 'not used
jmp #htx_asciiz ' Host requested string output to terminal
jmp #htx_break ' Send host debug data to terminal, then halt
jmp #htx_dbg_data ' Send host debug data to terminal
jmp #htx_hexdump ' Dump raw data to terminal
jmp #connect_info
jmp #dev_disconnect
jmp #parse_dev_desc ' Parse string data in the device descriptor
jmp #parse_con_desc ' Parse config descriptor to determine if it's a known device class
jmp #get_txn_result ' Get DTX_RESULT event data and jump to IRP result handler routine
jmp #get_tx_hresult
This would be a good place to use the JMPREL instruction
push #devent_exit ' Event handlers return here
jmprel devent
devent_jmp ret 'not used
jmp #htx_asciiz ' Host requested string output to terminal
jmp #htx_break ' Send host debug data to terminal, then halt
jmp #htx_dbg_data ' Send host debug data to terminal
jmp #htx_hexdump ' Dump raw data to terminal
jmp #connect_info
jmp #dev_disconnect
jmp #parse_dev_desc ' Parse string data in the device descriptor
jmp #parse_con_desc ' Parse config descriptor to determine if it's a known device class
jmp #get_txn_result ' Get DTX_RESULT event data and jump to IRP result handler routine
jmp #get_tx_hresult
Out of curiousity, what is the purpose of the unused ret instruction?
Out of curiousity, what is the purpose of the unused ret instruction?
I think that is for a 1-based index.
I was going to mention the sub dtmp, #1 in the original, could have been replaced with an empty table slot, for the same size, but faster overall.
Out of curiousity, what is the purpose of the unused ret instruction?
I think that is for a 1-based index.
I was going to mention the sub dtmp, #1 in the original, could have been replaced with an empty table slot, for the same size, but faster overall.
That's correct, in this case a zero index is unused/invalid.
I see great potential for JMPREL in things like bytecode interpreters (SPIN2) for rapid instruction group decoding.
Out of curiousity, what is the purpose of the unused ret instruction?
I think that is for a 1-based index.
I was going to mention the sub dtmp, #1 in the original, could have been replaced with an empty table slot, for the same size, but faster overall.
That's correct, in this case a zero index is unused/invalid.
I see great potential for JMPREL in things like bytecode interpreters (SPIN2) for rapid instruction group decoding.
Okay. I was just making sure there wasn't a caveat with JMPREL.
Happened again... Knew what to do this time. Cycled power on P123 and all better.
Is there any way code can mess up P2V in a way that survives reprogramming?
Do you mean FPGA reprogramming or just P2 code area reprogramming ?
I guess a simple P2 reset also fails ?
Is there a way to reload the FPGA bitstream, without cycling the power ? (just to exclude something other than FPGA)
If the issue needs a FPGA reset, as opposed to a P2 reload/reset, then maybe there is some logic that is not properly P2-reset covered ?
Is RAM also preloaded on FPGA reset ? That may be another way to get similar symptoms.
Adding/removing a clear all ram/fill random block should check that ?
Happened again... Knew what to do this time. Cycled power on P123 and all better.
Is there any way code can mess up P2V in a way that survives reprogramming?
The USB code is likely the instigator of this, as I've been down the power-cycle road on occasion. I don't doubt that it is programmer error that starts the ball rolling, but I have yet to find a scenario that will reliably reproduce it, yet. Whatever it is appears to lobotomize the USB smart pins, and when it's in this state, neither a code reload or hardware reset via the PB0 button on the Prop123-A9 board prior to reload works.
I got the board into this lobotomized state a bit ago, but this time I kept the board powered on and used the PGM/RUN switch and PX.exe to reload the FPGA image, then reloaded the code, and things were good. So it looks like whatever is going on is having an adverse effect on the FPGA image.
Comments
The D value in the REP instruction is a unsigned 9 bit offset to the end of the REP block.
Only positive offsets are allowed for REP instructions, so a @ instead of a #@ might be Chip's Pnut trick to solve this?
@ used for D in REP sets the number of instructions to repeat, minus one, based on a forward label after the instructions. REP must be encountered before the instructions to repeat, so a reverse branch is not possible.
pm_camtx long %0000_0000_000_0000000000000_01_11110_0 'async tx mode.
In Chip's smartpin_serial_turnaround.spin2 from v13, he waits for an empty tx buffer and then uses wypin to send a byte to tx pin (pin0).
When I do this, it hangs on me... but the following works fine:
notice... the condition (if_c) is wrong and I have an akpin in there, where I don't think I need it anymore.
Also... somewhere I got the idea that the bit period had a new calculation:
cambitper long (sys_clk/cambaud_rate)*$10_000 & $FFFFFC00 | 7 'sys_clk/baud_rate + bits-1
when I use this, I get an extra byte (=128) sent out through tx_pin following the correct byte...
but when I go back to the prior calculation for the bit period:
cambitper long (sys_clk/cambaud_rate)<<16 + 7 'sys_clk/baud_rate + bits-1
everything is as it should be, no extra byte.
I thought maybe I had accidentally used the wrong .rbf file, but I just re-loaded the image and the behavior is the same.
I have included a zip of the full code. The routine starts at line 866.
X[15:10] establishes the number of fractional clocks in a bit period.
The P2 receiver works exactly as expected... same wc condition on testin and no akpin required.
But to transmit I still have to use the wrong condition and put an akpin in... it works,
but I'm confused as why.
Also... when the P2 starts transmitting for the first time, it seems to throw out one extra byte. I have tried
various ways to get rid of this byte to no avail.... seems to be something at start-up.
Thanks
Rich
edit... on the P1 I have both rx and tx tied to ground.
edit #2... P1 and P2 share common ground. In the P2 code... the delay waitx ##160000 is required because I'm using ser.rxtime(1) on the P1 side.
This is what I use based on the P2 docs for async Tx.
I see you're using TESTIN on the tx pin -- in this case C is set when the buffer empties. Edit: is there any speed difference between using TESTIN or RDPIN/RQPIN? I know the latter is two clocks -- is TESTIN the same?
I don't have a problem using rdpin, but when I use the above code, it hangs and I have to throw an akpin to make if_c work:)
Remember... this is going straight to a Prop1.... not sure that it matters, but that is what I'm doing.
The reason I persist is that it just doesn't seem right... and I don't think it is my code.
I made a few tweaks to your P2 code, see if it works.
I also noticed that you have the Rx mode set for output, this can cause grief too.
The initial extra byte is still there. It occurs any time I recompile the P2 code.
Here is a consecutive list of the extra first values... each collected after a recompile:
10000000
11000000
11111100
11110000
00110000
11111000
11111111
11110000
00110000
11000000
11110000
11100000
11111111
11111000
Altogether I looked at over 20 values and didn't see a 101 pattern, which you would expect if the value was random. The value seen after power cycling the P123 board was variable.
How does it re-boot - from SPI or via serial loader ?
Is this testing a separate smart pin, or sharing the one used for Serial Boot ?
Can anyone else confirm an extra byte when P2 starts transmitting ?
My setup is serial between a P1 and P2... using pins: P1 rx=5; tx=4 ......... P2 rx=33 tx=32.
It's probably a simple line transition, as the pins get configured, that is being interpreted as a start bit.
It's very efficient. Like how it pushes the return address so can do a JMP with subroutine doing a RET that is basically tricked into returning to the address that was pushed.
The simple way I was doing it works, but uses much more space:
Out of curiousity, what is the purpose of the unused ret instruction?
I think that is for a 1-based index.
I was going to mention the sub dtmp, #1 in the original, could have been replaced with an empty table slot, for the same size, but faster overall.
I see great potential for JMPREL in things like bytecode interpreters (SPIN2) for rapid instruction group decoding.
Okay. I was just making sure there wasn't a caveat with JMPREL.
All of the sudden, my GUI w/ USB code stopped working.
Well, the USB part stopped working anyway.
Spent an hour trying to figure out what was wrong with the code.
Finally decided it had to be a hardware fault.
Sure enough, cycled power on my P123-A9 and then it started working again.
I'm guessing that somehow the shared cog LUT between cogs 6 and 7 got messed up over time. Not exactly sure how that can happen though...
Is there any way code can mess up P2V in a way that survives reprogramming?
I guess a simple P2 reset also fails ?
Is there a way to reload the FPGA bitstream, without cycling the power ? (just to exclude something other than FPGA)
If the issue needs a FPGA reset, as opposed to a P2 reload/reset, then maybe there is some logic that is not properly P2-reset covered ?
Is RAM also preloaded on FPGA reset ? That may be another way to get similar symptoms.
Adding/removing a clear all ram/fill random block should check that ?
I got the board into this lobotomized state a bit ago, but this time I kept the board powered on and used the PGM/RUN switch and PX.exe to reload the FPGA image, then reloaded the code, and things were good. So it looks like whatever is going on is having an adverse effect on the FPGA image.