Schematics: Buttons

As a generic game console emulating many classic ones, the FunKey requires numerous buttons:

  • A soft “ON/OFF” button
  • A “+” control pad with “Up”, “Down”, “Left” and “Right” buttons
  • A “x” control pad with “A”, “B”, “X” and “Y” buttons
  •  “Start” and a “Select” buttons
  • L and R shoulder buttons

As we have sen in the log on the PMIC, the soft “ON/OFF” button is directly connected to the power management chip, so we are left with 4 + 4 + 2 = 12 buttons for game control.

GPIO Requirements

The Allwinner v3s CPU comes in a large 128-pin TQFP package, with a lot of exposed (51!) GPIO pins:

  • PB0 to PB9 (10)
  • PC0 to PC3 (4)
  • PE0 to PE24 (25)
  • PF0 to PF5 (6)
  • PG0 to PG5 (6)

The FunKey specializes some of them for specific interfaces like SDCard, PWM, SPI and I2C buses, console UART, but most of them are left available for I/Os.

Button Interrupts

However, in order to detect when the buttons are pressed / released efficiently, the best solution is for them to generate an IRQ (Interrupt ReQuest) to warn the CPU that the corresponding button state has changed, instead of using an inefficient regular polling method.

Unfortunately in the V3s, only PB0 to PB9 and PG0 to PG5 support this GPIO IRQ capability. Worse, most of the pins PB0 to PB9 are already used for UART, I2C or PWM functions.

It is possible to route these functions to different pins and recover enough IRQ-capable GPIO pins: this is what we did for our #Funkey Zero project.

GPIO Expander

But for the FunKey device and given the small PCB size, this solution puts a lot of constraints on the PCB routing, at such a point that we decided to use a dedicated I2C GPIO expander chip to relieve the burden from the main V3s CPU.

A common chip for this purpose, that is well supported in the Linux kernel is NXP’s PCAL6416AHF.128. It is marketed as a “low-voltage translating 16-bit I2C-bus/SMBus I/O expander with interrupt output, reset, and configuration registers”: it just matches exactly what we need!

The connection with the V3s CPU is achieved using standard I2C clock (SCL) and data (SDA) signals, plus an additional IRQ signal driven by the I/O expander when pre-programmed conditions are met, such as a key press / release event. A RESET signal driven by the PMIC PWR_GOOD output is used to initialize the chip when required.

Schematics

Here is the corresponding main schematic for the buttons:

The main component is of course the I/O expander U1, with the control signals to the CPU/PMIC on the east side.

The chip’s /INT signal is pulled up to the +3V3 power supply by the resistor R1, such that the active-low interrupt signal is disabled by default.

The I/O expander chip features 2 separate power supplies VDD and VDDP for the core and peripheral respectively, each decoupled by a bulk capacitor C1 and C2.

Except for the GPIO I/Os, the only remaining pin is the ADDR pin 18 which provides the I2C address LSB bit, so that you can address 2 PCAL6416AHF.128 chips on the same I2C bus by wiring this pin differently.

One oddity is that the pin 6 (P0_5) is connected to the /RESET signal: it is a routing trick to get this signal to go through this pin pad, as it was very difficult to access it otherwise…

The “Start” and “Select” buttons S1 and S2 are 2 low-profile SMT tactile switches, each featuring an ESD protection TVS diode D8 and D5, as these buttons are of course accessible by the user!

The other buttons are wired in the same fashion:

The “U”, “L”, “D”, “R”, “A”, “B”, “X” and “Y” buttons S3, S4, S5, S6, S8, S9, S10 and S11 are of the same kind and also have a respective TVS diodes D2, D3, D4, D5, D6, D7, D8, D9, D10 and D11.

The left (S12) and right (S7) shoulder buttons are right angle SMT tactile buttons, with their TVS diode D1 and D12.

Benefit

The main advantage of this solutions is that the 12 signals to wire the buttons to the CPU are replaced by only 4 signals, from which 3 are shared with the other I2C peripherals (the PMIC) on the bus.

It is then much easier to route this dense PCB by delegating the button GPIO handling to a satellite chip.

Schematics: Audio

Playing audio is absolutely part of the gaming experience!

So for a retro gaming console like the FunKey, we need to have a decent audio playback, despite its lilliputian size.

By decency, we discarded the solution using a piezo-electric buzzer: these can get a loud sound in a small volume, but only at their resonance frequency, so the sound quality is extremely poor.

Turning back to the solutions used in modern smartphones as an example, there are 2 paths to consider:

  • playing audio internally by the mean of speaker(s)
  • playing audio externally by using headphones, with or without a cord

The speakers used in today’s smartphones are rather sophisticated and achieve very good performance. However, these are using made-to-measure speakers and cavities, such that they cannot be found and reused as standard parts in a design like ours.

