I wrote the first PCMCIA driver for Windows CE in 1995. At the time, CE had not been ported to the PC, so we had to rely on reference platforms and prototypes to debug. Some problems were not software related.

The first Windows CE reference platform was called PeRP (Pegasus Reference Platform, Pegasus was the code name for Windows CE 1.0). The designer did not understand how the software would use the PCMCIA memory mapped regions. He thought he would be thrifty and “save” three gates by making a byte appear at every DWORD address. This is why the CE 1.0 Card Services API included such functions as CardReadAttrByte and CardWriteIOByte. A vestige of this design decision remained until CE 5.0 in CardMapWindow’s pGranularity parameter. On the PeRP, pGranularity would be set to 4 or sizeof(DWORD). On all other platforms it is 1.

The next Microsoft developed reference platform was called the Odo (after a Star Trek character). It had a pluggable CPU architecture so we could test the various processors supported by CE at the time. Those in charge of the decision were sometimes too quick to approve a new CPU board. In their view, I guess booting CE to the shell was good enough. The PCMCIA support always seemed to get overlooked. I was left scrambling to figure out another reason why PCMCIA was failing on yet another Odo CPU board. I became quite adept at setting up the logic analyzer for monitoring the PCMCIA bus, and adept at reading the traces. Sometimes this wasn’t enough.

On one flavor of MIPS CPU board for Odo, some cards would work fine, and others would get recognized, but then could not be used in I/O mode. By simply reading some of the PCMCIA lines with a multi-meter we found that the power lines had not even been attached! The cards were being powered by the address lines! This of course limited the amount of power available to the card. Any card requiring more than a certain amount of power would not work in I/O mode. A card in memory mode (the initial mode a card is in when first inserted) has minimal power requirements since the attribute memory is usually a small ROM. I/O mode usually requires much more power. The amount of power varies from one card to another. This is why some worked and others did not.

I have encountered many similar power related problems. Much of the time the root cause is that the batteries cannot supply enough power for the card. A closely related problem is that the device on battery power cannot power a card to operating voltage in enough time. That is why there is the power-on delay registry setting. Often, plugging in the A/C power adapter provides enough power in these cases.

            Another interesting problem had nothing to do with the PCMCIA controller hardware implementation and nothing to do with power. In version 1.0, CE did not support 16 bit I/O on PCMCIA. When support for it was added, there were some platforms that had problems. When I finally put the logic analyzer to work, I discovered that accesses to some byte-wide registers were not appearing in the trace. There were only 16 bit accesses. Configuring the software for the platform to report support for only 8 bit PCMCIA I/O obviously worked since the platform worked with CE 1.0. A visit to the MIPS architecture manual revealed the reason – MIPS has no instructions for byte-wide memory accesses! On MIPS, you either support 16 bit PCMCIA access or 8 bit, but not both. The same MIPS instruction is used for both; the PCMCIA subsystem generates an 8 bit access on the PCMCIA bus if it is configured for 8 bit. Many card designs are modeled from PC (x86) architecture designs and so they freely allow mixed 8 and 16 bit I/O accesses, often to the same register. Because of this a MIPS based device almost always has to support 8 bit only PCMCIA I/O.