Open danielkucera opened 9 months ago
The firmware is designed to be uploaded into RAM. If you use my libsigrok branch then sigrok will automatically upload the fw
file when it detects a FX3 SuperSpeed Explorer board. Note that due to the device switching from a USB2 to a USB3 bus after fw upload, sigrok will fail to detect the device coming back. Just start sigrok again and it should detect the already programmed device.
You can also use fx3load to load the fw into RAM manually if you like.
Is there a way to store it permanently in SPI flash?
I've rebased your branch on latest master and disabled the firmware upload because it was not trivial to rebase the changes: https://github.com/sigrokproject/libsigrok/compare/master...danielkucera:libsigrok:fx3
The firmware works when loaded by fx3load but doesn't enumerate when I flash the same file to 0x0 of SPI flash. Do you have an idea what could be wrong?
Nope, sorry. I never tried to flash anything on the SuperSpeed Explorer. Probably it needs to be in some other format? Or if the flash is XIP the code may need to be relocated to a different address, or prefixed with a loader binary...
At the end, the format was right but the firmware was stuck on this loop: https://github.com/zeldin/fx3lafw/blob/master/bsp/usb.c#L564 After changing while to if, it started to work.
Interresting. I guess you need to do things a little differently when not renumerating.
Changing the while
to an if
is equivalent to removing the code altogether (since executing the empty statement or not will not make any difference), so that is hardly the correct fix...
I was trying to understand the meaning of FX3_UIB_POWER_ACTIVE
bit but haven't found much.
I searched github but found only: CY_U3P_UIB_POWER_ADDRESS
used in CyU3PDmaSocketIsValid
used in CyU3PDmaChannelGetHandle
with almost no usages.
Do you have some reference where this is used?
The register is documented on page 385 of the TRM as a mechanism for performing a reset on the UIB block, and checking when its initialization is done. I don't remember any more details than this (it's been almost 6 years...).
Since the reset operation works when booting from RAM but not from SPI, my guess would be that it is depending on some part of the chip being powered or initialized which isn't when booting from SPI, but which is (implicitly) when booting from RAM because the bootloader has already been using USB. In which case powering/initializing that part before doing the UIB reset should fix the issue.
Now I noticed that the bit is acctually not writable (from software), check this table:
If you check the register definition, there is only R
:
When comparing to UIBIN_POWER
, it has R/W
there:
Or I2S_POWER
:
So it is probably not possible to reset it from software. What do you think?
Weird. It also says that the ACTIVE
bit is read-only for the HW, which makes absolutely no sense given the description.
Given that the actual description of the bits is identical to that of the other IP blocks, and that the section before the bit descriptions state that "Every IP block" should implement these same functions, I'd be inclined to believe that the differing direction indication here is just a misprint. Unfortunately there are several of those in the TRM... :confused:
Could you please test if setting/resetting the bit has any effect on the ACTIVE bit?
Well, you'll probably get the results quicker if you do it yourself. :smile:
interesting, the same code:
char buf[64];
snprintf(buf, sizeof(buf), "power val %lx\n", Fx3ReadReg32(FX3_UIB_POWER));
Fx3UartTxString(buf);
Fx3SetReg32(FX3_UIB_POWER, FX3_UIB_POWER_RESETN);
Fx3UtilDelayUs(100);
snprintf(buf, sizeof(buf), "power val %lx\n", Fx3ReadReg32(FX3_UIB_POWER));
Fx3UartTxString(buf);
Fx3ClearReg32(FX3_UIB_POWER, FX3_UIB_POWER_RESETN);
Fx3UtilDelayUs(50);
snprintf(buf, sizeof(buf), "power val %lx\n", Fx3ReadReg32(FX3_UIB_POWER));
Fx3UartTxString(buf);
Fx3SetReg32(FX3_UIB_POWER, FX3_UIB_POWER_RESETN);
Fx3UtilDelayUs(100);
snprintf(buf, sizeof(buf), "power val %lx\n", Fx3ReadReg32(FX3_UIB_POWER));
Fx3UartTxString(buf);
behaves diferrently when run in boot from usb:
power val 80000001
power val 80000001
power val 0
power val 80000001
and when from SPI boot:
power val 0
power val 80000000
power val 0
power val 80000000
It is super-weird. Even if I put the value printing inside of main loop, it is still 80000000
, even during normal operation of the device.
req: c0 b2 value: 0000 index: 0000 length: 0001
CMD_GET_REVID_VERSION
Fx3UsbUsbCoreIsr
PROT
STATUS_STAGE
power val 80000000
power val 80000000
power val 80000000
power val 80000000
power val 80000000
power val 80000000
Fx3UsbUsbCoreIsr
PROT
SUTOK_EV
req: 40 b1 value: 0000 index: 0000 length: 0003
CMD_START
flags=80, sample_delay_h=00, sample_delay_l=02
Fx3UsbUsbCoreIsr
PROT
STATUS_STAGE
But when booted via USB:
req: c0 b2 value: 0000 index: 0000 length: 0001
CMD_GET_REVID_VERSION
Fx3UsbUsbCoreIsr
PROT
STATUS_STAGE
power val 80000001
power val 80000001
power val 80000001
power val 80000001
power val 80000001
power val 80000001
power val 80000001
power val 80000001
power val 80000001
power val 80000001
Fx3UsbUsbCoreIsr
PROT
SUTOK_EV
req: 40 b1 value: 0000 index: 0000 length: 0003
CMD_START
flags=80, sample_delay_h=00, sample_delay_l=03
Fx3UsbUsbCoreIsr
PROT
STATUS_STAGE
this looks like a silicon bug to me but :shrug:
Would you be okay with removing the check inside while?
So basically when running from RAM then the block is initially out of reset and active, which makes sense. Forcing it into reset makes it not active, and then when you let it out of reset it's active again. So far everything seems sane.
Now when you're running from SPI the block starts out in reset and not active. This also seems reasonable. The only weird thing is that when you release the reset, it does not become active. Then when you make a new reset again it does not become active. So this still feels like there is something that needs to be initialized first, which is implicitly done during USB boot but not SPI boot.
A relevant question is of course what the exact consequences of UIB not becoming "active" is, considering that you suggest that everything works seemingly correct even without it... Did you try USB2 (High Speed) mode as well? (IIRC "SUTOK_EV" means you are in the SuperSpeed path.)
Let me correct myself - when I don't deassert reset after SPI boot, it doesn't work (boot). After USB boot it works because it is runinng already. The register behaves the same in USB-HS. Additionaly, I found out it doesn't work (pulse view doesn't capture any samples) in USB-HS in any configuration.
Hello,
how do I load the firmware? These are my built files:
I tried flashing
fx3lafw-cypress-fx3.fw
directly to SPI flash but it doesn't boot.