We are working on using the UART communication on ...
# sky130
g
We are working on using the UART communication on the MPW-7 bring up boards, but cannot figure out how to get the FT232H to drive UART_EN low. There are two buffers which disconnect the UART when the housekeeping SPI is in use, but when you just use screen on the ft232’s serial port, the two buffers are disabled and no UART is received. We can connect the hardware jumper J2 to receive only from the management core, but that does not feel like the intended solution. Has anyone had any luck with this?
👀 1
m
AFAIK, you either have the jumper or you have to use any additional serial to USB converter
t
@jeffdi knows the solution to this, also possibly @Passant. There are hints in the
caravel_hkflash.py
file, which toggles the LED on ACBUS2 (and/or ACBUS3?). There are several not-well-documented procedures in pyftdi; in the code,
gpio = spi.get_gpio()
provides access to the low-level bit control over the FTDI chip ACBUS, and
gpio.set_direction()
,
gpio.configure()
, and
gpio.write()
control those bits. There is also in the python code a
class Led
which has a definition that looks to me like it would interfere with any attempt to control ACBUS pins other than the one driving the LED.
(It was never specifically mentioned, but the FTDI
ACBUS0
pin is the one that drives the enables on the switches of devices U2 and U3 which connect the FTDI to the UART pins on Caravel). It is also possible that only the header shunt has ever been used to drive the enable and that nobody has ever written a proper software solution for it.
g
Yes, I went there, but that doesn’t work because in UART mode those are not available as gpio pins. You can set the gpio pins in SPI mode, but then they get reset to tristate when you try to enter UART mode
g
For context, “It is not possible to assign the unused pins of an UART mode to arbitrary GPIO functions.” - https://eblot.github.io/pyftdi/api/uart.html#gpio-access “Upper pins (b7..b15), on devices that have ones, cannot be driven while UART port is enabled.”
t
That seems like a weird restriction.
g
It’s in the FT232H datasheet as well
t
I wasn't suggesting it isn't true, it's just weird. I can't think of a reason why they would make the chip behave that way.
g
Yeah me neither
We’re currently looking into whether we can add an inverter to the HKSPI CS line to use as UART_EN
Both those pins are accessible, so we will see if that works. I also just noticed that the HKSPI CS line is missing a pull-up resistor; in UART mode the pin used for HKSPI CS line is configured as CTS input, and the FT232 datasheet does not mention an internal pull-up, so the HKSPI CS line is potentially floating whenever the HKSPI is not in use
One other note, if the EEPROM were connected, it is allowed to configure certain pins of the ACBUS to CBUS I/O functionality during UART, and you could use the cbus_gpio commands in pyftdi to contol them, but it does not appear that you can configure those without the eeprom
t
Thanks for the investigation. I have raised the issue internally to Efabless and we'll look at possible solutions (i.e., board redesign, maybe try the EEPROM solution). Let me know if using the HKSPI CS line (inverted) works.
👍 1
g
The saleae trace attached has the full notes, but summary is no. The CS line does not go low during the entire time the HKSPI is being driven by the FTDI chip. It looks like you would need either an EEPROM ($0.70) or a two-interface chip (FT2232H is an option, ~$1 more than an FT232H) might be a better solution to just support simultaneous UART and SPI without all this fanciness.
t
Another fix we thought of is that you should be able to put a pull-up resistor on UART_EN. That way, when the UART is enabled on the FTDI and the line gets tristated, it will pull up and enable the UART. But then it is necessary to force that line to zero in the programs that run flash programming and housekeeping access. That might require some code changes (Note: I did not look at the schematic, so I may have the sense of the UART enable inverted).
g
That’s a great idea, I’ll look into it
t
Just watch out for the interactions between
gpio.set_direction()
,
gpio.write()
, and the routines defined in the
Led
class.
led.toggle()
does a
gpio.write()
when it really should be attempting to leave the state unchanged except for the one bit used for the LED.
g
Yeah, I got annoyed with how cluttered all those scripts were, I have a rewrite of them which has an HKSpi class to isolate the communication implementation portions that is a lot cleaner I’ll make available once I verify it works
t
Cool! Can we get hold of your version? I'd like to get rid of all the mess in the posted scripts as well.
(Sorry, posted before your edits.)
g
All good
We’re on a private gitlab instance right now, the repo’s public but it is probably still inaccessible
t
No, I get a log-in screen.
g
Cool, I’ll make that available in a better form in a bit
Here’s the new python scripts, both these and the old ones drive UART_EN high during SPI usage, so I added a 1kΩ resistor across the J2 jumper and everything appears to be happy. I get UART and can program and nothing seems to be letting out magic smoke. Note, the FTDI chip pulls UART_EN high with ~75kΩ in UART mode, so when I first used a 10kΩ, pulldown, that wasn’t enough to enable the buffers.
t
@gling: By the way, there are way more registers available in the housekeeping SPI than indicated by caravel_hkdebug.py. I suggest changing line 35 from
Copy code
for reg in [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12]:
to:
Copy code
for reg in range(0, 0x70):
There are some unused registers in that range but it covers all of them. I think most people are unaware that all the GPIOs can be configured and driven high/low directly through the SPI interface, and the full set isn't in the repository documentation. The mapping is defined in the caravel repository
verilog/rtl/housekeeping.v
lines 344 to 483.
👍 2
@jeffdi (@Andrew Wright): It would be nice to replace the caravel_board repository util/ directory with the contents of the zip file above, which is a much cleaner implementation (and corrects a few errors besides).
g
We discovered one issue with spi.close() not being supported on one installation of pyftdi we were using, so added a check to call terminate if close is not available. Also added the util changes as a pr to efabless/caravel_board.
t
I went ahead and approved the pull request.