timestamped reading doesn't work proper Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
dsteinwe
XCore Addict
Posts: 144
Joined: Wed Jun 29, 2016 8:59 am

Post by dsteinwe »

It is assigned at line 43. Maybe, you mean, that it isn't initialized in front of the while loop, i.e. after "t :> time;". This won't have an effect, because of the var locked. last_time isn't relevant in the first and second iteration, because locked is lower than 1:

Code: Select all

if (locked > 1 && ((duration < low_sr) || (duration > high_sr))) {
The code is some years old, but as far as I can remember, I figured out, that it tooks 2 iteration, until the timeout mechanism works proper.


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

Post by mon2 »

I am not following the code logic but the var last_time should be initialized to a known value before it can be used.

Line # 35 makes use of this unknown power up value. Not good.
Line # 36 performs a compare on this known power up value. Also not good.
User avatar
dsteinwe
XCore Addict
Posts: 144
Joined: Wed Jun 29, 2016 8:59 am

Post by dsteinwe »

Hi, Mon2. I have added the line "last_time = time;" after "t :> time;". Now, it is initialized. I have tested the code. The problem persists.
User avatar
akp
XCore Expert
Posts: 578
Joined: Thu Nov 26, 2015 11:47 pm

Post by akp »

I wonder if the 32 clocks delta between pt and pt1 is due to being 32 clocks to clock the 32 bit shift register?
User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Hi. Having difficulty following the code flow - could you please review and reply with the answer to the following?

Code: Select all

   // Calculating new port time
    pt = port_time + transport_bit_width;

    // Calculate new timeout
    t :> time;
    time += WCLK_WAIT_TIMEOUT;

    while (true) {
        [[ordered]]
        select {
            // When a word was received
            // 
            // can you explain the operation of the next line?
            // p_wclk is read @ pt time (where pt is calculated above)
            // the read contents of p_wclk is copied into the var value
            // then the current port counter value is stored into the var pt?
            //
            case p_wclk @ pt :> value @ pt :   
                // Check sample rate
                t :> time;
                last_time = time;
                //
                // now last_time and time are of the same value
                //
                // so duration will always be zero - correct?
                //
                unsigned duration = time - last_time;
  
Is this understanding correct?

the var duration will always be zero?
User avatar
dsteinwe
XCore Addict
Posts: 144
Joined: Wed Jun 29, 2016 8:59 am

Post by dsteinwe »

I wonder if the 32 clocks delta between pt and pt1 is due to being 32 clocks to clock the 32 bit shift register?
@akp: The delta is not 32 but -32 (negative). I suppose the real delta is something like (n*2¹⁶ -32). Why? I can't explain.

@all: Now, I have cut down my real project to a single source code file. I have created 2 projects. One of them runs only my prototype. The other one runs on the xmos multichannel audio board. Because Murphy is my best friend, the error doesn't occur on the xmos board ;-). The source code of both projects is mostly the same. Only the hardware initialization differs. I hope, you will to understand the code, when you see the whole inside a runnable projekt.

@mon2:
// can you explain the operation of the next line?
// p_wclk is read @ pt time (where pt is calculated above)
// the read contents of p_wclk is copied into the var value
// then the current port counter value is stored into the var pt?
"pt" is calculated inside the function "i2s_slave_rx_task" (have a look inside my zip). It's the port's counter timestamp, when wclk switches to 1 or 0. "i2s_slave_rx_task" contains an endless loop. It tries to detect a valid i2s signal, by watching the wclk port state. When the port switches between 1 and 0 in a defined time interval (function "wait_until_wclk_level"), the signal is locked, the port's counter timestamp is taken as parameter for the function "process_data", you already know. The function "process_data" is called from i2s_slave_rx_task, when the signal is locked.
case p_wclk @ pt :> value @ pt :
// Check sample rate
t :> time;
last_time = time;
// now last_time and time are of the same value
//
// so duration will always be zero - correct?
//
I expect, that the value is always greater zero, because "case p_wclk @ pt" will take a while until it is triggered (some nano seconds). But in the first iteration, the calculated duration will be lower than "low_sr", because the timestamp isn't taken at port state change but a little bit later. Therefore I have introduced "locked", to ignore the duration the 1st and 2nd iteration (and indirectly time and last_time).
Attachments
projects.zip
(261.17 KiB) Downloaded 185 times
projects.zip
(261.17 KiB) Downloaded 185 times
User avatar
dsteinwe
XCore Addict
Posts: 144
Joined: Wed Jun 29, 2016 8:59 am

Post by dsteinwe »

I have new results, I want to share:
1.) My test project has also the read problem. It was masked, because I had some code, that was executed before calling process_data(). The execution of this code took more than 1.3ms. As you may remember, the read error happens at neary 1.3ms.
2.) The xscope output is not the problem. I have removed the output and I set a port from low to high, when the read error happens. And the port goes high.
3.) Because the problem does not happen to the ma board, I suppose, it may be a problem of the i2s source. The ma board uses a cs5368. I use a ak4118. Fortunately, I have a separate board with a ak4118, that I could connect to the ma board. Surprise, surprise: Now, the read error happens even to the ma board. That means, that the ak4118 must causes the problem.
4.) What I still don't understand is the difference between pt and pt1. I would expect, that the values should be the same.
User avatar
dsteinwe
XCore Addict
Posts: 144
Joined: Wed Jun 29, 2016 8:59 am

Post by dsteinwe »

Well, I have found a register setting for the ak4118, that seems to fix the problem. When I set the bit 5 to high of the register at address 0h, the problem doesn't occur any more. Bit 4 and 5 configures the "Master Clock Operation Mode Select". Originally, I had set both bit set to zero. In this mode, the ak4118 even transmits a signal at a very low frequency, even when the ic has no input signal. If I set bit 5 to high, the low freq signal is not transmitted from the ak4118 any more, when the ic has no input signal. I don't really can explain, why the low freq signal causes the read error after 1.3ms. But my tests shows, that it is the cause.
Post Reply