Debug FX3 via JTAG

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
bojankoce
Level 3
Level 3
25 replies posted 10 replies posted 5 replies posted

Hello, guys!

I hope this message finds you well!

We have a custom board with FX3 USB SuperSpeed controller on it. We clock it with external 19.2MHz clock and use it in USB Boot mode (PMODE[2:0] = F11). Also, there is a JTAG connector on the board where we connect J-Link Base Segger debugger. We are using latest J-Link drivers (J-Link GDB Server V6.60d).

Eclipse-based EZ-USB Suite (version 1.3.4) is used as firmware development environment for FX3. Our firmware starting point is AN75779 with multi-thread ThreadX RTOS.

I followed instructions from EzUsbSuite_UG.pdf document on how to set-up Eclipse project and debug it via JTAG.

However, when I resume debugging right after initial breakpoint here is what I get:

Reading 64 bytes @ address 0x10001FC0

Reading 72 bytes @ address 0x00000000

Reading 72 bytes @ address 0x00000000

Reading 72 bytes @ address 0x400061C8

Starting target CPU...

ERROR: Bad JTAG communication: Write to IR: Expected 0x1, got 0x0 (TAP Command : 2) @ Off 0x5.

According to some threads from this forum (link), this error occurs with the FX3 family during JTAG debugging using the Segger J-Link. This is due to change in FX3 CPU frequency during runtime. This is also suggested on the page 20 of the Cypress ES-USB FX3 SDK release note document. I tried what they suggest (adding some commands to the Startup tab of Debug Configurations) but with no success!

Some other threads (e.g. here) suggest setting breakpoints at application define function (CyFxApplicationDefine()) as well as UVCAppThread_Entry() function. Although it is not quite clear how to debug after setting above breakpoints, I tried to debug with Step Over (F6) button. After successfully pressing a button a few times I get again the same above error!

Am I missing something here?

Some threads (e.g. this) say it is complicated to debug AN75779 firmware due to the presence of multi-thread RTOS. Is that true?

Is there any known issue with debugging FX3 via Segger J-Link? From this thread on Segger forum (March 2019), it seems that the CYUSB3014 is currently not officially supported.

Also, to the best of my understanding, default debugging interface in AN75779 example is UART interface that is initialized with CyU3PDebugInit() function. After that, CyU3PDebugPrint () function is used to print debug messages. I did not touch that part thinking that UART and JTAG can co-exist together. Is that assumption correct or I need to initialize JTAG interface somehow in my code and disable UART? AFAIK, JTAG debugging interface is not initialized in AN75779.

Is there any counterpart of the CyU3PDebugPrint () function that will allow me to print debug messages in JTAG mode?

Thank you very much, guys, for your time and efforts. It is really appreciated!

Sincerely,

Bojan.

0 Likes
1 Solution

Hello Bojan,

Can you check debugging the firmware after disabling CyU3PSysEnterSuspendMode mode API. It is working fine at my end(with SDK 1.3.4.

also let me know the SDK version you are using.

You can put the breakpoints in for {} loop and check. which parameters are you trying to debug.

Regards,

Rashi

Regards,
Rashi

View solution in original post

12 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello Bojan,

I tried to reproduce the problem at my end.

Please confirm that you have not put breakpoint at  CyU3PKernelEntry () . This is a non returnable call for initializing the RTOS kernel.

When i put a break point at this function call i got the similar error as mentioned by you

jtag_fx3.PNG

Re: fx3 segger CyU3PKernelEntry ();  As per this thread you can put the breakpoints CyFxApplicationDefine  and CyFX3AppThread_Entry

functions.

By default the debugger will stop at main, put the above mentioned breakpoints and then you can try debug step by step till CyU3PKernelEntry. To skip entering CyU3PKernelEntry you can do step over here and then normally run the debug. It should stop at CyFxApplicationDefine and then CyFX3AppThread_Entry

Please try this and let me know the results

Regards,

Rashi

Regards,
Rashi
0 Likes

Hello, RashiV_61​.

I confirm that I did not put any breakpoint at CyU3PKernelEntry().

I already noticed the thread you mention in your post about putting breakpoints at CyFxApplicationDefine() and CyFX3AppThread_EntryHere() functions. I put the breakpoints on the place where those functions are defined:

Untitled.png

Is that OK?

After that, when I start debugging, the debugger stops at apiRetStatus = CyU3PDeviceInit (0); line (first command after main). I suppose that is OK because we have specified that first breakpoint should be at main() function.

After that you suggest me to do step by step debugging. What exactly does that mean - pressing step over (F6) ?

I debug step by step by pressing step over (F6) button until the moment I arrive at CyU3PKernelEntry() function. Then I press step over (F6) one more time. My debugger stops at ptr1 = CyU3PMemAlloc (UVC_APP_THREAD_STACK); line. This is first line in CyFxApplicationDefine() function so I suppose this is also OK.

After that I press Resume (F8) button and my debugger stops at CyFxUVCApplnDebugInit (); line. This is the first command inside UVCAppThread_Entry() function so I suppose this is also OK.

When I press Resume (F8) button one more time I get the error:

Setting breakpoint @ address 0x40005788, Size = 4, BPHandle = 0x002E

Setting breakpoint @ address 0x400060A4, Size = 4, BPHandle = 0x002F

Starting target CPU...

ERROR: Bad JTAG communication: Write to IR: Expected 0x1, got 0x0 (TAP Command : 2) @ Off 0x5.

Is there anything I am doing wrong or missing?

Sincerely,

Bojan.

0 Likes

Hello Bojan,

Please try this and let me know the results

- After stopping at main(), put the breakpoint inside for {} (inside CyFxAppThread_Entry)

- Press Resume F8. Is the debugger stopping there. If yes, press again F8 Resume

If this doesn't work please share the snippets of debug configurations for each tab

Regards,

Rashi

Regards,
Rashi
0 Likes

Hello, RashiV_61​.

Here is what I did:

1) Removed breakpoints from UVCAppThread_Entry() and CyFxApplicationDefine() functions.

