BerkeleyLab / Marble-Mini

"Marble-Mini" Simple FMC carrier board with SFP, 2x FMC, PoE
16 stars 6 forks source link

Annoying MMC reset behavior #60

Closed ldoolitt closed 4 years ago

ldoolitt commented 4 years ago

On every USB connection to the FT4232 UART attached to the MMC (/dev/ttyUSB3 on Linux), the DTR line is asserted and the MMC gets reset. Having some ability to reset the MMC via USB is clearly a helpful feature, but it shouldn't be a mandatory side effect of attaching to the UART. We've searched for a way to not trigger a reset using FT4232 features, and come up short.

Our colleagues at LNLS found similar behavior on one of their boards, and ended up using a XNOR gate on DTR and RTS to generate the reset. That empirically works; the skew between DTR and RTS on a connection event is small enough that an 0.1 ms RC filter on the output of the XNOR gate can avoid spurious resets.

Would it also work to move the reset logic on DTR from port D to port B (currently unused)?

gkasprow commented 4 years ago

IN AFCZ design I added a SMT "DIP" switch to solve that issue.

michael-betz commented 4 years ago

Does it happen when plugging in the cable or when opening the UART?

It's a workaround but in miniterm.py you can set the initial state of the DTR line:

miniterm.py /dev/ttyUSB3 115200 --dtr 0/1

I wonder if that would help.

I like the XOR idea!

Am Mo., 15. Juni 2020 um 06:45 Uhr schrieb Greg Kasprowicz < notifications@github.com>:

IN AFCZ design I added a SMT "DIP" switch to solve that issue.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/BerkeleyLab/Marble-Mini/issues/60#issuecomment-644144527, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABWOMKZ2WFL3GL5GHL4RDTTRWYQX5ANCNFSM4N526N4Q .

gkasprow commented 4 years ago

Look at this circuit. I had an issue with resetting MMC while USB insertion. It was caused by FET capacitance obraz

ldoolitt commented 4 years ago

That's the circuit we use now. No problems on USB insertion. MMC goes into reset when you attach a terminal program. I don't have a board in front of me; someone else needs to try @yetifrisstlama's miniterm.py recipe.

gkasprow commented 4 years ago

OK, I use Termite and don't have issues, but colleagues who use Linux report such a problem. That's why I added the switch. Make sure that when you add some logics, the default flashing utility will still work.

smpaiagua commented 4 years ago

I can confirm that while this doesn't work: miniterm.py /dev/ttyUSB3 115200 --dtr 0

This does: miniterm.py /dev/ttyUSB3 115200 --dtr 0 --rts 0

Which is what I've been doing manually with gtkterm.

Thanks for the workaround @yetifrisstlama !

ldoolitt commented 4 years ago

In AFCZ design I added a SMT "DIP" switch to solve that issue.

I can't find such a DIP switch in my copy of the AFCZ schematic. Is that version of the design published somewhere?

gkasprow commented 4 years ago

It's on the MMC schematic obraz

smpaiagua commented 4 years ago

I can confirm that while this doesn't work: miniterm.py /dev/ttyUSB3 115200 --dtr 0

This does: miniterm.py /dev/ttyUSB3 115200 --dtr 0 --rts 0

Which is what I've been doing manually with gtkterm.

Thanks for the workaround @yetifrisstlama !

Unfortunately while this makes it easier to connect to the MMC, there's still a reset glitch when opening the connection. This reminded me of a long-running pyserial thread I ran into when I first encountered this issue: DTR and RTS control lines toggle unintentionally when opening port

augustofg commented 4 years ago

The Linux kernel will raise the DTR and RTS lines (lower in logic levels) every time a program successfully opens a serial port, causing a reset if one of these signals is connected directly to the microcontroller reset pin. This is a kernel behaviour and can not be changed by a userland application:

https://github.com/torvalds/linux/blob/a5dc8300df75e8b8384b4c82225f1e4a0b4d9b55/drivers/tty/tty_port.c#L408-L420

https://github.com/torvalds/linux/blob/a5dc8300df75e8b8384b4c82225f1e4a0b4d9b55/drivers/tty/tty_port.c#L475-L481

https://github.com/torvalds/linux/blob/a5dc8300df75e8b8384b4c82225f1e4a0b4d9b55/drivers/tty/tty_port.c#L697-L699

You could patch your kernel to avoid this behaviour (just comment out the contents of the tty_port_raise_dtr_rts function, it works but it isn't an elegant solution).

I can confirm that while this doesn't work: miniterm.py /dev/ttyUSB3 115200 --dtr 0

This does: miniterm.py /dev/ttyUSB3 115200 --dtr 0 --rts 0

Which is what I've been doing manually with gtkterm.

Thanks for the workaround @yetifrisstlama !

It will reset the microcontroller, but the terminal application will lower DTR and RTS (raise in logic levels) as soon it opens the serial port so the microcontroller restarts, unless there is a sufficiently large RC filter that prevents this (from my measurements, it takes about ~2ms to change the DTR/RTS signals back when using USB-to-Serial converters, but I wouldn't consider it a reliable delay).

As mentioned by @ldoolitt we at LNLS have dealt with this problem using a XNOR gate between DTR and RTS and a small RC filter as DTR and RTS don't change exactly at the same time:

screenshot-2020-06-11_19-42-17

ldoolitt commented 4 years ago

Supposedly fixed for the next batch (in the fab2 branch) commit 0f366d635, by moving RTS_OUT and DTR_OUT from U23 (FT4232) bank D to bank B. This is something retrofittable on the first batch, by someone skilled with cutting traces and adding white wires. That would allow testing this fix for unwanted side effects.