As for the external audio solution, we have a problem: the FunKey is so small that it is not possible to integrate an audio jack to connect headphones! And despite our search, there is no simple and small enough way to use Bluetooth to output audio to cordless headphones either.

The best solution we have found consists in using a single tiny speaker from CUI CDM-10008, that is able to output 72 dB spl @ 1m from a 0.3W input power, with relatively modest dimensions: 10 mm diameter and only a 2.9 mm thickness.

Connections are not easy though, since this speaker is meant to have wires soldered to its pads, but we are trying to convert it into an SMT device in order to gain space in our small enclosure! We don’t have a satisfying solution yet that is possible to use for mass production, we are still working on it!

Schematic

The resulting schematic is simple, as the Allwinner V3s already contains an analog stereo audio codec (coder/decoder): we only have to take one of its headphone output channel (left or right) and feed it to a mono audio amplifier.

We chose the PAM8301 chip because of its cheap price, good availability, its more than sufficient output power of 1.5W and its filterless operation, meaning that no bulky series capacitor is required to drive the speaker.

Here is the corresponding schematic:

We chose the right headphone channel HPOUTR that is fed to the audio amplifier U2 through a DC-bias filter capacitor C3.

The audio amplifier /SD shutdown input is driven by one V3s GPIO, with a pull-down resistor R2 to disable the amplifier by default.

The audio amplifier power supply is filtered using a ferrite bead L1 in order to eliminate high-frequency digital noise, and decoupled by 2 capacitors C4 and C5, as recommended in the device datasheet.

The speaker SP1 is driven in differential mode in order to get the maximum voltage swing and thus the maximum power available for a given output current.

Two ESD protection TVS diodes D13 and D14 are added, since the speaker may be accessible to the user through the enclosure grid in front of the speaker.

Schematics: USB

In the FunKey device, the USB interface has 2 purposes:

  • provide an external power supply source for both powering the device and charging the built-in LiPo battery
  • provide a data interface to transfer firmware upgrades, configuration files, game emulators and game ROMs

The first purpose only requires the +5V USB power and GND pins. The second purpose requires to wire the additional differential data lines D+ and D-. As we only need to operate as an USB device and although the V3s is able to work as either an USB host or USB device using the USB OTG protocol, we don’t need the ID pin to determine by the cable wiring which role we must take.

The USB schematic is the following:

Before connecting 2 devices using an USB cable, they may be at completely different absolute voltages, and during cable insertion, the shield will be in contact before the other pins, including GND. The C6 capacitor between the Protective Earth (Shield) and GND is here to provide an AC path for sinking this difference in voltage and align the GND levels when plugin the cable. 

The resistor R4 on the USB ID connector pin should probably not be mounted: as we act only as an USB device, this pin should be left floating.

The capacitors C7, C8, C10 and ferrite bead L2 form a constant-k 3 pole CLC low pass filter to remove any spurious in/out on the USB power supply wire. The USB 2.0 specification limits the maximum bulk capacitance value to 10 µF in order to avoid power supply excessive droops when plugin in a device with a discharged large bulk capacitor.

D15 is a combined TVS protection diode for the VBUS pin and a set of clamping diodes that will limit the voltage on D+ and D- pins to stay between GND and VBUS levels to  in order to protect the V3s USB driver from under / over-voltages.

Schematics: Console

The Allwinner V3s provides 3x UARTs (UnAsynchronous Receivers / Transmitters): UART0 with only RX and TX signals, and UART1 and UART2with additional RTS and CTS flow control signals.

As almost all SoCs, tha Allwinner V3s provides a serial console as a control terminal for debug or normal operation. By default, it is mapped to UART0, and it is used by the BROM (Boot Rom), the U-Boot bootloader and by the Linux kernel to output messages during the boot process, and later by the Linux kernel to log messages during normal operation. Depending on the configuration, it can be used too for loging into the system over an UART.

The Console schematic only requires a minimum of external components:

Besides the 3-pin 1.27 mm  (0.05″) pitch header J1 that will not be mounted on standard products, there is only a single series resistor R3.

What is the purpose of this resistor?

  • As explained previously for the SD Card clock signal, this may be to prevent ringing. But given the relatively slow signal speed (115200 bps), it is not the case here
  • If it were placed on the RX input signal, this could prevent frying the input pin if a large voltage (+5V, for example) is applied to it by dissipating the excessive voltage as heat in the resistor. It is not the case here, since the resistor is on the TX output signal, but we could have one added, if only we had some space left on the board…
  • In fact, the resistor is on the output TX signal to prevent short-circuits if the serial cable is reversed and the 2 TX outputs are connected together, one driving the signal low, while the other is driving it high: again in this case, the voltage difference between the 2 outputs will be burned as heat in the resistor, saving the output buffers!

Note that there is no ESD protection TVS diodes: this interface is not supposed to be mounted in the final user device, and PCB space is really constrained in this area, so they are omitted.


1 2