mirror of
https://github.com/FunKey-Project/FunKey-Project.github.io.git
synced 2026-10-30 01:15:18 +01:00
1 line
191 KiB
JSON
1 line
191 KiB
JSON
{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Welcome to FunKey!","text":"<p>Thank you for choosing the FunKey S!</p> <p>The FunKey S is the world's smallest foldable retro-gaming console.</p> <p>Because of its foldable design, the FunKey S provides a surprisingly large screen and comfortable key pads while open, but it stays compatible with a keychain usage when closed.</p>"},{"location":"#basic-operation","title":"Basic operation","text":"<p>The FunKey S operation is so straightforward that a 6-year old child should be able to operate it without any user's manual for the most common tasks. But just to make sure you are not missing something, you can find the basic device operation description in the Tutorials section.</p>"},{"location":"#more-advanced-features","title":"More advanced features","text":"<p>Despite its size, the FunKey S is packed with features, and this documentation will also provide more advanced tips in the Tutorials section.</p>"},{"location":"#developers","title":"Developers","text":"<p>For developers, a full guide is included, with both Hardware and Software subsections.</p>"},{"location":"#open-source-files","title":"Open source files","text":"<ul> <li>All the software repositories are accessible on our Github. The developer section is a great way to understand its secrets.</li> <li>All the electronic schematics and layouts are accessible here.</li> <li>For mechanical tinkerers or professionals, all the 3D step files are accessible on Grabcad</li> </ul>"},{"location":"#miscellaenous-stuff","title":"Miscellaenous stuff","text":"<p>Last but not least, this documentation would not be complete without a Glossary of terms for reference.</p>"},{"location":"developer_guide/hardware_reference/","title":"Hardware Reference","text":"<p>The FunKey S is the world's smallest foldable retro-gaming console.</p> <p>Holding a world's record is great, but we wanted a device that was actually playable and that still could be attached to a keychain.</p> <p>Reaching this goal required more than just the usual job to shrink everything you can: it required a radical change in the design itself.</p>"},{"location":"developer_guide/hardware_reference/#foldable-design","title":"Foldable Design","text":"<p>The idea to use a foldable clamshell design came up rapidly as the only way to get both a small form factor when closed, and offer the largest screen and keypads while playing.</p> <p>But this solution also brings a lot of challenges, as the required hinge make connections between the 2 halfs of the shell more difficult.</p> <p>However, this has been done before in the classic Game Boy Advance SP, or in many clamshell cellphones from some years ago, so why can't we?</p>"},{"location":"developer_guide/hardware_reference/#design-goals","title":"Design Goals","text":"<p>Passed this first design decision, we fixed ourselves some additional goals in order to provide the user a good gaming experience:</p> <ul> <li> <p>have a CPU that is powerful enough to be able to emulate most retro-gaming consoles, up to the PS1</p> </li> <li> <p>have a good quality screen with a resolution large enough to display even the games featuring small texts</p> </li> <li> <p>have a set of keys and pads large enough and complete enough to be able to play comfortably</p> </li> <li> <p>have a built-in audio capability (who can play without sound?)</p> </li> <li> <p>be able for a 6-year old child to add games and emulators</p> </li> <li> <p>as an extremely nomad device, be able to stop playing just by closing the console, and restart when opening it just where you left (we call this feature \"Instant Play\")</p> </li> </ul>"},{"location":"developer_guide/hardware_reference/#design-constraints","title":"Design Constraints","text":"<p>Besides the constraint brought by the hinge listed above, the main difficulty is due to the maximum device dimensions that should not exceed those of a (large) car key.</p> <p>And because of the foldable design, the most constrained dimension is thickness: having a folding screen also means doubling the plastic enclosure around the screen and the other internal parts.</p> <p>In order to meet these constraints, we had to take more (heart-breaking) decisions:</p> <ul> <li> <p>a CPU with external DRAM chips would take too much real-estate on the PCB, so we had to find a CPU with integrated DRAM</p> </li> <li> <p>an audio Jack would be very difficult to integrate, so we decided to use an internal speaker instead</p> </li> <li> <p>an USB C connector is too thick and large, so we used a Micro USB connector instead</p> </li> <li> <p>a Micro SD connector with external access would be too large, as the required \"push/push\" mechanism, plus the mechanical design to make sure the card does not get loose make the solution much larger</p> </li> <li> <p>because of real-estate constraints on the PCB as well as power consumption constraints, we decided to not integrate Wi-Fi and/or Bluetooth</p> </li> <li> <p>the only keypad technology able to meet our thickness goal is using integrated tactile switches</p> </li> <li> <p>battery capacity had to be adjusted to the maximum available internal volume, using standard battery dimensions</p> </li> </ul>"},{"location":"developer_guide/hardware_reference/architecture/","title":"Architecture","text":""},{"location":"developer_guide/hardware_reference/architecture/#block-diagram","title":"Block Diagram","text":"<p>Eventually, the design constraints listed in the previous section led to the following electronic diagram, featuring 3 main blocks:</p> <ul> <li> <p>1x main PCB (0.8 mm thickness) with components on both sides, the maximum component height above PCB on both sides is 1.5 mm. Current revision for this board is Revision E</p> </li> <li> <p>1x 1.54\u201d IPS TFT LCD screen with SPI interface and using a custom flex cable, containing a built-in screen controller chip</p> </li> <li> <p>1x 420 mAh 402540 LiPo battery, containing an active protection circuitry</p> </li> </ul> <p></p>"},{"location":"developer_guide/hardware_reference/architecture/#3d-view","title":"3D View","text":"<p>A 3D rendering of the PCBA done in KiCAD produces the images below:</p> <p></p> <p></p>"},{"location":"developer_guide/hardware_reference/architecture/#bom","title":"BOM","text":"<p>An interactive BOM is available in the next section.</p>"},{"location":"developer_guide/hardware_reference/architecture/#schematics-and-layout","title":"Schematics and Layout","text":"<p>All the hardware design and production files required to build the FunKey S retro-gaming console electronic PCBA using the KiCAD ECAD tools are available as Open Hardware in the FunKey S Hardware repository.</p> Topological vs. logical schematic symbols <p>The FunKey S schematics use symbols and placement that are as close as possible to their corresponding physical package and layout, instead of defining symbols that are conveniently arranged by logical properties. Even if this makes schematics more complex at first sight, the benefit of this approach is that the step to go from the schematics to the physical layout becomes much easier, and so is the debugging of the physical board, which is then very close to the schematics too.</p> Explicit schematic wires <p>Another habit that is used everywhere in the FunKey S schematics is that all signals (except power supplies and GND) are routed using explicit wires, rather than counting on invisible connection by net names and relying of the reader to search these names all over the place. This forces related components to be clustered in compact groups to shorten the wires, and put more focus on inter-cluster signals, with a natural inclination to unravel wire nests in the schematics before laying out the actual board.</p> Power supply nets <p>There are some \"PWR_FLAG\" symbols added here and there, which is the proper way in KiCAD to declare that a given net has a known supply and thus prevent the ERC (Electrical Rule Check) to throw an error.</p> <p>The schematics will be discussed function by function in the following sections.</p>"},{"location":"developer_guide/hardware_reference/audio/","title":"Audio","text":"<p>Playing audio is absolutely part of the gaming experience!</p> <p>So for a retro gaming console like the FunKey S, having a decent audio playback is a requirement, despite its lilliputian size.</p> <p>We discarded the solution of 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.</p> <p>Turning back to the solutions used in modern smartphones as an example, there are 2 paths to consider:</p> <ul> <li> <p>playing audio internally by the mean of speaker(s)</p> </li> <li> <p>playing audio externally by using headphones, with or without a cord</p> </li> </ul> <p>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.</p> <p>As for the external audio solution, the FunKey S is so small that it is not possible to integrate an audio jack on the PCB to connect headphones! And despite our search, there is no simple and small enough way to integrate Bluetooth to output audio to cordless headphones either.</p> <p></p> <p>The best solution we have found consists in using a single tiny CUI CDM-10008 speaker, 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, out of which 1.4 mm can be inserted into a PCB hole, thus only having a height above PCB of only 1.5 mm.</p> <p>Connections are not easy though, since this speaker is meant to have wires soldered to its pads, but we used 2x castellated (half-round plated holes) pads with a placement just over the speaker pads that enables manual soldering between the speaker and the PCB with a solder blob.</p>"},{"location":"developer_guide/hardware_reference/audio/#schematic","title":"Schematic","text":"<p>The audio 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.</p> <p>We chose the Diodes Inc. 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.</p> <p>Here is the corresponding schematic:</p> <p></p> <p>We chose the right headphone channel HPOUTR that is fed to the audio amplifier U2 through a coupling capacitor C3.</p> <p>The audio amplifier /SD shutdown input is driven by one V3s GPIO (PF7 on pin 100), with a pull-down resistor R2 to disable the amplifier by default.</p> <p>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.</p> <p>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.</p> <p>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.</p>"},{"location":"developer_guide/hardware_reference/buttons/","title":"Buttons","text":"<p>As a generic game console emulating many classic ones, the FunKey requires numerous buttons:</p> <ul> <li>A soft \"ON/OFF\" button</li> <li>A \"+\" control pad with \"Up\", \"Down\", \"Left\" and \"Right\" buttons</li> <li>A \"X\" control pad with \"A\", \"B\", \"X\" and \"Y\" buttons</li> <li>\"Start\" and a \"Fn\" buttons</li> <li>At least L1 and R1 shoulder buttons</li> </ul> <p>As can be seen in the page 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.</p> <p>After testing tactile domes in our FunKey Zero prototype, we decided to go back to integrated tactile switches, as their placement is much easier using a regular SMT pick & place machine like any other components on the PCB, whereas the separate tactile domes required an adhesive tape to be place manually with less accuracy.</p> <p></p> <p>The Mitsumi BYS-055A1x12 is the same footprint (2.5mm x 1.6mm x 0.55mm) as the more expensive Panasonic EVBBBxAAB00 tactile switches, with a 1.2N actuating force for the \"+\" and \"X\" pads, and a 1.6N actuating force for the \"Start\", \"Fn\" and \"ON/OFF\" buttons. We found these actuating force the best match to provide a good feedback to the user.</p> <p></p> <p>For the rear left and right shoulder buttons, we exeperimented several models between PCBA rev. C, D and E, until we eventually decided for a replacement for the expensive Panasonic EVP-AEBB2A-1:</p> <p>This one as an actuating force of 1.6N.</p>"},{"location":"developer_guide/hardware_reference/buttons/#gpio-requirements","title":"GPIO Requirements","text":"<p>The Allwinner v3s CPU comes in a large 128-pin TQFP package, with a lot of exposed (51!) GPIO pins:</p> <ul> <li>PB0 to PB9 (10)</li> <li>PC0 to PC3 (4)</li> <li>PE0 to PE24 (25)</li> <li>PF0 to PF5 (6)</li> <li>PG0 to PG5 (6)</li> </ul> <p>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.</p>"},{"location":"developer_guide/hardware_reference/buttons/#gpio-expander","title":"GPIO Expander","text":"<p>But for the FunKey S device and given the small PCB size, wiring all the buttons directly to the V3s 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.</p> <p>We use a common chip for this purpose, that is well supported in the Linux kernel: the NXP 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\" that just matches exactly our needs.</p> <p>As a bonus, this chip features software-controlable internal pull-up/pull-down resistors, so we don't need to add external ones to fix the defaut button states.</p> <p>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 is used to initialize the chip when required.</p>"},{"location":"developer_guide/hardware_reference/buttons/#schematics","title":"Schematics","text":"<p>Here is the corresponding main schematic for the buttons:</p> <p></p> <p>The main component is of course the I/O expander U1, with the control signals to the CPU/PMIC on the north side.</p> <p>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.</p> <p>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.</p> <p>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.</p> <p>Tip</p> <p>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...</p> <p>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!</p> <p>The other buttons are wired in the same fashion:</p> <p></p> <p>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.</p> <p>The left (S12) and right (S7) shoulder buttons are right angle SMT tactile buttons, with their TVS diode D1 and D12.</p>"},{"location":"developer_guide/hardware_reference/buttons/#benefit","title":"Benefit","text":"<p>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.</p> <p>It is then much easier to route this dense PCB by delegating the button GPIO handling to a satellite chip.</p>"},{"location":"developer_guide/hardware_reference/cpu/","title":"CPU","text":"<p>The main part in the FunKey S device is of course its CPU.</p> <p>As discussed in the Design Constraints section, a CPU with external DRAM chips would take too much real-estate on the PCB, so we had to find a CPU with integrated DRAM.</p> <p>There are several options for integrating RAM in a SoC:</p> <ul> <li> <p>use SRAM: not possible because of the small amount of memory available (64Mbit max.)</p> </li> <li> <p>embedded DRAM on the same chip: This is the solution used in the Apple M1 chip, but this chip is not available for retail and no other solutions seems readily available</p> </li> <li> <p>Stacked Chip-on-Chip (PoP): This is the solution used on some Raspberry Pi boards, but this solution is only available for custom designs, with minimum order quantities not compatible with the FunKey S low volumes</p> </li> <li> <p>DRAM die in SiP: with capacities ranging from 64Mbit to 1Gbit</p> </li> </ul> <p>We found only 2 manufacturers providing the last option: Microchip and Allwinner Technology. Microchip solutions are too limited in term of CPU power for our needs (ARM926EJ-S or Cortex A5), so we did not consider them.</p> <p>And with the exception of the mostly similar Allwinner S3 CPU which features the same characteristics but with 128MB DDR3 DRAM in an FBGA234 package, the Allwinner V3s is the CPU with integrated DRAM having the highest memory capacity (512Mbit / 64MB DDR2 DRAM):</p> <p></p> <p>Despite its larger package size (16mm x 16mm vs. 11mm x 11mm), we selected the V3s over the S3 because of its better availability and ease of soldering of the LQFP128 over the FBGA234 package for the prototypes.</p> <p>The V3s features a rather powerful single-core ARM Cortex A7-A clocked @ 1.2GHz with an additional Vector Floating Point Version 4 (vfpv4) FPU extension and an SIMD NEON architecture with a 32 \u00d7 64-bit register file and 64-bit ALU, but unfortunately no GPU or 2D graphic engine containing a hardware scaler that could be extremely useful for the retro-gaming emulators.</p> <p>As a bonus, as the V3s is based on an ARM Cortex A7-A low-power architecture, it also features a low power consumption which is required by our battery operation.</p> <p>These characteristics do not look very impressive compared to a Raspberry Pi for example, but using many optimizations and after running many tests, we found them nevertheless satisfactory for our purpose.</p>"},{"location":"developer_guide/hardware_reference/cpu/#cpu-schematics","title":"CPU Schematics","text":"<p>Here is the part of the schematics corresponding to the CPU core:</p> <p></p>"},{"location":"developer_guide/hardware_reference/cpu/#soc-blocks","title":"SoC Blocks","text":"<p>As can be seen, there is not much besides the CPU chip U3 itself... The CPU is in fact a SoC (System on Chip) containing a collection of built-in peripheral and memory blocks along with the CPU itself:</p> <ul> <li> <p>the LCD / DSi display peripheral</p> </li> <li> <p>the GPIO port G / SDC1 (SD Card #1) interface</p> </li> <li> <p>the AUDIO codec</p> </li> <li> <p>the LRADC0 (Low-Resolution Analog to Digital Converter)</p> </li> <li> <p>the USB OTG controller</p> </li> <li> <p>the GPIO port F / SDC0 (SD Card #0) / UART0 interface</p> </li> <li> <p>the RTC (Real Time Clock) timer</p> </li> <li> <p>the EPHY (Ethernet PHYsical) interface</p> </li> <li> <p>the MIPI CSi camera interface</p> </li> <li> <p>the built-in 64 MB DDR2 DRAM</p> </li> <li> <p>the GPIO port C / SPI interface</p> </li> <li> <p>the GPIO port B / UART2 / PWM0 / PWM1 / TWI0 (I2C #0) / TWI1 (I2C #1)</p> </li> </ul> <p>Among these, the FunKey device only uses a few blocks:</p> <ul> <li> <p>AUDIO</p> </li> <li> <p>USB (as device only)</p> </li> <li> <p>SDC0 (for SD Card)</p> </li> <li> <p>RTC</p> </li> <li> <p>DRAM</p> </li> <li> <p>SPI (for the LCD screen)</p> </li> <li> <p>PWM0 (for backlight)</p> </li> <li> <p>TWI0 (for I2C bus to control the GPIO expander and power management chips)</p> </li> <li> <p>A couple of GPIOs to power the audio power amplifier and get feedback interrupt signals from the the GPIO expander and power management chips</p> </li> </ul>"},{"location":"developer_guide/hardware_reference/cpu/#cpu-power-supplies","title":"CPU Power Supplies","text":"<p>What is remarkable though is that the V3s requires a lot of different voltages for its power supply:</p> <ul> <li>+3V3 for the I/O power supply</li> <li>+3V3_AO for the Always-On power supply (RTC timer)</li> <li>+3V0 for analog power supply</li> <li>+1V8 for the DDR2 DRAM power supply</li> <li>+1V25 for the core power supply</li> </ul> <p>This profusion of different power supplies as well as the high power drawn by some of them (1.2A for +3V3, 1.6A for +1.25V) requires a sophisticated power management that will be detailed further.</p>"},{"location":"developer_guide/hardware_reference/cpu/#lradc0","title":"LRADC0","text":"<p>The LRADC0 (Low-Resolution Analog to Digital Converter #0) is designed to measure the voltage of a resistor ladder switched by keyboard keys: this single input is thus in theory able to manage a keyboard of up to 10 keys @ 250 Hz.</p> <p>Unfortunately, the FunKey has 12 keys (U/D/L/R, A/B/X/Y, RR/RL, Start and Fn), and the resulting key detection accuracy is not compatible with a gaming usage because of long term stability problems. This is the reason why it is not used in the FunKey and just terminated by a proper low-pass filter R6/C9 to avoid picking up noise glitches.</p>"},{"location":"developer_guide/hardware_reference/cpu/#sd-card","title":"SD Card","text":"<p>The SD Card interface is almost a direct connection between the chip and the dedicated SD Card connector. Only a single series resistor R8 is required on the high-speed clock line in order to prevent ringing.</p>"},{"location":"developer_guide/hardware_reference/cpu/#crystals","title":"Crystals","text":"<p>The V3s chips requires 2 crystals:</p> <ul> <li> <p>one low-frequency 32.768 kHz crystal Y1 for the RTC clock</p> </li> <li> <p>one high-frequency 24 MHz crystal Y2 for deriving the 1.2 GHz clock</p> </li> </ul> <p>The 24 MHz crystal is used by an internal oscillator to lock the phase of the 1.2 GHz oscillator using a PLL (Phase-Locked Loop).</p> <p>The 32.768 kHz crystal is used by another internal oscillator to tick the RTC (Real-Time Clock) at a standard watch frequency.</p> <p>These crystals require 2 load capacitors each (C12/C13 and C14/C15 respectively) in order to guarantee that the oscillators still start and work with a comfortable operation margin taking into account voltage, temperature and aging.</p> <p>The 32.768 kHz crystal features an additional high-value resistor R12 in order to limit the internal oscillator's output current and thus reduce further the RTC timer power consumption.</p> <p>For more details on crystal oscillator design, please check this application note from STM.</p>"},{"location":"developer_guide/hardware_reference/cpu/#dram","title":"DRAM","text":"<p>The DRAM within the V3s chip is a DDR2 one, meaning that its data lines are clocked using both edges of an up to 400 MHz clock signal.</p> <p>At these high frequencies, even short wires have a length that is of the same order of magnitude as the signal's wavelength and thus each signal should be considered as a transmission line, for which impedance must be matched to avoid signal reflections, requiring termination resistors on the data lines DQx.</p> <p>DDR2 or DDR3 DRAMs feature merged drivers and dynamic on-chip termination like this (\"VDDQ/2\" is labeled \"SVREF\" in our schematic):</p> <p></p> <p>The V3s DDR2 DRAM has an active termination calibration circuitry and procedure called \"ZQ Calibration\" requiring an accurate 1% 240 \u2126 resistor R11 connected internally like this:</p> <p></p> <p>More information on the DDR2 DRAM ZQ Calibration subject can be found in this Micron Application Note.</p>"},{"location":"developer_guide/hardware_reference/magnetic_switch/","title":"Magnetic Switch","text":"<p>The FunKey S features no ON/OFF switch. Instead, a small magnet placed near the LCD screen in the lid is detected using a magnetic sensor that is placed in front of it when the lid is closed.</p> <p>The magnetic sensor controls the PMIC N_OE (Negative logic Output Enable) input, which turns off all voltage rails except the +3.3V Always On when the signal is at the high level.</p> <p>We thus need a sensor that will close when a magnetic field is detected, and in order to reduce power consumption when the FunKey S is turned off and preserve its battery when stored on a shelf, it should be a fully passive device. This rules out magnetic Hall effect sensors, wich require some power for their operation.</p> <p>The only practical solution is to use a \"Reed switch\", which is a relatively thin flexible piece of metal inside the switch envelope that is sensitive to a magnetic field, which opens or closes a contact accordingly.</p> <p>Most of the Reed switch available are made of a tiny glass tube, which is rather fragile and may break if the device falls on the floor, something quite usual for a keychain...</p> <p>We found only a unique plastic-molded model which almost meets our low-profile requirements of 1.5 mm (1.6 mm height!): the Standex Meder MK24.</p> <p>Here is the corresponding schematics, already covered in the PMIC discussion:</p> <p></p> <p>The global PMIC chip enable signal N_OE is activated by default through a 47k\u2126 resistor R17 to GND, but the magnetic Reed switch S14 can disable it by forcing its level to +VOUT, with a filter capacitor C83.</p>"},{"location":"developer_guide/hardware_reference/screen/","title":"Screen","text":"<p>The second most important part in the FunKey S is certainly its screen: in an overall form factor of roughly 45mm x 45mm x 15mm (1.75\" x 1.75\" x 0.6\"), it has to be comfortable enough to provide a good gaming experience.</p> <p>In theory, 1.75\" would allows to shoehorn a 2.4\" (diagonal) square screen, but in practice, 2.4\" screens are seldom square and more rectangular in shape.</p> <p>Unless you are a large manufacturer and selling millions of devices, you are limited to using the existing screen sizes that are available on the market, which most of the time were designed for a long-forgotten specific devices (think of PDAs, MP3 players, clam-shell phones, pods, etc.) and standard aspect ratio are either 1:1, 5:3 or 16:9. Thus, for a given pixel technology, this results in rather standard screen sizes.</p> <p>So the next available size down are 2\" and 1.8\", but these screens tend to be quite thick and based on an older technology, so their typical resolution is rather limited @ 128x160 pixels: too small for gamers.</p> <p>Still going down in size, you can find 1.5\" to 1.55\" screens with an interesting resolution of 240x240 or even 320 x 320 (\"Retina\") pixels, but most of them use a fast MIPI DSi interface. These particular screens were popular as they were used in the 6<sup>th</sup>-generation \"square\" iPods, but unfortunately, they require a dedicated controller on the host side, which is only available in higher-end SoC.</p> <p>Another important characteristic of the required screen is that it needs to have a narrow flex cable in order to be rolled into the hinge (like a fly-paper) in order to spread the mechanical flex constraint over several loop rather than at always the same section, resulting in less wear and an expected longer lifespan.</p> <p>Fortunately, we found this 1.54\" LCD screen on AliBaba:</p> <p></p> <p>What makes this screen special is its standard SPI interface, which only requires a few wires and thus a narrow flex cable like the MIPI DSi interface, so it is easy to roll into a hinge. But unlike the MIPI DSi one, the SPI interface is readily available on most of the SoC, including the Allwinner V3s.</p> <p>This 1.54\" display features a 240x240 16/18-bit full color pixel resolution and is an IPS display, so the color looks great up to 80 degrees off-axis in any direction.</p> <p>However, in order to achieve a 50 fps @ 240 x 240 pixel resolution in RGB565 (2 bytes / pixel), this requires a ~44 MHz SPI clock rate, which is rather high.</p> <p>Once again, we were fortunate as both the V3s CPU and the screen built-in controller (a Sitronix ST7789V) both support this high clock speed (after checking with the manufacturer and despite the controller datasheet that specifies only a serial clock cycle (Write) of 66 ns or 15 MHz!).</p> <p>We were even luckier as its backlight consists in 3 white LEDs in parallel and not in series, such that no additional step-up DC-DC converter is required, as a standard 3.3V / 60 mA (typical) power supply is sufficient. Of course, we won't be able to drive this current directly from a CPU GPIO and the backlight will require an additional transistor to interface to the LCD backlight.</p> <p>Its flex cable requires a mating Hirose 0.4 mm pitch DF37NB-24DS-0.4V dual row SMT connector, out of which only one single row is actually used.</p>"},{"location":"developer_guide/hardware_reference/screen/#customization","title":"Customization","text":"<p>Unfortunately, the flex cable for the stock LCD screen we found does not match our particular FunKey S mechanical design.</p> <p>For the prototypes, we designed custom flex extension cables for a ~ $100 cost, but we had to design our own custom flex and have this standard screen assembly attached to it for mass production, with a one-time tooling fee of ~ $800.</p>"},{"location":"developer_guide/hardware_reference/screen/#schematic","title":"Schematic","text":"<p>The schematic is quite simple:</p> <p></p> <p>The main component is of course the Hirose screen connector J3, with the following signals:</p> <ul> <li>LEDA: the backlight LED common Anode connection (+)</li> <li>GND</li> <li>+3V3 power supply</li> <li>/SPI_CS: SPI Chip Select</li> <li>SPI_MOSI: SPI Master Out / Slave In</li> <li>SPI_CLK: SPI Clock</li> <li>TE: Tearing Effect sync signal from the screen</li> <li>RS: LCD-specific Register/Memory Select (or Data/Control Select)</li> <li>LCD_RESET: LCD Reset</li> </ul> <p>All data signals feature an ESD TVS protection diode D19-D24 and D37, and except for the power supplies and LEDA + LCD_RESET and TE signals, all signals are directly connected to the V3s CPU's SPI interface, so there is not much to say about these.</p> <p>The LCD_RESET signal is controlled by a V3s GPIO (PB2 on pin 41).</p> <p>The TE signal from the screen controller is fed to an interrupt-enabled input pin PB1 (pin 40) in order to synchronize the sending of data to the screen with its inactive period in order to avoid the hardware tearing effect.</p>"},{"location":"developer_guide/hardware_reference/screen/#backlight-pwm","title":"Backlight PWM","text":"<p>The backlight control requires a few more components: a MOSFET-P transistor Q1 and 2 resistors R5 and R7 to provide its polarization, more on this below.</p> <p>As the backlight LEDs cathode (-) pin are directly tied to GND within the screen, we need to drive these LEDs \"from the high-side\", i.e. between the +3V3 power supply and the LEDA pin, so a MOSFET-P transistor is necessary:</p> <p></p> <p>As we want the backlight to be on by default, we need to drive it to GND by default: this is the role of R7. The role of R5 is then to make sure that -Vgs is driven below its threshold voltage and turns off the transistor when the CPU drives a GPIO high.</p> <p>As an ultimate sophistication, we can drive the backlight from the CPU using one of its built-in PWM controllers PWM0 with a varying duty-cycle, thus controlling the LCD backlight brightness accurately. For this purpose, the other end of the R5 resistor is connected to the PB4 output (pin 43) on the V3s, wich provides this function.</p>"},{"location":"developer_guide/hardware_reference/sd-card/","title":"SD Card","text":"<p>The FunKey S game console uses the SD Card both as its boot device and its only storage device, so a good operation of this interface is absolutely mandatory.</p> <p>The Allwinner V3s provides 2x 4-bit MMC / SD Card / SDIO interfaces. In the FunKey, only interface #0 is used.</p> <p>If you look on the Web, you will find many contradictory SD Card interface designs, with a combination of pull-up / pull-down resistors, ESD devices and power supply filtering, with all pins wired or not, such that it is very difficult to know what is really required. To better understand the situation, we need to go back to the specifications.</p>"},{"location":"developer_guide/hardware_reference/sd-card/#specifications","title":"Specifications","text":"<p>The SD Card physical interface is provided in the \"SD specifications, part 1, Physical Layer Specification version 2.00, May 9, 2006\", for which a simplified version is available here.</p> <p>The MMC phyiscal interface can be found in the \"Multi Media Card System Specification version 4.3, JESD84-A43, November 2007\", available here (registration required).</p> <p>But a good summary of the requirements is given in the \"AN10911 SD(HC)-memory card and MMC Interface conditioning\" application note from NXP, from which this schematic is taken:</p> <p></p> <p>Warning</p> <p>This schematic does not include details concerning card-supply and typical power-supply decoupling capacitors.</p>"},{"location":"developer_guide/hardware_reference/sd-card/#write-protect-wp","title":"Write Protect (WP)","text":"<p>A mechanical write protect switch is provided in the full-size SD Card, but not in the mini or micro SD Card form factor. As we plan to use a micro SD Card only, it is not used for the FunKey, along with its pull-up resistor and ESD protection.</p>"},{"location":"developer_guide/hardware_reference/sd-card/#card-detection-cd","title":"Card Detection (CD)","text":"<p>As the SD Card is mandatory to boot the FunKey S, is always inserted and opening the device is required for its removal, we don't need the optional card detect mechanical switch feature (even if the chosen connector provides it) and its related pull-up resistor and ESD protection.</p> <p>The SD Card specification provides another mean to detect the card using a card built-in pull-up resistor on its DAT3 signal, that can be later disconnected during normal operation using he SET_CLR_CARD_DETECT (ACMD42) command. In order to correctly detect if the card is inserted, a high value external pull-down resistor (> 270 k\u2126) is required to drive the detect signal low when no card is inserted, while the card built-in 10-50 k\u2126 resistor will drive this signal high when inserted.</p> <p>However, this feature is not compatible with MMC cards, so its usage should be avoided and the mechanical detection is preferred.</p>"},{"location":"developer_guide/hardware_reference/sd-card/#pull-up-resistors","title":"Pull-Up Resistors","text":"<p>Both the SD Card and MMC specifications require not to leave the interface signals floating, except for the CLK signal, where a pull resistor would cause significant signal distortion because of the required high speed and short rise/fall times. However, it is recommended to add a series resistor on this CLK signal as close as possible to the clock source (the CPU) to avoid ringing, as we already discussed it in the page about the CPU.</p> <p>Fortunately, the Allwinner V3s CPU provides internal pull-up resistors for all these signals, so we don't have to add external pull-up resistors. These resistors are given with a typical value of 100 k\u2126 (50 min, 150 max). Unfortunately, the CMD signal for MMC card features an open-drain output mode, and its value should be undercut (down to 4.7 k\u2126) to guarantee a sufficiently short rise time in this mode.</p>"},{"location":"developer_guide/hardware_reference/sd-card/#schematics","title":"Schematics","text":"<p>The FunKey SD Card interface schematic is the following:</p> <p></p> <p></p> <p>As can be expected, the main component is the Micro SD (TF Card) Push/Pull connector J4, which has been selected for its low-profile (1.3 mm height) characteristic and overall minimal dimensions.</p> <p>Tip</p> <p>\"Push-Pull\" means that you have to \"Push\" to insert the card and to \"Pull\" to remove it, i.e. the operation is completely manual, whereas \"Push/Push\" implies that you have a bistable mechanism to remove the card.</p> <p>Even if in the FunKey device the SD Card and its connector are not accessible without opening the enclosure, there may be some situations where the user may decide to do so. We thus attach an ESD protection TVS diode (D16, D17, D18, D25, D26, D27, D28) on each signal to avoid any ESD hazard.</p> <p>As discussed above, a single pull-up resistor R10 is used on the CMD signal for MMC compatibility.</p> <p>The micro SD Card connector built-in card detection switch is not used, since the card must always be inserted for the FunKey S to boot, and the corresponding pins are thus connected to GND.</p> <p>The SD Card power supply is applied through an RC low-pass filter R9 / C11 in order to provide a soft-start operation, as the card built-in large bulk capacitor on its power rail may collapse the supply voltage when initially powered up.</p>"},{"location":"developer_guide/hardware_reference/uart/","title":"UART","text":"<p>The Allwinner V3s provides 3x UARTs (Universal Asynchronous Receivers / Transmitters): UART0 with only RX and TX signals, and UART1 and UART2 with additional RTS and CTS hardware flow control signals.</p> <p>Like most SoCs, the Allwinner V3s provides a serial console as a control terminal for debug and/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.</p> <p>The Console schematic only requires a minimum of external components:</p> <p></p> <p>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.</p> <p>What is the purpose of this resistor?</p> <ul> <li> <p>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</p> </li> <li> <p>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, as the resistor is placed on the TX output signal, but we could have added one, if only we had some space left on the board... But as the V3s SoC can tolerate input voltages up to +3.6V on its pins, we should be safe!</p> </li> <li> <p>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 internal output buffers!</p> </li> </ul> <p>Warning</p> <p>There is no ESD protection TVS diodes on the UART: 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.</p>"},{"location":"developer_guide/hardware_reference/usb/","title":"USB","text":"<p>In the FunKey S device, the USB interface has 2 functions:</p> <ul> <li>provide an external power supply source for both powering the device and charging the built-in LiPo battery</li> <li>provide a data interface to transfer firmware upgrades, configuration files, game emulators and game ROMs</li> </ul> <p>The first function only requires the +5V USB power and GND pins. The second function 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.</p> <p></p> <p>The main part is of course the Micro USB edge-mounted connector J2, which we chose in order to \"mask out\" its already low-profile height into the PCB thickness. And with its \"harpoon-like\" through-hole legs, it should avoid tearing it off the board if the user don't pull the chord straight.</p> <p>The USB schematic is the following:</p> <p></p> <p>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.</p> <p>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.</p> <p>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 \u00b5F in order to avoid power supply excessive droops when plugin in a device with a discharged large bulk capacitor.</p> <p>D15 is a NXP PRTR5V0U2X,215 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.</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/","title":"Decoupling","text":""},{"location":"developer_guide/hardware_reference/power/decoupling/#capacitor-usage","title":"Capacitor Usage","text":"<p>So far, we already encountered capacitors for many different usages:</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/#load-capacitors","title":"Load Capacitors","text":"<p>We have seen load capacitors used with the 2 crystals in the discussion about CPU.</p> <p>A quartz crystal always provides both series and parallel resonance, the series resonance being a few kilohertz lower than the parallel one.</p> <p>Crystals below 30 MHz like ours are generally operated between series and parallel resonance, which means that the crystal appears as an inductive reactance in operation, this inductance forming a parallel resonant circuit with externally connected parallel \"load\" capacitance. Any small additional capacitance added in parallel with the crystal pulls the frequency lower in the range between the series and parallel resonance frequencies, insuring crystal startup and stable operation.</p> <p>For modern circuits, these load capacitors have a typical small value < 20 pF.</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/#bulk-capacitors","title":"Bulk Capacitors","text":"<p>Bulk capacitors are used to prevent a power supply from dropping too far during the periods when current is not available. At the same time, they help to reduce the power supply voltage ripples by smoothing their output voltage.</p> <p>Many such capacitors are used at both the input and output of the numerous linear and switched mode power supplies in the PMIC discussion.</p> <p>The main bulk capacitor value is generally high (some \u00b5F), but there may be smaller parallel capacitors added for stability.</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/#coupling-capacitors","title":"Coupling Capacitors","text":"<p>As you probably know, capacitors are made of 2 parallel conductive electrodes separated by a (thin) isolating dielectric material (even if these electrodes are rolled or layered to reduce the component size). Thus by construction, no DC (Direct Current) can flow from one electrode to the other, but by influence using the electric field, AC (Alternative Current) still can go through. This is how coupling capacitors are used to link 2 circuits while removing any DC bias voltage on one side or the other of the capacitor.</p> <p>We use such a coupling capacitor in the Audio schematic description for feeding the audio power amplifier from the CPU audio output.</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/#filter-capacitors","title":"Filter Capacitors","text":"<p>We have seen many examples where capacitors are used within passive filter circuits along with resistors or inductors, mainly to remove unwanted frequencies from a power supply or a signal.</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/#decoupling-bypass-capacitors","title":"Decoupling (Bypass) Capacitors","text":"<p>We use some decoupling capacitors in the buttons circuit.</p> <p>Active components such as transistors and chips are connected to their power supplies through conductors featuring a (small) common impedance made up of complex (resistive, capacitive and inductive) value. Because of these parasitic components, a device that suddenly draws some current in spikes will generate a drop in its voltage power supply. If many devices are sharing the same power supply and impedance, the state of one device will be coupled to the other ones through the common impedance of the power supply conductors and may affect their operation.</p> <p>In order to decouple the devices, capacitors placed as close as possible to the device power supply input pins are used, which act as local energy storage. These capacitors are also named \"bypass capacitors\" as they shunt transient energy from the power supplies past the device to be decoupled, right to the GND return path.</p> <p>There may be different capacitors values placed on the same power supply pins in order to filter transients at different frequencies: the bigger the capacitor value, the lower the frequency. A typical value is 100 nF, and values from 1 \u00b5F to 10 \u00b5F are used for lower frequencies and / or higher current draws, while lower values of a few nF are used for filtering higher frequencies.</p> <p>In essence, decoupling capacitors are not very different in their function from bulk capacitors: the only difference is one of scale, both of current and of transient duration. Bulk capacitors deal with large currents and periods of 10s of ms, whereas decoupling capacitors are used for much lower currents and much briefer periods (typically 10s of ns for TTL or CMOS devices) .</p>"},{"location":"developer_guide/hardware_reference/power/decoupling/#schematics","title":"Schematics","text":"<p>The last part of the FunKey schematics merely contains only decoupling capacitors:</p> <p></p> <p>One exception is the Allwinner V3s CPU HPR/HPL circuit which features an RC-to-ground circuit between the amplifier and the preamplifier input with the resistor R27 and capacitors C79 and C81, as recommended in the V3s hardware design guide.</p> <p>The only other remarkable point left in this schematic is the resistor divider R25/R28 which provides a reference voltage at half the DRAM power supply voltage level, which is used for the integrated DDR2 DRAM merged drivers and dynamic on-chip termination already discussed at the end of the previous CPU schematic description.</p>"},{"location":"developer_guide/hardware_reference/power/dram_power/","title":"DRAM Power","text":"<p>A separate Sylergy SY8088 Buck DC/DC SMPS chip is used to provide the DDR2 +1V8 DDR2 DRAM power.</p> <p>This is because the AXP20x is originally the PMU (Power Management Unit) used by most Allwinner SoCs (A10, A13 and A20), which do not integrate SDRAM, so the board designer has a wide choice of memory option: DDR2, DDR3, DDR3L, LPDDR3, LPDDR4 with various voltage requirements.</p> <p>But no specific PMIC was created for the Allwinner V3s used in the FunKey device which however integrates a fixed SiP (System In Package) 512Mbit (64MB) DDR2 SDRAM.</p> <p>We thus have to design a separate SMPS (DC-DC) power supply for providing the +1.8V 1A required for the DDR2 DRAM power supply.</p> <p>For this purpose, we followed closely the Allwinner Reference Design.</p> <p>Here is the corresponding DRAM Power schematics:</p> <p></p> <p>Nothing very fancy here: the SMPS chip U4 has its required input filter capacitor C37 and output capacitors C65 and C73.</p> <p>The low-profile ferrite-core power inductor L6 (rated with a saturation current of 1.76A and low < 0.1 \u2126 resistance) provides the DC-DC energy storage element.</p> <p>The R20/R23 precision voltage divider provides the required +0.6V feedback voltage from the +1.8V output voltage by having a \u2153 resistor ratio.</p> <p>The last component is a pull-up resistor R19 which ties the SMPS chip enable input to its active level permanently. The pull-up voltage is +3.0V (just as in the original reference design), probably as it is the next higher voltage available, in order to limit the current in it to its lowest possible value.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/","title":"Multiple Power Supply Voltages","text":"<p>Looking back at the section on the CPU schematics, the FunKey S device clearly needs a sophisticated power supply in order to fulfill the CPU power requirements. They are recalled below, along with the maximum current requirements found in the Allwinner V3s reference design (page 3):</p> <ul> <li>+3.3V / 1.2A for the I/O power supply</li> <li>+3.3V_AO / 30 mA for the Always-On power supply (RTC timer)</li> <li>+3.0V / 200 mA for the analog power supply</li> <li>+1.8V / 1A for the DDR2 DRAM power supply</li> <li>+1.25V / 1.6 A for the core power supply</li> </ul> <p>But why in the first place are there so many different power supply voltages required?</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#power-efficiency","title":"Power Efficiency","text":"<p>A first answer is: for better power efficiency.</p> <p>As P = U x I (Electrical power is the product of voltage level by current intensity), you can reduce power by decreasing the required current or by reducing the operating voltage. Assuming you already do your best to reduce the required current, you can still reduce power by reducing the voltage.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#reducing-power-supply-voltage","title":"Reducing Power Supply Voltage","text":""},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#voltage-drop","title":"Voltage Drop","text":"<p>But how far can you go? Over long distance, you have the voltage drop from the conductor linear resistance, but this effect can be neglected for small boards.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#noise-margin","title":"Noise Margin","text":"<p>You have inductive and capacitive coupling between conductive wires and planes too, but within a PCB, these coupling only have a limited direct effect on voltage. However, these coupling play a role in that they will pick up external electromagnetic noise from the surroundings and inject it into the circuit.</p> <p>And with digital circuits, a critical limit when lowering the operating voltage is the \"noise margin\" or difference in absolute voltage levels between a logical '0' and logical '1', which determines the maximum amplitude of spurious voltage spikes that a conductor can pick up that will trigger an erroneous logic level change.</p> <p>This phenomenon mostly depends on the circuit scale: a long-distance circuit between boards will require higher voltages (typically +12V or +24V) to limit this effect, whereas a circuit between boards a few meters apart or using through-hole chips on the same board wile require a lower voltage (typically +5V like the old Arduinos). Using SMT chips will allow even smaller boards and lower voltages (+3.3V is typical today), and with wires running on the same silicon die, it is possible to go down to +1.2V, given the current technological limits.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#voltage-swing","title":"Voltage Swing","text":"<p>There are other reasons why you should try to minimize voltages: the core CPU for example needs to run as fast as possible, and lowering its operating voltage will shorten the signal rise and fall duration as the voltage swing is reduced.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#other-power-supply-considerations","title":"Other Power Supply Considerations","text":"<p>Besides reducing the operating voltage, there are other considerations that may push to multiply the number of power supplies in a design:</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#quiescent-current","title":"Quiescent Current","text":"<p>As for power supply used for standby operation providing small currents, a very-low leakage current (\"quiescent current\") is required as it can no longer be neglected compared to the current required by the light load and even more importantly because this current consumption is permanent.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#ripple-voltage","title":"Ripple Voltage","text":"<p>For sensitive circuits such as ADCs (Analog to Digital Converters) or PLLs (Phase-Locked Loops) which rely on comparing very small voltage differences, a \"clean\" power supply featuring very low ripple voltage amplitude is required to achieve a good resolution and/or accuracy. This characteristic is only possible to obtain using LDOs and not SMPS, and the figure to pay attention to is then the PSRR (Power Supply Rejection Ratio) or how much a variation in the input voltage will affect the output voltage: the higher, the better! A value > 50 dB is a good starting point.</p>"},{"location":"developer_guide/hardware_reference/power/multiple_voltages/#application-to-the-funkey-design","title":"Application to the FunKey Design","text":"<p>Based on these considerations, it is now clear that each V3s power supply voltage has a good reason to exist:</p> <ul> <li>+3.3V / 1.2A is used for powering the I/Os to connect between chips on the board. Given the required current, a SMPS is required for reaching a good efficiency</li> <li>+3.3V_AO / 30 mA for the Always-On power supply (RTC timer) requires a low quiescent-current, so an LDO is used</li> <li>+3.0V / 200 mA for the analog power supply also requires an LDO, this time to minimize the ripple voltage</li> <li>+1.8V / 1A for the DDR2 DRAM power supply: this strange voltage level is typical for DDR2 DRAM memory chips, and is the result of driving the large memory array inside the chip</li> <li>+1.25V / 1.6 A for powering the CPU core to minimize the voltage swing and increase the possible CPU frequency. Given the required current, a SMPS is required for reaching a good efficiency, too</li> </ul>"},{"location":"developer_guide/hardware_reference/power/pmic/","title":"PMIC","text":"<p>From the previous section, we can summarize the V3s power supply requirements to:</p> <ul> <li>SMPS for +3.3V / 1.2A for the I/O power supply</li> <li>LDO for +3.3V_AO / 30 mA for the Always-On power supply (RTC timer)</li> <li>LDO for +3.0V / 200 mA for the analog power supply</li> <li>SMPS for +1.8V / 1A for the DDR2 DRAM power supply</li> <li>SMPS for +1.25V / 1.6 A for the core power supply</li> </ul> <p>On the LicheePi Zero board used in our FunKey Zero prototype, a triple SMPS EA3036 is used for generating these +3.3V, +1.8V and +1.2V voltages, with an additional XC6206 LDO for the +3.0V (the +3.3V Always On is connected directly to +3.3V). Although compact (the EA3036 is a tiny 3 mm x 3 mm QFN20 package), this solution is not ideal as it does not provide a battery charger and monitoring capability, which is a requirement for the FunKey S device.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#pmics","title":"PMICs","text":"<p>As it is generally the case with such a complex SoC requiring multiple voltages, high current and proper voltage sequencing, all major manufacturers provide dedicated companion chips called PMICs (Power Management Integrated Circuits), in charge of these tasks. Allwinner is not an exception through its sister company X-Powers.</p> <p>Their AXP20x products are highly-integrated PMICs that are optimized for applications requiring single-cell Li-battery (Li-Ion/Polymer), multiple output DC-DC converters and LDOs. Here is a block diagram:</p> <p></p> <p>The AXP20x features:</p> <ul> <li> <p>A wide choice of input power source, the best source is output as IPSOUT inside the IPS (Intelligent Power Select) block:</p> <ul> <li> <p>USB VBUS</p> </li> <li> <p>Battery BAT</p> </li> <li> <p>ACIN wall plug (not used in the FunKey S)</p> </li> <li> <p>BACKUP battery (not used in the FunKey S)</p> </li> </ul> </li> <li> <p>A 1.8A fast PWM battery charger (also called DC/DC1) with battery voltage / current sense and programmable charge indication LED</p> </li> <li> <p>A soft key power-on/off logic with timer (just as in smartphones!)</p> </li> <li> <p>An I2C interface with interrupt signal to communicate with the CPU</p> </li> <li> <p>An optional battery temperature monitoring if the battery is equipped with an NTC resistor (not used in the FunKey S)</p> </li> <li> <p>A reference voltage</p> </li> <li> <p>A built-in 12-channel 12 bit ADC that measures various voltages and currents data, as well as feeding an internal Coulomb counter and fuel gauge system (more on this later)</p> </li> <li> <p>A \"power OK\" output used to generate the global RESET signal for the FunKey S</p> </li> <li> <p>5x GPIOs (not used in the FunKey S), GPIO0 can be programmed as LDO5 output</p> </li> <li> <p>2x DC/DC SMPS DC-DC2 and DC-DC3</p> </li> <li> <p>5x LDOs (only 2 are used in the FunKey S, LDO5 is optionnaly output to GPIO0)</p> </li> </ul> <p>Looking at their datasheets, it is difficult to tell the difference between the AXP202, AXP203 and AXP209 (any hint welcome!). In the FunKey S design, we use an AXP209 because it is the one that comes along with the V3s when you buy it on AliExpress.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#axp20x-application-diagram","title":"AXP20x Application Diagram","text":"<p>For complex dedicated chips like this, the best option is to follow as much as possible the application diagram and reference design given by the manufacturer, as the internals of the chips are seldom fully disclosed, so you need to take their word on some of the external component values to use.</p> <p>The Allwinner V3s Reference Design contains on page 6 the schematics for using an AXP203 to supply the power to a V3s-based dashboard camera design. It follows closely the application diagram provided in the AXP20x datasheets:</p> <p></p> <p>More hints are provided in our self-translated V3s Hardware Design Guide (page 7) too.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#pmic-schematics","title":"PMIC Schematics","text":"<p>The FunKey S device uses all of the U5 AXP209 integrated SMPS:</p> <ul> <li>the PWM charger DC-DC1 for the battery</li> <li>the DC-DC2 for providing the +1.25 V / 1.6A to the core</li> <li>the DC-DC3 for providing the +3.3V / 1.2A to the I/Os</li> </ul> <p>But compared to the sophisticated reference design above, the FunKey S device only uses 2 out of the 5 integrated LDOs:</p> <ul> <li>LDO1 supplies the +3.3V / 30 mA Always On for the RTC</li> <li>LDO2 provides the +3.0V / 200 mA for the analog power supply</li> <li>LDO3 / LDO4 / LDO5 are not used in the FunKey S</li> </ul> <p>Here are the PMIC schematics:</p> <p></p> <p>These schematics may look intimidating and complex, but they are in fact just a collection of simple basic elements, and it is actually very close to the manufacturer-recommended design.</p> <p>Here are the details for each PMIC functions, one by one:</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#power-inputs-east-side","title":"Power Inputs (East side)","text":"<p>A wall-plug AC adapter input is not used in the FunKey S device, so +VIN is just filtered using C75 on pins 32 and 33.</p> <p>The USB power input +VUSB on pin 31 is filtered using C70, and the best (between +VUSB and +VBAT) available voltage is output to +VOUT on pins 34 and 35 and filtered using C78.</p> <p>The BACKUP supply on pin 30 is not used and is left unconnected.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#internal-connections-all-sides","title":"Internal Connections (All sides)","text":"<p>Some AXP20x signals are externally available and should be connected to external components:</p> <ul> <li> <p>The BIAS connection on pin 23 is connected to a precision 200k 1% resistor R22, as recommended</p> </li> <li> <p>The reference voltage VREF on pin 24 is decoupled with C64</p> </li> <li> <p>The +2.5V internal logic voltage VINT on pin 26 is filtered using the recommended value for C67</p> </li> </ul> <p>Additionally, the AXP20x is actually made up of separate flexible blocks that require external interconnections to set their desired operation:</p> <ul> <li> <p>All DC/DC inputs (VIN1 on pin 44, VIN2 on pin 7 and VIN3 on pin 14), as well as LDO3IN input on pin 40 are connected to the best available voltage +VOUT with filter capacitors C59, C23, C30, and C69, respectively</p> </li> <li> <p>LDO1SET on pin 27 is used to set the initial voltage of LDO1, and according to the datasheets, setting it to VINT sets its voltage to the desired +3.3V for the +3.3V Always On power supply</p> </li> <li> <p>OTOH, combined LDO 2 and 4 input LDOIN24 on pin 13 is instead connected to +3.3V in order to minimize the voltage drop for LDO2 to generate the +3.0V. Here too, there is a filter capacitor C34</p> </li> <li> <p>It is not clear what is the exact function of APS on pin 21 (it is described as \"Internal Power Input\"), but it must be connected to +VOUT, too</p> </li> </ul>"},{"location":"developer_guide/hardware_reference/power/pmic/#dc-dc1-pwm-battery-charger-north-east-side","title":"DC-DC1 PWM Battery Charger (North East side)","text":"<p>The battery is connected to J5 (a 2-pin JST 1.0 mm pitch receptacle) and uses R21 as a precision current sense resistor, with C53/C56/C60 filter capacitors and L5 (a low-profile ferrite-core power inductor rated with a saturation current of 1.2A and low < 0.1 \u2126 resistance).</p> <p>Warning</p> <p>The battery is not protected on the board against reversing polarity, as the model used already contains a built-in protection.</p> <p>R24 is mounted to simulate a battery NTC resistor for measuring temperature, as the chosen LiPo battery does not feature this temperature sensor.</p> <p>A user-programmable (through the I2C interface) charge LED D30 is provided, with its current-limiting resistor R26, as well as a TVS diode d31 to prevent ESD, as the LED body will be indirectly accessible to user.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#dc-dc2-125v-16a-west-side","title":"DC-DC2 +1.25V / 1.6A (West side)","text":"<p>This SMPS is built around the ferrite core power inductor L3 and filter capacitors C26 and C29.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#dc-dc3-33v-12a-south-side","title":"DC-DC3 +3.3V / 1.2A (South side)","text":"<p>This SMPS is built around the ferrite core power inductor L4 and filter capacitors C39 and C43.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#ldo1-33v-always-on-30ma-south-east-side","title":"LDO1 +3.3V Always On 30mA (South East side)","text":"<p>The LDO output on pin 28 is filtered with capacitor C72.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#ldo2-30v-200ma-south-west-side","title":"LDO2 +3.0V / 200mA (South West side)","text":"<p>The LDO output on pin 12 is filtered with capacitor C33.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#ldo3-north-side","title":"LDO3 (North side)","text":"<p>This LDO is not used and its output on pin 41 is nevertheless filtered with a capacitor C63.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#ldo4-south-west-side","title":"LDO4 (South West side)","text":"<p>This LDO is not used and its output on pin 11 is nevertheless filtered with a capacitor C38.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#power-key-north-west-side","title":"Power Key (North West side)","text":"<p>The AXP20x features a soft power key with internal short and long-press detection with user-programmable time settings, which enables turning power ON or OFF much like the way it is done in cellular phones.</p> <p>Only a few external components are required: the tactile switch S13, its ESD protection TVS D29, and a low-pass filter R18 and C42 for debouncing the switch.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#i2c-bus-north-west-side","title":"I2C Bus (North West side)","text":"<p>The AXP20x can be externally controlled by the main CPU using the I2C bus on pins 1 and 2. This bus has pull-up resistors to +3.3V R14 and R16, and the IRQ/WAKEUP signal on pin 48 enables warning or waking up the CPU on a selection of AXP20x-generated events, with a pull-up resistor R13 to +3.3V.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#gpios-south-and-west-sides","title":"GPIOs (South and West sides)","text":"<p>GPIO0-3 on pins 19, 18, 5 and 3 are not used in the FunKey S and are left unconnected.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#pwrok-south-west-side","title":"PWROK (South West side)","text":"<p>The PWROK signal on pin 25 is used to generate the global RESET signal for the whole board, with a pull-up resistor R15 to the +3.3V Always On power supply and a filter capacitor C18.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#enable-signals-west-side","title":"Enable Signals (West side)","text":"<p>The global chip enable signal N_OE on pin 4 is activated by default through a 47k\u2126 resistor R17 to GND, but a magnetic Reed switch S14 can disable it by forcing its level to +VOUT, with a filter capacitor C83. This circuit will be disscused later in the Magnetic Switch section.</p> <p>The USB enable signal N_VBUSEN on pin 6 is directly tied to GND to always enable power from the USB bus.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#monitoring","title":"Monitoring","text":"<p>Through the I2C bus and the numerous internal available registers, the AXP20x provides a very fine control of its operation, including many threshold and timing settings, but also many voltage and curent monitoring values.</p>"},{"location":"developer_guide/hardware_reference/power/pmic/#coulomb-counters-fuel-gauge","title":"Coulomb Counters / Fuel Gauge","text":"<p>It is well known that battery discharge voltage curve over time is very flat, making it very difficult to estimate the real charge/discharge state of the battery. Moreover, this state will vary with temperature, load, and aging.</p> <p>The only accurate way to monitor the battery status is to actually count the energy that is stored when charging, and the one that is consumed. This particularly important feature is achieved in the AXP20x using a dual Coulomb counter which continuously sums the current intensity over time for monitoring the battery accurate charge and discharge status, with user-defined alert thresholds.</p> <p>This fuel gauge is providing the ability to precisely report the remaining battery capacity, just like people are used to with cellular phones.</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/","title":"Regulated DC Power Supply Topologies","text":"<p>Simple DC electronic circuits can be powered by directly connecting a battery. However, more complex circuits usually require a constant input voltage for proper operation.</p> <p>This page is a small sidetrack to explain the different regulated DC power supply topologies, before looking at the FunKey S power supply schematics in details.</p> <p>If you are already comfortable with this subject, you can skip this section entirely!</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#linear-regulators","title":"Linear Regulators","text":"<p>The easiest method to achieve a constant voltage viewed from the load despite a varying source voltage is to linearly control the resistance of the regulator in accordance with the load, resulting in a constant output voltage.</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#shunt-regulator","title":"Shunt Regulator","text":"<p>The simplest voltage regulator is the shunt regulator, built around a Zener diode which most interesting characteristic is to maintain a constant voltage across itself when the current through it is sufficient to take it into the Zener breakdown region. A simple shunt regulator looks like this:</p> <p></p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#series-regulator","title":"Series Regulator","text":"<p>By adding a emitter-follower transistor to the simple shunt regulator, the small base current of the transistor forms a very light load on the Zener, thereby minimizing variation in Zener voltage due to variation in the load, resulting in a better regulation. Here is a schematic for this series regulator:</p> <p></p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#integrated-linear-regulator","title":"Integrated Linear Regulator","text":"<p>In integrated voltage regulators, the discrete Zener diode is replaced by a more sophisticated (but easier to integrate) circuit built around a resistor divider feeding an operational amplifier, a voltage reference, and a transistor driving the emitter-follower pass transistor:</p> <p></p> <p>Usually, the pass transistor and its driving transistor are combined into a single Darlington transistor plus a controllable current source like this:</p> <p></p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#ldo-low-drop-out-regulator","title":"LDO (Low Drop-Out) Regulator","text":"<p>The above circuit works well, but its drop-out voltage (the difference between the input and output voltage) is rather high because of this transistor cascade, around 1.5V to 2.5V.</p> <p>By replacing the emitter-follower Darlington transistor by a PNP transistor in an open collector or open drain topology, the drop-out voltage is reduced to 0.7V or lower:</p> <p></p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#smps-switched-mode-power-supply-or-dcdc-converters","title":"SMPS (Switched-Mode Power Supply) or DC/DC Converters","text":"<p>A linear regulator provides the desired output voltage by dissipating excess power as heat in the Zener diode or in the pass transistor. Hence its maximum power efficiency is VOUT/ VIN since the voltage difference is wasted to heat the birds.</p> <p>In contrast, a Switched-Mode Power Supply changes output voltage and current by switching non-linear storage elements, such as inductors, transformers and capacitors between different electrical configurations.</p> <p>These elements are said to be non-linear because the inductor and transformer respond to changes in current by inducing its own voltage to counter the change in current, whereas a capacitor responds to changes in voltage by inducing its own current to counter the change in voltage.</p> <p>Thus, depending on the way the components are arranged, it is possible to obtain SMPS circuits that either have an output voltage higher than the input voltage (\"Boost Converters\"), or lower than the input voltage (\"Buck Converters\", as is it subtracts or \u201cBucks\u201d the supply voltage).</p> <p>Because of technology, power inductors are easier to manufacture, take less space and are more stable over time than their counterpart capacitors. This is why most power DC/DC converters are built using inductors. Capacitor-based SMPS are generally used for lower power applications, such as for generating the +12V and -12V voltages required by true RS232 from a +3.3V or +5V power supply in the ubiquitous MAX232 drivers.</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#boost-converter","title":"Boost Converter","text":"<p>The most basic circuit for the Boost converter is the following:</p> <p></p> <p>If the switch is driven by a square wave, the peak-to-peak voltage of the waveform measured across the switch can exceed the input voltage from the DC source. This is because the non-linear characteristic of the inductor, and this voltage adds to the source voltage while the switch is open.</p> <p>Warning</p> <p>In this converter, the output voltage is not isolated from the input voltage.</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#buck-converter","title":"Buck Converter","text":"<p>The corresponding basic circuit for the Buck converter is the following:</p> <p></p> <p>The way this converter works is described in details here. Basically, when the switch is closed, the inductor will produce an opposing voltage across its terminals in response to the changing current, reducing the output voltage, and meanwhile the inductor stores this energy in the form of a magnetic field. When the switch is opened, the current will decrease and will produce a voltage drop across the inductor, and now the inductor becomes a current source, where the stored energy in the inductor's magnetic field is restored and fed to the load.</p> <p>Warning</p> <p>In this converter too, the output voltage is not isolated from the input voltage.</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#isolated-smps","title":"Isolated SMPS","text":"<p>Isolated Switched-Mode Power Supplies use a transformer to isolate the input voltage from the output voltage, and thus can produce an output of higher or lower voltage than the input by adjusting the turns ratio.</p>"},{"location":"developer_guide/hardware_reference/power/power_supplies_topologies/#pros-and-cons","title":"Pros and Cons","text":"<p>Linear regulators are simpler than SMPS, and their linear behavior produce a very clean output voltage, but their efficiency is directly proportional to the difference between the input and output voltage, which is dissipated as heat.</p> <p>However, for light loads and/or when the voltage drop-out is low, LDOs are very useful.</p> <p>OTOH, SMPS are more complex and require more components, but their efficiency is much better (typically 80-90%), resulting in less heat, with the drawback of a switching electrical noise pollution of both the input voltage (that may couple electrical switching noise back onto the mains power line) and the output voltage (with electromagnetic interference (EMI) and a ripple voltage at the switching frequency and all its harmonic frequencies).</p> <p>SMPS are thus almost exclusively used when heavy loads are used and/or when the voltage drop-out is important.</p>"},{"location":"developer_guide/software_reference/","title":"Software Reference","text":"<p>The FunKey S retro-gaming console software contains a set of console emulators, standalone games, applications and utilities using a custom Operating System (OS) that from now on will be referenced as FunKey OS.</p> <p>The FunKey OS is a Linux-based operating system, optimized for the FunKey S hardware, with a special focus on performance and fast boot time.</p>"},{"location":"developer_guide/software_reference/#instant-action","title":"Instant Action","text":"<p>The FunKey S introduces a unique feature called Instant Action, which enables automatically saving the running state when closing the console before turning it off, and restoring this state when opening and turning it back on in a matter of seconds.</p> <p>This feature is only possible because of the optimized fast boot time detailed in the Boot Process section.</p>"},{"location":"developer_guide/software_reference/#storage","title":"Storage","text":"<p>The only storage system available in the FunKey S is its integrated MicroSD card. Most of its contents is made available to a host computer when connected over USB.</p>"},{"location":"developer_guide/software_reference/#video-processing","title":"Video Processing","text":"<p>The FunKey S CPU does not feature a GPU. For this reason, the FunKey S cannot use a hardware-accelerated OpenGL engine, and adding a software-emulated OpenGL-ES engine is not efficient, given the limited CPU performance.</p> <p>However, because of the small screen size and the fact that all applications are used in full-screen mode only, there is no need for a full-blown windowing system like X11, which greatly simplifies the video processing as no window overlapping or frame decoration is thus required.</p> <p>Instead, all graphical computations are performed by the CPU itself, directly into the video frame buffer that will be sent to the screen for display.</p>"},{"location":"developer_guide/software_reference/#user-input","title":"User Input","text":"<p>The FunKey S has no standard keyboard but features common console-oriented controls in the form of a D-Pad, A/B/X/Y Pad, Menu/On/Off, Fn and Start buttons.</p>"},{"location":"developer_guide/software_reference/boot_process/","title":"Boot Process","text":"<p>Quote</p> <p>Analyzing the boot processes of systems that are functioning well prepares users and developers to deal with the inevitable failures.</p> <p>Alison Chaiken in \"Analyzing the Linux boot process\"</p> <p>Learning how the FunKey S boots and shuts down is not required in order to develop for this platform, but it is certainly an interesting experience in order to understand the way to optimize a Linux embedded system.</p> <p>And then, when something goes wrong, it provides some useful insight on where to find the solution...</p>"},{"location":"developer_guide/software_reference/boot_process/#startup-process","title":"Startup Process","text":"<p>The startup process for a Linux machine is like a space rocket launch, but in reverse order: you start small and end up big, each stage helping to launch the next one.</p> <p>The reason for this is because many resources are involved when booting a Linux system, that require a significant amount of set up before you can use them, as they are not available right from the beginning; the most critical ones are probably memory and system clocks.</p> <p>When the FunKey S is started, its CPU is merely as powerful as an Arduino board: what is available is a 32-bit ARM CPU running @ 24MHz, with no reliable memory besides its 30 internal registers and a 32KB boot ROM.</p> <p>In order to get up to full speed (1.2GHz) and with all its memory (64MB DRAM, access to the 8GB SDcard) requires several steps, in order:</p> <ul> <li> <p>The Boot ROM</p> </li> <li> <p>The SPL (Secondary Program Loader)</p> </li> <li> <p>The U-Boot bootloader</p> </li> <li> <p>The Linux kernel</p> </li> <li> <p>The userland System V init scripts</p> </li> </ul>"},{"location":"developer_guide/software_reference/boot_process/#shutdown-process","title":"Shutdown Process","text":"<p>Unlike the startup process, the shutdown process is much more straightforward, but it must be optimized to run as quiclky as possible, as the time from when the shutdown is initiated when the user press the key or close the FunKey S lid to actual poweroff is extremely short (3 s).</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/","title":"Boot ROM","text":"<p>According to the Allwinner V3s datasheet, the integrated boot system consists in a 32KB boot ROM mapped at addresses <code>0xffff0000-0xffff7fff</code>, that can boot from SPI NOR Flash, SPI NAND Flash, SD Card and USB.</p> <p>In Allwinner terminology, this boot ROM is called \"BROM\" (for \"Boot ROM\") or \"eGON.BRM\" (for \"Embedded GO-ON Bootloader Boot ROM\", who knows what this means exactly?).</p> <p>But in another place in the same datasheet, it is stated that it can boot from eMMC, too.</p> <p>Wrong!</p> <p>We found that the available information is either incomplete, inacurate, misleading or completely false.</p> <p>What triggered our suspicion was this first mismatch and the lack of details regarding the boot process: not a single explanation on the boot firmware format and/or exact location.</p> <p>The original v3s_lichee.zip SDK is not very helpful in this regard.</p> <p>Hopefully, as Allwinner tends to use a rather consistent similar boot process for all its SoCs, the lichee-v2.0.tar.gz from Olimex is actually giving some clues, albeit it does not mention the V3s.</p> <p>But the best source of information on the Allwinner chips is certainly the sunxi community, that is dedicated to gather information around the Allwinner SoCs.</p> <p>And although it describes in details the Allwinner A10/A20 and A31 chips and not the V3s, their BROM page is a golden mine.</p> <p>The A20-V1.2.tar.gz SDK from Olimex is also relevant, as it contains some original source code for the Allwinner A20 SoC bootloader.</p> <p>Eventually, in order to clear all doubts regarding the Boot ROM role, we had to reverse-engineer the Allwinner V3s Boot ROM by disassembling its source code. The current findings are available in our repository, in the \"brom.s\" file, with our comments added:</p> <p>https://github.com/FunKey-Project/Allwinner-V3s-BROM</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#power-on-reset-por","title":"Power-On Reset (POR)","text":"<p>As it is common to all ARM Cortex-A architecture CPUs, the Allwinner V3s fetches the first instruction to execute from the first 32-bit word in a vector table located at address <code>0xffff0000</code>.</p> <p>On the V3s, this location is the first 32-bit word in the Boot ROM, that contains as its first vector a branch instruction to the <code>reset</code> function\", located immediately after the vector table.</p> <p>And except for the irq vector that contains a branch instruction to the first-level routine handling interrupt request, all other standard ARM vectors only contain a branch to a \"forever loop\" as they are not implemented at this stage.</p> <p>Note</p> <p>A non-standard \"FEL\" vector is appended at the end of the vector table.</p> <p>This provides an indirect way to access the FEL code, allowing to change its actual location while keeping the ability to address it using a fixed location.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#reset-function","title":"Reset Function","text":"<p>The <code>reset</code> function is the first useful piece of code executed on the CPU.</p> <p>At this point, the only known-working hardware is the CPU 24 MHz clock derived from the external crystal, the CPU itself and its internal registers which may not even be initialized.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#register-initialization","title":"Register Initialization","text":"<p>This is the role of the short <code>reset</code> function that clears all CPU registers (except r0 that is set to <code>1</code>) and jumps to the actual BROM header first 32-bit word.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#brom-header","title":"BROM Header","text":"<p>The BROM location contains a \"BROM header\" structure made up of:</p> <ul> <li> <p>a 32-bit word branch instruction that jumps to the <code>start</code> function</p> </li> <li> <p>an ASCII magic signature \"eGON.BRM\"</p> </li> <li> <p>a header length in bytes (32)</p> </li> <li> <p>a boot version in ASCII (\"1100\" for version 1.1.00)</p> </li> <li> <p>an eGON version in ASCII (\"1100\" for version 1.1.00)</p> </li> <li> <p>a platform information in ASCII (\"1681\" for the V3s)</p> </li> <li> <p>a 32-bit word padding</p> </li> </ul>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#start-function","title":"Start Function","text":"<p>The <code>start</code> function role is to setup a minimal execution environment with a call stack, using the internal static RAM A1 and C memory.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#brom-output-pin-toggling","title":"BROM Output Pin Toggling","text":"<p>We found that the first step of the <code>start</code> function consists in toggling an unidentified \"BROM Output\" pin.</p> <p>This guess is based on the fact that, according to the H6 User Manual which has a register with similar offset (<code>0xa4</code>) in its system configuration block, it is indeed <code>BROM_OUTPUT_REG</code>, and its bit 0 is <code>BROM_OUTPUT_ENABLE</code>, and bit 1 is <code>BROM_OUTPUT_VALUE</code>.</p> <p>Tip</p> <p>If this pin is actually available, this would allow to check with an oscilloscope if the CPU is running or not, but we were not able to locate it.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#multi-cpu-check","title":"Multi-CPU Check","text":"<p>The second step in the <code>start</code> function is to check for multi-CPUs. This is unlikely to do anything, as the V3s only contains a single CPU, but the code is probably here for compatibility with other multi-core SoCs.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#start-cpu-0","title":"Start CPU #0","text":"<p>The third step in the <code>start</code> function is to initialize the CPU #0 operating mode:</p> <ul> <li> <p>define the system as an ARMv4+ architecture</p> </li> <li> <p>set the CPU #0 in SVC (supervisor) mode</p> </li> <li> <p>disable both normal IRQ and fast FIRQ interrupt requests</p> </li> <li> <p>set the system as little-endian</p> </li> </ul>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#disable-memory-access-features","title":"Disable Memory Access Features","text":"<p>The next step in the <code>start</code> function is to disable all kind of memory access optimization features:</p> <ul> <li> <p>disable the MMU</p> </li> <li> <p>disable the data cache (D-Cache)</p> </li> <li> <p>disable the program flow prediction and the instruction cache (I-Cache)</p> </li> </ul>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#disable-watchdog","title":"Disable Watchdog","text":"<p>The next step in sequence in the <code>start</code> function is to disable the watchdog.</p> <p>Tip</p> <p>However, this is described in the datasheet as having \"no effect\"?</p> <p>It may be a write-once capability that is disabled when written anything but zeros.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#configure-internal-system-bus-clocks","title":"Configure Internal System Bus Clocks","text":"<p>The clocks for the AHB1 (Advanced High-speed Bus #1) and APB1 (Advanced Peripheral Bus #1) bus clocks are set up to enable access to most of the internal peripheral controllers, except UART, TWI that are on APB2 bus and EMAC and USB that are on AHB2 bus, as can be seen in the diagram below:</p> <p></p> <p>Bug</p> <p>In the above diagram taken from the datasheet, the BROM looks like is located on the APB1 bus, which is certainly not possible, as the system already accesses it before enabling its clock!</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#initialize-dma-and-pio","title":"Initialize DMA and PIO","text":"<p>In the next step in the <code>start</code> function:</p> <ul> <li> <p>the DMA engine is enabled</p> </li> <li> <p>the PIO (Peripheral I/O) controller is enabled to access external pins</p> </li> <li> <p>the DMA engine is reset</p> </li> </ul>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#initialize-stack-pointer-in-sram-a1","title":"Initialize Stack Pointer in SRAM A1","text":"<p>At this stage, the 16KB SRAM A1 is available at addresses <code>0x00000000-0x00003fff</code>, so a first stack pointer is initialized at the top of SRAM A1 memory.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#resume-from-standby-mode","title":"Resume from Standby Mode","text":"<p>A check is then performed to see if the CPU is resuming from standby mode.</p> <p>Hint</p> <p>This standby mode is not documented anywhere!</p> <p>If yes, a jump to the <code>resume_from_standby</code> function is done, where further checking is performed on the resume header:</p> <ul> <li> <p>check for a \"eGON.BT0\" signature at an address <code>0x01f01da8</code> that is suspected to be a \"standby resume entry address register\"</p> </li> <li> <p>check if the resume address the follows the signature is valid (if its 10 MSB bits are all zeros)</p> </li> <li> <p>verify the header checksum</p> </li> </ul> <p>If all these checks passed, the resume entry point is called, otherwise a call to the <code>boot</code> function is performed to try to resume the normal boot sequence.</p> <p>Bug</p> <p>However, the normal boot sequence will not be able to continue, as the next steps to enable the SRAM C block are skipped, so this is expected to fail!</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#enable-sram-c","title":"Enable SRAM C","text":"<p>In the next to final step of the <code>start</code> function, the SRAM C (44 KB) is enabled at addresses <code>0x00004000-0x000efff</code>:</p> <ul> <li> <p>first, an undocumented register in System Control block is cleared, that is suspected to enable SRAM C access to the CPU and the DMA</p> </li> <li> <p>Then the Video Engine (VE) is started by enabling its clock and reseting it. It is suspected that the reason it is done here is because the SRAM C block is tied to the Video Engine function</p> </li> </ul>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#initialize-stack-pointer-in-sram-c","title":"Initialize Stack Pointer in SRAM C","text":"<p>In the last step of the <code>start</code> function, the stack pointer is set 4KB below the end of SRAM C (address <code>0x0000dffc</code>), before calling the final <code>boot</code> function.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#boot-function","title":"Boot Function","text":"<p>The role of the <code>boot</code> function is to implement the boot sequence described in the datasheet:</p> <p></p> <p>Wrong!</p> <p>However, we found out that this diagram is inacurate!</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#check-uboot-button","title":"Check UBoot Button","text":"<p>The first step in the <code>boot</code> function is to check if an \"UBoot button\" is pressed by calling the <code>check_uboot</code> function.</p> <p>Note</p> <p>Here, \"UBoot\" stands for \"USB Boot\", it has nothing to do whith \"Das U-Boot\" bootloader!</p> <p>However, as the <code>check_uboot</code> function uses a special register to check the input pin rather than the standard PIO controller, it is not possible to determine from the code which pin is actually involved.</p> <p>We are not aware of any pin on the V3s that has this capability, although we suspected the PF6 pin (pin 100) to have this function as it has no alternate function like all the other pins, but this is not the case: pulling this pin to GND during the boot process has no effect, so likely, this function is not implemented on the V3s.</p> <p>If this hypothetical button is pressed during the boot sequence, the <code>boot</code> function would branch directly to the FEL USB Boot code, bypassing the normal boot process.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#boot-from-flash-memory","title":"Boot from Flash Memory","text":"<p>Unlike what is describe in the control flow diagram above, the V3s search order for the Flash memory to boot from is actually the following:</p> <ol> <li> <p>SD Card on SDC0 interface</p> </li> <li> <p>eMMC chip on SDC2 interface</p> </li> <li> <p>SD Card on SDC2 interface</p> </li> <li> <p>NOR Flash chip on SPI interface</p> </li> <li> <p>NAND Flash chip on SPI interface</p> </li> </ol> <p>For all Flash memory types, the boot process is similar:</p> <ul> <li> <p>read one 512 byte block at address <code>0x00000000</code> from the Flash device to get a \"BOOT0 Header\"</p> </li> <li> <p>check the \"eGON.BT0\" signature at the very beginning of the loaded block using the <code>check_magic</code> function (example for booting from MMC0)</p> </li> <li> <p>check the length field at offset 16: the second stage bootloader length must be < 32KB (0x8000), example for booting from MMC0</p> </li> <li> <p>check if the length field bits 24:31 are null (which is always true anyway because of the test above, example for booting from MMC0)</p> </li> <li> <p>perform 2 attempts to read the required number of 512-byte blocks for the specified length and load them at address <code>0x00000000</code> from the Flash device (it looks like the first block is re-read, example for booting from MMC0). The reason to perform 2 attempts is unknown</p> </li> <li> <p>eventually, jump to the <code>.boot_spl</code> function, which:</p> <ul> <li> <p>loads <code>0xfc</code> into register r1 and <code>0x0</code> into register r0</p> </li> <li> <p>calls the <code>jump_spl</code> function that:</p> </li> <li> <p>saves the r0 contents to r4</p> </li> <li> <p>calls in turn the <code>jump_to</code> function that:</p> <ul> <li>loads r0 into the program counter and never returns, actually launching the loaded SPL (Secondary Program Loader) at address <code>0x00000000</code> in SRAM A1 and C</li> </ul> </li> </ul> </li> </ul> <p>If no bootable Flash memory is found, the <code>boot</code> function will branch to the FEL USB Boot code.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#booting-from-sd-card","title":"Booting from SD Card","text":"<p>As on the FunKey S the only available Flash memory to boot from is the SD Card, we will focus on this one and ignore the other devices.</p> <p>The only SD Card specificity regarding the boot process is that the BOOT0 header above is fetched from 2 byte-offsets from the beginning of the card:</p> <ul> <li> <p>at offset 8KB</p> </li> <li> <p>at offset 128KB</p> </li> </ul> <p>The reason why these particular offsets were chosen is unknown, but they are not very convenient for card following a standard partitioning scheme:</p> <ul> <li> <p>the 8KB offset falls in the middle of the Primary GPT in a GUID Partition Table scheme. As most SD Card are optimized in hardware for the old MBR scheme, it is not critical</p> </li> <li> <p>both offsets fall within the first 1GB on the disk, which is most of the time not allocated for disk partitions, so they require specific tools to access them</p> </li> </ul> <p>On the FunKey S, the 8KB offset is used for the SPL, detailed in the next section.</p> <p>The SD Card interface used (0 or 2) is stored into the BOOT0 header in the byte at offset 40, and bit 5 in this byte is set to <code>1</code> when the BOOT0 header is loaded from offset 128 KB, and to <code>0</code> when booted from offset 8KB by this code.</p>"},{"location":"developer_guide/software_reference/boot_process/boot_rom/#fel","title":"FEL","text":"<p>The FEL is a low-level subroutine also contained in the BootROM on Allwinner devices. It is used for initial programming and recovery of devices using USB.</p> <p>The FEL is actually implementing a tiny USB stack for a proprietary USB protocol different from the standard DFU (Device Firmware Update) protocol used by many other devices.</p> <p>Using some specific tools on the host computer, it is possible to read or write data to/from the device over USB and execute code on it, providing a way to boot the system over USB.</p> <p>These \"sunxi-tools\" are described here and here.</p> <p>Warning</p> <p>For the V3s, it is mandatory to build the version from the repository, as the versions packaged in the different operating systems are too old and do not take into account the V3s chip.</p> <p>Using the \"sunxi-tools\" and the built-in FEL mode from the BootROM, it is possible to boot the V3s CPU over USB without any attached Flash storage.</p>"},{"location":"developer_guide/software_reference/boot_process/spl/","title":"SPL","text":"<p>The SPL is the Secondary Program Loader (the Primary Program Loader being the code in the Boot ROM), it is the first user-customizable piece of code run on the CPU.</p> <p>The SPL is built as part of the U-Boot bootlader. Actually, it shares most of its code with it.</p> <p>The SPL is loaded by the Boot ROM at address <code>0x00000000</code> in SRAM A1 and C, and has a maximum size of 32KB. It contains a \"BOOT0 Header\" that has been checked previously by the Boot ROM, and its byte at offset 40 has been updated with the SD card interface used to boot, with its bit 5 set to <code>1</code> if it was loaded from offset 128KB from the SD Card, or <code>0</code> if was loaded from offset 8KB.</p> <p>The role of the SPL stage is to set up the CPU clocks to their nominal speeds and set up the main SDRAM memory in order to load into it the next boot stage: either the U-Boot bootloader or the Linux kernel, as these are too large to fit into the small SRAM memory.</p>"},{"location":"developer_guide/software_reference/sd_card_layout/","title":"SD-Card Layout","text":""},{"location":"developer_guide/software_reference/sd_card_layout/directory_structure/","title":"Directory Structure","text":"<p>As the FunKey OS is based on Linux, it conforms with a few exceptions to the Filesystem Hierarchy Standard (FHS).</p>"},{"location":"developer_guide/software_reference/sd_card_layout/directory_structure/#hierarchies","title":"Hierarchies","text":"<p>The FHS defines 3 hierarchies of directories:</p> <ol> <li> <p>The primary hierarchy is mandatory and contains all required directories and essential binaries, as well as the other hierarchies</p> </li> <li> <p>The secondary hierarchy contains read-only, shareable user data and incldues the majority of user utilities and applications</p> </li> <li> <p>The tertiary hierarchy contains local data specific to a host</p> </li> </ol> Directory Description <code>/</code> Primary hierarchy root and root directory of the entire file system hierarchy. <code>/bin</code> Essential command binaries that need to be available in single-user mode, including to bring up the system or repair it, for all users (e.g., cat, ls, cp). <code>/boot</code> Boot loader files: the Linux kernel and its Device Tree blob (configuration file for the Linux kernel). <code>/dev</code> Device files (e.g., <code>/dev/null</code>, <code>/dev/disk0</code>, <code>/dev/sda1</code>, <code>/dev/tty</code>, <code>/dev/random</code>). <code>/etc</code> Host-specific system-wide configuration files. <code>/lib</code> Run-time libraries essential for the binaries in <code>/bin</code> and <code>/sbin</code>. <code>/media</code> Mount points for removable media such as CD-ROMs (appeared in FHS-2.3 in 2004). <code>/mnt</code> Temporarily mounted filesystems. <code>/opt</code> Optional application software packages. <code>/proc</code> Virtual filesystem providing process and kernel information as files. In Linux, corresponds to a procfs mount. Generally, automatically generated and populated by the system, on the fly. <code>/root</code> Home directory for the root user. <code>/run</code> Run-time variable data: Information about the running system since last boot, e.g., currently logged-in users and running daemons. Files under this directory must be either removed or truncated at the beginning of the boot process, but this is not necessary on systems that provide this directory as a temporary filesystem (tmpfs). <code>/sbin</code> Essential system binaries (e.g., fsck, init, route). <code>/sys</code> Contains information about devices, drivers, and some kernel features. <code>/tmp</code> Temporary folder <code>/usr</code> Secondary hierarchy for read-only user data; contains the majority of (multi-)user utilities and applications. Should be shareable and read-only. <code>/usr/bin</code> Non-essential command executable <code>/usr/lib</code> Library (computer science) <code>/usr/local</code> Tertiary hierarchy for local data, specific to this host. Typically has further subdirectories (e.g., <code>bin</code>, <code>lib</code>, <code>share</code>). <code>/usr/sbin</code> Non-essential system binaries (e.g., Daemon (computer software) <code>/usr/share</code> Architecture-independent (shared) data. <code>/var</code> Variable files: files whose content is expected to continually change during normal operation of the system, such as logs, spool files, etc. <code>/var/cache</code> Application cache data. Such data are locally generated as a result of time-consuming I/O or calculation. The application must be able to regenerate or restore the data. The cached files can be deleted without loss of data. <code>/var/lib</code> State information. Persistent data modified by programs as they run (e.g., databases, packaging system metadata, etc.). <code>/var/lock</code> Lock files. Files keeping track of resources currently in use. <code>/var/log</code> Log files. Various logs. <code>/var/opt</code> Variable data from add-on packages that are stored in <code>/opt</code>. <code>/var/run</code> Run-time variable data. This directory contains system information data describing the system since it was booted.In FHS 3.0, <code>/var/run</code> is replaced by <code>/run</code>; a system should either continue to provide a <code>/var/run</code> directory or provide a symbolic link from <code>/var/run</code> to <code>/run</code> for backwards compatibility. <code>/var/spool</code> Spool for tasks waiting to be processed (e.g., print queues and outgoing mail queue). <code>/var/tmp</code> Temporary files to be preserved between reboots Directory Description <code>/etc/opt</code> Configuration files for add-on packages that are stored in <code>/opt</code>. <code>/etc/sgml</code> Configuration files, such as catalogs, for software that processes SGML. <code>/etc/X11</code> Configuration files for the X Window System, version 11. <code>/etc/xml</code> Configuration files, such as catalogs, for software that processes XML. <code>/home</code> Users' home directory <code>/lib<qual></code> Alternate format essential libraries. These are typically used on systems that support more than one executable code format, such as systems supporting 32-bit and 64-bit versions of an instruction set. Such directories are optional, but if they exist, they have some requirements. <code>/srv</code> Site-specific data served by this system, such as data and scripts for web servers, data offered by FTP servers, and repositories for version control systems (appeared in FHS-2.3 in 2004). <code>/usr/include</code> Standard header file <code>/usr/lib<qual></code> Alternative-format libraries (e.g., <code>/usr/lib32</code> for 32-bit libraries on a 64-bit machine (optional)). <code>/usr/src</code> Source code (e.g., the kernel source code with its header files). <code>/usr/X11R6</code> X Window System, Version 11, Release 6 (up to FHS-2.3, optional). <code>/var/mail</code> Mailbox files. In some distributions, these files may be located in the deprecated <code>/var/spool/mail</code>. <code>/var/spool/mail</code> Deprecated location for users' mailboxes. <pre><code>/\n\u251c\u2500\u2500 bin\n\u251c\u2500\u2500 boot\n\u251c\u2500\u2500 dev\n\u2502 \u251c\u2500\u2500 pts\n\u2502 \u2514\u2500\u2500 shm\n\u251c\u2500\u2500 etc\n\u2502 \u251c\u2500\u2500 cron.d\n\u2502 \u251c\u2500\u2500 default\n\u2502 \u251c\u2500\u2500 dropbear -> /tmp\n\u2502 \u251c\u2500\u2500 init.d\n\u2502 \u251c\u2500\u2500 libnl\n\u2502 \u251c\u2500\u2500 network\n\u2502 \u2502 \u251c\u2500\u2500 if-down.d\n\u2502 \u2502 \u251c\u2500\u2500 if-post-down.d\n\u2502 \u2502 \u251c\u2500\u2500 if-pre-up.d\n\u2502 \u2502 \u251c\u2500\u2500 if-up.d\n\u2502 \u2502 \u2514\u2500\u2500 interfaces.d\n\u2502 \u251c\u2500\u2500 profile.d\n\u2502 \u2514\u2500\u2500 sysconfig\n\u251c\u2500\u2500 lib\n\u2502 \u251c\u2500\u2500 dhcpcd\n\u2502 \u2502 \u2514\u2500\u2500 dhcpcd-hooks\n\u2502 \u251c\u2500\u2500 lsb\n\u2502 \u2514\u2500\u2500 modules\n\u2502 \u2514\u2500\u2500 4.14.14-funkey\n\u2502 \u2514\u2500\u2500 kernel\n\u2502 \u251c\u2500\u2500 crypto\n\u2502 \u2514\u2500\u2500 drivers\n\u2502 \u251c\u2500\u2500 usb\n\u2502 \u2502 \u2514\u2500\u2500 gadget\n\u2502 \u2502 \u251c\u2500\u2500 function\n\u2502 \u2502 \u2514\u2500\u2500 legacy\n\u2502 \u2514\u2500\u2500 video\n\u2502 \u2514\u2500\u2500 backlight\n\u251c\u2500\u2500 lib32 -> lib\n\u251c\u2500\u2500 media -> /mnt\n\u251c\u2500\u2500 mnt\n\u2502 \u251c\u2500\u2500 Applications\n\u2502 \u251c\u2500\u2500 Atari lynx\n\u2502 \u251c\u2500\u2500 Emulators\n\u2502 \u251c\u2500\u2500 FunKey\n\u2502 \u2502 \u251c\u2500\u2500 .gmenu2x\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 applications\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 emulators\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 games\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 skins\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 240x240\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 ScanlinesBlue\n\u2502 \u2502 \u251c\u2500\u2500 Launchers\n\u2502 \u2502 \u251c\u2500\u2500 .mednafen\n\u2502 \u2502 \u251c\u2500\u2500 .pcsx\n\u2502 \u2502 \u251c\u2500\u2500 .sm64-port\n\u2502 \u2502 \u2514\u2500\u2500 snapshots\n\u2502 \u251c\u2500\u2500 Game Boy\n\u2502 \u251c\u2500\u2500 Game Boy Advance\n\u2502 \u251c\u2500\u2500 Game Boy Color\n\u2502 \u251c\u2500\u2500 Game Gear\n\u2502 \u251c\u2500\u2500 Games\n\u2502 \u251c\u2500\u2500 Neo Geo Pocket\n\u2502 \u251c\u2500\u2500 NES\n\u2502 \u251c\u2500\u2500 PCE-TurboGrafx\n\u2502 \u251c\u2500\u2500 PS1\n\u2502 \u2502 \u251c\u2500\u2500 bios\n\u2502 \u2502 \u2514\u2500\u2500 memcards\n\u2502 \u251c\u2500\u2500 Sega Genesis\n\u2502 \u251c\u2500\u2500 Sega Master System\n\u2502 \u251c\u2500\u2500 SNES\n\u2502 \u251c\u2500\u2500 System Volume Information\n\u2502 \u2514\u2500\u2500 WonderSwan\n\u251c\u2500\u2500 opk\n\u251c\u2500\u2500 opt\n\u251c\u2500\u2500 proc\n\u251c\u2500\u2500 root\n\u251c\u2500\u2500 run\n\u251c\u2500\u2500 sbin\n\u251c\u2500\u2500 sys\n\u251c\u2500\u2500 tmp\n\u2502 \u2514\u2500\u2500 sa\n\u251c\u2500\u2500 usr\n\u2502 \u251c\u2500\u2500 bin\n\u2502 \u251c\u2500\u2500 games\n\u2502 \u2502 \u251c\u2500\u2500 collections\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Atari lynx\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Advance\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Color\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Gear\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Main\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Neo Geo Pocket\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 NES\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 PCE-TurboGrafx\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 PS1\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Genesis\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Master System\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 SNES\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 WonderSwan\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u251c\u2500\u2500 core\n\u2502 \u2502 \u251c\u2500\u2500 launchers\n\u2502 \u2502 \u251c\u2500\u2500 layouts\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Classic\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 collections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Atari lynx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Advance\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Color\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Gear\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Neo Geo Pocket\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 NES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PCE-TurboGrafx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PS1\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Genesis\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Master System\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 SNES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 WonderSwan\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 images\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 sounds\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 Flat\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 collections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Atari lynx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Advance\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Color\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Gear\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Neo Geo Pocket\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 NES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PCE-TurboGrafx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PS1\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Genesis\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Master System\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 SNES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 WonderSwan\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 images\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 sounds\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 FunKey\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 collections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Atari lynx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Advance\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Color\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Gear\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Neo Geo Pocket\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 NES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PCE-TurboGrafx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PS1\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Genesis\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Master System\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 SNES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 WonderSwan\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 images\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 sounds\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 TFT\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 collections\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Atari lynx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Advance\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Boy Color\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Game Gear\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Neo Geo Pocket\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 NES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PCE-TurboGrafx\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 PS1\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Genesis\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Sega Master System\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 SNES\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 WonderSwan\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 system_artwork\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 images\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 sounds\n\u2502 \u2502 \u251c\u2500\u2500 menu_resources\n\u2502 \u2502 \u2514\u2500\u2500 opk\n\u2502 \u251c\u2500\u2500 lib\n\u2502 \u2502 \u251c\u2500\u2500 e2fsprogs\n\u2502 \u2502 \u251c\u2500\u2500 gstreamer-1.0\n\u2502 \u2502 \u251c\u2500\u2500 icu\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 67.1\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 current -> 67.1\n\u2502 \u2502 \u251c\u2500\u2500 lua\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 5.3\n\u2502 \u2502 \u251c\u2500\u2500 mpg123\n\u2502 \u2502 \u251c\u2500\u2500 sa\n\u2502 \u2502 \u2514\u2500\u2500 terminfo -> ../share/terminfo\n\u2502 \u251c\u2500\u2500 lib32 -> lib\n\u2502 \u251c\u2500\u2500 libexec\n\u2502 \u2502 \u2514\u2500\u2500 gstreamer-1.0\n\u2502 \u251c\u2500\u2500 local\n\u2502 \u2502 \u251c\u2500\u2500 lib\n\u2502 \u2502 \u251c\u2500\u2500 sbin\n\u2502 \u2502 \u2514\u2500\u2500 share\n\u2502 \u2502 \u2514\u2500\u2500 ProdResources\n\u2502 \u251c\u2500\u2500 sbin\n\u2502 \u2514\u2500\u2500 share\n\u2502 \u251c\u2500\u2500 alsa\n\u2502 \u2502 \u251c\u2500\u2500 cards\n\u2502 \u2502 \u251c\u2500\u2500 init\n\u2502 \u2502 \u251c\u2500\u2500 pcm\n\u2502 \u2502 \u2514\u2500\u2500 speaker-test\n\u2502 \u251c\u2500\u2500 aumix\n\u2502 \u251c\u2500\u2500 dhcpcd\n\u2502 \u2502 \u2514\u2500\u2500 hooks\n\u2502 \u251c\u2500\u2500 et\n\u2502 \u251c\u2500\u2500 fonts\n\u2502 \u2502 \u251c\u2500\u2500 dejavu\n\u2502 \u2502 \u251c\u2500\u2500 droid\n\u2502 \u2502 \u2514\u2500\u2500 truetype -> .\n\u2502 \u251c\u2500\u2500 gettext\n\u2502 \u2502 \u2514\u2500\u2500 its\n\u2502 \u251c\u2500\u2500 glib-2.0\n\u2502 \u2502 \u251c\u2500\u2500 schemas\n\u2502 \u2502 \u2514\u2500\u2500 valgrind\n\u2502 \u251c\u2500\u2500 gmenu2x\n\u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 games\n\u2502 \u2502 \u251c\u2500\u2500 skins\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 1280x720\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons -> ../../320x240/Default/icons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs -> ../../320x240/Default/imgs\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections -> ../../320x240/Default/sections\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 240x160\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons -> ../../320x240/Default/icons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs -> ../../320x240/Default/imgs\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections -> ../../320x240/Default/sections\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 240x240\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 GCW\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 ScanlinesBlue\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 fonts\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 ScanlinesRed\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 fonts\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 320x240\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 GCW\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 ScanlinesBlue\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 fonts\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 ScanlinesRed\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 fonts\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs\n\u2502 \u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 battery\n\u2502 \u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 buttons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 sections\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 640x480\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 icons -> ../../320x240/Default/icons\n\u2502 \u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs -> ../../320x240/Default/imgs\n\u2502 \u2502 \u2502 \u2502 \u2514\u2500\u2500 sections -> ../../320x240/Default/sections\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 800x480\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 Default\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 icons -> ../../320x240/Default/icons\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 imgs -> ../../320x240/Default/imgs\n\u2502 \u2502 \u2502 \u251c\u2500\u2500 sections -> ../../320x240/Default/sections\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 wallpapers\n\u2502 \u2502 \u2514\u2500\u2500 translations\n\u2502 \u251c\u2500\u2500 gst-plugins-base\n\u2502 \u2502 \u2514\u2500\u2500 1.0\n\u2502 \u251c\u2500\u2500 gstreamer-1.0\n\u2502 \u2502 \u2514\u2500\u2500 gdb\n\u2502 \u251c\u2500\u2500 locale\n\u2502 \u251c\u2500\u2500 lua\n\u2502 \u2502 \u2514\u2500\u2500 5.3\n\u2502 \u251c\u2500\u2500 mime\n\u2502 \u251c\u2500\u2500 sounds\n\u2502 \u2502 \u2514\u2500\u2500 alsa\n\u2502 \u251c\u2500\u2500 ss\n\u2502 \u251c\u2500\u2500 terminfo\n\u2502 \u2502 \u251c\u2500\u2500 a\n\u2502 \u2502 \u251c\u2500\u2500 d\n\u2502 \u2502 \u251c\u2500\u2500 l\n\u2502 \u2502 \u251c\u2500\u2500 p\n\u2502 \u2502 \u251c\u2500\u2500 s\n\u2502 \u2502 \u251c\u2500\u2500 v\n\u2502 \u2502 \u2514\u2500\u2500 x\n\u2502 \u2514\u2500\u2500 udhcpc\n\u2502 \u2514\u2500\u2500 default.script.d\n\u2514\u2500\u2500 var\n\u251c\u2500\u2500 cache -> ../tmp\n\u251c\u2500\u2500 lib\n\u2502 \u251c\u2500\u2500 alsa\n\u2502 \u251c\u2500\u2500 dhcp -> /tmp\n\u2502 \u2514\u2500\u2500 misc -> ../../tmp\n\u251c\u2500\u2500 lock -> ../tmp \n\u251c\u2500\u2500 log -> ../tmp \n\u251c\u2500\u2500 run -> ../run \n\u251c\u2500\u2500 spool -> ../tmp \n\u2514\u2500\u2500 tmp -> ../tmp \n</code></pre>"},{"location":"developer_guide/tutorials/access_recovery/","title":"Access the Recovery Boot Mode","text":"<p>The Recovery Mode is a special boot mode that can be entered when booting the FunKey S console.</p> <p>Its main purpose is to handle system updates, but it can also be used to recover the main system when it is no longer accessible, or to access some advanced test or developement features.</p>"},{"location":"developer_guide/tutorials/access_recovery/#enter-the-recovery-mode","title":"Enter the Recovery Mode","text":"<p>There are 2 different ways to enter Recovery Mode:</p> <ul> <li> <p>by holding both the and the keys at the same time while booting the FunKey S console</p> </li> <li> <p>by typing the following command at the Shell prompt, either using ssh over USB Ethernet or the serial console:</p> </li> </ul> <pre><code>$ recovery_mode\n</code></pre> <p>While booting, the system will display the following logo instead of the familiar FunKey S logo:</p> <p></p>"},{"location":"developer_guide/tutorials/access_recovery/#recovery-mode-commands","title":"Recovery mode commands","text":"<p>The Recovery Mode automatically enables the USB network client upon startup, allowing ssh connection over the USB cable for debug purposes.</p> <p>At the same time, the Recovery mode provides a simple text menu, with the current menu item displayed at the top of the screen.</p> <p>Navigation through the menu commands is using the and keys, and validation is using the key.</p>"},{"location":"developer_guide/tutorials/access_recovery/#info","title":"INFO","text":"<p>This command displays useful information regarding the FunKey S:</p> <ul> <li> <p>the Recovery Mode version</p> </li> <li> <p>the rootfs (e.g. \"Normal\" Mode) version</p> </li> <li> <p>if connected to a host through USB network, the device IP address</p> <pre><code>Recovery: 2.3.0\nrootfs : 2.3.0\nIP addr : 192.168.137.20\n</code></pre> </li> </ul>"},{"location":"developer_guide/tutorials/access_recovery/#usb-mountunmount","title":"USB MOUNT/UNMOUNT","text":"<p>This toggle commands performs the same way as the FunKey menu command, except that no confirmation is asked.</p>"},{"location":"developer_guide/tutorials/access_recovery/#usb-check","title":"USB CHECK","text":"<p>This command performs a check of the FAT32 USB partition, and try to repair it if it finds some errors, such as when the partition was not cleanly unmounted from a host computer.</p>"},{"location":"developer_guide/tutorials/access_recovery/#usb-format","title":"USB FORMAT","text":"<p>This commands formats the FAT32 USB partition.</p> <p>Warning</p> <p>This function will delete all the files on the USB partition, so be careful!</p>"},{"location":"developer_guide/tutorials/access_recovery/#network-enabledisable","title":"NETWORK ENABLE/DISABLE","text":"<p>This toggle command will enable/disable the USB network upon next boot.</p>"},{"location":"developer_guide/tutorials/access_recovery/#qr-code","title":"QR CODE","text":"<p>This command will display a full screen QR Code containing the FunKey S serial number:</p> <p></p>"},{"location":"developer_guide/tutorials/access_recovery/#factory-test-enabledisable","title":"FACTORY TEST ENABLE/DISABLE","text":"<p>This toggle command will enable/disable the factory tests upon next boot.</p>"},{"location":"developer_guide/tutorials/access_recovery/#first-boot-enabledisable","title":"FIRST BOOT ENABLE/DISABLE","text":"<p>This toggle command will enable/disable the \"first boot\" sequence that:</p> <ul> <li> <p>expands the rootfs \"Normal\" system partition</p> </li> <li> <p>create the swap partition</p> </li> <li> <p>create the USB shared partition</p> </li> <li> <p>install the free built-in games</p> </li> </ul>"},{"location":"developer_guide/tutorials/access_recovery/#exit-recovery","title":"EXIT RECOVERY","text":"<p>This comand exits the Recovery Mode and reboots in Normal Mode.</p>"},{"location":"developer_guide/tutorials/build_system/","title":"Build System","text":"<p>The FunKey S console is based on a sophisticated Allwinner V3s ARM Cortex-A7 1.2GHz CPU, an Operating System is mandatory in order to access all the hardware resources without re-inventing the wheel.</p> <p>Programs made for other computers will not work on the FunKey S, and developing programs on the FunKey S itself is rather impractical (too slow, not enough RAM, etc.).</p> <p>Instead, development for embedded devices like the FunKey S uses a method known as cross compilation for building software on a host platform (such as a desktop computer) to be used on another target platform (like the FunKey S).</p> <p>The FunKey OS repository on Github contains all the sources required to build the Open-Source firmware at the heart of the FunKey S retro-gaming console.</p> <p>This repository also contains a standalone SDK, which is a cross-compilation environment based on the GNU GCC compiler and binutils binary object tools, including the compiler toolchain and all the required libraries available on the FunKey S in order to build software for it.</p> <p>FunKey OS is based on Linux, and is built from scratch using the buildroot tool that simplifies and automates the process of building a complete Linux system for an embedded system like this.</p> <p>Technically speaking, FunKey OS is a buildroot (v2) based external tree for building the bootloader, the Linux kernel and user utilities, as well as the optimized retro-game launchers and console emulators.</p> <p>For detailed explanations on how to use buildroot itself, please refer to the Buildroot Manual.</p>"},{"location":"developer_guide/tutorials/build_system/build_program_using_sdk/","title":"Build Programs using SDK","text":"<p>This page will guide you through building a very simple application for FunKey using the SDK.</p> <p>FunKey is an embedded Linux device with an ARM processor at its core. Programs made for other computers will not work on FunKey, and developing programs on the FunKey itself is rather impractical. Instead, development for embedded devices like FunKey almost always uses a method known as cross compilation: building software on one platform (such as a desktop computer) to be used on another (like FunKey).</p> <p>The FunKey SDK contains a cross-compilation environment based on GCC, including the compiler toolchain and the libraries available on the FunKey.</p> <p>Before we can begin, setup a Linux-based compilation environment as shown on this page.</p>"},{"location":"developer_guide/tutorials/build_system/build_program_using_sdk/#installing-the-funkey-sdk","title":"Installing the FunKey SDK","text":"<p>The FunKey-SDK is included in releases of the FunKey OS, starting from version 2.0.0, and can be found on GitHub. Alternatively, you can compile the SDK yourself.</p> <p>Unpack the SDK's .tar.gz file somewhere on your build system. Before you can use the SDK you must first run the relocate-sdk.sh script. This will update all references paths in the SDK to its current location. If you decide to move the SDK to another directory at a later point, don't forget to re-run the script.</p> <p>The SDK is now ready to use. For additional convenience it is highly recommended to <code>source</code> the environment-setup of the SDK. This will add the SDK utilities to the PATH, setup standard variables such as CC and LD to refer to the SDK versions of the toolchain, setup standard options for CFLAGS, and create aliases for configure and cmake to work with the SDK.</p>"},{"location":"developer_guide/tutorials/build_system/build_program_using_sdk/#your-first-application","title":"Your first application","text":""},{"location":"developer_guide/tutorials/build_system/build_program_using_sdk/#building","title":"Building","text":"<p>Let's build a simple application to test that everything is working. Below is a small C program that will use SDL to display a green square for 5 seconds, and then exits.</p> <pre><code>#include <SDL/SDL.h>\n\nint main(int argc, char *argv[])\n{ \n // Init SDL Video\n SDL_Init(SDL_INIT_VIDEO);\n\n // Open HW screen and set video mode 240x240, with double buffering \n SDL_Surface* hw_surface =\n SDL_SetVideoMode(240, 240, 32,\n SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);\n\n // Hide the cursor, FunKey doesn't come with a mouse\n SDL_ShowCursor(0);\n\n // Draw a green square in the middle of the screen\n SDL_Rect draw_rect = {.x=70, .y=70, .w=100, .h=100};\n Uint32 color = SDL_MapRGB(hw_surface->format, 0, 255, 0);\n SDL_FillRect(hw_surface, &draw_rect, color);\n\n // Switch buffers to show the square we just drew\n SDL_Flip(hw_surface);\n\n // Sleep for 5 seconds\n SDL_Delay(5000);\n\n /// Deinit SDL\n SDL_Quit();\n\n return 0;\n}\n</code></pre> <p>Save this file as hello.c somewhere outside of the SDK directory. If you've sourced the environment-setup you can use the variable CC to refer to the C compiler in the SDK. Let's build our program as hello:</p> <pre><code>$CC hello.c -o hello -lSDL\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/build_program_using_sdk/#packing","title":"Packing","text":"<p>The hello program you've just created is a valid executable for FunKey, but in order for the launcher to find it we must first bundle the program in an OPK package. Create a new folder for the contents of the package and put into it:</p> <ul> <li>The hello program.</li> <li>An icon for your program in PNG format, 32 x 32 pixels in size, called hello.png.</li> <li>A desktop file called hello.funkey-s.desktop (\"funkey-s\" is mandatory here), containing the following text:</li> </ul> <pre><code>[Desktop Entry]\nName=Hello\nComment=A simple test app\nExec=hello\nIcon=hello\nCategories=applications\n</code></pre> <p>Note: You need to add an extra empty line at the end of the .desktop file or it won't work!</p> <p>This file describes your program to the launcher:</p> <ul> <li>Name: This is the name of the application shown in the launcher</li> <li>Comment: A description of the application</li> <li>Exec: This the command to execute your program</li> <li>Icon: The name of the icon file, without the .png extension</li> <li>Categories: The categories under which the launcher will show the application, in a semicolon-separated list</li> </ul> <p>Once you've got everything ready you can turn the folder into a package using the OpenPackage Creator. Select your folder with the Open button, or drag it over the window. The OpenPackage Creator will note that you've already created .desktop file. Choose the \"Use existing as is\" option. Finally, click the Pack button to create hello.opk, ready to be transferred to the FunKey.</p>"},{"location":"developer_guide/tutorials/build_system/build_program_using_sdk/#installing","title":"Installing","text":"<p>Connect the FunKey to your computer via USB. Open the menu on the FunKey, select Mount USB and press A twice to confirm. Your FunKey will now be visible as a USB drive on your computer. You can place your application in any 1<sup>st</sup>-level folder, and you can create as many as you want to organise your applications. Let's create a new folder called Applications and place hello.opk in there. Safely remove the USB drive from your computer, and in the FunKey menu select Eject USB and press A twice to confirm.</p> <p></p> <p>Your application is now installed on FunKey. Note that only the GMENU2X launcher can open custom applications. So switch to that launcher via the FunKey menu if you haven't already. You should find an application called Hello under the applications category in the launcher.</p> <p></p>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/","title":"Compilation Environments","text":"<p>Even if the resulting disk image and firmware update files are relatively small (350MB and 110MB, respectively), the size of the corresponding sources and the compilation by-products tend to be rather large, such that an available disk space of at least 12GB is required during the build.</p> <p>And even if the resulting FunKey OS boots in less than 5s, it still requires a fair amount of time to compile: please account for \u00bd hour on a modern multi-core CPU with SSD drives and a decent Internet bandwidth.</p> <p>The FunKey OS is meant to be built on a native Ubuntu or Debian Linux host machine (Ubuntu 20.04 LTS in our case, but this should also work with other versions, too). And with only a few changes to the prerequisites, it can certainly be adapted to build on other common Linux distros.</p> <p>However, if your development machine does not match this setup, there are still several available solutions:</p> <ul> <li> <p>use a lightweight container system such as Docker and run an Ubuntu or Debian Linux container in it</p> </li> <li> <p>use a VM (Virtual Machine), such as provided by VirtualBox and run an Ubuntu or Debian Linux in it</p> </li> <li> <p>for Windows 10 users, use the WSL2 (Windows System for Linux 2) subsystem and run an Ubuntu Linux distro in it</p> </li> </ul> <p>In order to install one of these virtualized environments on your machine, please refer to the corresponding documentation.</p>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#build-on-a-physicalvirtual-machine","title":"Build on a Physical/Virtual Machine","text":""},{"location":"developer_guide/tutorials/build_system/compilation_environments/#prerequisites","title":"Prerequisites","text":"<p>While Buildroot itself will build most host packages it needs for the compilation, some standard Linux utilities are expected to be already installed on the host system. If not already present, you will need to install the following packages beforehand:</p> <ul> <li>bash</li> <li>bc</li> <li>binutils</li> <li>build-essential</li> <li>bzip2</li> <li>ca-certificates</li> <li>cpio</li> <li>cvs</li> <li>expect</li> <li>file</li> <li>g++</li> <li>gcc</li> <li>git</li> <li>gzip</li> <li>liblscp-dev</li> <li>libncurses5-dev</li> <li>locales</li> <li>make</li> <li>mercurial</li> <li>openssh-client</li> <li>patch</li> <li>perl</li> <li>procps</li> <li>python</li> <li>python-dev</li> <li>python3</li> <li>python3-dev</li> <li>python3-distutils</li> <li>python3-setuptools</li> <li>rsync</li> <li>rsync</li> <li>sed</li> <li>subversion</li> <li>sudo</li> <li>tar</li> <li>unzip</li> <li>wget</li> <li>xxd</li> </ul> <p>On Ubuntu/Debian Linux, this is achieved by running the following command:</p> <pre><code>$ sudo apt install bash bc binutils build-essential bzip2 ca-certificates cpio cvs expect file g++ gcc git gzip liblscp-dev libncurses5-dev locales make mercurial openssh-client patch perl procps python python-dev python3 python3-dev python3-distutils python3-setuptools rsync rsync sed subversion sudo tar unzip wget xxd\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#build-in-a-docker-container","title":"Build in a Docker Container","text":""},{"location":"developer_guide/tutorials/build_system/compilation_environments/#prerequisites_1","title":"Prerequisites","text":"<p>When using a Docker container, all the prerequisites are automatically installed.</p>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#build-on-windows-1011-with-wsl2","title":"Build on Windows 10/11 with WSL2","text":""},{"location":"developer_guide/tutorials/build_system/compilation_environments/#prerequisites_2","title":"Prerequisites","text":"<p>First, make sure your version of Windows 10 is new enough (any version of Windows 11 should be fine). Press Win + R to open the Run window and type in <code>winver</code> to check your Windows version and build number. The version should be 2004 or higher, the build number 19041 or higher.</p>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#enabling-windows-features","title":"Enabling Windows Features","text":"<p>Some addition Windows features need to be enabled. Open the Windows Features window either by searching for \"Windows Features\" in the Start Menu, or by opening Settings -> Apps & features -> Optional features -> More Windows features. There ensure that both Virtual Machine Platform and Windows Subsystem for Linux are enabled. After pressing OK to confirm, Windows will ask you to reboot your computer to complete installation.</p>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#download-the-linux-kernel-update-package","title":"Download the Linux kernel update package","text":"<p>An additional update is required to run WSL2. Download and install the following package from Microsoft:</p> <ul> <li>WSL2 Linux kernel update package for x64 machines</li> </ul>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#set-wsl2-as-your-default-version-optional","title":"Set WSL2 as your default version (optional)","text":"<p>You can run the following command in PowerShell to make WSL2 the default version. New installations of Linux distributions on Windows will then automatically use WSL2. Otherwise they will use WSL version 1 by default.</p> <pre><code>wsl --set-default-version 2\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#install-ubuntu-using-the-microsoft-store","title":"Install Ubuntu using the Microsoft Store","text":"<p>Now that WSL2 is ready to be used you can download a Linux distribution from the Microsoft Store. For this guide, it is recommended to install Ubuntu 20.04 LTS. After installing, Ubuntu can be started by either selecting it from the Start Menu or typing <code>ubuntu2004</code> on the command prompt. The first time you run Ubuntu you will be asked to create a new user account with a username and password. These do not have to be the same as your Windows account.</p> <p>If you've enabled WSL2 as the default version in the previous step, Ubuntu will be automatically configured to use that version. If you haven't set WSL2 as default, or if you've installed Ubuntu before setting WSL2 as default, it's possible to manually change the version for this distro. First, open a PowerShell window and type the following command to list all installed Linux distributions:</p> <pre><code>wsl --list --verbose\n</code></pre> <p>Check the name of the distribution you want to upgrade and run:</p> <pre><code>wsl --set-version <distribution name> <versionNumber>\n</code></pre> <p>With <code><versionNumber></code> set to <code>2</code> to use WSL2. You can use the same command with version number <code>1</code> to return to WSL 1.</p>"},{"location":"developer_guide/tutorials/build_system/compilation_environments/#wsl2-is-now-ready-to-be-used","title":"WSL2 is now ready to be used","text":"<p>Your Ubuntu installation is now ready to be used. Starting Ubuntu from the Start Menu will open a terminal with a Bash prompt. Everything you type here will be executed in Ubuntu. You can run and install applications within Ubuntu as you would on a complete installation or virtual machine.</p> <p>Follow the instructions in the Build on a Physical/Virtual Machine section to install the requirements needed to build FunKey OS.</p> <p>You can access the Windows filesystem via <code>/mnt</code>; the C: drive is mounted as <code>/mnt/c</code>. From Windows you can access the Linux filesystem via the special path <code>\\\\wsl$</code>. Note that you can only access the files there when Ubuntu is running on WSL2.</p>"},{"location":"developer_guide/tutorials/build_system/compile_distribution/","title":"Compile Distribution","text":""},{"location":"developer_guide/tutorials/build_system/compile_distribution/#on-a-physical-machine-in-a-virtual-machine","title":"On a Physical Machine / In a Virtual Machine","text":"<p>You may now build your FunKey with:</p> <p><pre><code>$ make\n</code></pre> This may take a while (~30 minutes), so consider getting yourself a cup, a glass or a bottle of your favorite beverage ;-)</p> <p>Note: you will need to have access to the network, since buildroot will download the package sources.</p> <p>After building, you should obtain the SD Card image <code>FunKey-sdcard-X.Y.Z.img</code>, the SDK file <code>FunKey-sdk-X.Y.Z.tar.gz</code> and the firmware update file <code>FunKey-rootfs-X.Y.fwu</code> in the <code>images</code> directory.</p>"},{"location":"developer_guide/tutorials/build_system/compile_distribution/#in-a-docker-container","title":"In a Docker Container","text":"<p>You may now build your FunKey with:</p> <pre><code>$ docker run --name funkey-os funkeyproject/funkey-os\n</code></pre> <p>Or alternatively, you can run it in the background with:</p> <pre><code>$ docker run -d --name funkey-os funkeyproject/funkey-os\n</code></pre> <p>If you launch it in the background, you can still follow what is going on with either:</p> <p><pre><code>$ docker top funkey-os\n</code></pre> Or:</p> <pre><code>$ docker logs funkey-os\n</code></pre> <p>This may take a while (~1h30), so consider getting yourself a cup, a glass or a bottle of your favorite beverage ;-)</p> <p>Note: you will need to have access to the network, since buildroot will download the package sources.</p> <p>After building, you can copy the SD Card image <code>sdcard.img</code>, the SDK file <code>FunKey-sdk-X.Y.tar.gz</code> and the firmware update file <code>FunKey-rootfs-X.Y.fwu</code> from the container into the host current directory:</p> <pre><code>$ mkdir images\n$ docker cp funkey-os:/home/funkey/FunKey-OS/images/FunKey-sdcard-X.Y.Z.img images/\n$ docker cp funkey-os:/home/funkey/FunKey-OS/images/FunKey-sdk-X.Y.Z.tar.gz images/\n$ docker cp funkey-os:/home/funkey/FunKey-OS/images/FunKey-rootfs-X.Y.Z.fwu images/\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/compile_sdk/","title":"Compile SDK","text":"<p>Starting from version 2.0.0, the pre-compiled FunKey SDK is available on Github, and it is also compiled automatically as a first step when building the full FunKey OS distribution.</p> <p>However, if you want to compile the SDK only, here are the instructions below:</p>"},{"location":"developer_guide/tutorials/build_system/compile_sdk/#on-a-physical-machine-in-a-virtual-machine","title":"On a Physical Machine / In a Virtual Machine","text":"<p>You may now build the SDK with:</p> <pre><code>$ make sdk\n</code></pre> <p>This may take a while (~1h), so consider getting yourself a cup, a glass or a bottle of your favorite beverage ;-)</p> <p>Note: you will need to have access to the network, since buildroot will download the package sources.</p> <p>After building, you should obtain the SDK file <code>FunKey-sdk-X.Y.Z.tar.gz</code> in the <code>images</code> directory.</p>"},{"location":"developer_guide/tutorials/build_system/compile_sdk/#in-a-docker-container","title":"In a Docker Container","text":"<p>You may now build your FunKey with: <pre><code>$ docker run --name funkey-os funkeyproject/funkey-os make sdk -C /home/funkey/FunKey-OS\n</code></pre></p> <p>Or alternatively, you can run it in the background with: <pre><code>$ docker run -d --name funkey-os funkeyproject/funkey-os make sdk -C /home/funkey/FunKey-OS\n</code></pre></p> <p>If you launch it in the background, you can still follow what is going on with either: <pre><code>$ docker top funkey-os\n</code></pre> Or:</p> <pre><code>$ docker logs funkey-os\n</code></pre> <p>This may take a while (~1h), so consider getting yourself a cup, a glass or a bottle of your favorite beverage ;-)</p> <p>Note: you will need to have access to the network, since buildroot will download the package sources.</p> <p>After building, you can copy the SDK file <code>FunKey-sdk-X.Y.tar.gz</code> from the container into the host current directory:</p> <pre><code>$ mkdir images\n$ docker cp funkey-os:/home/funkey/FunKey-OS/images/FunKey-sdk-X.Y.Z.tar.gz images/\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/get_sources/","title":"Get the Sources","text":""},{"location":"developer_guide/tutorials/build_system/get_sources/#on-a-physical-machine-in-a-virtual-machine","title":"On a Physical Machine / In a Virtual Machine","text":"<p>When using either physical Linux machine or virtual Linux machines (VirtualBox or WSL2), you must clone the FunKey OS repository from Github (here we place it into a <code>FunKey-OS</code> directory):</p> <pre><code>$ git clone https://github.com/DrUm78/FunKey-OS\n</code></pre> <p>Then enter into the newly created directory:</p> <pre><code>$ cd FunKey-OS\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/get_sources/#in-a-docker-container","title":"In a Docker Container","text":"<p>When using a Docker container, you must first create a new directory (here we create a <code>FunKey-OS</code> directory) and get the FunKey OS Dockerfile in it:</p> <pre><code>$ mkdir FunKey-OS\n$ cd FunKey-OS\n$ wget https://raw.githubusercontent.com/DrUm78/FunKey-OS/master/docker/Dockerfile -o Dockerfile\n</code></pre> <p>You must then build the docker image (don't forget the final dot!):</p> <pre><code>$ docker build -t funkeyproject/funkey-os .\n</code></pre>"},{"location":"developer_guide/tutorials/build_system/write_image/","title":"Write firmware to SD Card","text":""},{"location":"developer_guide/tutorials/build_system/write_image/#how-to-flash-the-firmware-to-the-sd-card","title":"How to Flash the Firmware to the SD Card","text":"<p>You can copy the bootable <code>images/sdcard.img</code> onto an SD card using \"dd\":</p> <p><pre><code>$ sudo dd if=images/FunKey-sdcard-X.Y.Z.img of=/dev/sdX\n</code></pre> Warning: Please make sure that /dev/sdX device corresponds to your SD Card, otherwise you may wipe out one of your hard drive partitions!</p> <p>Alternatively, you can use the Balena-Etcher graphical tool to burn the image to the SD card safely and on any platform:</p> <p>https://www.balena.io/etcher/</p> <p>Once the SD card is burnt, insert it into the FunKey S console slot, and power it up. Your new system should come up now and start a console on the UART0 serial port and display the RetroFE game launcher on the graphical screen.</p>"},{"location":"developer_guide/tutorials/build_system/write_image/#how-to-update-the-funkey-s-firmware","title":"How to Update the FunKey S Firmware","text":"<p>It is possible to update the FunKey S over USB, please follow the steps described in the Firmware Upgrade section.</p>"},{"location":"miscellaneous/glossary/","title":"Glossary","text":""},{"location":"miscellaneous/glossary/#a","title":"A","text":"<ul> <li>ADC: Analog to Digital Converter</li> </ul>"},{"location":"miscellaneous/glossary/#c","title":"C","text":"<ul> <li>CPU: Central Processing Unit</li> <li>CSi: Camera Serial Interface</li> </ul>"},{"location":"miscellaneous/glossary/#d","title":"D","text":"<ul> <li>DAC: Digital to Analog Converter</li> <li>DFU: Device Firmware Update</li> <li>DMA: Direct Memory Access</li> <li>DDR: Dual Data Rate</li> <li>DRAM: Dynamic Random-Access Memory</li> <li>DSi: Display Serial Interface</li> </ul>"},{"location":"miscellaneous/glossary/#e","title":"E","text":"<ul> <li>ERC: Electrical Rule Check</li> <li>ESD: Electro-Static Discharge</li> </ul>"},{"location":"miscellaneous/glossary/#f","title":"F","text":"<ul> <li>FPU: Floating Point Unit</li> </ul>"},{"location":"miscellaneous/glossary/#g","title":"G","text":"<ul> <li>GPIO: General-Purpose Input/Output</li> <li>GPU: Graphic Processing Unit</li> </ul>"},{"location":"miscellaneous/glossary/#i","title":"I","text":"<ul> <li>I/O: Input/Output</li> <li>I2C: Inter-Integrated Circuit Bus</li> <li>IPS: In-Plane Switching or Intelligent Power Select</li> <li>IRQ: Interrupt ReQuest</li> </ul>"},{"location":"miscellaneous/glossary/#l","title":"L","text":"<ul> <li>LED: Ligh-Emitting Diode</li> <li>LCD: Liquid-Crystal Display</li> <li>LDO: Low Drop-Out</li> <li>LiPo: Lithium Polymer</li> </ul>"},{"location":"miscellaneous/glossary/#m","title":"M","text":"<ul> <li>MMU: Memory Management Unit</li> <li>MIPI: Mobile Industry Processor Interface</li> </ul>"},{"location":"miscellaneous/glossary/#n","title":"N","text":"<ul> <li>NTC: Negative Temperature Coefficient</li> </ul>"},{"location":"miscellaneous/glossary/#o","title":"O","text":"<ul> <li>OPK: Open Package</li> <li>OTG: On-The-Go</li> </ul>"},{"location":"miscellaneous/glossary/#p","title":"P","text":"<ul> <li>PCBA: Printed Circuit Board Assembly</li> <li>PCB: Printed Circuit Board</li> <li>PIO: Peripheral I/O</li> <li>PLL: Phase-Locked Loop</li> <li>PMIC: Power Management Integrated Circuit</li> <li>PMU: Power Managment Unit</li> <li>PoP: Package on Package</li> <li>PSRR: Power Supply Rejection Ratio</li> <li>PWM: Pulse Width Modulation</li> </ul>"},{"location":"miscellaneous/glossary/#r","title":"R","text":"<ul> <li>RAM: Random-Access Memory</li> <li>ROM: Read-Only Memory</li> <li>RTC: Real-Time Clock</li> </ul>"},{"location":"miscellaneous/glossary/#s","title":"S","text":"<ul> <li>SD: Secure Digital</li> <li>SIMD: Single Instruction Multiple Data</li> <li>SiP: System in Package</li> <li>SMPS: Switched-Mode Power Supply</li> <li>SoC: System on Chip</li> <li>SPI: Serial Peripheral Interface</li> <li>SPL: Secondary Program Loader</li> <li>SRAM: Static Random-Access Memory</li> </ul>"},{"location":"miscellaneous/glossary/#t","title":"T","text":"<ul> <li>TFT LCD: Thin-Film-Transistor Liquid-Crystal Display</li> <li>TVS: Transcient Voltage Suppressor</li> </ul>"},{"location":"miscellaneous/glossary/#u","title":"U","text":"<ul> <li>UART: Universal Asynchronous Receiver/Transmitter</li> <li>USB: Universal Serial Bus</li> </ul>"},{"location":"user_manual/tutorials/hardware/change_buttons/","title":"Change the Buttons","text":"<p>You FunKey S is delivered with 4 extra sets of buttons (red, blue, yellow and green) so that you can customize them at will. It only requires a standard Phillips screwdriver (PH0), tweezers and a knife or scissors for cutting up the plastic holding the new buttons together.</p> <p>Note</p> <p>Be careful when opening up the console. FunKey Project is not responsible for any damage done to your console when changing the buttons.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-1-removing-the-screws","title":"STEP 1 - Removing the screws","text":"<p>Using a standard Phillips PH0 screwdriver, remove the 2 screws on the back of your FunKey S.</p> <p>Warning</p> <p>Be careful to use the correct screwdriver head size and type to prevent damaging the screws (do not use JIS screwdrivers). FunKey Project is not responsible for replacing damaged screws.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-2-opening-up-the-console","title":"STEP 2 - Opening up the console","text":"<p>Carefully remove the plastic back of the console by pulling up the hinge side first</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-3-removing-the-keychain-lanyard","title":"STEP 3 - Removing the keychain lanyard","text":"<p>Carefully remove the keychain lanyard and its axis by pulling gently (it may fall off when opening).</p> <p>Warning</p> <p>The axis is a small part, be careful not to loose it.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-4-removing-the-lr-buttons","title":"STEP 4 - Removing the LR buttons","text":"<p>Carefully remove the L/R plastic buttons by gently pulling them out of their axis</p> <p>Warning</p> <p>Be careful not to damage the L/R switches on the circuit board!</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-5-unplugging-the-battery","title":"STEP 5 - Unplugging the battery","text":"<p>Note</p> <p>This step is not required for changing the buttons, but we still advise it. You can however jump to the next step and not unplug the battery.</p> <p>Lift the battery and pull gently by the top of the circuit board to unplug the battery. The battery may be stuck to the processor with double-sided adhesive, it's perfectly normal if you have to lift with a bit of force to unstick it.</p> <p>Warning</p> <p>Be sure to pull on the connector and NOT the wires when removing the battery. It is recommended to use tweezers.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-6-unplugging-the-screen","title":"STEP 6 - Unplugging the screen","text":"<p>Now that you have access to the circuit board, you can unplug the screen. </p> <p>Warning</p> <p>This connector is fragile, unplug it vertically without force. It is recommended to use tweezers.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-7-removing-the-circuit-board","title":"STEP 7 - Removing the circuit board","text":"<p>By grabbing it by the hinge side, gently pull up the circuit board from the plastic casing.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-8-removing-the-buttons-you-wish-to-change","title":"STEP 8 - Removing the buttons you wish to change","text":"<p>Remove the buttons from their socket. It is recommended to use tweezers.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-9-separating-the-new-buttons","title":"STEP 9 - Separating the new buttons","text":"<p>Cut up the buttons from the four sets of colors included with your FunKey S.</p> <p>In this exemple one of the A/B/X/Y button is cut from each color.</p> <p>Warning</p> <p>When replacing a specific button, for example the top arrow, you need to get the same exact button (top arrow). For example a left arrow should not replace a top arrow or the console might not close properly when reassembling it.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-10-assembling-the-new-buttons","title":"STEP 10 - Assembling the new buttons","text":"<p>Reassemble the new cut buttons in their hole.</p>"},{"location":"user_manual/tutorials/hardware/change_buttons/#step-11-reassembly","title":"STEP 11 - Reassembly","text":"<p>Insert first the speaker into its location in the casing before putting the circuit board back in the case, like in the pictures.</p> <p>Reassemble the console by following the previous steps in reverse order.</p> <p>Warning</p> <p>Be careful not to damage the switches on the circuit board when putting back the L/R plastic buttons.</p>"},{"location":"user_manual/tutorials/hardware/fix_unstuck_screen/","title":"Fix Loose Glass","text":"<p>Some FunKey S consoles coming from the first production batch might have an issue with the front glass not sticking correctly to the left side of the casing:</p> <p></p> <p>The following tutorial explains how to simply stick back the screen using standard cyanoacrylate glue. The necessary material is:</p> <ul> <li>Standard cyanoacrylate glue (US: Gorilla Super Glue, Europe: Loctite Superglue)</li> <li>A toothpick </li> <li>Tape</li> </ul> <p></p>"},{"location":"user_manual/tutorials/hardware/fix_unstuck_screen/#step-1-protect-the-plastic-casing-with-tape","title":"STEP 1 - Protect the plastic casing with tape","text":"<p>Stick a piece of tape on the plastic casing to the left side of the screen. This will avoid any glue spilling on it.</p>"},{"location":"user_manual/tutorials/hardware/fix_unstuck_screen/#step-2-prepare-the-glue","title":"STEP 2 - Prepare the glue","text":"<p>Appy one drop of glue on a flat waterproof surface (such as the back of some tape for example). One drop is enough.</p>"},{"location":"user_manual/tutorials/hardware/fix_unstuck_screen/#step-3-apply-the-glue","title":"STEP 3 - Apply the glue","text":"<p>Dip the tip of the toothpick in the glue and apply it inside the plastic casing alongside the left edge. Multiple dips can be necessary to cover the whole side.</p> <p>The toothpick tip will soften with the glue and act as a paintbrush.</p> <p>Warning</p> <p>Be careful not to put too much glue in the casing!</p>"},{"location":"user_manual/tutorials/hardware/fix_unstuck_screen/#step-4-stick-the-glass","title":"STEP 4 - Stick the glass","text":"<p>Use your thumb to apply force on the left side of the glass for at least 2 minutes (the longer the better, this leaves more time for the glue to stick).</p> <p>You can remove the protective tape in the meantime.</p>"},{"location":"user_manual/tutorials/hardware/fix_unstuck_screen/#step-5-all-done","title":"STEP 5 - All done","text":"<p>The glass should now hold tightly to the left side of the casing, you are ready to play!</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/","title":"Flashing a new micro-SD card","text":"<p>The following steps describe how to flash a micro-SD card with the latest version of FunKey OS. This must be done before switching micro-SD cards inside the console.</p> <p>Note: Everything on the micro-SD card will be lost, be sure to save your data.</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#download-the-latest-funkey-os-image-file","title":"Download the latest FunKey OS image file","text":"<p>Get the latest \"FunKey-rootfs-x.y.z.img\" SD card image file directly from here or from the bottom of the latest release page in the \"assets\" section:</p> <p>https://github.com/DrUm78/FunKey-OS/releases/latest</p> <p></p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#flash-the-micro-sd-card-with-balenaetcher","title":"Flash the micro-SD card with balenaEtcher","text":"<ul> <li> <p>Download and install balenaEtcher for Windows/Mac OS/Linux from balena.io</p> </li> <li> <p>Run balenaEtcher and click on \"Flash from file\" to select the FunKey OS image file</p> </li> <li> <p>Insert the micro-SD card in your computer and select the SD card drive (balenaEtcher should automatically detect it for you)</p> </li> <li> <p>Finally, click Flash </p> </li> <li> <p>You'll see a progress bar. Once complete, make sure the flashing was successful, otherwise retry to flash the SD card. The program will automatically unmount the SD card so it's safe to remove it from your computer.</p> </li> </ul> <p></p> <p></p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#switching-micro-sd-cards","title":"Switching micro-SD cards","text":"<p>On the FunKey S, the micro-SD card was voluntarily placed against the casing so that it has no degree of freedom and cannot move by accident during the eventful life of a keychain.</p> <p>Removing/switching the micro-SD card was nevertheless designed to be pretty straightforward and only require a standard Phillips screwdriver (PH0) and optionally some tweezers.</p> <p>Please follow the steps below carefully:</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#step-1-removing-the-screws","title":"STEP 1 - Removing the screws","text":"<p>Using a standard Phillips PH0 screwdriver, remove the 2 screws on the back of your FunKey S.</p> <p>Warning</p> <p>Be careful to use the correct screwdriver head size and type to prevent damaging the screws (do not use JIS screwdrivers!). FunKey Project is not responsible for replacing damaged screws.</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#step-2-opening-up-the-console","title":"STEP 2 - Opening up the console","text":"<p>Carefully remove:</p> <ol> <li>The plastic back of the console by pulling up the hinge side first</li> <li>The L/R plastic buttons by gently pulling them up out of their axis</li> <li>The keychain lanyard and axis</li> </ol> <p>Warning</p> <p>Be careful not to damage the L/R switches on the circuit board!</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#step-3-exposing-the-circuit-board","title":"STEP 3 - Exposing the circuit board","text":"<p>Remove the keychain lanyard axis, as it may fall off when opening.</p> <p>Lift the battery (but leave it connected) to expose the circuit board.</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#step-4-accessing-the-sd-card","title":"STEP 4 - Accessing the SD card","text":"<p>By grabbing it by the micro-USB port, gently pull up the circuit board until you have access to the SD card.</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#step-5-switching-sd-cards","title":"STEP 5 - Switching SD cards","text":"<p>You can now remove the old micro-SD card from its socket and insert the new one (previously flashed as described in the 1<sup>st</sup> part of this tutorial).</p> <p>Note</p> <p>You may need to use some tweezers and pull with some strength in order to remove the micro-SD card from its socket, as it is strongly inserted to prevent loose connections.</p>"},{"location":"user_manual/tutorials/hardware/flash_change_sd_card/#step-6-reassembly","title":"STEP 6 - Reassembly","text":"<p>Insert first the speaker into its location in the casing before putting the circuit board back in the case, like in the pictures.</p> <p>Reassemble the console by following the previous steps in reverse order.</p> <p>Warning</p> <p>Be careful not to damage the switches on the circuit board when putting back the L/R plastic buttons.</p>"},{"location":"user_manual/tutorials/hardware/teardown/","title":"Teardown","text":"<p>The FunKey S teardown was designed to be pretty straightforward. It only require a standard Phillips screwdriver (PH0) and tweezers.</p> <p>Note</p> <p>FunKey Project is not responsible for any damage done to your console during a teardown.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-1-removing-the-screws","title":"STEP 1 - Removing the screws","text":"<p>Using a standard Phillips PH0 screwdriver, remove the 2 screws on the back of your FunKey S.</p> <p>Warning</p> <p>Be careful to use the correct screwdriver head size and type to prevent damaging the screws (do not use JIS screwdrivers). FunKey Project is not responsible for replacing damaged screws.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-2-opening-up-the-console","title":"STEP 2 - Opening up the console","text":"<p>Carefully remove the plastic back of the console by pulling up the hinge side first</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-3-removing-the-keychain-lanyard","title":"STEP 3 - Removing the keychain lanyard","text":"<p>Carefully remove the keychain lanyard and its axis by pulling gently (it may fall off when opening).</p> <p>Warning</p> <p>The axis is a small part, be careful not to loose it.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-4-removing-the-lr-buttons","title":"STEP 4 - Removing the LR buttons","text":"<p>Carefully remove the L/R plastic buttons by gently pulling them out of their axis.</p> <p>Warning</p> <p>Be careful not to damage the L/R switches on the circuit board!</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-5-unplugging-the-battery","title":"STEP 5 - Unplugging the battery","text":"<p>Lift the battery and pull gently by the top of the circuit board to unplug the battery. The battery may be stuck to the processor with double-sided adhesive, it's perfectly normal if you have to lift with a bit of force to unstick it.</p> <p>Warning</p> <p>Be sure to pull on the connector and NOT the wires when removing the battery. It is recommended to use tweezers.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-6-unplugging-the-screen","title":"STEP 6 - Unplugging the screen","text":"<p>Now that you have access to the circuit board, you can unplug the screen.</p> <p>Warning</p> <p>This connector is fragile, unplug it vertically without force. It is recommended to use tweezers.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-7-removing-the-circuit-board","title":"STEP 7 - Removing the circuit board","text":"<p>By grabbing it by the hinge side, gently pull up the circuit board from the plastic casing.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-8-removing-the-micro-sd-card","title":"STEP 8 - Removing the micro-SD card","text":"<p>Remove the micro-SD card from its socket.</p> <p>Note</p> <p>You may need to use some tweezers and pull with some strength in order to remove the micro-SD card from its socket, as it is strongly inserted to prevent loose connections.</p> <p>Warning</p> <p>During this step be very careful not to damage the L/R switches. Never put the PCB on a flat surface (this would apply force on the LR switches) and do not grab the PCB by these switches.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-9-removing-the-buttons","title":"STEP 9 - Removing the buttons","text":"<p>Remove the buttons from their socket. It is recommended to use tweezers.</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-10-teardown-complete","title":"STEP 10 - Teardown complete","text":"<p>Good job the teardown is complete!</p>"},{"location":"user_manual/tutorials/hardware/teardown/#step-11-reassembly","title":"STEP 11 - Reassembly","text":"<p>Insert first the speaker into its location in the casing before putting the circuit board back in the case, like in the pictures.</p> <p>Reassemble the console by following the previous steps in reverse order.</p> <p>Warning</p> <p>Be careful not to damage the switches on the circuit board when putting back the L/R plastic buttons.</p>"},{"location":"user_manual/tutorials/software/add_opk/","title":"Add OPK Files","text":"<p>OPK (Open PacKage) files are archive files that contains emulators, standalone games, applications or utilities along with all their associated resources like icons packed into a single file that does not require installation to be able to run them.</p> <p>Note</p> <p>In the current release of the FunKey OS (DrUm78's version), the OPK files are available both for the GMenu2X and RetroFE launchers. See documentation here.</p> <p>7-Zip can be used to extract OPK files, and Open Package Creator is a useful tool if you want to re-package an OPK or customize icons, add additional games and much more.</p> <p>Connect your FunKey S console to your computer and add OPK files as simply as you would do it with a simple USB memory stick:</p> Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with GMenu2X), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Drag & drop the OPK file into any 1<sup>st</sup>-level folder<sup>1</sup> in this USB drive on your computer and they will be automatically available on the FunKey S Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen <p>Of course, you can remove OPK files from the FunKey S console as you would do with a USB memory stick, too!</p> <ol> <li> <p>You can create additional 1<sup>st</sup>-level folders in order to organize your OPK files just like you want.\u00a0\u21a9</p> </li> </ol>"},{"location":"user_manual/tutorials/software/add_roms/","title":"Add New ROMs","text":""},{"location":"user_manual/tutorials/software/add_roms/#how-to-get-roms-legally","title":"How to Get ROMs Legally","text":"<p>Yes legally! Despite the general opinion, it is perfectly possible to purchase and play famous ROMs legally such as Sonic, Castlevania, Megaman and more, read the note below for more details.</p> <p>The FunKey Wiki maintains lists of legal sources for ROMs, including freeware ROMs and commercial ROMs.</p> <p>Note about ROM emulation</p> <p>While ROM emulation is often seen as illegal, and sometimes by extension emulation itself, it is simply not true.</p> <p>Emulating hardware is perfectly legal, no gray area about this.</p> <p>Sharing a software copy though is illegal, so websites that host copied ROMs or bios are illegal, as well as downloading ROMs or bios from them.</p> <p>However, if some videogame companies have decided not to share their games as ROMs, it is not the case for all of them. Many companies, even such giants as SEGA, ATARI or Konami sell their retro-games online as ROMs.</p> <p>For example, it is perfectly legal to purchase the SEGA Mega Drive and Genesis Classics on Steam and play Sonic on your FunKey S.</p>"},{"location":"user_manual/tutorials/software/add_roms/#add-roms-to-the-funkey-s","title":"Add ROMs to the FunKey S","text":"<p>Connect your FunKey S console to your computer and add new games as simply as you would do it with a simple USB memory stick:</p> Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with RetroFE), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Drag & drop the ROM file and optional artwork file into the folder corresponding to the emulated console in this USB drive on your computerThe artwork file must have the same base name as the ROM file with a .png or .jpg extension. It is recommended to resize the artwork to a maximum dimension of 240px (big files will make scrolling less fluid on the launcher)An extensive list of artwork files (already resized to 240x240) has been made by Coolie Coolster here. An otherwise complete list of artwork can be found here. Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen <p>Of course, you can remove games from the FunKey S console as you would do with a USB memory stick, too!</p>"},{"location":"user_manual/tutorials/software/aspect_ratio/","title":"Change Aspect Ratio","text":"<p>The FunKey S provides 2 ways to to allow in-game change of the display aspect ratio:</p> <ol> <li> <p>Using quick shortcuts</p> </li> <li> <p>Using the FunKey menu</p> </li> </ol>"},{"location":"user_manual/tutorials/software/aspect_ratio/#quick-shortcuts","title":"Quick shortcuts","text":"<ul> <li> <p> + : Change Aspect Ratio (AR), cycle between:</p> <ul> <li> <p>Stretched (default)</p> </li> <li> <p>Cropped</p> </li> <li> <p>Scaled</p> </li> <li> <p>Manual Zoom (not available with PicoArch)</p> </li> </ul> </li> <li> <p> + : Decrease zoom level by 10%</p> </li> <li> <p> + : Increase Zoom level by 10%</p> </li> </ul>"},{"location":"user_manual/tutorials/software/aspect_ratio/#funkey-menu","title":"FunKey menu","text":"<ul> <li> <p>Press the key to enter the FunKey menu</p> </li> <li> <p>Press the or key to select the \"ASPECT RATIO\" setting</p> </li> <li> <p>Use the and keys to change the aspect ratio</p> </li> </ul> Display Aspect Ratio Stretched (default): The display is stretched horizontally and vertically to fill the screen in both directions Cropped (Zoom 100%), The display fills the screen vertically, and is clipped vertically to the left and right of the screen Scaled (Zoom 0%): The display is scaled down in both directions to be fully visible, both horizontally and vertically Manual zoom: The display is zoomed in/out manually (not available with PicoArch) <ul> <li>Press the key again to exit from the FunKey menu</li> </ul>"},{"location":"user_manual/tutorials/software/aspect_ratio/#aspect-ratio-preview","title":"Aspect ratio preview","text":"<p>Here is a short preview of what the different aspect ratios look like:</p> Display Aspect Ratio Stretched (default): The display is stretched horizontally and vertically to fill the screen in both directions Cropped (Zoom 100%): The display fills the screen vertically, and is clipped vertically to the left and right of the screen Scaled (Zoom 0%): The display is scaled down in both directions to be fully visible, both horizontally and vertically Manual zoom 0% (Scaled): The display is scaled down in both directions to be fully visible, both horizontally and vertically Manual zoom 10% Manual zoom 20% Manual zoom 30% Manual zoom 40% Manual zoom 50% (default zoom level) Manual zoom 60% Manual zoom 70% Manual zoom 80% Manual zoom 90% Manual zoom 100% (Cropped): The display fills the screen vertically, and is clipped vertically to the left and right of the screen"},{"location":"user_manual/tutorials/software/firmware_update/","title":"Firmware Upgrade","text":"<p>A firmware upgrade can be performed simply over USB without opening the FunKey S console.</p> <p>Get the latest \"FunKey-rootfs-x.y.z.fwu\" firmware update file directly from here or from the bottom of the latest release page in the \"assets\" section: </p> <p>https://github.com/DrUm78/FunKey-OS/releases/latest</p> <p></p> Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with RetroFE), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Drag & drop the ***FunKey-rootfs-x.y.z.fwu file you just downloaded at the root of this USB drive on your computer Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm The FunKey S will then reboot and perform the upgrade"},{"location":"user_manual/tutorials/software/gb_palette/","title":"Change Game Boy Palette","text":"<p>This tutorial applies to the previous OS update with the default emulators. For PicoArch GB/GBC emulator, palettes can now be set through the core options.</p>"},{"location":"user_manual/tutorials/software/gb_palette/#palette-description","title":"Palette Description","text":"<p>The default FunKey S Game Boy emulator: gnuboy allows to set the palette used for grayscale when running DMG (original mono Game Boy) ROMs.</p> <p>There are four variables for this purpose, allowing the background, window, and both sprite palettes to be colored differently. Each one is made up of four numbers, the color to use for each shade of gray, from lightest to darkest.</p> <p>Colors are represented as 24-bit hexadecimal numbers, with red component in the low (rightmost) 2 digits, green component in the middle 2 digits and blue component in the upper (leftmost) 2 digits.</p> <p>For example, to set the background to shades of white, the window to shades of red, and the sprite palettes to shades of green and blue, you could use:</p> <pre><code>set dmg_bgp 0xffffff 0xaaaaaa 0x555555 0x000000\nset dmg_wndp 0x0000ff 0x0000aa 0x000055 0x000000\nset dmg_obp0 0x00ff00 0x00aa00 0x005500 0x000000\nset dmg_obp1 0xff0000 0xaa0000 0x550000 0x000000\n</code></pre> <p>This will of course look rather ugly, but it does the job illustrating how you set various colors.</p> <p>Here is a list of example palettes proposed by the gnuboy emulator:</p> <pre><code># Default palette used in the FunKey S.\nset dmg_bgp 0x98d0e0 0x68a0b0 0x60707C 0x2C3C3C\nset dmg_wndp 0x98d0e0 0x68a0b0 0x60707C 0x2C3C3C\nset dmg_obp0 0x98d0e0 0x68a0b0 0x60707C 0x2C3C3C\nset dmg_obp1 0x98d0e0 0x68a0b0 0x60707C 0x2C3C3C\n\n# Old default palette from 0.8.0 thru 0.9.13.\n# This was designed for use on a laptop display, \n# so it's probably way too yellowish.\nset dmg_bgp 0x78f0f0 0x58b8b8 0x487878 0x184848\nset dmg_wndp 0x78f0f0 0x58b8b8 0x487878 0x184848\nset dmg_obp0 0x78f0f0 0x58b8b8 0x487878 0x184848\nset dmg_obp1 0x78f0f0 0x58b8b8 0x487878 0x184848\n\n# Old dim grayscale.\nset dmg_bgp 0xc0c0c0 0x808080 0x404040 0x000000\nset dmg_wndp 0xc0c0c0 0x808080 0x404040 0x000000\nset dmg_obp0 0xc0c0c0 0x808080 0x404040 0x000000\nset dmg_obp1 0xc0c0c0 0x808080 0x404040 0x000000\n\n# Light grayscale.\nset dmg_bgp 0xffffff 0xc0c0c0 0x808080 0x404040\nset dmg_wndp 0xffffff 0xc0c0c0 0x808080 0x404040\nset dmg_obp0 0xffffff 0xc0c0c0 0x808080 0x404040\nset dmg_obp1 0xffffff 0xc0c0c0 0x808080 0x404040\n\n# Full contrast grayscale.\nset dmg_bgp 0xffffff 0xaaaaaa 0x555555 0x000000\nset dmg_wndp 0xffffff 0xaaaaaa 0x555555 0x000000\nset dmg_obp0 0xffffff 0xaaaaaa 0x555555 0x000000\nset dmg_obp1 0xffffff 0xaaaaaa 0x555555 0x000000\n\n# Debug palette. \n# Each of the four layers is colored differently, \n# making it easier to debug visual glitches in \n# roms that use them all together cleverly.\nset dmg_bgp 0xf898c8 0xf83098 0xc80060 0x600030\nset dmg_wndp 0xd0c0c0 0xa88080 0x785050 0x382828\nset dmg_obp0 0x9898f8 0x3030f8 0x0000c8 0x000060\nset dmg_obp1 0xc8f898 0x98f830 0x60c800 0x306000\n\n# Sprites standout. \n# Similar to above, but the colors are more subdued and \n# the window and background are the same. This palette\n# may actually be suitable for playing some games...\nset dmg_bgp 0xd0c0c0 0xa88080 0x785050 0x382828\nset dmg_wndp 0xd0c0c0 0xa88080 0x785050 0x382828\nset dmg_obp0 0xc8e0f8 0x90a8e8 0x4878a8 0x183850\nset dmg_obp1 0x98b8f8 0x3050f8 0x2040a8 0x002060\n\n# LCD yellows and grays. \n# An earlier version of the new default palette.\nset dmg_bgp 0x88e0f0 0x68a8b8 0x586878 0x283838\nset dmg_wndp 0x88e0f0 0x68a8b8 0x586878 0x283838\nset dmg_obp0 0x88e0f0 0x68a8b8 0x586878 0x283838\nset dmg_obp1 0x88e0f0 0x68a8b8 0x586878 0x283838\n\n# LCD yellowscale. \n# And another similar one.\nset dmg_bgp 0x88e0f0 0x68a8b8 0x486878 0x203838\nset dmg_wndp 0x88e0f0 0x68a8b8 0x486878 0x203838\nset dmg_obp0 0x88e0f0 0x68a8b8 0x486878 0x203838\nset dmg_obp1 0x88e0f0 0x68a8b8 0x486878 0x203838\n\n# Slightly colorful. \n# Not just a plain lightness gradient, but some \n# change in hue as well. Looks ok with some games; \n# designed in particular for the FFL series.\nset dmg_bgp 0x98e0f8 0x78a0c0 0x747080 0x604038\nset dmg_wndp 0x98e0f8 0x78a0c0 0x747080 0x604038\nset dmg_obp0 0x98e0f8 0x78a0c0 0x747080 0x604038\nset dmg_obp1 0x98e0f8 0x78a0c0 0x747080 0x604038\n\n# Optionally use these with the above palette to \n# make sprites stand out a bit.\nset dmg_obp0 0x98e0f8 0x5090c0 0x507898 0x583838\nset dmg_obp1 0x98e0f8 0x5090c0 0x686078 0x383838\n\n# R-Type 1 palette from R-Type DX\nset dmg_bgp 0xc0ffff 0x408080 0x204040 0x000000\nset dmg_wndp 0xc0ffff 0x408080 0x204040 0x000000\nset dmg_obp0 0xc0ffff 0x408080 0x204040 0x000000\nset dmg_obp1 0xc0ffff 0x408080 0x204040 0x000000`\n</code></pre>"},{"location":"user_manual/tutorials/software/gb_palette/#changing-the-palette","title":"Changing the Palette","text":"Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with RetroFE), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) In the FunKey folder, create a new folder .gnuboy if it does not already exist. In the FunKey/.gnuboy/ folder create a file gnuboy.rc if it does not already exist. Open the gnuboy.rc file with a text editor and add the palette you want. Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen Launch any Game Boy game to see the results of your new palette settings."},{"location":"user_manual/tutorials/software/gba_bios/","title":"Install the GBA/PS1 BIOS","text":"<p>This tutorial applies to the previous OS update with the default emulators. For PicoArch emulators, BIOS files now go into FunKey/.picoarch/system/ folder.</p> <p>Most retro-gaming console software emulators are able to run game ROMs directly.</p> <p>However, the Game Boy Advance an PS1 emulators do require an additional BIOS file in order to emulate all or some of the game ROMs.</p>"},{"location":"user_manual/tutorials/software/gba_bios/#gba","title":"GBA","text":"<p>If you launch a GBA game for the first time, you will get this screen:</p> <p></p> <p>This means that you will need to install on the FunKey S a BIOS file with the right name, size and MD5 checksum before you can actually play.</p> <ul> <li>BIOS file name: gba_bios.bin</li> <li>MD5: a860e8c0b6d573d191e4ec7db1b1e4f6</li> </ul>"},{"location":"user_manual/tutorials/software/gba_bios/#installation-procedure","title":"Installation procedure","text":"Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with RetroFE), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Drag & drop the gba_bios.bin BIOS file into the Game Boy Advance/bios/ folder in this USB drive on your computer Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen"},{"location":"user_manual/tutorials/software/gba_bios/#ps1","title":"PS1","text":"<p>As for the GBA, if you launch a PS1 game for the first time, you will get this screen:</p> <p></p> <p>This means that you will need to install on the FunKey S a BIOS file with the right name and size before you can actually play.</p> <p>BIOS file name: SCPH1001.BIN</p>"},{"location":"user_manual/tutorials/software/gba_bios/#installation-procedure_1","title":"Installation procedure","text":"Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with RetroFE), press the Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Drag & drop the SCPH1001.BIN BIOS file into the FunKey/.pcsx/bios/ folder in this USB drive on your computer Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen"},{"location":"user_manual/tutorials/software/gmenu2x_wallpaper/","title":"Change GMenu2X Wallpaper","text":"<p>Changing the GMenu2X wallpaper is easy: the chosen picture must be a PNG file with a 240x240 pixel resolution.</p> <p>Connect your FunKey S console to your computer and add wallpaper files as simply as you would do it with a simple USB memory stick:</p> Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with GMenu2X), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Navigate to the FunKey/.gmenu2x/skins/240x240/Default/wallpapers folder in this USB drive If they do not exist already, create the required folders hierarchically Drag & drop the wallpapers file into this folder Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen Navigate to the Settings tab using the or keys, select the Wallpaper icon using the , , or keys, then press the key Choose the wallpaper using the , , , , or keys, then press the key The selected wallpaper becomes the new GMenu2X wallpaper <p>Of course, you can remove wallpaper files from the FunKey S console as you would do with a USB memory stick, too!</p> <p>The wallpaper is copyright \u00a9 2020 kiks_way.</p>"},{"location":"user_manual/tutorials/software/snapshot/","title":"Take a Snapshot","text":"<p>The FunKey S allows to take in-game snapshots using a simple shortcut: just press the Fn + UP keys simultaneously.</p> <p>The snapshot files will be located in the FunKey/snapshots folder on the host computer and they will be numbered following a \"IMG_nnnn.PNG\" pattern, with \"nnnn\" being a number starting at 0001 and up to 9999.</p> <p>In order to access the snapshots, follow these simple steps:</p> Display Action Connect the FunKey S to your computer using the provided micro USB cable, then open it to turn it on At the launcher's main screen (example here with RetroFE), press the key Press the or keys until you see \"MOUNT USB\" Press the key twice to confirm \"EJECT USB\" is now displayed instead, now go to your host computer and open a File Explorer window You should see the FunKey S appear as an USB drive on your computer in the File Explorer (example here with Windows 10) Drag & drop / Copy / Move / Delete the snapshots files from the FunKey/snapshots/ folder in this USB drive on your computer as required Eject cleanly the USB drive from your computer Back on the FunKey S, at the \"EJECT USB\" menu entry, press the key twice to confirm Press the key to return to the launcher screen"}]} |