2) Started debuging that stops at main().

3) Put breakpoint inside for{} loop of UVCAppThread_Entry() function (this is the equivalent of CyFxAppThread_Entry() function in AN75779 example).

4) Press Resume F8. Debugger stopped on the breakpoint specified in point 3)

5) Pressing Resume F8 again throws an error:

Reading 64 bytes @ address 0x4003B500

Read 4 bytes @ address 0x00000000 (Data = 0xE59FF028)

Reading 72 bytes @ address 0x40005794

Performing single step...

Reading all registers

Setting breakpoint @ address 0x40005794, Size = 4, BPHandle = 0x0003

Starting target CPU...

ERROR: Bad JTAG communication: Write to IR: Expected 0x1, got 0x0 (TAP Command : 2) @ Off 0x5.

Here are debug configuration snippets:

Main.png

Debugger.png

Startup.png

This should be according to the instructions from EzUsbSuite_UG.pdf document.

Regards,

Bojan.

0 Likes

Hello Bojan.

Please let me know the clock frequency your  application. Have you set the system clock to default i.e 384 MHz  using CyU3PDeviceInit (0); or set it to 403.2 MHz

The commands you passed in the setup tab are incorrect.

If the clock input is 19.2 MHz and CPU at highest frequency 384 MHz

Add these two commands in the window

monitor memU32 0xE0052000 = 0x00080014

monitor sleep 1000

OR if clock input is 19.2 MHz and CPU at highest frequency 403.2 MHz add

monitor memU32 0xE0052000 = 0x00080015

monitor sleep 1000

If this still doesn't work. Please try the debugging gpioapp example from the SDK.

- the debugger will stop at main

- Keep one break point in for loop

- Press Resume F8

Regards,

Rashi

Regards,
Rashi
0 Likes

Hello, RashiV_61​.

Please let me know the clock frequency your  application. Have you set the system clock to default i.e 384 MHz  using CyU3PDeviceInit (0); or set it to 403.2 MHz

FX3 is clocked with 19.2MHz and master clock frequency is set to default (i.e. 384MHz with CyU3PDeviceInit (0)).

The commands you passed in the setup tab are incorrect.

If the clock input is 19.2 MHz and CPU at highest frequency 384 MHz

Add these two commands in the window

monitor memU32 0xE0052000 = 0x00080014

monitor sleep 1000

If you take a closer look in the setup tab, you will see that all the command lines are commented with #. I was playing earlier with both monitor memU32 0xE0052000 = 0x00080014 and monitor memU32 0xE0052000 = 0x00080015 commands. According to the Getting Started with FX3 SDK.pdf document (page 42, 5.1.1 Clock Settings), there is a transient instability on the device interfaces if we change the master clock frequency. Given the fact that we leave the master frequency to be default one by calling CyU3PDeviceInit () function with NULL argument, there will be no need to put any command inside setup tab.

If this still doesn't work. Please try the debugging gpioapp example from the SDK.

- the debugger will stop at main

- Keep one break point in for loop

- Press Resume F8

I was able to successfully debug gpioapp example the way you explained to me. It was also needed to set a breakpoint to CyU3PKernelEntry (); function and Step over (F6) while debugging because this is non returnable call.

I returned back to my AN75779 app and realized that debug error always comes after this line:

apiRetStatus = CyU3PSysEnterSuspendMode(CY_U3P_SYS_USB_BUS_ACTVTY_WAKEUP_SRC, 0, &wakeReason);

