Xunlong Orange Pi PC

Orange Pi PC is H3 based development board produced by Xunlong.

= Identification = The PCB has the following silkscreened on it: Orange Pi PC V1.2

= Sunxi support =

Current status
The H3 and Orange Pi PC support is progressing nicely. It is possible to find a usable mainline 4.x kernel (plus some patches) and a legacy 3.4 kernel in various work-in-progress git branches. See the Manual build section for more details.

Manual build
You can build things for yourself by following our Manual build howto and by choosing from the configurations available below.

Mainline U-Boot
Use the orangepi_pc build target (supported since v2016.01-rc2).

It can boot from the SD card or via FEL. Only the initial basic functionality is implemented and there are still no USB host and Ethernet drivers for H3 in U-Boot v2016.01 (it affects only u-boot functionality, device would work in linux as long kernel supports it).

Sunxi/Legacy Kernel
The 3.4 kernel from the official Allwinner's git repository does not support H3 yet. But it is possible to use one of the kernel forks, based on the lichee H3 SDK tarball:
 * Siarhei Siamashka's branch '20151207-embedded-lima-memtester-h3' at https://github.com/ssvb/linux-sunxi/tree/20151207-embedded-lima-memtester-h3

Configure this kernel using sun8i_h3_defconfig, the rest is explained in the kernel compilation guide.

Use the xunlong_orange_pi_pc.fex file for generating script.bin.

When booting the legacy 3.4 kernel with the mainline U-Boot, add the following line to boot.cmd:

setenv machid 1029 setenv bootm_boot_mode sec

Mainline kernel
Initial H3 patches have been submitted to the mainline kernel, but have not landed yet. Currently you can find these patches in the arm-linux mailing list, or alternatively in one of the work-in-progress kernel forks:
 * Maxime Ripard's branch 'sunxi/for-next' at https://git.kernel.org/cgit/linux/kernel/git/mripard/linux.git/log/?h=sunxi/for-next (very basic H3 support, without USB)
 * Hans de Goede's branch 'sunxi-wip' at https://github.com/jwrdegoede/linux-sunxi/tree/sunxi-wip (many work-in-progress patches, including H3 and USB support for it)
 * Siarhei Siamashka's branch '20151223-h3-mainline-smp-hack' at https://github.com/ssvb/linux-sunxi/tree/20151223-h3-mainline-smp-hack (minimal set of H3 patches, with USB and SMP)
 * Chen-Yu Tsai's branch 'h3-emac' at https://github.com/wens/linux/tree/h3-emac (working Ethernet and USB)

Use the sun8i-h3-orangepi-pc.dtb device-tree binary.

= Tips, Tricks, Caveats =


 * Heat issues when using common OS images for the OPi PC. Without a heatsink the Orange Pi PC overheats easily and will drop cores to thwart further temperature increase and unfortunately the heatsink provided by the manufacturer does little to help. The low cost $15 variant does not have any heatsink included at all. This is the result of 'factory settings' overclocking/overvolting the H3 way too much. With adjusted dvfs entries and an upper limit of 1.2 GHz SoC temperature stays below 75°C without heatsink when running cpuburn-a7 on all 4 cores. Using a quality heatsink, some airflow and reasonable cpufreq settings the H3 remains below 60°C even under full load at an ambient temperature of 22°C.


 * It is also possible to power the device via GPIO pin header: connect +5V to either pin 2 or 4 (both are connected to DCIN test point) and GND to pin 6.

FEL mode
The Orange Pi PC will fail over to FEL mode if it doesn't detect a card present in the µSD slot. There is no dedicated FEL button.

LEDs


The board has two LEDs:
 * A red LED, connected to the PA15 pin.
 * A green LED, connected to the PL10 pin.

When using kernel 3.4 with Xunlong's or loboris' settings then the LEDs can only be switched on/off. By changing the definition in the fex file (see patch or fex with applied fix) both LEDs can be used the usual way (using different triggers and so on)

