libquadflash/hardware timer conflicts? Topic is solved

If you have a simple question and just want an answer.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

libquadflash/hardware timer conflicts?

Post by cjameshuff »

We have one task which sets up an interrupt using a hardware timer. The handler is trivial, all it does is update some counters and toggle a port pin. Another task performs firmware downloads using libquadflash.

We are seeing very strange errors where fl_writePage() and fl_readPage() fail, the readback differing from what was written. Sometimes it's a genuine write failure (the issue was discovered through flash corruption) and sometimes it's the readback that fails, two consecutive readbacks differing from each other. The failed readback being all-FF's in all cases I've seen. The errors occur only if the interrupt is running, and their rate tracks the interrupt frequency.

Has anything like this been encountered before? Any thoughts on possible causes or troubleshooting approaches?


View Solution
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Not an official reply but based on your observations, could you block the interrupt from running when you are performing your flash access using libquadflash? Just a suggestion for a work around.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

Post by cjameshuff »

The interrupt is keeping an audio clock running at the correct rate, the side effects would be severe. Aside from that, there's no apparent reason for these pieces of code to interfere with each other.

One additional bit of information: it only appears to happen if the task that starts the interrupt and the task that accesses the flash are in the same combined block.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

Post by cjameshuff »

Attached is a stripped down test project that reproduces the issue.
Attachments
interrupt_flash_issue.tgz
(364.17 KiB) Downloaded 226 times
interrupt_flash_issue.tgz
(364.17 KiB) Downloaded 226 times
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

Post by cjameshuff »

Forgot to mention: this is a project for the xCORE-200 MC Audio eval board.

The test project uses combined tasks because that's the situation the problem was encountered in. It also occurs if the flash access is done in the same task that the interrupt is configured in. The problem seems to result from the interrupt running on the same core as the flash code. It does not occur if they run on separate cores.
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Comment out the printf line in your combinable code. What are your results?

Code: Select all

[[combinable]]
void timekeeper_task()
{
    timer tmr;
    unsigned t;
    
    pll_ctrl_init();
    
    tmr :> t;
    t += REFCLK_HZ;
    
    while ( 1 ) {
        select {
            case tmr when timerafter(t) :> t:
            {
                uint32_t count;
                int32_t stamp;
                
                pll_ctrl_get_stats(count, stamp);
             //    printf("count=%lu stamp=%ld\n", count, stamp);   // comment out this line for testing
                
                t += REFCLK_HZ*2;
                
                break;
            }
        }
    }
}
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

Post by cjameshuff »

mon2 wrote:Comment out the printf line in your combinable code. What are your results?

Code: Select all

[[combinable]]
void timekeeper_task()
{
    timer tmr;
    unsigned t;
    
    pll_ctrl_init();
    
    tmr :> t;
    t += REFCLK_HZ;
    
    while ( 1 ) {
        select {
            case tmr when timerafter(t) :> t:
            {
                uint32_t count;
                int32_t stamp;
                
                pll_ctrl_get_stats(count, stamp);
             //    printf("count=%lu stamp=%ld\n", count, stamp);   // comment out this line for testing
                
                t += REFCLK_HZ*2;
                
                break;
            }
        }
    }
}
...I stop getting printouts of the interrupt count and timestamp.
Were you expecting something different?
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Does your flash access code work after this line is made into a comment?

Concern is that the general printf method is blocking and will impact the timing due to the very slow printing process.

You have options to use printf in realtime for similar debugging:

http://www.xmos.com/de/support/tools/do ... ion=X1093A

If you are already using the faster method for printf then ignore this suggestion otherwise the removal of this printf should have improved your results. Please post your results when convenient.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

Post by cjameshuff »

The printf() statement has no effect on the flash read and write errors.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm
Contact:

Post by cjameshuff »

A further-simplified version of the test code: the interrupt and flash activities take place in a single task instead of relying on the compiler to combine two tasks, and a test pattern is written to a single page of flash, and then repeatedly read. This can be run continuously without burning out the flash, and every flash operation should be identical. I also added code to print out the failed readback attempts, changed the test pattern to make it clearer what was going on, and configured the XScope I/O to handle the additional debug output. This in turn required changing the interrupt rate, as the flash reads synchronized with it in a way that tended to avoid failures for long stretches at a time.

The failures seem to consistently happen two bytes in a row, each failure dropping several bytes. A logic analyzer shows the dropped bytes being read from the flash and the SPI transaction being extended by the number of dropped bytes, reading 0xFFs once the page is completed. fl_ReadPage() always writes 256 B to the buffer, adding those 0xFFs at the end.

It would be straightforward to write my own flash code, but that leaves the possibility of the interrupt continuing to do something it shouldn't and causing other problems, it's only a solution if the issue is caused by a defect in libquadflash. How and why is this interrupt interfering with the libquadflash code in this manner?
Attachments
interrupt_flash_issue2.tgz
(364.06 KiB) Downloaded 225 times
interrupt_flash_issue2.tgz
(364.06 KiB) Downloaded 225 times
Post Reply