EXT Cartridge Module

I’m currently in progress of making an EXT module which accepts carts via the slot on the top.

Following design considerations were made:

  • Cart should have USB to allow things like an SDR to be put in
  • All GPIO should be exposed on the cart connector
    • The fan is switched with an I2C port expander to keep it separate
  • The two original USB ports should still be available
  • GPIOs should be buffered to not accidentally destroy the DevTerm
    • This also allows the GPIO to be switched between 5V/3V3

Current schematic:


Routing is ~90% done.

Current hurdles:

  • Determining the USB sockets on the original EXT board, or finding a suitable alternative.
    • Found the Molex 482580001 which seems like a good fit
  • Same with the fan connector

I hope I can find out more about the USB sockets or at least the fan connector when my unit arrives.

Shoutouts to this excellent thread by DustinWoods for providing a table with the RPI compatible GPIO assignments.

This is still a WIP, and surely I’ve made some mistakes in the design.
I’d be happy letting me know about those if you spot some.

5 Likes

This sounds like a great idea. While the printer can be useful, especially for making stickers, having the option to better use that space in the devterm would be appreciated, and there are likely many like me who don’t have the skills to make their own ext board waiting for something like this.

Out of interest, are you intending on having the cartridge slot inside the devterm or have the connector just inside the door, with the cartridge on the outside allowing for bigger wierder shaped cartridges? Is there any plan for a breakout for camera connection in this or no?

My hope is that maybe you could cartridgeize the printer, but I have no idea about the dimensions yet.

It’s the former one I believe, here’s a rough draft in FreeCAD.

I routed the camera pins to the same FPC connector as the original EXT board,
with the difference that CAM_ENABLE and CAM_LED are driven by an GPIO expander.

18 IO that goes to your cart, I’m not sure what you plan to do with that.

As an example, to address 64kB of memory, a 6502 need 16 wires for the address bus, 8 for the data bus, and a one pin for the Read/Write signal, which in total make 25 IOs.

You don’t need to be compatible with the raspberry pi header, in fact, I would recommend to not be. You can drop all but one of the ground, all but one of +5V and same for the +3.3V. I don’t know what you want to do with that “VCOM” but as you already provide 5V and 3.3V to the connector it is useless.

Keeping only one 5V, one 3.3 and one ground would give you 15 more pin that can be used as IOs.

And as I’m here, the TXS0108 are not necessarily the most suited, you probably want to use the TXB0108 instead. The TXS are meant to be used for open drain link like I2C, the TXB for all the rest.

To use the TXS as general purpose you need to have pull-up on each IOs. Also I highly recommend to to the voltage translation if needed in the cart, not on that board. It will save price and complexity on that board and no need to have a switch that people will forget to move. But if you really want to use that way I would recommend to call that voltage rail VIO instead of VCOM.

Also as I’m thinking about it, use a proper edge connector and not these rubbish 2x20 pin connectors like the one used on the rPi. It will be easier to install/remove the cart and with a little bit of mechanical design you can make it as a proper cart that you insert in the device instead of having protruding board that will only wait to break because of their weight.

At least that how I would do it.

1 Like

Hooking it up to hardware like with a raspberry pi, if I need to flash a chip, or scan some I2C bus for instance. I see what you’re getting at tough, for more elaborate things this doesn’t cut it.

Correct, but the DevTerm only has 18 IOs in the first place, I could use something like the FT232H instead of the native IOs instead tough.

Thanks for spotting that mistake, I’ll use the TXB0108.
Those are primarily for protection just in case, I’d rather fry a $2 component than the much more expensive core. The level shifting is really just a gimmik that came free with it.

The only redeeming qualities of those are tough that they’re widely available and easy to implement, which is why I just went with these.
I could wire up a cartridge with a perfboard if I want to. With an edge connector, you’d need a custom PCB. Looking into that, finding a connector seems harder than anticipated.
I agree tough, an edge connector would be very much nicer.

Thanks for pointing these issues out.

Cool, just FYI there are no cables out there that let you connect the Devterm FPC connector to a pi camera so might be a good suggestion to change it to the one the Pi Zero uses as it’s only slightly bigger

Will do, not using the Pi Zero one tough but rather for the standard RPI.
If I’m not mistaken it’s 1mm pitch with pinout being identical to what’s on the original EXT.

Might as well use this post for an update:
I decided to redesign the entire board! Instead of pinheaders, it’ll use the C64 cartridge edge connector. It’s the easiest to design around by far, modern edge connector shopping makes my head spin.
That’s 44 pins available.

Next thing is IO: Rather than using the native IOs, I’ll incorporate a FT4232H, that’s 32 IOs total.
Then there will be one USB connection and the DevTerm’s I2C bus, the latter to maybe autodetect a plugged cart.
Then with 4xGND, 2x5V and 2x3V3, all 44 pins are assigned.
Here’s the WIP on the pinout:

For more IOs you already have the ones from the MCP23008 which are not used, and you can add a second one to add even more Its. They will be slower than GPIO directly from the CPU, but that’s still more IOs

If you just want outputs, you can chain a couple of 74xx594 or 595, and if you want to go the other way you can simply use some 74xx165, there are probably some that can do both way.

And don’t bother with a USB→GPIO module, this will be more painful than anything and with somewhat unpredictable latency, I would not recommend.

But after all it is your design, I just express my own vision here :slight_smile:

1 Like

With that many pins on the connector, it might be useful to reserve one as a cartridge presence detect that requires minimal/no logic on the cartridge.

Should be easy enough to implement - it’ll just be a GPIO on the edge connector which will be pulled low by the cartridge when inserted. A simple cartridge could use a resister connecting the presence detect pin to a ground pin - or a more complex cartridge might boot up a microprocessor which then pulls the pin low.

Might also be interesting to expect an I²C eeprom on a certain address on the cartridge with some identification information to handle “plug and play” style detection of which device is in the slot.

None of this would be needed for usb-only devices, of course, since usb has its own hot-plug/detection support.

oh yes, active sensing with part identification!

a few options:

  1. eeprom as you mentioned
  2. a simple shift register on the cartridge, with each input pin connecting to vcc or gnd.
  3. analog stuff. use ADC to identify parts (common in retro tech?).

this will be essential for cartridge plug-n-play.

also it can enable some dynamics re-routing for the cartridge, if there’s the need. all pins stay hi-z on cartridge connection, until the part is identified, and the data paths configured properly.

Hm, is it really that bad? It’s the easiest solution by far.
I think tough that I’ve got an idea that works better.
Maybe it’s best to also bridge the GPIOs (J3) from the mainboard over to the module, then there’s no additional components needed, no latency or anything. No idea how yet, I’ll just have to wait for my unit to arrive to have a look at that connector.

Excellent idea, simple solution too. I’ll go with the active low idea for pin 1 and if need be, you can put an I2C EEPROM on the cart for more information.

Nak there’s no free pins there. Occupied by sdmmc/wifi/bt etc.

No free pins? Bummer.

I got a new idea tough.
How about a Teensy driving the IOs, with the peripherals/memory of the chip exposed via SPI?
Some back of the envelope calculations:
Assuming the DevTerms SPI is configured at 250MHz, and each memory access is 72 bits (1 byte instruction, 4 bytes address, 4 bytes response/argument) that would be 3.47 MBaud.
Assuming 5 ports to be serviced, that’ll be 10 read+writes, resulting in a 347kHz refresh rate.

You could make the protocol for peeking/poking slimmer tough to 40 bits (1 byte instruction, 1 byte GPIO Port number, 4 byte argument), equaling to 6.25 MBaud. Then assuming you need 2 instructions to read and write that would be a refresh rate of 3.125MHz if I’m not mistaken. That’s usable in my opinion.
Plus not to mention the peripherals. Having to bitbang protocols is a dealbreaker for me, plus ADCs are nice to have. I think there’s potential with this idea.

A shift register chain’s refresh rate for 16 inputs and 16 outputs would be roughly 250MHz/32 = 7.8125MHz, including a bit of error it’s twice as fast.

I2C port expanders are dog slow, those are also out of the question for that reason.

My gut feeling is to keep GPIO/bitbanging away from the arm core.
Latency wise it’s really not the most stable thing. And it’s no fun if Linux decides that the core needs a nap time during a critical flashing/communication/whatever session…
So +1 for onboard MCU :slight_smile:
Only connect core pins for hardware-accelerated stuff: I2S, I2C, MIPI, (is there SPI? I forgot…) etc.

wrt Teensy4.1: yeah I have that installed in my unit. Works great as a music production tool. My main concern would be cost and power efficiency – it draws +500mA from wall charger when I turn it on, and that’s why I decided to add power switches for my internal usb hub mod. Not sure about low power mode though.

But overall I think this is a good direction: an onboard MCU that does part sensing and identification, then ask the arm core to send over proper firmware for interfacing – how cool is that :smiley:

ps: there are a few free pins from the dt keyboard though! probably 6 of them are free.

After some deliberation, I settled on the Teensy4.0.
Might be a pain to solder to get access to all of the IOs, but well worth it as the 4.1 is simply too big for the board to route comfortably. Plus, the 4.0 is a match made in heaven in that regard, the communication traces just line up perfectly. Notably, the power consumption is generally less and the thing can be suspended when not in use. The 2nd USB (host) peripheral in there can apparently be configured as an device, so I connected it via the host interface to the USB hub.
The current plan is not being able to flash the Teensy unless you connect to its USB socket,
Not nearly as cool, but some concession have to be made.

I also added a simple header for the debug serial for convenience, but it requires that you bring your own adapter.

Here’s the current state of parts placed:

I’m currently wondering which of the DevTerms GPIO is interrupt capable.
Might be useful to have a signal coming from the Teensy when data is ready for instance.
The current state of the DevTerm GPIO assignments is the following:


Teensy STM IRQ would be the interrupt from the µC to the DevTerm.

Update: Here’s the pinout of the cartridge slot

1 Like

Nice! And interesting way to draw the IO bus that never occurred to me before :stuck_out_tongue:

How many UARTs does Teensy have :open_mouth: Feels like 4x4 midi will be within reach very soon!

I’m currently wondering which of the DevTerms GPIO is interrupt capable.

A lot of them are.

Mind throwing a bunch of these in? https://assets.nexperia.com/documents/data-sheet/74HC_HCT4053.pdf

This could allow cartridges to carry dt core-hardware-accelerated stuff, like a camera, hdmi-to-mipi-csi, HiFi audio (just 2 channels unfortunately, I looked up the rk3399 (A06) datasheet) etc, that each cartridge pin can be multiplexed to different purposes.

How many UARTs does Teensy have :open_mouth: Feels like 4x4 midi will be within reach very soon!

It has 7! I guess implementing a 4x4 MIDI cart would be trivial with these.

A lot of them are.

Good to know, any hints on where I can quickly reference this. Maybe the device tree?

Mind throwing a bunch of these in? This could allow cartridges to carry dt core-hardware-accelerated stuff, like a camera, hdmi-to-mipi-csi, HiFi audio (just 2 channels unfortunately, I looked up the rk3399 (A06) datasheet) etc, that each cartridge pin can be multiplexed to different purposes.

Oh man. I’m a fan of this idea but that means extra work.
I can switch 10 IOs with minimal additional effort.
That would for instance mean that all the camera lanes can be MUXed.
Can they be useful tough outside of camera applications? How hard is it to reconfigure linux if there are other accelerated signals available on these IOs?
Incorporating the PCM interface is possible, which would leave 6 signals. Just enough to have the RPI style camera connector in a cart. So a mix of these two. I think I’ll move forward with this.

That will be the last thing that can fit real estate wise. :wink:


Update: I read somewhere the following:

The CSI lines meet the MIPI D-PHY spec, so switch voltage based on whether in Low Power (LP) or High Speed (HS) mode.

If I read that correctly, the HCT4053 can be an analog switch right?
Is it like a voltage follower or does it clamp the voltage to the one supplied to VEE?
If it’s the latter, I’ll just add the PCM interface.

Good to know, any hints on where I can quickly reference this. Maybe the device tree?

The rockchip TRM is the first place to go: https://opensource.rock-chips.com/images/e/ee/Rockchip_RK3399TRM_V1.4_Part1-20170408.pdf
DeviceTrees extract info from this and turn it into mysterious code (despite some magic numbers are defined in the bindings, people still write plain numbers :frowning: )
Read Chapter 20, GPIO.

Interrupts
Port A can be programmed to accept external signals as interrupt sources on any of the bits of
the signal. The type of interrupt is programmable with one of the following settings:
 Active-high and level
 Active-low and level
 Rising edge
 Falling edge

… So all banks (0-4) x portA(a0-a7) can do interrupts. In the kernel, you just first request a gpio pin, and then request an irq for that pin, and call it a day.

If I read that correctly, the HCT4053 can be an analog switch right?
Is it like a voltage follower or does it clamp the voltage to the one supplied to VEE?

Yeah 4053 is an analog switch :smiley: (mind that the T variation only works with 5V!)
It’s more like a plain wire (bi-directional) than a voltage follower, with some 600ns per volt (there are faster variants, see below), but I think it clamps to Vcc, not Vee. I guess we can have Vcc=5V and Vee=3.3v so that Teensy gets comfortable with the switch signals, but agnostic about the mux/demux

Here’s a pin-compatible, high speed chip, MAX4619: https://datasheets.maximintegrated.com/en/ds/MAX4617-MAX4619.pdf

  • This guy does not have Vee, but the digital side (pin A/B/C) are 3.3v-compatible no matter what Vcc is.
  • Typical characteristics on Vcc=3.3v:
  • Typical characteristics on Vcc=5v:
  • Higher the Vcc, faster the chip is
  • At Vcc=5v, the On-resistance is consistently under 5ohm (a long long copper wire :stuck_out_tongue: ):

Can they be useful tough outside of camera applications? How hard is it to reconfigure linux if there are other accelerated signals available on these IOs?

The only thing I’m aware of is hdmi-mipi converter, which could turn dt into:

  • a KVM thing.
  • if the cartridge is a self-sustained system, that’s where the video output would go

The kernel has to be configured in a few spots – the device tree (for pinctrl, and enabling the rockchip mipi driver), and a camera driver (mipi is just a protocol, a camera needs init sequence packets) if I understand correctly.

1 Like

Wow, thanks for the in-depth response!
Hopefully I did the idea justice first try.

Update RevB v.0.2:

Here’s the current schematic:


We got D0±, D1±, CN± and as promised the PCM interface on Mode B.
The camera connector has been dropped from the equation with that addition.
Some things:

  • Minor mistake: I did cross MISO/MOSI on the communication lines, silly of me to confuse it with USART.
  • Since I got the DevTerm today, I found out which connector to use for the fan, so that’s all components sorted.
  • Will the MUX routing hold up?
    I did use some vias and the lengths aren’t matched on the differential pairs (it’s not too that bad tough).
  • I’m considering embedding python into the Teensy’s firmware.
    You can’t flash it from the DevTerm, but wouldn’t it be neat to send some interpreter code over?
    Plus you could embed the compiled interpreter code in the cart enumeration EEPROM.
  • Do we want to use a battery with the Teensy? Used to retain state when suspending and also provides an RTC. I think the SoC in the DevTerm already has one.

About those cart ideas…

a KVM thing

Neato, so basically a capture card with HID forwarded?
Too bad the USB device is already taken, tough theoretically possible if you port TinyUSB and bitbang it.

cartridge is a self-sustained system

Now that’s an idea, what if you put in an FPGA (plugging your thread here).
That is something that might get me into doing VHDL again. :smirk:

First thing tough I’m designing for it is just a plain RPI card. It’s hacker industry standard love it or hate it.
Also makes developing easier, talking to hats and such.

A GameBoy Camera type of thing would not only be cute, but interesting.

1 Like

Great job! Enjoy your first contact with DT :smiley:

  • Do we want to use a battery with the Teensy? Used to retain state when suspending and also provides an RTC. I think the SoC in the DevTerm already has one.

DT does not have RTC battery. But I don’t think Teensy would lose the states in low power mode either…
It is important though, to plan ahead (when designing the board), the mechanism for Teensy to suspend/wakeup. Not all interrupts can wake up the chip – learned it when I try to drop the DT keyboard into low power mode but it cannot wake up anymore ((

Plus you could embed the compiled interpreter code in the cart enumeration EEPROM.

  • NES: 6502 execute code from cartridge
  • DT: … executes python from cartridge

This is so retro-future. :exploding_head:

Too bad the USB device is already taken, tough theoretically possible if you port TinyUSB and bitbang it.

There are still two free SPDTs on U9… cough cough