raphnet / dreamcast_usb

Dreamcast controller to USB adapter firmware
GNU General Public License v2.0
30 stars 5 forks source link

Arduino Micro: Getting a weird 6.64us gap in some requests #3

Open bryanparadis opened 4 months ago

bryanparadis commented 4 months ago

I'm new to embedded electronics and I am porting this to Arduino IDE using an Arduino Micro. I have the code communicating with the controller but I am having weird issues that result in LRC errors. I am guessing it has to do with some requests having a weird gap in the middle of 6.64us.

Gap image

No Gap image

Going to keep looking into it! Thought I would document here. Maybe someone else is curious.

bryanparadis commented 4 months ago

Looks like I am never seeing any weird gaps in the signal from the controller only on transmit. Gaps can be almost anywhere. Time to understand a bit better how these are sent.

bryanparadis commented 4 months ago

Haven't been able to reproduce the issue in the signal after shoving noInterrupts() in setup but the LRC errors remain. Will need to look further into what could be happening. The responses look identical for successful and unsuccessful STATE_READ_PAD requests

bryanparadis commented 4 months ago

Still don't understand what LRC is but if I define NOLRC the controller data seems to be ok. The NOLRC ifndef block itself seems to mutate data.

bryanparadis commented 4 months ago

Here are the two results I am getting with data[i] being output as DEC:

Successful Read

1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128  42 0 0 191 212 196 0 0 1 216 64 6 4 1 

LRC Error

1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 0 191 212 196 0 0 1 216 64 6 4 1 

No visual difference in signals at all on the oscilloscope or logic analyzer. At least that I have spotted yet. Might need a closer look. The main difference seems to be that data[4] is 1 instead of 0 and data[8] - data[9] are before button byte1+2 instead of afterwards.

bryanparadis commented 4 months ago

It's working great with NOLRC defined. Still no 100% about LRC check and what it was doing.

raphnet commented 4 months ago

There is probably a mix of issues here.

You certainly want to disable interrupts when receiving data from the controller, since this is very intensive - there is absolutely no time to be interrupted. Looks like you took care of this globally, but it should only be necessary when receiving data from the controller.

LRC is to detect transmission errors. Maybe there are none, but if there are, you may see occasional buttons presses or glitches which may cause undesired operations in-game.

I'm not sure what your setup is, but the analog traces shown in your first screenshot are suspiciously smooth and of low amplitude. They should be full swing between 0 and 3.3v. Not something like what I see here where the voltage sometimes oscillates between 0 and 2v. When the voltage is not high enough, what was supposed to be a logic 1 might be interpreted as a 0.. This may be a source of LRC errors.

How are you converting the Data signals between 5v to 3.3v? What is the MCU used on your board? What is your clock source and frequency?

I wrote this page about the development of this project, there are screenshot of what the signals should look like. Those should be quite square (almost like the logic analyzer waveforms) and have a full swing.

https://www.raphnet.net/programmation/dreamcast_usb/index_en.php

bryanparadis commented 3 months ago

You certainly want to disable interrupts when receiving data from the controller, since this is very intensive - there is absolutely no time to be interrupted. Looks like you took care of this globally, but it should only be necessary when receiving data from the controller.

I just wrapped it around send/receive but I can wrap it just around the asm for both things for sure.

LRC is to detect transmission errors. Maybe there are none, but if there are, you may see occasional buttons presses or glitches which may cause undesired operations in-game.

Thanks for explaining what it is for. I need to take another good look at it since I am way more familiar with the maplebus code now. What does LRC stand for?

I'm not sure what your setup is, but the analog traces shown in your first screenshot are suspiciously smooth and of low amplitude. They should be full swing between 0 and 3.3v. Not something like what I see here where the voltage sometimes oscillates between 0 and 2v. When the voltage is not high enough, what was supposed to be a logic 1 might be interpreted as a 0.. This may be a source of LRC errors.

Sorry about that. It's the Analog for the same channel on the Saleae Logic Analyzer 8 with a sample rate too low to give me nice square signals.

How are you converting the Data signals between 5v to 3.3v?

