Lab Power, Timing issues, Dodgy eBay Vendors, ESP32 and Sound!
This is a multipart post to get some of the project activities over the past couple of weeks documented. Let’s start with “Lab Power!”
I decided it was high time that I invested in a proper lab power supply. I was initially drawn to look to Jaycar by one of their regular ‘junk’ mail. It advertised this dual-output monster, but at $400, I couldn’t justify the price tag. The supply in the image above was a much more reasonable $179 and gave me what I wanted. It’s a 0 to 30VDC 0 to 5A regulated power supply. Most critically it has a current limited variable output. I see a lot of home-built ATX-based power supplies on Hackaday, but these are not current limited. Why is that important? Well, current limiting the supply during the first board bring up is important to avoid burning out any components that may have accidental shorts. During the board start up of my CPC2 custom board, I experienced a major issue with a supply short somewhere. As I did not have a current limited supply, all I could do was pray that nothing blew during the first start up. Fortunately it didn’t, but there were two shorts that I had to find and fix. The first of which I had prior knowledge of, being the same issue as my first custom build. This was a dead short to ground, having stupidly wired the GND pin to the +3.3v line. This killed the entire board until the short was removed. The biggest risk during the bring up was that the short circuit protection in the regulators was not effective and the device heated to the point of destruction. Fortunately that was not the case, but using a current limited supply, I could have started the board with 5v @ 300mA, so that a short would never have exceeded that current. The regulator was not at risk and I wouldn’t risk melting my very fine 8mil power PCB tracks.
In the event of an overcurrent situation, such as my dead short, a lab supply reduces the voltage until the current is at it maximum setting, in this case 300mA. As an example, using Ohms Law, we can work out what a dead short would look like on the display. The current path is never zero in the real world, so let’s say the resistance of the regulator output, tracks, solder and short are 1ohm. Using Ohms Law, we can calculate that at the current limiter value, the display would show (V = I x R, where I = 0.3 and R = 1) giving 0.3v @ 300mA, which is 90mW. Certainly not enough to release the magic blue smoke!
As a bonus, the lab supply can be used to directly power prototype circuits built without a regulator, such as my cupboard stocks of USB232R, which require a 3.3v supply for the data output to modern chips. For prototyping, this could be extremely useful and save some dollars, meaning I can focus on building just the components for prototyping.
I then got to thinking that I haven’t really checked the current consumption of my CPC2 board and since the connection is a direct USB link to a USB power supply or into the back of my PC, it’s hard to get a multimeter in there and still have it work properly. I can also check it’s reliability for the variations in USB supplies, as these can vary from as low as 4v up to 5.5v. I’ll be turning to my friends at OSHPark very soon to build a harness to take the output from the lab supply and pipe it into USB-A ports so that I can take some measurements on the CPC2 boards appetite for power! I’ll also provide jumpers for power and data connection monitoring. I have a vague glimmer of a project for a USB protocol analyser after CPC2, but that’s a way off yet. Look out for a post soon on this power harness.
I’ve talked about timing issues that became evident when the keyboard interface was implemented. Key repeat was much slower than a real CPC, yet the clock speeds were the same. I’ve actually struggled with this for over 2 years, since my original proof of concept of the CPC verilog core. My source of many thing CPC, Grimware, shows the details of the Gate Array in the CPC here. Scroll down to the Interrupt Generator section where a nice set of rules describe the operation of the INTn line on the CPC.
It looks complicated, but when it comes down to it, the CRTC drives the INTn line based on seeing 52 HSYNCs, generating an interrupt 300 times per second at the CPC PAL resolution of 832 x 312.5 x 50. However, Grimware notes that the int pulse is 1.4uS long:
This is fine in a real CPC, but what I forgot was that I’m using a Verilog implementation of a Z80 processor, and it doesn’t work quite the same. I noted during simulation that sometimes there was no interrupt acknowledge following the interrupt pulse. For two years, I thought nothing of that, thinking that maybe the CPU was busy executing a firmware call that disabled interrupts. However, changing the width of the INTn pulse to 4uS showed an interrupt acknowledge at every interrupt. The Verilog implementation was missing about 40%-70% of these interrupts. Testing confirmed this when I patched the INT38 routine to count up and toggle a pixel every 300 counts. This ran way slower that it should and showed that the INTs were not at the required 300Hz. In the end, I used a smart INTn signal that goes active until it sees an interrupt acknowledge, or 6uS elapses, which ever is sooner. 6uS was chosen as within 6uS the interrupt routine will have set the program counter to 0x0038. If it’s held low any longer than this, then it could re-trigger an interrupt within the interrupt handler, as it does some clever stuff to check for an external (peripheral) interrupt by re-enabling the interrupt flag with the EI command. If you disassemble the routine called by 0x0038 you’ll see the EI command in there.
Once I’ve figured this out, the timing between my WinApe emulator and my CPC2 were the same. I wrote some code and stored it in a custom ROM to execute within both machines. I patched 0x0038 directly and counted up to 300 for the raw INT test, counted the 50 VSYNCs for my frame flyback tests and repeated the tests with the firmware routines (0xBCE0 and friends). These were all identical – great news. However, something is still not quite right as the cursor doesn’t flash at the correct speed in the MAXAM editor, so I expect there’s still some things to work out. However, key repeat and event interrupts are good for now. Yippee!
When I get the ink flashing and PAL rendering working, I’ll come back to this again.
Dodgy eBay Vendors
Well, it’s been an interesting couple of weeks. One of the objectives of the project was to provide a Bluetooth interface for keyboards and joysticks. While I was at it, a WIFI connection wouldn’t hurt either. I expected that I would be able to use the USB connection to provide both of these interfaces, either through a hub or a combined device. I found this neat little device on eBay, a combined bluetooth and WIFI USB dongle. It seemed ideal for the job, and at $12 a bargain.
Unfortunately, when the device arrived it was DOA (dead on arrival). In my 70-odd purchases on eBay, this is the first one that had failed in any form. I contacted the vendor to ask for next steps. I expected that they would ask me to send the device back for a replacement. As postage costs were $13.77 to China, I would politely decline and write off my $12 as bad luck. Events did not turn out that way. Over the course of the next two weeks, they asked me to perform weird and wonderful convolutions, such as sending a video of the device doing nothing when it was plugged in, installing the drivers, even when the device refused to enumerate, and finally asking me to take this tiny device to a local repairer. Who repairs $12 wireless USB anyway? We got as far as agreeing to a refund IF I gave them positive(!) feedback. I was tempted to do this just to call it quits, but then they refused to pay out UNTIL I’d given them the positive feedback. This just seemed wrong, they’d already proven themselves untrustworthy by treating me badly and they were asking me to trust them again. I asked eBay to step in and within a couple of hours, I had my refund. But I’d also lost my chance to tell everyone that if you buy something and it doesn’t work, these guys are not your friend. I tried to play along, even when they were asking silly things, on the basis that I shouldn’t damage their online reputation with hasty action. The transaction was voided and I couldn’t leave feedback after that, so I suspect that was their plan all along to avoid negative feedback. So, look out if you see dadidashop on eBay! I would not recommend them. It’s only when things go wrong, do you really see great (or bad) customer service.
As a result of the disastrous USB purchase on eBay, combined with the newly discovered knowledge that USB2 high speed devices rarely work in full speed ports, I was left to consider how to deliver the promised Bluetooth and WIFI. A USB WiFi and Bluetooth adapter would be extremely flexible, but would require a lot of work to write a driver for it. I had considered the ESP32 in an earlier post, so it was time to revisit this. I have order the WROOM32 pre-build module from Little Bird Electronics along with a development board. I’ll be able to proof my ESP32 software on the development board then flash the WROOM32 on the CPC2.0 with the appropriate firmware. This will provide both bluetooth and WiFi across a serial connection. It also has “built in” stacks for things like RFCOMM and eventually Bluetooth Audio (although the ESP32 forums suggest it’s not there yet).
I considered using the ESP32 as the main supervisor controller, as it was certainly capable, but it didn’t have the desired USB connection and I didn’t want to add another chip like the FT231X for serial communication. Also, while the ESP32 has enough pins, the WROOM32 has a more limited set of pins provided on it’s I/O and wouldn’t have been enough for USB/eMMC/FPGA Config as well as the Bluetooth/Wifi connection. I’ll provide an update once I’ve played with the ESP32 a bit.
Yes! We have sound from the CPC2. Sound is provided courtesy of the TV through the HDMI connection. In the end, the RTL turned out to be very simple. Take a look at i2s_audio.v for the code. While this is very simple, the support code is essential to enabling the HDMI to process the data. Take a look at hdmi_powerup() in hdmi.c for this code. It wasn’t as simple as dumping a digital stream to to the I2S pins, as the HDMI needs to know some things about the format of the data that is provided. The channels (2-8), frequency and word size are obvious, but not so obvious is that you’ll need to provide the relationship between the HDMI video clock and the audio data rate(N+CTS values). Since the audio is transmitted as data patterns off-screen, there is no inherent clocking to the data. The HDMI chip needs to know how often to provide audio data per frame of video so that they stay in sync. The ADV7513 will do this automatically where it can, but where the relationship isn’t simple, it will struggle to synchronise and will lock then drop out as the chip tries to resync. Using the values according to the programming reference didn’t work and the audio couldn’t lock to the incoming signal. It didn’t help that I was not being able to provide the correct 48KHz frequency to the audio SCLK pin. It’s slightly faster because of a limitation in the PLL blocks within the Altera Cyclone chip. I only connected the clock to one clock input pin, so I could only use one Altera PLL. I needed to use a fractional PLL for my required 3.072MHz audio clock signal from the 50MHz input clock, which will require it’s own PLL. So while I get audio output, it’s fractured and crackly. The next revision of the board will fix this, but it’s enough to hear the classic beep of the CPC.
The sound chip model I’m using is a YM2149 that looks like it’s taken from fpgaarcade.com. This will only be temporary, because it written in VHDL and only outputs in mono, rather than three separate channels. It violates the principle that I would develop all of this code myself so that I know it inside and out! For now, I’ll take it so that I’m making forward progress, but will rewrite this later.
I’ve posted the latest code in GitHub for your viewing pleasure!
All of this extra logic is starting to stress the FPGA. It’s starting to get warm as I’m using 75% of the logic resources now, most of which will be active at the same time. I also managed to crash it, by trying to use a Finite Impulse Response Filter IP block to filter out the very low-end and very high end audio signals. Incredibly, it completely reset back to an unconfigured state and I had to reprogram it. It must have used a fair amount of noisy power for this to happen, as the chip got really hot before resetting. I’d not considered a heatsink before, but maybe I’ll need to consider one before I’m done once the memory and video handler is in.
Also, the TMDS lines are showing signs of stress as I started to get noise showing on the screen when the audio was playing at full volume, suggesting a problem either with switching noise or the fact that the signals are not impedance matched (probably both). Issuing a paper 1:pen 0:cls command to the CPC also cause some significant noise on the lines. I found very early that it couldn’t handle the full 24-bit colour space, losing syncronisation when more than 18-bits were used. I expect the sound is an extension of that same problem, even though I only use the high 8-bits of the sound channels.
I’m getting to the point where I need to commit to my next build to make further progress, so I’ll work through the few prototyping items first, then get the new board designed and manufactured. I will create a prototype board for the Microchip USB3320 chip, to see if I can add USB2 high-speed support to the board, which will be useful for wireless keyboards.
Last Post <—-> Next Post
2 thoughts on “Retro CPC Dongle – Part 26”
Great posts! I truly admire your persistence – it’s not easy to take such a long-term project from the idea to the working device. I’ve already failed a few FPGA projects (also retro-computing related) simply because of not being systematic enough 🙂
It’d be great if you included more architecture details in your posts – I’d really love to read more about what goes into FPGA.
Keep up the good work!
Thanks codepainters! Yes, it’s tough to keep going over such a long period, but the small success make it worth it. If you’re interested in the architecture, take a look at Post 9 where I post the latest block diagram. Posts 1+2 also explain the overall project vision. Take a look at the index page for overall reference. Thanks for the comments. Feel free to ask me any questions on the FPGA work, I feel I really learned a lot on this project.