The v0.6 host would give up if a STALL handshake is received on a control read/write. In my collection of full-speed devices, most enumerate reliably, but a few are finicky. It's kind of like Forest Gump and his box of chocolates :frown:
Does it always stall at the mouse SetIdle()? Sometimes repeated disconnect/reconnect will result in success.
The next drop of the demo isn't far away, and I just ordered this model combo to add to my test group - we'll get it to work
It will also contain a "minimal" host/driver version that has all of the demo's verbose descriptor output code and data removed, making it more suitable for a "production" environment.
PS: Just tried Logitech Bluetooth combo (MX 5500). Doesn't work:
<Full-Speed device connected.>
Bummer! I don't know what to do with this device.
Yep, Bluetooth is a whole different animal. From what I've read, finding a Bluetooth keyboard/mouse that supports the HID "boot protocol" interface is a rare animal.
Edit: BTW, the next demo drop can identify all of the USB-IF registered device/interface base class types, from the class/subclass/protocol "triad" that's in the device and interface descriptors. Subclass and protocol identification can get pretty gnarly, so getting detailed info for these is optional, but it's pretty easy to add, if desired. The demo does the full triad for HID, Mass Storage and the Bluetooth subset of the "Wireless Controller" base class.
And the occasional need to reload the FPGA image after a USB error issue is looking like it's resolved (LUT initialization programmer error).
This LUT bug just bit me again...
It's so rare that I think it must be what I just did in code that messed it up...
Takes a while before I realize that it must be this bug and load an old version of code to verify.
There is definitely something wrong with P2V for this to happen.
I'm assuming that PNUT is resetting the P2V.
This should clear all memory, including LUT memory, AFAIK
This should clear all memory, including LUT memory, AFAIK
Are you sure ?
Memory clear is not usually inherent in any MCU.
It can be done in a loop, but using software.
If you wanted a parallel reset on RAM, that costs more silicon.
Or did you mean that P2 Reset plus a Software-clear-loop, clears all RAM ?
That is more common.
As @ozpropdev said, the LUT space isn't cleared on reset or code reload.
In the short term, in the host and driver cog startup code, write zero to LUT locations $1fc (H_EVENT) and $1fd (D_EVENT), and see if the problem disappears.
A LUT initialize would double the cog launch time.
Also be aware that on P2 reset the "ROM Booter" loads cog & lut ram with code.
' Move code into position
'
setq #cog_end-cog_code-1 'move cog code into position
rdlong cog_start,##@cog_code
setq2 #lut_end-lut_code-1 'move lut code into position
rdlong lut_start,##@lut_code
The "Fast Block Move" feature is a neat way to initialize the lut with values.
dat org
loc ptra,#@var0 'point to template
setq2 #3 '4 longs (4-1)
rdlong 0,ptra 'move hub to lut address 0
'.
'.
'.
orgh $1000
'lut initialize template
var0 long 1
var1 long $aa
var2 long $ff0
var3 long $3333
LUT initialization from COGINIT would have to be optional I think.
COGINIT already allows you to restart a cog without reloading cog ram now.
If LUT is used as a table for video palette or DAC table it has to be loaded post COGINIT anyway.
The same for LUT execution code, it is loaded in a second step from user code.
The remaining use case is for variables/stacks.
In this case a simple REP loop can initialize the RAM or the example above with a template.
@rayman: I think I found the cause of your Logitech Mk520's SetIdle() STALL. Yet another instance where my failure to read EVERY STINKING WORD of USB documentation comes back to bite me in the a** >:(
I've got this and other testing yet to do, but I hope to get the next USB demo version out tomorrow.
LUT initialization from COGINIT would have to be optional I think.
Yes, it needs to be optional.
One means to manage this could be a choice of Boot-detail, where you can (optionally) 'fill-the-rest' as part of the Loader step.
You can do that 'long-hand' by always giving an image sized to all RAM, but the SW-Fill would be faster.
If ROM manages this as a Build-type switch, that frees up some valuable user code space.
What happens if two cogs are running code with two different things in LUT and then
you run code with their LUT's shared?
When you read LUT, which one do you get?
If it works the way I imagine then:
Actually, maybe this is way for the dominant cog to have switchable access between two different LUT's? That could be useful perhaps...
I've been really stumped a few times by what turned out to be just software out-of-order r/w issues in shared hub memory. The solutions were always simple. It was just a matter of realizing where the trip-up was happening. The same issues are potential in shared LUTs.
If you are launching two cogs concurrently with LUT-sharing in mind, it might be good to have each one start by clearing its own LUT and then turning on LUT sharing. Remember that LUT sharing does not makes two LUTs equal, only that they each can receive a copy of their neighbor's individual WRLUT operations.
Garryj, I think I asked before, but do you have a Prop123-A9 board? I can do an updated A9 compile today and post it. It uses bit 3 of the readback status in the USB mode to tell whether SE0/K/J have been valid for 7+ USB bit periods, while bits 2/1/0 express immediate SE0/K/J states, without any delays.
The new compile would also cover the bug where CALLPA/CALLPB and the event jumps couldn't branch backwards using 9-bit relative addresses.
Thanks Chip, I remember how the shared LUT works now.
I just took a quick peek at documentation, but don't see any notes that LUT is not initialized by coginit. I think this needs to be made very clear. Maybe in both LUT description section and coginit section.
Also, I didn't see the option of not clearing cog RAM in there either...
Garryj, I think I asked before, but do you have a Prop123-A9 board? I can do an updated A9 compile today and post it. It uses bit 3 of the readback status in the USB mode to tell whether SE0/K/J have been valid for 7+ USB bit periods, while bits 2/1/0 express immediate SE0/K/J states, without any delays.
The new compile would also cover the bug where CALLPA/CALLPB and the event jumps couldn't branch backwards using 9-bit relative addresses.
Yep, a Prop123-A9, and the status bit changes look good.
host_reset
'RJA Trying to fix occasional glitch that needed P2V reboot
'write zero to LUT locations $1fc (H_EVENT) and $1fd (D_EVENT),
wrlut #0,#$1fc
wrlut #0,#$1fd
Don't know if I did it right, but at least doesn't make it not work...
host_reset
'RJA Trying to fix occasional glitch that needed P2V reboot
'write zero to LUT locations $1fc (H_EVENT) and $1fd (D_EVENT),
wrlut #0,#$1fc
wrlut #0,#$1fd
Don't know if I did it right, but at least doesn't make it not work...
The D_EVENT location is "owned" and read by the driver cog, so it should go here:
class_start
call #serial_init ' Init serial I/O and startup splash to terminal
call #load_kbd_lut ' Copy keyboard conversion table to LUT
dirh #DRIVER_BLINKY_LED ' DEBUG
wrlut #D_READY, #D_EVENT ' Reset shared LUT eventID
I'm almost finished testing the next drop of the USB demo. So far, I haven't had to power-cycle once, so I'm optimistic that this bug is squashed.
To me, it sounds like it still loads the cog and just starts from somewhere else besides address #0.
Yes, I agree.
IIRC I started playing with this mode based on a passing comment by Chip of a new feature.
It also needs to mention that stopping the cog clears the DIRx registers too.
This can be a issue if restarting at an address that may skip port initialization.
Comments
If one of those works, should be great for one thing I have in mind...
Does it always stall at the mouse SetIdle()? Sometimes repeated disconnect/reconnect will result in success.
The next drop of the demo isn't far away, and I just ordered this model combo to add to my test group - we'll get it to work
It will also contain a "minimal" host/driver version that has all of the demo's verbose descriptor output code and data removed, making it more suitable for a "production" environment.
Yep, Bluetooth is a whole different animal. From what I've read, finding a Bluetooth keyboard/mouse that supports the HID "boot protocol" interface is a rare animal.
Edit: BTW, the next demo drop can identify all of the USB-IF registered device/interface base class types, from the class/subclass/protocol "triad" that's in the device and interface descriptors. Subclass and protocol identification can get pretty gnarly, so getting detailed info for these is optional, but it's pretty easy to add, if desired. The demo does the full triad for HID, Mass Storage and the Bluetooth subset of the "Wireless Controller" base class.
And the occasional need to reload the FPGA image after a USB error issue is looking like it's resolved (LUT initialization programmer error).
So it was an uninitialized variable type bug ? (aka involves no Chip Verilog changes)
Yep, not a Verilog issue.
It's so rare that I think it must be what I just did in code that messed it up...
Takes a while before I realize that it must be this bug and load an old version of code to verify.
There is definitely something wrong with P2V for this to happen.
I'm assuming that PNUT is resetting the P2V.
This should clear all memory, including LUT memory, AFAIK
Are you sure ?
Memory clear is not usually inherent in any MCU.
It can be done in a loop, but using software.
If you wanted a parallel reset on RAM, that costs more silicon.
Or did you mean that P2 Reset plus a Software-clear-loop, clears all RAM ?
That is more common.
In the short term, in the host and driver cog startup code, write zero to LUT locations $1fc (H_EVENT) and $1fd (D_EVENT), and see if the problem disappears.
Seems like coginit command should clear LUT RAM.
Also be aware that on P2 reset the "ROM Booter" loads cog & lut ram with code.
COGINIT already allows you to restart a cog without reloading cog ram now.
If LUT is used as a table for video palette or DAC table it has to be loaded post COGINIT anyway.
The same for LUT execution code, it is loaded in a second step from user code.
The remaining use case is for variables/stacks.
In this case a simple REP loop can initialize the RAM or the example above with a template.
I've got this and other testing yet to do, but I hope to get the next USB demo version out tomorrow.
One means to manage this could be a choice of Boot-detail, where you can (optionally) 'fill-the-rest' as part of the Loader step.
You can do that 'long-hand' by always giving an image sized to all RAM, but the SW-Fill would be faster.
If ROM manages this as a Build-type switch, that frees up some valuable user code space.
you run code with their LUT's shared?
When you read LUT, which one do you get?
If it works the way I imagine then:
Actually, maybe this is way for the dominant cog to have switchable access between two different LUT's? That could be useful perhaps...
If you are launching two cogs concurrently with LUT-sharing in mind, it might be good to have each one start by clearing its own LUT and then turning on LUT sharing. Remember that LUT sharing does not makes two LUTs equal, only that they each can receive a copy of their neighbor's individual WRLUT operations.
The new compile would also cover the bug where CALLPA/CALLPB and the event jumps couldn't branch backwards using 9-bit relative addresses.
I just took a quick peek at documentation, but don't see any notes that LUT is not initialized by coginit. I think this needs to be made very clear. Maybe in both LUT description section and coginit section.
Also, I didn't see the option of not clearing cog RAM in there either...
Yep, a Prop123-A9, and the status bit changes look good.
Thanks, Chip, and remember to take it easy!
Don't know if I did it right, but at least doesn't make it not work...
From the P2 docs for "STARTING AND STOPPING COGS"
This option enables you to restart a stopped cog at any address without a cog reload.
Look here for an example.
http://forums.parallax.com/discussion/164300/restarting-stopped-cogs-power-save-mode
Get out of the P2 for a well deserved rest and recouperate!!!
To me, it sounds like it still loads the cog and just starts from somewhere else besides address #0.
IIRC I started playing with this mode based on a passing comment by Chip of a new feature.
It also needs to mention that stopping the cog clears the DIRx registers too.
This can be a issue if restarting at an address that may skip port initialization.
But, the P2 is trying to get out of ME.
Be careful Chip!
I have found Quartus to be be a massive source of stress!!