CPU clock speed limit
The Allwinner H3 manual does not provide the CPU clock speed information. But the following is a common comment in the FEX files from various H3 SDK variants: It means that this comment likely originates from Allwinner, rather than something added by Xunlong or any other H3 device manufacturer.
 * dvfs voltage-frequency table configuration
 * pmuic_type:0:none, 1:gpio, 2:i2c
 * pmu_gpio0: gpio config.
 * pmu_levelx: 0~9999: voltage(mV), 10000~90000:gpio0 state. voltage form high to low.
 * extremity_freq(Hz): cpu extremity frequency when run benckmark or demo apk
 * 1536MHz@1500mV with radiator, 1296MHz@1340mV without radiator
 * max_freq: cpu maximum frequency, based on Hz, can not be more than 1200MHz
 * min_freq: cpu minimum frequency, based on Hz, can not be less than 60MHz
 * LV_count: count of LV_freq/LV_volt, must be < 16
 * LV1: core vdd is 1.50v if cpu frequency is (1296Mhz, 1536Mhz]
 * LV2: core vdd is 1.34v if cpu frequency is (1200Mhz, 1296Mhz]
 * LV3: core vdd is 1.32v if cpu frequency is (1008Mhz, 1200Mhz]
 * LV4: core vdd is 1.20v if cpu frequency is (816Mhz,  1008Mhz]
 * LV5: core vdd is 1.10v if cpu frequency is (648Mhz,   816Mhz]
 * LV6: core vdd is 1.04v if cpu frequency is (0Mhz,     648Mhz]
 * LV7: core vdd is 1.04v if cpu frequency is (0Mhz,     648Mhz]
 * LV8: core vdd is 1.04v if cpu frequency is (0Mhz,     648Mhz]
 * LV5: core vdd is 1.10v if cpu frequency is (648Mhz,   816Mhz]
 * LV6: core vdd is 1.04v if cpu frequency is (0Mhz,     648Mhz]
 * LV7: core vdd is 1.04v if cpu frequency is (0Mhz,     648Mhz]
 * LV8: core vdd is 1.04v if cpu frequency is (0Mhz,     648Mhz]

The Orange Pi PC board uses the SY8106A voltage regulator for providing the CPU core voltage (VDD_CPUX). The default CPU voltage is 1.2V after power-on (selected by the resistors on the PCB) and can be changed at runtime by software via I2C interface. According to the table above, this default voltage should be safe for using with the CPU clock frequencies up to 1008MHz. The H3 datasheet specifies 1.5V as the absolute maximum for the VDD_CPUX voltage and 1.4V as the recommended maximum.

DRAM clock speed limit
DRAM is clocked at 672 MHz by the hardware vendor. But the reliability still needs to be verified. One of the ways of doing reliability tests may be https://github.com/ssvb/lima-memtester/releases/tag/20151207-orange-pi-pc-fel-test (it checks the Orange Pi PC DRAM setup in the current mainline U-Boot v2016.01-rc2 + a bugfix).

'''We need still more test results in the table above in order to have more accurate statistics and finally pick a safe default DRAM clock speed for U-Boot. Preferably there should be at least 10 entries in the table (more is always better). And there are no "good" or "bad" test results. Even if your result looks very similar to the already reported results from the other people, please still add yours to the table! Because if people don't feel like reporting their "boring" results, then "interesting" outliers will unfortunately skew the statistics. Thanks!'''

Below is an intermediate analysis of the currently reported results, using the lima-memtester-genchart script. Assuming that the Gaussian distribution is a good approximation (this is yet to be confirmed!), try to predict what percentage of boards is expected to pass the lima-memetser test at different DRAM clock frequencies. Having even more test results from different Orange Pi PC boards is important to verify if this estimation is accurate.

Analysing the first 6 reported results:
echo '672 672 648 672 720 672' | lima-memtester-genchart 12 chart.png



Analysing the first 12 reported results:
echo '672 672 648 672 720 672 672 744 696 696 672 672' | ./lima-memtester-genchart 12 chart.png



