... What Evanh lucked upon is maybe a sufficient trick, but it's only by virtue of subtlety in the hardware implementation that it works.
What Chip is saying there is that something like variations in production batches could change behaviour of what locks up and what doesn't when not using the workaround.
Funnily, Cluso, you were the one who first complained about it. At the time I had long placed all the reliability issues at the feet of USB, of which did have its own issues but wasn't the biggie in this case.
There is no opt-out option when dealing with the raw HUBSET instruction. Compiler writers have to package any _HUBSET() function with the workaround baked in. Loaders have to follow one of the two handover options.
And if prior-mode handover is selected then half the burden of the handover procedure is placed on the loaded program.
Huh, just been looking at loadp2 sources, I think I see something unintended in loadp2.c. It looks like Dave has at some stage changed the clock frequency integer representation from MHz to Hz. There is a compare in the get_clock_mode() function that checks for >180 and then changes XDIVP from 2 to 1 if true. It's pretty obvious this is intended to be 180 MHz but since it's only 180 Hz that means loadp2 is always using XDIVP = 1. Doesn't have a downside really and I'm not in favour of such a high intended threshold so it's better as is.
I've updated the loadp2 fast loader to always go back to RCFAST mode unless the -PATCH flag was given on the command line. This means that -PATCH is now required for p2gcc and similar compilers that expect the frequency and baud rate to be set up by the loader, but it makes the fast loader behavior match that of the original ROM loader (-SINGLE).
Adding further to detecting boards, here's one for Rev A/B silicon detect.
'Silicon Rev A/B detect
dat org
getscp pa 'save current scope mode
mov pb,pa
add pb,#1
setscp pb 'change scope mode
getscp pb 'read back scope mode
setscp pa 'restore scope mode
cmp pa,pb wz
drvnz #56 'no match = Rev B silicon
jmp #$
Oz,
That is way buggy. GETSCP, on revB, reads data, not the config. On revA it seems to effectively be a NOP. So there is no way to preserve any prior config without an explicit reserved variable/mailbox for it. However, I've noted in Eric's sources that he is starting a self terminating fresh cog to run the check. The launcher task waits for it to fill a hubRAM location. This way, the config within that fresh cog is temporary.
I'm not a fan of Cluso's solution because it relies on the copied ROM binary still existing in hubRAM.
Cluso,
XORO32 is like ALTS, it replaces the data of subsequent instruction's S operand. So that "0" is just a filler for the assembler. I use the 0-0 convention myself.
I'll give it a test ...
EDIT: All good:
RevA chip compares these two values
42a01290 50ad0021
RevB chip compares these two values
84908405 62690201
This is one cycle quicker and changes only one arbitrary register:
mov reg,#1
xoro32 reg
cmp reg,0 wc 'C = 1 if rev A
Good idea Tony. Not touching PTRA is tidier.
Cluso,
XORO32 is like ALTS, it replaces the data of subsequent instruction's S operand. So that "0" is just a filler for the assembler. I use the 0-0 convention myself.
I'll give it a test ...
EDIT: All good:
RevA chip compares these two values
42a01290 50ad0021
RevB chip compares these two values
84908405 62690201
I used 0 not 0-0 as my aim was smallest and quickest code with fewest characters. The following is an improvement on the last point, but doesn't work with #1:
mov reg,#2
xoro32 reg
or reg,0 wc 'C = 0 for rev A
Is it really a good idea to rely on the xoro32 sequence never changing again? I like the ptra++ methods because that does seem unlikely to change in future versions of the chip.
Comments
What Chip is saying there is that something like variations in production batches could change behaviour of what locks up and what doesn't when not using the workaround.
Obviously we are on a different page as I don't understand what you are trying to say. I do not see any bugs so please show me.
And if prior-mode handover is selected then half the burden of the handover procedure is placed on the loaded program.
Thanks for that link. I had skipped over your solution when I discovered that the [color]LOADERS ARE OVERWRITING USERS CODE!!![/color]
DO YOU GUYS REALISE WHAT IS HAPPENING !!!
ALL SORTS OF DANGERS HERE WHEN YOUR CODE STOPS WORKING !!!
IMHO BIGGEST TRAP HERE FOR USERS EVER !!!
Huh, just been looking at loadp2 sources, I think I see something unintended in loadp2.c. It looks like Dave has at some stage changed the clock frequency integer representation from MHz to Hz. There is a compare in the get_clock_mode() function that checks for >180 and then changes XDIVP from 2 to 1 if true. It's pretty obvious this is intended to be 180 MHz but since it's only 180 Hz that means loadp2 is always using XDIVP = 1. Doesn't have a downside really and I'm not in favour of such a high intended threshold so it's better as is.
loadp2 only changes anything in the user code if you give it the -PATCH option. By default it leaves the user's code alone.
PNut never patches anything.
Are there any other loaders? I think ozpropdev had a Python loader, but I don't think it patches anything either.
Small improvement for the new non-patching RCFAST handover code - shift the HUBSET #0 up one line ahead of the WAITX. See https://forums.parallax.com/discussion/comment/1475472/#Comment_1475472 for the reason.
Thanks Evan.
Oz,
That is way buggy. GETSCP, on revB, reads data, not the config. On revA it seems to effectively be a NOP. So there is no way to preserve any prior config without an explicit reserved variable/mailbox for it. However, I've noted in Eric's sources that he is starting a self terminating fresh cog to run the check. The launcher task waits for it to fill a hubRAM location. This way, the config within that fresh cog is temporary.
I'm not a fan of Cluso's solution because it relies on the copied ROM binary still existing in hubRAM.
It worked for me with no issues but here's a better way.
Nice and simple! I like it
This is one cycle quicker and changes only one arbitrary register:
# missing
Cluso,
XORO32 is like ALTS, it replaces the data of subsequent instruction's S operand. So that "0" is just a filler for the assembler. I use the 0-0 convention myself.
I'll give it a test ...
EDIT: All good: Testing code:
I used 0 not 0-0 as my aim was smallest and quickest code with fewest characters. The following is an improvement on the last point, but doesn't work with #1:
or pa,0 wc
is confusing!!
Use
or pa,0-0 wc
as it shows that the s operand is being changed by the xoro32 instruction which is easily forgotten.