The line is inside this routing of the UVCAppThread_Entry() function:

            /* As per the USB3 specs, link layer takes 10ms (Max.) to leave U3 state. If the device sees some spurious (unwanted)
             * USB activity it will leave suspend mode (even though USB is in U3 state). The device can wait for 10ms (U3 exit LFPS duration)
             * and check the Link Layer State. If the link layer is not in U3 state, CX3 device will wake up else it will enter suspend mode */

              do

                {

                    apiRetStatus = CyU3PSysEnterSuspendMode(CY_U3P_SYS_USB_BUS_ACTVTY_WAKEUP_SRC, 0, &wakeReason);

                    if ((apiRetStatus != CY_U3P_SUCCESS) || (CyU3PUsbGetSpeed() != CY_U3P_SUPER_SPEED))

                        break;

                    /* Wait for the maximum U3 exit LFPS duration. */

                    CyU3PThreadSleep(10);

                    /* If the link is still in U3, we can continue to attempt Suspend mode entry. */

                    apiRetStatus = CyU3PUsbGetLinkPowerState(&usb3mode);

                    if ((apiRetStatus != CY_U3P_SUCCESS) || (usb3mode != CyU3PUsbLPM_U3))

                        break;

                }while(1);

Could I resolve the issue if I step over UVCAppThread_Entry() function? How can I do it, where exactly should I set breakpoint to be able to step over? I put a breakpoint on the place where the function is defined but pressing Step over (F6) drives me line by line through the function, until the point I call

apiRetStatus = CyU3PSysEnterSuspendMode(CY_U3P_SYS_USB_BUS_ACTVTY_WAKEUP_SRC, 0, &wakeReason);

After that, I get the debug error!

One more thing... Is there any way for us to print debugging messages through the JTAG interface (similarly like we do with CyU3PDebugPrint() function through UART debug interface?

Thanks in advance for your time and efforts, RashiV_61!

Sincerely,

Bojan.

0 Likes

Hello Bojan,

Can you check debugging the firmware after disabling CyU3PSysEnterSuspendMode mode API. It is working fine at my end(with SDK 1.3.4.

also let me know the SDK version you are using.

You can put the breakpoints in for {} loop and check. which parameters are you trying to debug.

Regards,

Rashi

Regards,
Rashi

Hello, RashiV_61​.

I am using SDK 1.3.4 as well.

I disabled the whole block with

    #ifdef false
                do
                {
                    apiRetStatus = CyU3PSysEnterSuspendMode(CY_U3P_SYS_USB_BUS_ACTVTY_WAKEUP_SRC, 0, &wakeReason);
                    if ((apiRetStatus != CY_U3P_SUCCESS) || (CyU3PUsbGetSpeed() != CY_U3P_SUPER_SPEED))
                        break;

                    /* Wait for the maximum U3 exit LFPS duration. */
                    CyU3PThreadSleep(10);

                    /* If the link is still in U3, we can continue to attempt Suspend mode entry. */
                    apiRetStatus = CyU3PUsbGetLinkPowerState(&usb3mode);
                    if ((apiRetStatus != CY_U3P_SUCCESS) || (usb3mode != CyU3PUsbLPM_U3))
                        break;
                }while(1);
    #endif

After that, I was indeed able to successfully debug! The question is now what would be the consequence of the above block being disabled?

I don't have any particular parameter I want to debug at the moment. Simply, I just wanted to properly set working environment before starting development. I would like to debug receiving command messages from PC side, communication with the FPGA etc. Is there any way we can print our messages in a CyU3PDebugPrint() way through JTAG interface?

Sincerely,

Bojan.

0 Likes

Hello Bojan,

Thank you for the update.

The UVC driver puts the USB bus into suspend mode when there is no bus activity (application is closed). This will generated the USB Suspend event. You can see this is handled in the CyFxUVCApplnUSBEventCB. When the USB bus is in suspend mode CyU3PSysEnterSuspendMode API is used to put FX3 device into suspend mode until any of the wakeup (in this case usb bus activity) sources are triggered.   So, calling this API will stop the CPU. If you don't want to call this API the FX3 device wouldn't be in low power mode. There wont be any effect on the application as such.

Is there any way we can print our messages in a CyU3PDebugPrint() way through JTAG interface?

>> Apologies for missing out this in previous post. There are no APIs provided in FX3 API guide which can send debug messages over JTAG.

Regards,

Rashi

Regards,
Rashi

Hi, RashiV_61​.

Thanks for additional clarification.

If there is no way to send debug messages over JTAG, how can I debug the code? What are debugging strategies in that case? How can I set some flags in my code that will help me to know the flow of the program? By using the breakpoints?

Sincerely,

Bojan.

0 Likes

Hello Bojan,

As per my understanding the JTAG debugging can be done using breakpoints i.e. checking the register values, variable values. You can use UART for debugging if you want to see some prints.

Regards,

Rashi

Regards,
Rashi
0 Likes

OK, RashiV_61​, thanks so much for your great support. I really appreciate it.

Cheers,

Bojan.

0 Likes