Verifying the assumption about having a Gaussian distribution
This can be done via one (or more than one) of the normality test methods. Here is an example of using R for doing this. We can just substitute the data in the 'x' vector by taking the middle of each DRAM clock frequency bin (for example, if lima-memtester passes at 672 MHz and fails at 696 MHz, then take 684 as the average because it is likely a crossover point between passing and failing): x <- c(684.0, 684.0, 660.0, 684.0, 732.0, 684.0, 684.0, 756.0, 708.0, 708.0, 684.0, 684.0)

Which results in a staircase-alike Q-Q plot and very low p-values (Shapiro-Wilk test: p-value = 0.01275, Kolmogorov-Smirnov test: p-value = 0.117, Anderson-Darling test: p-value = 0.002434). That's because we are dealing with 24 MHz granularity and having many samples with exactly the same value. And normality test methods typically don't like ties very much. We can also randomize the DRAM clock frequencies within each bin in order to get rid of ties (for example, if the test passes at 672 MHz and fails at 696 MHz, then we take some random value between 672 and 696): x <- c(673.1, 695.6, 652.5, 695.4, 728.3, 682.1, 691.2, 751.2, 713.9, 718.6, 675.2, 690.4) Which results in a more linear Q-Q plot and much higher p-values (Shapiro-Wilk test: p-value = 0.9411, Kolmogorov-Smirnov test: p-value = 0.7025, Anderson-Darling test: p-value = 0.7469). And this means that we still can't reject the assumption about having the Gaussian (Normal) distribution. There is also a criticism about normality tests, which demonstrates that they do not always behave well and should be taken with a grain of salt.

Exact multinomial test
We can also try to check if the estimated probabilities of encountering different maximum DRAM clock frequencies agree with the experimental results. For doing this, we randomly split the current 13 available DRAM clock frequency samples into a "training set" and a "validation set". The training set is used to calculate the theoretical probabilities of encountering different DRAM clock frequencies (see the "Share of boards expected to fail the lima-memtester test" table). And the validation set is used to check if the practice does not contradict with the theory. Because the number of samples is too small, the classic schoolbook Pearson's chi-squared test can't be used. So instead using Fisher's exact test (or the multinomial test in this particular case) is a much better choice. There is a nice XNomial library for R to do this job.

The training set and the validation sets can be just comma separated in the input data for the lima-memtester-genchart script: echo '648 672 672 672 672 696 720 744, 672 672 672 696 696' | ./lima-memtester-genchart 12 Example output: ...

> library(XNomial) > > prob <- c(0.0007283175419052768, 0.00744356779387656, 0.04317730632627215, 0.14247361868533098, 0.2679071710633351, 0.2873730067728857, 0.17586116428130794, 0.06134920915452913, 0.012180622334238, 0.0013734297459093714) > observed <- c(0, 0, 0, 0, 3, 2, 0, 0, 0, 0) > out <- xmulti(observed, prob, detail=3)

P value (LLR)  =  0.4117 P value (Prob) =  0.7255 P value (Chisq) = 0.514

Observed: 0 0 0 0 3 2 0 0 0 0 Expected ratio: 0.0007283175 0.007443568 0.04317731 0.1424736 0.2679072 0.287373 0.1758612 0.06134921 0.01218062 0.00137343 Total number of tables: 2002

Below are the results of trying different splits of samples between the training set and the validation set: Note that the exact multinomial test rejects our null hypothesis about the estimated DRAM clock speed frequencies distribution in the cases when the 744 MHz sample is not included into the training set. Basically, if 744 MHz is not present in the training set, then it gets estimated to have a very low probability. And then encountering it in the validation set is seen as a rather unusual outcome, resulting in a low p-value. Why do we care about this? The 744 MHz is an unusual extreme DRAM clock speed sample, which would not be predicted correctly by only analysing the first 6 reported samples. Fortunately or not, it is an extreme high DRAM clock speed. But if we had an extreme low DRAM clock speed sample instead, then we would have a bit of a problem with our original goal (estimating what is safe to use for U-Boot).

