Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

synchronization error #20

Open
1250364116 opened this issue Sep 18, 2024 · 7 comments
Open

synchronization error #20

1250364116 opened this issue Sep 18, 2024 · 7 comments

Comments

@1250364116
Copy link

hi alex. when i work with keyboard the device prints accidently synchronization error message. in other words device captures the strokes in some cycles and does not capture anything in other times because of synchronization error while I have configured the device speed correctly. what this synchronization error exactly means? because I saw when the size is more than 0xffff this message is printed out. what does this criteria mean?

@ataradov
Copy link
Owner

Synchronization error means that you likely started the capture in the middle of the packet and when this happens, there is no way it can recover, since it needs to track start of packet and end of packet markers to know when the packets start and end.

If this happens in the middle of the capture, then there is likely some noise on the line that gets interpreted as SOP, but EOP is not received for a long time.

This is an unfortunate side effect of the low performance device, there is no way to reliably detect the idle state. I made some improvements towards that in the recent updates and it made things better, but still not 100%.

This is why it works better when the sniffed device is reset before the capture starts, so there is no chance of capture starting in the middle of the packet.

@ataradov
Copy link
Owner

ataradov commented Sep 18, 2024

Note that there are a few vendors selling the hardware for the full sniffer on AliExpress now. I don't endorse any if them, but they are there if you want to try. And if you are doing serious work, then having the full version is so much better.

@1250364116
Copy link
Author

1250364116 commented Sep 18, 2024 via email

@ataradov
Copy link
Owner

It is not start of the bit, but start of the packet. SOP is denoted by a switch from idle to the K state. The sniffer does not have enough resources to really observe the idle state, I just assume that the line is idle and wait for the K state. But the K state is also used in signalling the bit states. So, if start the capture in the middle of the packet, it can't correctly receive the data.

Ideally capture need to observe both D+ and D- to make complete decisions about the line state, but PIO does not have enough resources to do so. I observe one line and derive the state of the other.

If the sync issue happens in the middle of the capture, then it may be the noise created by the wiring setup. Long exposed unshielded cables would pickup some noise. If the sync issue happen at the begging of the capture, it is just an unfortunate timing.

There is a chance you can do a bit better in finding the idle state before starting the capture, but I don't have any interest in doing so. When you can have a real sniffer for $30, wasting time on this very limited one does not seem to be worth it.

@1250364116
Copy link
Author

thank you, i have read what you have explained about pio asm code, and the possibility of starting the capture when the line is in the middle of a packet. thus some problems created in my mind:
first I understand the pio asm execution code sequence as follow:

1-the first moment after a reset or powering on, the PIO0 SM, executes line 31 of the code:

/* 31 */ OP_WAIT | WAIT_POL_1 | WAIT_SRC_PIN | WAIT_INDEX(2),

in which the PIO0 waits for PIO1 to trigger the start pin.PIO1, first checks
the EOP by executing the code bellow for multiple times:

/* 4 */  OP_MOV | MOV_DST_OSR | MOV_SRC_PINS | MOV_OP_BIT_REV,
/* 5 */  OP_OUT | OUT_DST_Y | OUT_CNT(2),
/* 6 */  OP_JMP | JMP_COND_Y_NZ_PD | JMP_ADDR(4/*wait_se0*/),

and then after ensuring the EOP, in USB line, it triggers start pin as follow:

/* 16 */ OP_SET | SET_DST_PINS | SET_DATA(1), // Set the START output
/* 17 */ OP_JMP | JMP_ADDR(17/*self*/), // Infinite loop

So, pio1 is sparing pio0 ,the first time after powering on, to recognize the first J state as idle(in low-speed mode) and we cannot
expect the capture unit to get into the packet's middle, while pio1 is performing like this. this is my opinion about start of capture after powering on or reset.

2.after the first idle state and SOP, the code always samples the packet bits exactly in the 5th cycle after the bit starts(as you
mentioned before the pio clock is 10 times of USB clock so it is exactly the middle of the bit), till the time EOP situation happens, so when the sampler sees EOP it pushes out both data and (0xfffffff-size), and then goes to these lines:

// poll_loop:
/* 25 */ OP_MOV | MOV_DST_OSR | MOV_SRC_PINS | MOV_OP_BIT_REV, // Sample D+ and D-
/* 26 */ OP_OUT | OUT_DST_Y | OUT_CNT(2),
/* 27 */ OP_JMP | JMP_COND_Y_NZ_PD | JMP_ADDR(0/*idle*/), // If either is not zero, back to idle
/* 28 */ OP_JMP | JMP_COND_X_NZ_PD | JMP_ADDR(25/*poll_loop*/),
/* 29 */ OP_MOV | MOV_DST_ISR | MOV_SRC_NULL | MOV_OP_INVERT,
/* 30 */ OP_PUSH,
// Wrap to 0 from here 

in the code above, the sampler is checking if the USB line remains in the EOP yet(by sampling both lines), or something else has happened. this will be repeated 31 times, if the line does not exit the EOP state after 31 cycles sampler will push a 0xffffffff number(perhaps as a USB reset flag) and then everything wraps to the first line where sampler is looking for an idle state.

so my conclusion is, when the PIO is looking for an idle state in the first line I think we are sure that certainly an EOP situation is exactly the last thing has happened before, because as I see the sampler can get to the first line in two ways, first after a start signal triggered by PIO1, second after EOP of the last sampled packet. and in both situations the capture cannot start from the middle of the packet if we use a proper clock for the PIO.
(so the synchronization error happens if USB frequency and pio frequency does not match)

@ataradov
Copy link
Owner

ataradov commented Sep 24, 2024

Your reasoning is correct. The EOP detection PIO was added much later and it reduced synchronization errors by a lot, but not entirely. I'm not so sure about your conclusion though. I don't think it has anything to odd with the clock mismatch.

The state machine here actually implements tracking of the clock and the sample point constantly adjusting, just like regular USB controllers do, so in theory it should be able to track any reasonable frequency deviations.

It is possible that there is some bug in that tracking or somewhere else, or some other scenario that we don't take into account. You can debug that if you want, I personally don't have any interest in it. This project was just a training to figure out how PIOs work and it achieved its goal. It is useful in a pinch, but if you really need to do any real work, use real tools.

@1250364116
Copy link
Author

1250364116 commented Sep 24, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants