I’ve been investigating ways to handle multiple supplies and consumers of +5V 500mA power in a single project, and it’s surprisingly complicated. My circuit may have up to three simultaneous external connections: a device needing +5V power at “A”, an external +5V supply at “B”, and something at “C” that might either supply +5V power or need +5V provided to it, depending on what mode the circuit is operating in. Any of these three could be present or absent, and the external +5V supplies could possibly be connected but turned off and not delivering power.
The simple solution would be to directly connect all of those +5V lines within my circuit. That would work, and maybe it’s what I’ll do, but it presents some risks of unintended current backflow into a supply. Imagine if B and C are both connected, with C configured as a supply. If one is turned off, the other would feed +5V into it. Depending on what that supply is and how it’s designed, feeding external +5V back into a device that’s turned off may cause weird behavior or damage. A similar problem could arise if a poorly-designed device on A actually powers the +5V line instead of drawing power from it, because it has batteries or an independent supply of its own.
I’m willing to handle the bidirectional nature of C with a physical switch. But I still need something that ensures current only flows in the intended direction in/out of A, B, and C, as shown in the diagram above. The ground connections aren’t shown, but they are all tied together. Current direction arrows mean diodes, right? I think diodes would theoretically work, but probably aren’t the best choice. A diode would cause a substantial voltage drop between the supply and whatever it was powering, and you need a diode that’s physically large in order to handle significant amounts of current.
A better solution might be a transistor. From studying similar circuits, a good choice might be a power MOSFET. These have a very low resistance when switched on, resulting in only a small voltage drop. A small-sized MOSFET could also handle all the 500mA current I need for this project. But I don’t have any experience working with single MOSFETs in this kind of application. I get a bit bogged down in discussions of N and P type, enhancement and depletion, high-side and low-side switching, and so forth. I’m not completely confident I’d know which specific MOSFET to select for my purpose, and how to connect it in the circuit, and what limitations or unexpected behaviors it might have.
An even better and simpler solution might be a power distribution switch IC, like the Microchip MIC2005A. This is basically a MOSFET, but one that’s designed for this specific purpose, with some extra features like soft start, current limiting, and thermal protection. And in the SOT-23 package I’d likely use, it’s not much more expensive than a generic MOSFET.
Power distribution ICs are designed to conditionally enable a power supply, and they have an /ENABLE pin to determine when to energize OUT from the supply at IN. But I would be using them always enabled, just to get the reverse current protection feature. Maybe that means this is the wrong tool for the job, and a different solution would be better?
A second question is whether a power distribution IC like the Microchip MIC2005A actually provides reverse current protection. It has terminals labeled IN and OUT, but it’s not clear if anything prevents current flowing from OUT to IN if OUT is energized by something else. I skimmed the datasheet, but couldn’t find any mention of this.
A final question is whether connecting the OUT terminals of several MIC2005A chips would cause problems. That’s what I’d need to do, if both B and C might function as +5V supplies. I can imagine this might cause a problem if one of the MIC2005A chips finds its OUT terminal at +5V even though its IN terminal is at 0. Or it might be a problem if both B and C were turned on at the same time, both delivering “5 volts”, but one was 4.9V and the other 5.1V. I didn’t see anything in the datasheet that addresses this either.
I’m trying very hard to keep the total cost of this solution low, like 50 cents or less. There are more complex power management ICs that might simplify things, but cost $2 or more apiece. Add the cost of assembly, and a retail markup sufficient to get acceptable margins, and the final sales price of the product would have to be increased by an unacceptable amount. I would probably choose to eliminate functionality instead, or just use the “connect all +5V supplies” approach, before I made a significant increase in product price just to support power management.
My diagram shows five current direction arrows, so potentially I would need five MOSFETs or MIC2005As. But I don’t actually need one on the line to the “circuit” cloud, because there’s no possibility of current flowing the wrong way. And the two arrows at C could probably be collapsed into a single arrow, if I used a DPDT switch that reversed the connections to the MOSFET or MIC2005A terminals. And I maybe don’t really need the arrow at A. If a device at A were to backflow +5V power, it would turn on the circuit, and possibly also supply power to C depending on the switch setting. That would be unexpected, but I don’t think it would harm anything. Applying all those simplifications, I might be able to get away with as few as two MOSFETs or MIC2005As, squeaking under my arbitrary $0.50 budget.Read 6 comments and join the conversation
Good news from my RetroUSB project! I finally have a working proof-of-concept, connecting a modern USB keyboard and mouse to a classic 1980s Macintosh SE computer. A microcontroller and small pile of related components perform the necessary conversion between USB and ADB, acting as a USB host and translating the input events into the Apple Desktop Bus protocol used by the Macintosh. It’s still a long way from being a finished design, but the hardest part is done, and I’ve proven that this approach can work.
Reading and writing ADB bus traffic is implemented entirely in software, checking and setting I/O pin values using hard-coded delays. The USB side of the converter uses the built-in USB functionality of the PIC32MX microcontroller. In order to avoid impacting the hard-coded delays in the ADB routines, interrupts are disabled whenever listening for or responding to ADB bus commands. These periods where interrupts are disabled can last for several milliseconds, and at first they caused major problems for USB communication, which I detailed in my previous post.
With the help of a logic analyzer, I eventually determined that the problem was caused by sending USB packets too late during the USB frame, so that they weren’t finished before the end of the frame. This was a side-effect of re-enabling interrupts midway through a USB frame, causing the PIC to start sending packets even though the 1 millisecond USB frame was almost over. Fortunately the PIC has a USB setting to handle this: U1SOF, the start-of-frame threshold. If the number of bit times remaining in the current USB frame is less than U1SOF, no new USB tokens will be started until after the next SOF has been transmitted. Through experimentation, I found that doubling or tripling the default U1SOF value eliminated the USB errors I was experiencing. Here’s a figure from the datasheet:
So the basic functions of a USB to ADB converter are now working, as you can see in the video. I can simulate multiple ADB keyboards and mice, complete with ADB collision detection and address remapping. And I can read up to eight USB keyboards and mice at the same time, directly connected or through a USB hub. I can also log traffic and statistics over the serial port for debugging. Now there are a million smaller details to address:
Brownouts. The ADB bus directly powers the whole collection of hardware, including the USB hub, keyboard, and mouse. It draws about 120 mA from the Macintosh SE, which is well within the 500 mA spec. Yet I measured the 5V line drooping as low as 4.3V, and the 3.3V supply for the PIC drooping as low as 2.6V. Sometimes the PIC’s supply voltage gets low enough to trigger a brownout reset. I’m not sure what’s going on here. Maybe my breadboard wires and hand-soldered ADB connector have a few ohms of resistance, causing a voltage drop.
Mouse Sensitivity. Initially the USB mouse was super sensitive, and only a tiny movement was needed to send the Mac’s mouse pointer all the way across the screen. I’m now dividing the mouse movement vectors by 4, but that makes motion less smooth.
Mouse Axis Mapping. An Amazon Basics brand optical mouse works fine, but a Dynex brand mouse appears to have its movement axes mapped weirdly. X and Y axis movements are combined and reported on the wheel axis, while wheel movements are reported on the X axis. This must be a software bug in the HID report parser.
Keypress Handling. I’m not truly handling USB keypresses properly, because a single USB key event is being translated into two separate down and up events for ADB. At present, it won’t correctly recognize when you press and hold a key.
Double Keypresses. Sometimes when I press a key once, it will be reported twice. Probably due to the dodgy keypress handling.
Power Button. Real ADB keyboards have a power button used to turn on the computer. This is a physical switch that completes a circuit between a dedicated ADB pin and ground. I’ll have to add a hardware button to my breadboard somewhere to act as the power switch.Read 6 comments and join the conversation
The mess on my desk is growing. In my attempt to use USB keyboards and mice with an old ADB-equipped Macintosh, I’ve got something that’s tantalizingly close to working. On the ADB side, I can simulate an ADB keyboard and mouse, complete with ADB collision detection and address remapping. It works great on the Macintosh, when I write a routine to generate fake input data. On the USB side, I can read a USB keyboard and mouse at the same time, through a hub. I can log all the collected data over the serial port. And I can do all of this from within the same program running on my PIC32MX230. Just not all at once.
Each interface seems to work fine by itself, but things go poorly when they’re combined. The USB-related interrupts introduce timing errors into my software bit-banged ADB implementation, so that ADB no longer works. Or if I disable interrupts during ADB activity, so the bit-banged ADB timing isn’t affected, then USB breaks in strange and subtle ways. USB devices will just stop reporting status after a short while, or attach/detach events will get missed, or the program will sporadically reboot itself. This is the problem of multi-tasking two interfaces that I anticipated last year while planning this project, and now here it is.
I know very little about how USB works “under the hood”, and would prefer to keep it that way, but it seems I’ll need to do a deep dive into the USB stack code. The multi-tasking interface failure is disappointing, because I’d almost convinced myself that the USB Host implementation should be able to tolerate occasional disabling of interrupts for the 5-10ms needed to handle an ADB transaction. Yes, USB activity is supposed to happen every 1ms, so 5-10ms with disabled interrupts would mean a lot of missed USB windows. But as the USB host, I initiate all USB activity, and ultimately I should get to determine when USB activity happens, whether that’s every 1ms or not. I was a bit surprised that it didn’t work, and even more surprised that it sometimes causes the program to reset. Maybe a buffer overrun somewhere causing a crash, or an intentional error handling mechanism somewhere in the USB stack?
I used a logic analyzer to observe that there’s still USB activity on the bus every 1ms, whether interrupts are disabled or not. That much must be performed in the PIC32’s USB peripheral, without any dependency on interrupts. But when interrupts are disabled, the USB traffic seems to consist entirely of 2.59 microsecond bursts that I’m guessing are the SOF (start of frame) packet and nothing else. With the ADB side disabled, I see occasional longer bursts of USB activity up to 126 microseconds mixed in with the shorter SOF-only packets. I assume these are the HID requests and reports, which seem to come every 10ms regardless of whether I request them more often.
I was able to partially debug what’s happening when input devices stop reporting status. The program appears to get stuck in a state where it requested an HID report, and is waiting forever for the reply. I’m not sure what caused that, or why there isn’t some timeout or error-detection in the USB stack. Perhaps there is, at a lower level of the USB stack that I haven’t yet examined, but then I need to understand why it’s apparently not working. Maybe I can fix this with some timeout-and-reset code, but there’s also the deeper problem lurking of the sporadic random reboots when multitasking ADB and USB. That scares me.
Some interesting little discoveries I’ve made while troubleshooting:
- The circuit draws 106 mA from the Macintosh’s ADB port, with my hardware plus an unpowered USB hub, one keyboard, and one mouse. That’s well within the 500 mA limit, and even within the lower 200 mA of the Powerbook computers.
- The axis data from my USB mouse is all backwards and confused. It’s something like Y axis movements reported on the X axis, and the wheel and X axis movements combined on the wheel axis. This probably means there’s a bug somewhere in the HID Report Descriptor parser in the USB stack. As I understand it, that’s the code responsible for understanding what format the report data will be delivered in.
- The USB mouse will detach and reattach itself every 30 seconds, if I don’t request an HID input report from it. As long as I request periodic input reports from it, it stays attached. In contrast, my keyboard is happy to sit there forever on the USB bus without me ever requesting an input report from it.
Long-time readers of this blog may remember a USB-to-ADB converter project that never made it past the concept stage. I wrote a series of posts about it last year, and made some decent progress with ADB emulation and USB host support. I ordered parts to build a second-generation prototype, but when they arrived, I let them sit on my desk collecting dust for 12 months. Until today.
The goal is to build a simple and reliable device for using modern USB peripherals with a vintage Macintosh or Apple IIgs computer. These classic machines normally use ADB peripherals, the Apple Desktop Bus. Last year I called this project “USB-to-ADB”, but that seemed to confuse many people into thinking it was for using ADB keyboards on a modern computer. In the hope of avoiding confusion, I’ve tentatively decided to rename this effort “Retro USB”. I welcome suggestions for better and less ambiguous names, especially names that somehow suggest a Mac and Apple II tie-in.
Today’s effort was about catching up to where I’d been a year ago. Using a breadboard and a bare PIC32MX230F256B, I assembled something more-or-less equivalent to the PIC32 USB Starter Kit board I’d used previously, and got it working. I also added an LCD screen for displaying diagnostic messages. Nothing terribly exciting yet, but it took me quite a long time just to get the PIC software installed, and learn how to wire up everything by hand for an LED blinker example.
PICs don’t seem to get much love in the hobby electronics world, so for those who didn’t read last year’s project posts, I’ll remind you how I ended up selecting the PIC32MX. To convert a USB keyboard and mouse to ADB, I need a microcontroller with USB Host support (uncommon, most only have USB Device support) and the ability to work with a USB hub, so a keyboard and mouse can be used simultaneously. This second requirement proved to be the more difficult one to meet, and the PIC32 series was the only one I found that had published sample code for accessing multiple USB devices through a HUB. In theory any microcontroller with USB Host could do it, since it’s “just software”, but I’m not interested in going deep into the bowels of writing my own USB stack.
I ran into a minor problem with the crystal oscillator. My example program worked fine with the PIC’s internal RC oscillator, but I couldn’t get it to work reliably with an external crystal and capacitors, as shown in the data sheet. It sort of worked sometimes, but was very flakey. I know crystal oscillator circuits are very sensitive to stray capacitance, and my breadboard circuits with their long component leads and loopy wires everywhere were probably too problematic. When I replaced the crystal circuit with an external clock in a can-type package, running at the same speed, it worked fine. I’m 95% sure this was just a breadboard problem, and if I reproduce the same crystal circuit on a well-designed PCB it will work fine.
It shouldn’t take me much longer to finish restoring the functionality I had with the old prototype, then I can finally begin the long-delayed work of stitching together the USB and ADB pieces of this project.Read 5 comments and join the conversation
The Snow White case for Floppy Emu is back in stock. This is my personal favorite: a matte white acrylic with a slightly textured surface, following Apple’s vintage Snow White design style, and with the looks of a miniature external floppy drive. It’s available with just the case, or as part of the Floppy Emu deluxe bundle.Be the first to comment!
Save 10% off Floppy Emu disk emulator hardware and accessories this week, in celebration of the 40th anniversary of the original West Coast Computer Faire! Use promo code FAIRE10 at the BMOW store to claim the discount, now through April 15.
The first West Coast Computer Faire in 1977 was a landmark event in the birth of the personal computer industry. Held April 15-17 in San Francisco, the show introduced kit and assembled computers to a general public audience of more than 10,000. WCC Faire was a key turning point in the evolution of computers from geeky curiosities into mainstream consumer products. The Apple II and Commodore PET both debuted at the event, along with hundreds of other exhibits of homebrew and commercial computer systems.
See original WCC Faire 1977 documents at DigiBarn.
Here’s an excerpt from a first-hand account of WCC Faire 1977 by David H. Ahl:
Ahl: You’ve got essentially what you call a black-box computer. Self-contained. You don’t really have to know anything except how to hit a switch. What type of market are you aiming at? Somebody that wants to do programming, play games, or what? Anything specific?
Markkula: All of the above and more. We really want to be the computer company, not the small-business computer company or something else – just the personal computer company! So that’s the reason you see a molded plastic case, BASIC in ROM, and so on. In fact we want to extend the whole concept to make it even easier to use.
Ahl: What’s the MPU chip in the Apple II?
Markkula: The 6502. It’s the most efficient chip for what we’re trying to do.
Ahl: What would a complete Apple II system require in terms of memory for the beginner?
Markkula: 4K is more than adequate. Remember the 4K that comes with a standard minimum system is all user space because the BASIC is in ROM. So almost all of the 4K RAM is available for programming and data.
Ahl: What would a system of that configuration cost?
Ahl: Is that assembled?
Markkula: Assembled, tested, complete with two game paddles and a complete carrying case so you can carry it around – all the cords and manuals and operation information.
Ahl: When do you start making deliveries?