Also having p-value > 0.05 (not failing the test) does not automatically mean that everything is fine. There are some nice explanations in the "Power analysis" section of the Exact test of goodness-of-fit article from the www.biostathandbook.com website. Basically, our number of samples is likely way too small. Power analysis via simulation or some other method should provide the number of required samples.

OpenRISC core
Also named as AR100, CPUS and "arisc" in various Allwinner materials, which may cause a bit of confusion. According to the Orange Pi PC schematics, VDD_CPUS is connected to VDD_RTC. It means that the voltage powering the OpenRISC core is programmable via the hardware register VDD_RTC_REG (at 0x1F00190) and can be configured between 0.7V and 1.4V. The H3 datasheet says that 1.4V is the absolute maximum for VDD_CPUS and 1.1V-1.3V is the recommended range. The reset default for VDD_RTC voltage is 1.1V.

Below is a quick evaluation of the potential clock speed limit of the OpenRISC core on just a single board (ssvb's) by running a naive recursive fibonacci function:

Without I-Cache, fetching each instruction from SRAM takes 3 cycles instead of just 1.

Please note that the intended use of the OpenRISC core in Allwinner devices is keeping a watch while the main Cortex-A7 CPU and the rest of the SoC peripherals are powered off in deep power save modes. In this usage scenario it is likely clocked at just the minimum possible clock frequency 32 KHz.

USB
It should be noted that unlike some of the more expensive Orange Pi models the 'PC' does not use an internal USB hub therefore the 4 available USB ports don't have to share bandwidth. First tests with kernel 4.4.0-rc4, a fast SSD and an enclosure capable of USB Attached SCSI show excellent sequential performance with mainline kernel: 39 MB/s write and 41.5 MB/s read (tests done with iozone using 4 GB test size and averaging the values of 4K/1M record size)

Camera module
Xunlong sells also a cheap 2MP camera (an attempt to fix the driver's limited resolutions can be found here). Unlike Orange Pi Plus/2 that can directly connect to the camera module for the PC an 'expansion board' is needed (see gallery below). If you order from Xunlong simply say that you need the camera for Orange Pi PC and they ship camera together with the small board.

1-Wire support
After applying a patch to the lichee kernel sources 1-wire can be used with H3 based Orange Pi's. After loading the approriate modules (w1-sunxi, w1-gpio and w1-therm) connected 1-wire slave devices should appear below /sys/bus/w1/devices/. To let 1-wire work the GPIO pin to be used has to be defined in fex/script.bin. All OS images that applied the 1-wire patch (all from loboris after applying his latest fixes, Armbian or the community's OpenELEC build) use "gpio = 20" in the fex file. Attention: This is a logical mapping that correlates with physical GPIO pin 37 (see the gallery image below). Please keep this in mind when following 1-wire tutorials for Raspberry Pi where GPIO pin 7 is normally used. On H3 devices the pin to connect the data line to is on the other end of the GPIO header.

Locating the UART
The UART pins are located between HDMI and power jack of the board. They are marked as TX, RX and GND on the PCB. Just attach some leads according to our UART Howto.

= Pictures =

= Variants =


 * The Orange Pi PC Plus adds 8GB eMMC and Realtek RTL8189FTV SDIO-based WiFi directly on the board (as opposed to a soldered-on module). The physical dimensions and connectors are the same as the Orange Pi PC.

= Also known as =

= See also =


 * Xunlong Orange Pi site
 * Official Github Repository.
 * Official Orange Pi Form.
 * H3_Manual_build_howto
 * Orange Pi PC Schematics 1.2

Manufacturer images
A various amount of prebuilt images is provided via OrangePi's Website most of them not containing latest fixes. Many people are also running images generated by forum user loboris ([http://filez.zoobab.com/allwinner/orangepi/mega/ mirror available). It should be noted that when using loboris' images it's always useful to execute his update_kernel.sh to get latest kernel fixes and settings for the board in question (various script.bin variants for different Orange Pis and display settings). To adjust script.bin settings (overclocked/overvolted) to linux-sunxi defaults there's informations and a script available in this thread.

= References =