I have a 5v->3v3 level shifter between it and the Dreamcast. I have some higher performance level shifters now that I could use as well. It's possible that they are a bit too slow causing ambiguity like you mentioned above.

What is the MCU used on your board?

It is a Atmega32u4 on a stock Arduino Micro.

What is your clock source and frequency? Onboard clocksource of the Arduino Micro which I believe ends up at 16Mhz.

I wrote this page about the development of this project, there are screenshot of what the signals should look like. Those should > be quite square (almost like the logic analyzer waveforms) and have a full swing.

Yes. I think they look much better on my scopes though I do remember them being maybe a tad slow and not quite square. The faster level shifters I picked up probably will improve the situation. I have it reading two controllers at a time now just fine without LRC.

I am going to have to look at the LRC a bit more to understand what is going on. I've had to change the pins that I am reading from so maybe that might have something to do with it. Either that or my level shifters are not performant enough.

Thanks so much for your response. Sorry for the low sample rate analog on the logic analyzer.

bryanparadis commented 2 months ago

Finally got around to looking at this again and I am pretty sure that my issues are due to my BMS138 logic level shifter not being able to keep up.

image image

Tried a TXS0108E based shifter but had nothing but problems. Doesn't seem to play well with what I am doing. Maybe I will need to try a 3.3v based device with my code to see if the LRC issues go away.

bryanparadis commented 2 months ago

So without level shifting and even better signal quality it seems I still have LRC issues

17:42:58.200 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.200 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1
17:42:58.200 -> 1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128 42  0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.200 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.200 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1
17:42:58.200 -> 1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128 42  0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1
17:42:58.200 -> 1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128 42  0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1
17:42:58.235 -> 1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128 42  0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.235 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 191 0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.235 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1
17:42:58.235 -> 1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128 42  0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.235 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 170 0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1
17:42:58.235 -> 1 0 0 0 0 0 0 1 255 255 0 0 128 128 128 128 42  0 149 24 129 2 5 1 9 57 21 0 37 7 LRC ERROR1
17:42:58.235 -> 1 0 0 0 1 0 0 0 0 0 255 255 128 128 128 128 250 0 149 24 129 2 5 1 9 57 21 0 37 7 READ SUCCESSFUL1

I will have to dig in a bit more here to see what I can find. The order seems to be changing. Other than that there is one value that moves around quite a bit 170/42/191/250 without any controller input

bryanparadis commented 2 months ago
1 0 0 0 1 0 0 0 0 0 255 255

Looks like the main issue is that the second 1 0 0 0 sometimes flips to 0 0 0 1 and at the same time the next 4 values of 255 255 0 0 also are flipped to 0 0 255 255.

bryanparadis commented 2 months ago

So if I print out the data array are decoding I get something like this:

READ SUCCESSFUL1
22:57:25.075 -> 1 0 0 0 0 0 0 1 FF FF 0 0 80 80 80 80 2A 0 95 18 81 2 5 1 9 39 15 0 25 7 35 
LRC ERROR1
22:57:25.550 -> 1 0 0 0 0 0 0 1 FF FF 0 0 80 80 80 80 2A 0 95 18 81 2 5 1 9 39 15 0 25 7 35

They are identical but one has an LRC ERROR and LRC = 213. Have to dig further to see XOR data into LRC sometimes fails.

bryanparadis commented 2 months ago

Looking further into it I cannot see any glitches or disturbances with a 50Mhz scope when the CRC is jumping around. If I switch the assembly to use rept instead, which I think adds 1 instruction per sample, it starts to fall apart further. Adding an additional nop and it pretty much breaks. Thinking maybe we are on the very edge of being able to sample the maplebus at 16mhz at 2 instructions per cycle. On my Saleae Logic 8 it decodes the maplebus data and crc properly 100% of the time.

bryanparadis commented 2 months ago

If I set up my Saleae Logic 8 analyzer to 8 MS/s which matches the original assembly (2 instructions per cycle? in + st) the crc isn't always read correctly. Now I am not familiar enough with any of this to understand exactly what sample rate this signal requires but looks like 16mhz is undercutting it. Maybe an atmega32u4 running at 3v3 would help enough to make the crc usable? I am reading at 5v logic level.