From 520118f143b056cc9d5b1040502c3b04677c9ee9 Mon Sep 17 00:00:00 2001 From: Owen Carter Date: Thu, 19 Sep 2024 14:52:55 +0200 Subject: [PATCH] Update tooling for custom kernels (#6) Improve support for custom device trees when kernel updates are received * Modified make-trees.sh so that it builds for all installed kernels. * A new script flash-latest.sh that copies the resulting .dtb files into the /etc/flash-kernel/dtbs/ override folder. The build-trees README is updated for this, and shows how to configure flash-kernel to use the custom .dtbs. Kernel upgrade should now go: [after a new kernel upgrade is installed] * Upgrade source: cd source && apt source linux-riscv * Build dtb's: cd build-trees &&; ./make_dtbs.sh * Install device tree via softlinks ./flash_latest.sh * Reboot --- GPIO-examples.md | 125 ++++++ README.md | 153 +++++-- alt-trees/README.md | 56 ++- alt-trees/hat/README.md | 71 +++ alt-trees/hat/mqpro-hat.dts | 425 ++++++++++++++++++ alt-trees/lora-hat/README.md | 45 ++ .../{lora => lora-hat}/mqpro-lora-hat.dts | 116 ++++- alt-trees/lora/README.md | 39 -- alt-trees/serial/README.md | 42 +- alt-trees/serial/mqpro-serial.dts | 110 ++++- alt-trees/{spi_i2c => spi-i2c}/README.md | 42 +- .../{spi_i2c => spi-i2c}/mqpro-spi-i2c.dts | 108 ++++- build-trees/README.md | 142 +++--- build-trees/flash_latest.sh | 60 +++ build-trees/make_dtb.sh | 43 -- build-trees/make_dtbs.sh | 76 ++++ tools/README.md | 49 ++ tools/list-pins.py | 7 +- 18 files changed, 1469 insertions(+), 240 deletions(-) create mode 100644 GPIO-examples.md create mode 100644 alt-trees/hat/README.md create mode 100644 alt-trees/hat/mqpro-hat.dts create mode 100644 alt-trees/lora-hat/README.md rename alt-trees/{lora => lora-hat}/mqpro-lora-hat.dts (73%) delete mode 100644 alt-trees/lora/README.md rename alt-trees/{spi_i2c => spi-i2c}/README.md (53%) rename alt-trees/{spi_i2c => spi-i2c}/mqpro-spi-i2c.dts (73%) create mode 100755 build-trees/flash_latest.sh delete mode 100755 build-trees/make_dtb.sh create mode 100755 build-trees/make_dtbs.sh create mode 100644 tools/README.md diff --git a/GPIO-examples.md b/GPIO-examples.md new file mode 100644 index 0000000..e2a656e --- /dev/null +++ b/GPIO-examples.md @@ -0,0 +1,125 @@ +# GPIO usage examples (for the MQ-Pro) +This guide assumes you have a correctly installed and set up board, with the correct device tree (plus overlays) to expose the pins you want to use. + +*Caveat:* notes here are biased towards Python usage, since that is what I will be using in my projects. + +## General Purpose GPIO (digital read/write) +**You do not need to use a custom Device Tree in order to use digital IO** +* The 'default' device tree for the MQ pro has 26 free pins to use! + +Look at the great guide here: https://worldbeyondlinux.be/posts/gpio-on-the-mango-pi/ + +It does a better job of explaining this than I can do in a short guide. + +## PWM +**working**, There are eight PWM timers available and GPIO pins can be mapped to these in a custom device tree +- The available mappings are somewhat limited, see the diagram in the main README to determine which pins on the GPIO connector can be used. +- The example below uses (legacy) `/sys/class` control, which in turn needs root access. PWM control from userland seems like a WIP for linux at present. +- I have not (yet) investigated using this via `lgpio` in Python. + +The following needs to be run as root. It uses `pwm2` (the `lora` example device tree attaches this to pin 31 on the GPIO connector). + +First, export the PWM interface: +``` +# echo 2 > /sys/class/pwm/pwmchip0/export +``` +- The node for the interface wil appear at `/sys/class/pwm/pwmchip0/pwm2/` + +Set a default period (10μs) and duty cycle (5μs, 50%): +``` +# echo 10000 > /sys/class/pwm/pwmchip0/pwm2/period` +# echo 5000 > /sys/class/pwm/pwmchip0/pwm2/duty_cycle` +``` +After setting the default you can enable it with: +``` +# echo 1 > /sys/class/pwm/pwmchip0/pwm2/enable` +``` +You can stop and detach the interface with: `# echo 2 > /sys/class/pwm/pwmchip0/unexport` + +The following is a shell script that implements a crude LED fader: + +```bash +#!/bin/bash +# PWM silly fader +# +pwm="/sys/class/pwm/pwmchip0/pwm2" + +echo normal > $pwm/polarity +echo 10000 > $pwm/period +echo 1 > $pwm/enable +while true ; do + for p in 40 100 400 1000 4000 10000 6000 1200 600 120 60 0 ; do + echo -n "." + echo $p > $pwm/duty_cycle + sleep 0.25 + done + echo +done +``` +See the [kernel guide](https://www.kernel.org/doc/html/latest/driver-api/pwm.html#using-pwms-with-the-sysfs-interface) for the parameters we set to assign and control the pin. + +## I2C +**Working**: I have read temperature, pressure and humidity from a BME280 sensor connected to pins `3` and `5`. + +Install [`pypi:bme280`](https://pypi.org/project/bme280/) and it's requirement `smbus-cffi`. +* I am using a [virtual environment](https://docs.python.org/3/tutorial/venv.html), rather than installing globally. +* Add the user to the group 'i2c' and re-login. +``` +$ sudo apt install python3-venv python3-dev i2c-tools + +$ sudo usermod -a -G i2c +# Log out then in again so that your user now has the `i2c` group membership + +# Create virtualenv in a directory './bme-env' and activate it (exit with `deactivate`, removing the directory+contents deletes the venv) +$ python3 -m venv bme-env +$ source bme-env/bin/activate +(bme-env) $ pip install --upgrade pip +(bme-env) $ pip install --upgrade smbus-cffi bme280 + +# The bme280 library provides a python API, and a commandline tool +(bme-env) $ which read_bme280 +/env/bin/read_bme280 + +# My bme280 defaults to address 0x76, and I'm using I2C0 +(bme-env) $ read_bme280 --i2c-bus 0 --i2c-address 0x76 +1024.85 hPa + 56.84 % + 21.59 C +``` + +## SPI +**Working?**: When I enable SPI1 in the device tree nodes a device at is registered at /sys/devices/platform/soc/4026000.spi/, it lists it's driver (correctly) as sun6i-spi and is a bus master. +* Kernel drivers that use spi via pinctl should be able to use this. +* But no block device appears at /dev/spi*. + * Normally spi-tools provides userland support via the /dev/spi* device. +* I do not plan to use SPI so I have not tested further. + +--------------------------------------------------------- + +# Extra! +## Status LED: +The onboard (blue) status LED is attached to gpio `PD18`, and can be controlled via the sys tree: + +`$ sudo sh -c "echo 1 > /sys/devices/platform/leds/leds/blue\:status/brightness"` to turn on + +`$ sudo sh -c "echo 0 > /sys/devices/platform/leds/leds/blue\:status/brightness"` to turn off + +You can make it flash as network traffic is seen with: + +`$ sudo sh -c "echo phy0rx > /sys/devices/platform/leds/leds/blue\:status/trigger"` + +Other control options are available, `$ sudo cat /sys/devices/platform/leds/leds/blue\:status/trigger` shows a list and the current selection. Most do not work or are not very useful; ymmv. +- `PD18` can also be re-mapped to `pwm-2` in a modified device tree if you want to manually control the LED and vary it's brightness. +- PD18 is also used as the LED_PWM pin on the DSI/LVDS output + + +## Onboard CPU temperature sensor: +```console +$ sudo apt install lm-sensors +$ sensors +cpu_thermal-virtual-0 +Adapter: Virtual device +temp1: +19.4°C +``` +**HOWEVER**: This is nonsense.. I'm testing with the board in a enclosure, and the attached BME280 sensor is showing room temp outside the enclosure as 22C, the CPU is not that cold. +- check out the device tree, maybe a bad offset. Or some kind of calibration/reference voltage needed? diff --git a/README.md b/README.md index ab9d779..1e40fe0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# MangoPI MQ Pro Install guide for Ubuntu Server 24.04.1 +# MangoPI MQ Pro Install guide +# - Ubuntu Server 24.04.1 The MQ pro is a single core RISC-V allwinner D1 64bit 1Ghz CPU, with 1Gb RAM, HDMI and Wifi, in a Pi-Zero form factor Single Board Computer. @@ -17,10 +18,19 @@ Once the LicheeRV image is booted you can swap the device tree it uses for the M - It is provided in the `linux-modules-` package for each kernel. - You can reconfigure `flash-kernel` to always select the MQ-Pro tree instead of the Lichee RV default in config. - This is future proof - - Each new kernel release also delivers a new set of device trees that to be installed as the kernel image is created. + - Each new kernel release is accompanied by a corresponding set of device trees that will be installed as the kernel image is created. -The idea of compiling a custom Device Tree is depreciated in favor of the vanilla MQ-Pro device tree and using [gpiod](https://www.kernel.org/doc/html/v4.17/driver-api/gpio/index.html) and [pinctl](https://www.kernel.org/doc/html/v4.15/driver-api/pinctl.html) to setup devices. -- However, I also have instructions for doing this, for those who like to tinker. +This default MQ Pro device tree does not assign any of the GPIO pins on the board apart from the serial console on pins `8` and `10` (115200 baud, no parity). + +For basic digital I/O this is all you need. Pins can be enabled, read as an input or set to a High / Low output as needed. + +The D1 used in the MQ Pro also supports a number of internal interfaces, eg PWM (Pulse Width Modulation), additional UARTs, I2C and SPI devices. In order to use these you need to modify the device tree on boot. +* Ideally this is done with an 'Overlay' which modifies the default tree and is applied to the kernel at init +* It can also be done by providing a modified Device Tree at init, with the required changes 'baked in' + +Overlays are easiest to use; but are not **yet** covered by this guide. I intend to get them working in the future but time and enthusiasm make this a low priority for me. (watch this space..) + +Instead, there is discussion of device trees, pin assignment, and a guide + tooling to build and maintain a custom Device Tree that exposes the interfaces you need. This [comes after](#device_trees) the Install guide. ----------------------------- @@ -32,7 +42,7 @@ If you have set up SD card based systems before the following should feel famili ### Notes Unfortunately HDMI only starts very late in the boot process, you cannot use it to select GRUB options, and the console is not usable until the boot is complete. - You may see some output appear and then it freezes, this is normal. It will recover in time for the `login: ` prompt. -- Once the console login is available You can use a USB keyboard with it, and install `gpm` to get a working mouse. +- Once the console login is available You can use a USB keyboard with it, and install `gpm` to get a working mouse. - Once I had bluetooth working I was able to attach and use a bluetooth kbd+mouse. If you have a USB serial adapter available you can follow the entire boot process @@ -50,7 +60,7 @@ If you have a Linux compatible USB Ethernet adapter you can attach that to the s - You will need to find the assigned IP from router logs, netscan, or looking on the console. ### Creating SD card -You will need a suitable machine to download the image file to, with a SD card writer so the image can be written. +You will need a suitable machine to download the image file to, with a SD card writer so the image can be written. - The instructions below are for a generic Linux system with a sd card writer. - As ever with this sort of operation make *absolutely* sure you are using the correct disk device when writing. - Windows users need to ignore the linux steps and use a tool such as Belena Etcher or similar to burn the SD card, before skipping to [first boot](#first-boot). @@ -148,12 +158,12 @@ This adds a new custom entry for the MQ Pro based on the default LicheeRV defini Make this the default with: ```console -ubuntu@ubuntu:~$ sudo echo 'MangoPI MQ pro' > /etc/flash-kernel/machine +$ sudo echo 'MangoPI MQ pro' > /etc/flash-kernel/machine ``` We now apply this by running `flash-kernel` manually. * *flash-kernel* will also be run automatically by `apt` and `dpkg` whenever kernel images are (re)installed. ```console -ubuntu@ubuntu:~$ sudo flash-kernel +$ sudo flash-kernel Using DTB: allwinner/sun20i-d1-mangopi-mq-pro.dtb Installing /lib/firmware/6.8.0-41-generic/device-tree/allwinner/sun20i-d1-mangopi-mq-pro.dtb into /boot/dtbs/6.8.0-41-generic/allwinner/sun20i-d1-mangopi-mq-pro.dtb Taking backup of sun20i-d1-mangopi-mq-pro.dtb. @@ -205,10 +215,12 @@ $ sudo systemctl enable --now mqpro-status-led.service ``` The Status LED should now be continually flashing with Network activity, there is more on controlling this below. -## Bask in glory! -Congratulations! 🎉 +## Bask in glory! 🎉 +Congratulations! -You now have a small Risc-V server that should run and be updated for several years. What you do with it is up to you! +You now have a small Risc-V server that should run and be updated for several years. +* What you do with it is up to you! +* If you want to do GPIO, read on.. -------------------------------------------------------------------- @@ -219,38 +231,35 @@ A device tree is a file in the `/boot/` area that defines the structure of the h It is used in several places during initial boot to discover storage, console and other devices as needed. Once the linux kernel starts it is used to provision devices such as UART, network, gpu and other hardware. The device tree itself is a source file that is compiled into a binary to be loaded during boot. -In this guide we only replace the device tree used by the kernel when Linux is started in the final stages of boot up. +##### Note: +In this guide we only replace the device tree used by the kernel when Linux is started in the final stages of boot up. We do not modify the device tree used by U-Boot & SPL, they still use the default (Sipeed Lichee RV) device tree they were compiled against. Because this part of the boot process already works correctly we can avoid the complexity of recompiling these components. -We do not need to modify the device tree used by U-Boot, or the kernel init processes, they still use the default (Sipeed Lichee RV) device tree they were compiled against. Because this part of the boot process already works correctly we can avoid the complexity of recompiling anything. +## Device Tree Overlays (Work In Progress) +The 'vanilla', empty, device tree we installed above only enables the console UART on the GPIO connector, no other pins are assigned. + +In order to enable devices (such as UART, I2C, SPI, etc) on the MQ pro's GPIO connector you need to 'add' an assignment to it via a 'Device Tree Overlay' + +**I am working on this but do not (yet) have any working examples** + +I will update this guide once I have worked it out; *in the meantime you can proceed with a full device tree modification* as described below. ## Roll Your Own Device Tree -Hopefully you can do what you need with the default tree, and dynamically create your devices on it via `gpiod` and `pinctl`. +The guide to compiling the tree, scripts to build the them correctly, and link the compiled trees into `/etc/flash_kernel` are in the [build-trees](/build-trees) folder. See the README there for details and examples. -But if not; my somewhat limited notes on compiling the tree, plus a script that handles running the C preprocessor on them (needed to get a working binary) are in the [build-trees](./build-trees) folder. There are also instructions on how to configure *flash-kernel* to override the upstream trees with localally built ones. - -## Status LED notes: -The onboard (blue) status LED can be controlled via the sys tree: - -`$ sudo sh -c "echo 1 > /sys/devices/platform/leds/leds/blue\:status/brightness"` to turn on - -`$ sudo sh -c "echo 0 > /sys/devices/platform/leds/leds/blue\:status/brightness"` to turn off - -You can make it flash as network traffic is seen with: - -`$ sudo sh -c "echo phy0rx > /sys/devices/platform/leds/leds/blue\:status/trigger"` - -Other control options are available, `$ sudo cat /sys/devices/platform/leds/leds/blue\:status/brightness` shows a list and the current selection. Most do not work or are not very useful; ymmv. +The section `MQ Pro GPIO`, below, has information on the available interfaces and pin assignment options. There are example device trees in the [alt-trees](/alt-trees) folder that can be used as templates. ## My Motivation: My MQ PRO is connected to a Waveshare LORA hat, I want to make it work but the default device tree conflicts with some of the pins my HAT uses. So I decided to 'fix' this by putting a better device tree on my board. ![My Hardware](reference/waveshare_SX1268_LoRa_HAT/overview.jpg) -## MQ Pro GPIO -Providing a full GPIO how-to is beyond the scope of this document, I use LGPIO in python to do this. But have also used direct pinctl control via the `/sys/class/gpio` tree. +--------------------------------------------------------------- -For some basic GPIO use look at the following: -https://worldbeyondlinux.be/posts/gpio-on-the-mango-pi/ +# MQ Pro GPIO + +The following is a discussion and reference for the MQ Pro GPIO capabilities. + +For examples of **using GPIO** see the seperate [GPIO-examples](/GPIO-examples) page showing my GPIO tests and use examples. That is not a definitive guide; Linux GPIO is a complex and evolving topic, it cannot be covered in depth here. ## Allwinner D1 GPIO pins The **D1** SOC runs at 3v3, and you must not exceed this on any of the GPIO pins. The drive current is also very limited, a maximum of 4mA on any individual pin, and 6mA total across a bank of pins (eg the 12 pins in the `*PB*` bank combined cannot draw more than 6mA!). @@ -270,15 +279,88 @@ The **D1** chip uses a 'pin muxer' to connect pins to signals. Each pin can conn You can browse the full range of mappings in the Allwinner D1 datasheet, Table 4-3. - A copy of this table is available here: [reference/d1-pins.pdf](reference/d1-pins.pdf)). +- Note: Allwinner use the acronym **TWI** (Two Wire Interface) in place of **I2C** in their documentation. All pins are high-impedance digital inputs by default, they all have configurable pull-up and pull-down resistors, and can generate interrupts. Every pin can also be set to a HIGH or LOW digital output. PWM output and ADC input capable pins are limited, see the datasheet for more. +## MQ Pro GPIO connector + +### Pinmux assignment +Each pin on the connector has a 'pinmux' number, these map to the GPIO connector like this: +``` +Gpio Header: + pinmux des pin pin des pinmux + 3v3 1 --o o-- 2 5v + 205 PG13 3 --o o-- 4 5v + 204 PG12 5 --o o-- 6 gnd + 39 PB7 7 --o o-- 8 PB8 40 + gnd 9 --o o-- 10 PB9 41 + 117 PD21 11 --o o-- 12 PB5 37 + 118 PD22 13 --o o-- 14 gnd + 32 PB0 15 --o o-- 16 PB1 33 + 3v3 17 --o o-- 18 PD14 110 + 108 PD12 19 --o o-- 20 gnd + 109 PD13 21 --o o-- 22 PC1 65 + 107 PD11 23 --o o-- 24 PD10 106 + gnd 25 --o o-- 26 PD15 111 + 145 PE17 27 --o o-- 28 PE16 144 + 42 PB10 29 --o o-- 30 gnd + 43 PB11 31 --o o-- 32 PC0 64 + 44 PB12 33 --o o-- 34 gnd + 38 PB6 35 --o o-- 36 PB2 34 + 113 PD17 37 --o o-- 38 PB3 35 + gnd 39 --o o-- 40 PB4 36 +Also: + PD18: Blue Status Led - pinmux 114 +``` + +When controlling pins via the (legacy) `/sys/class/gpio` interface or `lgpio` in Python you need to use this pinmux number when addressing them. + +You can query the current pin mapping at any time with: +```console +$ sudo cat /sys/kernel/debug/pinctrl/2000000.pinctrl/pinmux-pins +``` +This produces a long output that lists all the D1's gpio pins and states, not just the pins exposed on the GPIO connector. +* The `list-pins.py` tool in the [tools](/tools) folder uses the output from the above and produces an ascii-art diagram of just the GPIO connector pins and their assignments. + +### Functional assignments +The following shows all the function combinations available on the MQ Pro GPIO connector. +* **All** pins can also do Digital Input and Output when not assigned to a specific internal interface. +* I do not list all interface types here, eg SPI (audio) and IR functions are available on GPIO pins but not covered in this guide. Creating overlays and using them is quite possible but I do not need these features and have limited resources, so I leave it as an excercise for others / the future. Sorry.. + +```text +Gpio Header: + func des pin pin des func + 3v3 1 --o o-- 2 5v + i2c0-sda, uart1-rx, pwm-2 PG13 3 --o o-- 4 5v + i2c0-scl, uart1-tx, pwm-0 PG12 5 --o o-- 6 gnd + i2c3-sda, uart3-rx PB7 7 --o o-- 8 PB8 i2c2-sck, spi1-hold, uart0-tx, uart1-tx, pwm-5 + gnd 9 --o o-- 10 PB9 i2c2-sda, spi1-miso, uart0-rx, uart1-rx, pwm-6 + i2c2-sda, uart1-tx, pwm-5 PD21 11 --o o-- 12 PB5 i2c1-sda, uart5-rx,pwm-0 + uart1-rx, pwm-7 PD22 13 --o o-- 14 gnd +i2c2-sck, spi1-wp, uart0-tx, uart2-tx, pwm-3 PB0 15 --o o-- 16 PB1 i2c2-sda, uart0-rx, uart2-rx, pwm-4 + 3v3 17 --o o-- 18 PD14 spi1-hold, uart3-cts + i2c0-sda, spi1-mosi PD12 19 --o o-- 20 gnd + spi1-miso, uart3-rts PD13 21 --o o-- 22 PC1 i2c2-sda, uart2-rx + spi1-clk, uart3-rx PD11 23 --o o-- 24 PD10 spi1-cs, uart3-tx + gnd 25 --o o-- 26 PD15 spi1-wp + i2c3-sda PE17 27 --o o-- 28 PE16 i2c3-sck, pwm-7 + i2c0-sck, spi1-mosi, uart1-rts, pwm-7 PB10 29 --o o-- 30 gnd + i2c0-sda, spi1-clk, uart1-cts, pwm-2 PB11 31 --o o-- 32 PC0 i2c2-sck, uart2-tx + spi1-cs, pwm-0 PB12 33 --o o-- 34 gnd + i2s3-sck, uart3-tx, pwm-1 PB6 35 --o o-- 36 PB2 i2c0-sda, uart4-tx + pwm-1 PD17 37 --o o-- 38 PB3 i2c0-sck, uart4-rx + gnd 39 --o o-- 40 PB4 i2c1-sck, uart5-tx +``` +- The I2C pins `3`, `5`, `27` and `28` (`PG13`, `PG12`, `PE17` and `PE16`) have 10K pullup resistors to 3v3 on the board. These cannot be disabled, but are useful if you are using I2C. + ### Internal interfaces The MQ Pro uses several of the **D1**s interfaces on-board, specifically: * `UART1` is used to connect to the the bluetooth device by default (with flow control) using `PG6`, `PG7`, `PG8` and `PG9`. It can be reconfigured onto GPIO pins if bluetooth is not required. -* `TWI2` (`I2C2`) can be mapped to the DVP connector (for touchscreen interfaces) via pins `PE12` and `PE13`. -* `TWI3` (`I2C3`) can be mapped to the DSI/LVDS connector via pins `PE16` and `PE17`; which also appear on the GPIO connector. -* `SPI0` is mapped to the optional SPI flash chip (not fitted on consumer units), and cannot be mapped to the GPIO connector. +* `SPI0` is mapped to the optional SPI flash chip (not fitted on consumer units), and cannot be mapped to the GPIO connector. It is present but `disabled` in the device tree by default. +* If you are using LCD panels on the DVP or DSI/LVDS ports these also assign I2C ports for touchscreens etc. + * `TWI2` (`I2C2`) can be mapped to the DVP connector via pins `PE12` and `PE13`. + * `TWI3` (`I2C3`) can be mapped to the DSI/LVDS connector via pins `PE16` and `PE17`; which also appear on the GPIO connector. ## References There are reference copies of the MQ PRO schematic and the AllWinner D1 datasheet in the [references](./reference) folder. @@ -287,3 +369,4 @@ Online: * https://mangopi.org/mangopi_mqpro * https://linux-sunxi.org/MangoPi_MQ-Pro * https://github.com/boosterl/awesome-mango-pi-mq-pro + diff --git a/alt-trees/README.md b/alt-trees/README.md index ddf31eb..9b2fbf6 100644 --- a/alt-trees/README.md +++ b/alt-trees/README.md @@ -1,19 +1,34 @@ # Alternate device tree Examples: Each folder contains a `.dts` file and a README showing the GPIO pin mappings. -Copy the desired `.dts` file to the [build-trees](../build-trees) folder and follow the readme there to build the device-tree binaries. +## Use +Copy the desired `.dts` file(s) to the [build-trees](../build-trees) folder and follow the readme there to build the device-tree binaries. -There are instructions at the end of that document on how you can use a custom `.dtb` and make it permanent across reboots and kernel upgrades. +There are instructions at the end of that document on how to make this permanent across reboots and kernel upgrades, some example flash-kernel database entries are given below for convenience. +## Caveat The issue with using these trees is that **if** the upstream device tree or includes is modified you need to manually rebuild these trees. EG any changes to the upstream `sun20i-d1-mangopi-mq-pro.dts` source needs to be detected and applied too. You need to examine file histories to do this. - Fortunately this should not be an issue in practice; the kernel *should* remain very stable going forward. Ubuntu 24.04.1 is a LTS release.. -The authors personal advice is to use this only if needed; or as a learning excercise. +## HAT +[Emulates a standard PI hat pinout](./hat) +* 1x SPI +* 2x I2C +* Console UART only +* 16 unassigned GPIO pins + +## LoRa HAT +[Expanded HAT pinout for my LoRa hat use](./lora-hat) +* 1x SPI +* 2x I2C +* 1x UART (plus the console uart) +* 4x PWM +* 11 unassigned GPIO pins ## SPI and I2C -[SPI plus I2C interfaces](./spi_i2c) +[SPI plus I2C interfaces](./spi-i2c) * 1x SPI * 4x I2C * 3x UART (plus the console uart) @@ -25,3 +40,36 @@ The authors personal advice is to use this only if needed; or as a learning exce * UART3 has RTC/CTS pins available too * 2x I2C * 12 unassigned GPIO pins + +#### Example `/etc/flash-kernel/db` entries +```text +# Custom kernels + +Machine: MQpro HAT +Kernel-Flavors: any +DTB-Id: custom/mqpro-hat.dtb +Boot-Script-Path: /boot/boot.scr +U-Boot-Script-Name: bootscr.uboot-generic +Required-Packages: u-boot-tools + +Machine: MQpro LoRa HAT +Kernel-Flavors: any +DTB-Id: custom/mqpro-lora-hat.dtb +Boot-Script-Path: /boot/boot.scr +U-Boot-Script-Name: bootscr.uboot-generic +Required-Packages: u-boot-tools + +Machine: MQpro Serial +Kernel-Flavors: any +DTB-Id: custom/mqpro-serial.dtb +Boot-Script-Path: /boot/boot.scr +U-Boot-Script-Name: bootscr.uboot-generic +Required-Packages: u-boot-tools + +Machine: MQpro SPI I2C +Kernel-Flavors: any +DTB-Id: custom/mqpro-spi-i2c.dtb +Boot-Script-Path: /boot/boot.scr +U-Boot-Script-Name: bootscr.uboot-generic +Required-Packages: u-boot-tools +``` diff --git a/alt-trees/hat/README.md b/alt-trees/hat/README.md new file mode 100644 index 0000000..868531a --- /dev/null +++ b/alt-trees/hat/README.md @@ -0,0 +1,71 @@ +# A device tree for Raspberry PI HATs.. + +Designed to mimic the standard PI gpio assignments for use with PI HAT's +* i2c**0** and spi**1** ports are located on the same Pins as the PI I2C-**1** and SPI-**0** on the PI gpio header + * i2c3 is on the same pins as I2C-0 on the Pi (normally reserved as the Pi EEPROM Data pins) + +``` + MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) + +Gpio Header: + func des pin pin des func + 3v3 1 --o o-- 2 5v + i2c0.sda (2502000.i2c:205) PG13 3 --o o-- 4 5v + i2c0.scl (2502000.i2c:204) PG12 5 --o o-- 6 gnd + free (39) PB7 7 --o o-- 8 PB8 uart0.tx (2500000.serial:40) + gnd 9 --o o-- 10 PB9 uart0.rx (2500000.serial:41) + free (117) PD21 11 --o o-- 12 PB5 free (37) + free (118) PD22 13 --o o-- 14 gnd + free (32) PB0 15 --o o-- 16 PB1 free (33) + 3v3 17 --o o-- 18 PD14 spi1.hold (4026000.spi:110) + spi1.mosi (4026000.spi:108) PD12 19 --o o-- 20 gnd + spi1.miso (4026000.spi:109) PD13 21 --o o-- 22 PC1 free (65) + spi1.clk (4026000.spi:107) PD11 23 --o o-- 24 PD10 spi1.cs (4026000.spi:106) + gnd 25 --o o-- 26 PD15 spi1.wp (4026000.spi:111) + i2c3.sda (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3.sck (2502c00.i2c:144) + free (42) PB10 29 --o o-- 30 gnd + free (43) PB11 31 --o o-- 32 PC0 free (64) + free (44) PB12 33 --o o-- 34 gnd + free (38) PB6 35 --o o-- 36 PB2 free (34) + free (113) PD17 37 --o o-- 38 PB3 free (35) + gnd 39 --o o-- 40 PB4 free (36) + +Other gpio outputs of interest: +-- PD18: Blue Status Led - gpio (2000000.pinctrl:114) + +Notes: +- I2C pins 3,5,27 and 28 (PG13, PG12, PE17 and PE16) have 10K pullup resistors to 3v3 +- The Status LED (PD18) is common with the LED_PWM pin on the DSI/LVDS output +``` + + MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) + +Gpio Header: + func des pin pin des func + 3v3 1 --o o-- 2 5v + i2c0 (2502000.i2c:205) PG13 3 --o o-- 4 5v + i2c0 (2502000.i2c:204) PG12 5 --o o-- 6 gnd + free (39) PB7 7 --o o-- 8 PB8 uart0 (2500000.serial:40) + gnd 9 --o o-- 10 PB9 uart0 (2500000.serial:41) + free (117) PD21 11 --o o-- 12 PB5 free (37) + free (118) PD22 13 --o o-- 14 gnd + free (32) PB0 15 --o o-- 16 PB1 free (33) + 3v3 17 --o o-- 18 PD14 spi1 (4026000.spi:110) + spi1 (4026000.spi:108) PD12 19 --o o-- 20 gnd + spi1 (4026000.spi:109) PD13 21 --o o-- 22 PC1 free (65) + spi1 (4026000.spi:107) PD11 23 --o o-- 24 PD10 spi1 (4026000.spi:106) + gnd 25 --o o-- 26 PD15 spi1 (4026000.spi:111) + i2c3 (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3 (2502c00.i2c:144) + free (42) PB10 29 --o o-- 30 gnd + free (43) PB11 31 --o o-- 32 PC0 free (64) + free (44) PB12 33 --o o-- 34 gnd + free (38) PB6 35 --o o-- 36 PB2 free (34) + free (113) PD17 37 --o o-- 38 PB3 free (35) + gnd 39 --o o-- 40 PB4 free (36) + +Other gpio outputs of interest: +-- PD18: Blue Status Led - gpio (2000000.pinctrl:114) + +Notes: +- I2C pins 3,5,27 and 28 (PG13, PG12, PE17 and PE16) have 10K pullup resistors to 3v3 +- The Status LED (PD18) is common with the LED_PWM pin on the DSI/LVDS output diff --git a/alt-trees/hat/mqpro-hat.dts b/alt-trees/hat/mqpro-hat.dts new file mode 100644 index 0000000..2944f0b --- /dev/null +++ b/alt-trees/hat/mqpro-hat.dts @@ -0,0 +1,425 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +// Copyright (C) 2022 Samuel Holland + +#include +#include + +/dts-v1/; + +#include "sun20i-d1.dtsi" +#include "sun20i-common-regulators.dtsi" + +/ { + model = "MangoPi MQ Pro"; + compatible = "widora,mangopi-mq-pro", "allwinner,sun20i-d1"; + + aliases { + ethernet0 = &rtl8723ds; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + hdmi_connector: connector { + compatible = "hdmi-connector"; + type = "c"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_out_connector>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */ + }; + }; + + reg_avdd2v8: avdd2v8 { + compatible = "regulator-fixed"; + regulator-name = "avdd2v8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + vin-supply = <®_vcc_3v3>; + }; + + reg_dvdd: dvdd { + compatible = "regulator-fixed"; + regulator-name = "dvdd"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + vin-supply = <®_vcc_3v3>; + }; + + reg_vdd_cpu: vdd-cpu { + compatible = "regulator-fixed"; + regulator-name = "vdd-cpu"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <®_vcc>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pio 6 17 GPIO_ACTIVE_LOW>; /* PG17 */ + }; +}; + +&cpu0 { + cpu-supply = <®_vdd_cpu>; +}; + +&dcxo { + clock-frequency = <24000000>; +}; + +&codec { + routing = "Internal Speaker", "HPOUTL", + "Internal Speaker", "HPOUTR"; + widgets = "Speaker", "Internal Speaker"; + status = "okay"; +}; + +&de { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_out { + hdmi_out_connector: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; +}; + +&hdmi_phy { + status = "okay"; +}; + +&mmc0 { + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + disable-wp; + vmmc-supply = <®_vcc_3v3>; + vqmmc-supply = <®_vcc_3v3>; + pinctrl-0 = <&mmc0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&mmc1 { + bus-width = <4>; + mmc-pwrseq = <&wifi_pwrseq>; + non-removable; + vmmc-supply = <®_vcc_3v3>; + vqmmc-supply = <®_vcc_3v3>; + pinctrl-0 = <&mmc1_pins>; + pinctrl-names = "default"; + status = "okay"; + + rtl8723ds: wifi@1 { + reg = <1>; + interrupt-parent = <&pio>; + interrupts = <6 10 IRQ_TYPE_LEVEL_LOW>; /* PG10 */ + interrupt-names = "host-wake"; + }; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pe-supply = <®_avdd2v8>; + + /omit-if-no-ref/ + i2c0_pg12_pins: i2c0-pg12-pins { + pins = "PG12", "PG13"; + function = "i2c0"; + }; + + /omit-if-no-ref/ + i2c1_pb4_pins: i2c1-pb4-pins { + pins = "PB4", "PB5"; + function = "i2c1"; + }; + + /omit-if-no-ref/ + i2c2_pb0_pins: i2c2-pb0-pins { + pins = "PB0", "PB1"; + function = "i2c2"; + }; + + /omit-if-no-ref/ + i2c2_pc0_pins: i2c2-pc0-pins { + pins = "PC0", "PC1"; + function = "i2c2"; + }; + + /omit-if-no-ref/ + i2c3_pe16_pins: i2c3-pe16-pins { + pins = "PE16", "PE17"; + function = "i2c3"; + }; + + /omit-if-no-ref/ + uart2_pc0_pins: uart2-pc0-pins { + pins = "PC0", "PC1"; + function = "uart2"; + }; + + /omit-if-no-ref/ + uart3_pd10_pins: uart3-pd10-pins { + pins = "PD10", "PD11"; + function = "uart3"; + }; + + /omit-if-no-ref/ + uart3_pd13_rts_cts_pins: uart3-pd13-rts-cts-pins { + pins = "PD13", "PD14"; + function = "uart3"; + }; + + /omit-if-no-ref/ + uart3_pb6_pins: uart3-pb6-pins { + pins = "PB6", "PB7"; + function = "uart3"; + }; + + /omit-if-no-ref/ + uart4_pb2_pins: uart4-pb2-pins { + pins = "PB2", "PB3"; + function = "uart4"; + }; + + /omit-if-no-ref/ + uart5_pb4_pins: uart5-pb4-pins { + pins = "PB4", "PB5"; + function = "uart5"; + }; + + /omit-if-no-ref/ + pwm0_pb5_pin: pwm0-pb5-pin { + pins = "PB5"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pb12_pin: pwm0-pb12-pin { + pins = "PB12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pg12_pin: pwm0-pg12-pin { + pins = "PG12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm1_pb6_pin: pwm1-pb6-pin { + pins = "PB6"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm1_pd17_pin: pwm1-pd17-pin { + pins = "PD17"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm2_pb11_pin: pwm2-pb11-pin { + pins = "PB11"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm2_pg13_pin: pwm2-pg13-pin { + pins = "PG13"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm3_pb0_pin: pwm3-pb0-pin { + pins = "PB0"; + function = "pwm3"; + }; + + /omit-if-no-ref/ + pwm4_pb1_pin: pwm4-pb1-pin { + pins = "PB1"; + function = "pwm4"; + }; + + /omit-if-no-ref/ + pwm5_pb8_pin: pwm5-pb8-pin { + pins = "PB8"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm5_pd21_pin: pwm5-pd21-pin { + pins = "PD21"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm6_pb9_pin: pwm6-pb9-pin { + pins = "PB9"; + function = "pwm6"; + }; + + /omit-if-no-ref/ + pwm7_pb10_pin: pwm7-pb10-pin { + pins = "PB10"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pd22_pin: pwm7-pd22-pin { + pins = "PD22"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pe16_pin: pwm7-pe16-pin { + pins = "PE16"; + function = "pwm7"; + }; +}; + +/* disabled +&pwm { + pinctrl-0 = <&pwm0_pb12_pin>, <&pwm1_pb6_pin>, <&pwm2_pb11_pin>, <&pwm4_pb1_pin>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +&spi1 { + pinctrl-0 = <&spi1_pd_pins>; // can conflict uart3 + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0_pg12_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +/* disabled +&i2c1 { + pinctrl-0 = <&i2c1_pb4_pins>; // can conflict uart5 + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled +&i2c2 { + pinctrl-0 = <&i2c2_pb0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled +&i2c2 { + pinctrl-0 = <&i2c2_pc0_pins>; // can conflict uart2 + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +&i2c3 { + pinctrl-0 = <&i2c3_pe16_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_pb8_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart1 { + uart-has-rtscts; + pinctrl-0 = <&uart1_pg6_pins>, <&uart1_pg8_rts_cts_pins>; + pinctrl-names = "default"; + status = "okay"; + + bluetooth { + compatible = "realtek,rtl8723ds-bt"; + device-wake-gpios = <&pio 6 18 GPIO_ACTIVE_HIGH>; /* PG18 */ + enable-gpios = <&pio 6 15 GPIO_ACTIVE_HIGH>; /* PG15 */ + host-wake-gpios = <&pio 6 14 GPIO_ACTIVE_HIGH>; /* PG14 */ + }; +}; + +/* disabled +&uart2 { + pinctrl-0 = <&uart2_pc0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled +&uart3 { + uart-has-rtscts; + pinctrl-0 = <&uart3_pd10_pins>, <&uart3_pd13_rts_cts_pins>; // conflicts spi1 + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled +&uart3 { + pinctrl-0 = <&uart3_pb6_pins>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled +&uart4 { + pinctrl-0 = <&uart4_pb2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled +&uart5 { + pinctrl-0 = <&uart5_pb4_pins>; // conflicts i2c1 + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +&usb_otg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_vcc>; + status = "okay"; +}; diff --git a/alt-trees/lora-hat/README.md b/alt-trees/lora-hat/README.md new file mode 100644 index 0000000..3a7a8bb --- /dev/null +++ b/alt-trees/lora-hat/README.md @@ -0,0 +1,45 @@ +# A device tree for my LORA HAT.. + +Designed to mimic the standard PI gpio assignments for use with PI HAT's +* i2c0 and spi1 ports are located on the same Pins as the PI I2C-1 and SPI-0 on the PI gpio header + * i2c3 is on the same pins as I2C-0 on the Pi (normally reserved as the Pi EEPROM Data pins) + +In addition it: +* Brings uart4 out on pins 36 and 38 (so I can leave the console free) +* Has 4 PWM channels for a RGB status led, and I2C screen brightness + + +Nb: screen is https://www.waveshare.com/wiki/3.5inch_RPi_LCD_(A) +``` + MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) + +Gpio Header: + func des pin pin des func + 3v3 1 --o o-- 2 5v + i2c0.sda (2502000.i2c:205) PG13 3 --o o-- 4 5v + i2c0.scl (2502000.i2c:204) PG12 5 --o o-- 6 gnd + free (39) PB7 7 --o o-- 8 PB8 uart0.tx (2500000.serial:40) + gnd 9 --o o-- 10 PB9 uart0.rx (2500000.serial:41) + free (117) PD21 11 --o o-- 12 PB5 free (37) + free (118) PD22 13 --o o-- 14 gnd + free (32) PB0 15 --o o-- 16 PB1 pwm4 (2000c00.pwm:33) + 3v3 17 --o o-- 18 PD14 spi1.hold (4026000.spi:110) + spi1.mosi (4026000.spi:108) PD12 19 --o o-- 20 gnd + spi1.miso (4026000.spi:109) PD13 21 --o o-- 22 PC1 free (65) + spi1.clk (4026000.spi:107) PD11 23 --o o-- 24 PD10 spi1.cs (4026000.spi:106) + gnd 25 --o o-- 26 PD15 spi1.wp (4026000.spi:111) + i2c3.sda (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3.sck (2502c00.i2c:144) + free (42) PB10 29 --o o-- 30 gnd + pwm2 (2000c00.pwm:43) PB11 31 --o o-- 32 PC0 free (64) + pwm0 (2000c00.pwm:44) PB12 33 --o o-- 34 gnd + pwm1 (2000c00.pwm:38) PB6 35 --o o-- 36 PB2 uart4.tx (2501000.serial:34) + free (113) PD17 37 --o o-- 38 PB3 uart4.rx (2501000.serial:35) + gnd 39 --o o-- 40 PB4 free (36) + +Other gpio outputs of interest: +-- PD18: Blue Status Led - gpio (2000000.pinctrl:114) + +Notes: +- I2C pins 3,5,27 and 28 (PG13, PG12, PE17 and PE16) have 10K pullup resistors to 3v3 +- The Status LED (PD18) is common with the LED_PWM pin on the DSI/LVDS output +``` diff --git a/alt-trees/lora/mqpro-lora-hat.dts b/alt-trees/lora-hat/mqpro-lora-hat.dts similarity index 73% rename from alt-trees/lora/mqpro-lora-hat.dts rename to alt-trees/lora-hat/mqpro-lora-hat.dts index e31736c..6aaf76b 100644 --- a/alt-trees/lora/mqpro-lora-hat.dts +++ b/alt-trees/lora-hat/mqpro-lora-hat.dts @@ -211,10 +211,106 @@ pins = "PB4", "PB5"; function = "uart5"; }; + + /omit-if-no-ref/ + pwm0_pb5_pin: pwm0-pb5-pin { + pins = "PB5"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pb12_pin: pwm0-pb12-pin { + pins = "PB12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pg12_pin: pwm0-pg12-pin { + pins = "PG12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm1_pb6_pin: pwm1-pb6-pin { + pins = "PB6"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm1_pd17_pin: pwm1-pd17-pin { + pins = "PD17"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm2_pb11_pin: pwm2-pb11-pin { + pins = "PB11"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm2_pg13_pin: pwm2-pg13-pin { + pins = "PG13"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm3_pb0_pin: pwm3-pb0-pin { + pins = "PB0"; + function = "pwm3"; + }; + + /omit-if-no-ref/ + pwm4_pb1_pin: pwm4-pb1-pin { + pins = "PB1"; + function = "pwm4"; + }; + + /omit-if-no-ref/ + pwm5_pb8_pin: pwm5-pb8-pin { + pins = "PB8"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm5_pd21_pin: pwm5-pd21-pin { + pins = "PD21"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm6_pb9_pin: pwm6-pb9-pin { + pins = "PB9"; + function = "pwm6"; + }; + + /omit-if-no-ref/ + pwm7_pb10_pin: pwm7-pb10-pin { + pins = "PB10"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pd22_pin: pwm7-pd22-pin { + pins = "PD22"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pe16_pin: pwm7-pe16-pin { + pins = "PE16"; + function = "pwm7"; + }; +}; + +&pwm { + pinctrl-0 = <&pwm0_pb12_pin>, <&pwm1_pb6_pin>, <&pwm2_pb11_pin>, <&pwm4_pb1_pin>; + pinctrl-names = "default"; + status = "okay"; }; &spi1 { - pinctrl-0 = <&spi1_pd_pins>; // conflicts uart3 + pinctrl-0 = <&spi1_pd_pins>; // can conflict uart3 pinctrl-names = "default"; status = "okay"; }; @@ -227,29 +323,33 @@ /* disabled &i2c1 { - pinctrl-0 = <&i2c1_pb4_pins>; // conflicts uart5 + pinctrl-0 = <&i2c1_pb4_pins>; // can conflict uart5 pinctrl-names = "default"; status = "okay"; }; +*/ +/* disabled &i2c2 { pinctrl-0 = <&i2c2_pb0_pins>; pinctrl-names = "default"; status = "okay"; }; +*/ +/* disabled &i2c2 { - pinctrl-0 = <&i2c2_pc0_pins>; // conflicts uart2 + pinctrl-0 = <&i2c2_pc0_pins>; // can conflict uart2 pinctrl-names = "default"; status = "okay"; }; +*/ &i2c3 { pinctrl-0 = <&i2c3_pe16_pins>; pinctrl-names = "default"; status = "okay"; }; -*/ &uart0 { pinctrl-0 = <&uart0_pb8_pins>; @@ -271,20 +371,24 @@ }; }; -/* Disabled +/* disabled &uart2 { pinctrl-0 = <&uart2_pc0_pins>; pinctrl-names = "default"; status = "okay"; }; +*/ +/* disabled &uart3 { uart-has-rtscts; pinctrl-0 = <&uart3_pd10_pins>, <&uart3_pd13_rts_cts_pins>; // conflicts spi1 pinctrl-names = "default"; status = "okay"; }; +*/ +/* disabled &uart3 { pinctrl-0 = <&uart3_pb6_pins>; pinctrl-names = "default"; @@ -298,7 +402,7 @@ status = "okay"; }; -/* Disabled +/* disabled &uart5 { pinctrl-0 = <&uart5_pb4_pins>; // conflicts i2c1 pinctrl-names = "default"; diff --git a/alt-trees/lora/README.md b/alt-trees/lora/README.md deleted file mode 100644 index a824156..0000000 --- a/alt-trees/lora/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# A device tree for my LORA HAT.. -* Brings a UART out for talking to the HAT -* Leaves pins `7`, `13` and `15` free since these are used to control and monitor the HAT -* Has the SPI interface in case I add a screen, and an I2C interface for talking to peripherals. - -Nb: screen is https://www.waveshare.com/wiki/3.5inch_RPi_LCD_(A) -``` - MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) - -Gpio Header: - func des pin pin des func - 3v3 1 --o o-- 2 5v - i2c0 (2502000.i2c:205) PG13 3 --o o-- 4 5v - i2c0 (2502000.i2c:204) PG12 5 --o o-- 6 gnd - free (39) PB7 7 --o o-- 8 PB8 uart0 (2500000.serial:40) - gnd 9 --o o-- 10 PB9 uart0 (2500000.serial:41) - free (117) PD21 11 --o o-- 12 PB5 free (37) - free (118) PD22 13 --o o-- 14 gnd - free (32) PB0 15 --o o-- 16 PB1 free (33) - 3v3 17 --o o-- 18 PD14 spi1 (4026000.spi:110) - spi1 (4026000.spi:108) PD12 19 --o o-- 20 gnd - spi1 (4026000.spi:109) PD13 21 --o o-- 22 PC1 free (65) - spi1 (4026000.spi:107) PD11 23 --o o-- 24 PD10 spi1 (4026000.spi:106) - gnd 25 --o o-- 26 PD15 spi1 (4026000.spi:111) - free (145) PE17 27 --o o-- 28 PE16 free (144) - free (42) PB10 29 --o o-- 30 gnd - free (43) PB11 31 --o o-- 32 PC0 free (64) - free (44) PB12 33 --o o-- 34 gnd - free (38) PB6 35 --o o-- 36 PB2 uart4 (2501000.serial:34) - free (113) PD17 37 --o o-- 38 PB3 uart4 (2501000.serial:35) - gnd 39 --o o-- 40 PB4 free (36) - -Other gpio outputs of interest: --- PD18: Blue Status Led - gpio (2000000.pinctrl:114) - -Notes: -- I2C pins 3,5,27 and 28 (PG13, PG12, PE17 and PE16) have 10K pullup resistors to 3v3 -- The Status LED (PD18) is common with the LED_PWM pin on the DSI/LVDS output -``` diff --git a/alt-trees/serial/README.md b/alt-trees/serial/README.md index fe02d89..dfbdf37 100644 --- a/alt-trees/serial/README.md +++ b/alt-trees/serial/README.md @@ -2,27 +2,27 @@ MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) Gpio Header: - func des pin pin des func - 3v3 1 --o o-- 2 5v - i2c0.sda (2502000.i2c:205) PG13 3 --o o-- 4 5v - i2c0.sck (2502000.i2c:204) PG12 5 --o o-- 6 gnd - free (39) PB7 7 --o o-- 8 PB8 uart0.tx (2500000.serial:40) - gnd 9 --o o-- 10 PB9 uart0.rx (2500000.serial:41) - free (117) PD21 11 --o o-- 12 PB5 uart5.rx (2501400.serial:37) - free (118) PD22 13 --o o-- 14 gnd - free (32) PB0 15 --o o-- 16 PB1 free (33) - 3v3 17 --o o-- 18 PD14 uart3.cts (2500c00.serial:110) - free (108) PD12 19 --o o-- 20 gnd - uart3.rts (2500c00.serial:109) PD13 21 --o o-- 22 PC1 uart2.rx (2500800.serial:65) - uart3.rx (2500c00.serial:107) PD11 23 --o o-- 24 PD10 uart3.tx (2500c00.serial:106) - gnd 25 --o o-- 26 PD15 free (111) - i2c3.sda (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3.sck (2502c00.i2c:144) - free (42) PB10 29 --o o-- 30 gnd - free (43) PB11 31 --o o-- 32 PC0 uart2.tx (2500800.serial:64) - free (44) PB12 33 --o o-- 34 gnd - free (38) PB6 35 --o o-- 36 PB2 uart4.tx (2501000.serial:34) - free (113) PD17 37 --o o-- 38 PB3 uart4.rx (2501000.serial:35) - gnd 39 --o o-- 40 PB4 uart5.tx (2501400.serial:36) + func des pin pin des func + 3v3 1 --o o-- 2 5v + i2c0.sda (2502000.i2c:205) PG13 3 --o o-- 4 5v + i2c0.sck (2502000.i2c:204) PG12 5 --o o-- 6 gnd + free (39) PB7 7 --o o-- 8 PB8 uart0.tx (2500000.serial:40) + gnd 9 --o o-- 10 PB9 uart0.rx (2500000.serial:41) + free (117) PD21 11 --o o-- 12 PB5 uart5.rx (2501400.serial:37) + free (118) PD22 13 --o o-- 14 gnd + free (32) PB0 15 --o o-- 16 PB1 free (33) + 3v3 17 --o o-- 18 PD14 uart3.cts (2500c00.serial:110) + free (108) PD12 19 --o o-- 20 gnd + uart3.rts (2500c00.serial:109) PD13 21 --o o-- 22 PC1 uart2.rx (2500800.serial:65) + uart3.rx (2500c00.serial:107) PD11 23 --o o-- 24 PD10 uart3.tx (2500c00.serial:106) + gnd 25 --o o-- 26 PD15 free (111) + i2c3.sda (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3.sck (2502c00.i2c:144) + free (42) PB10 29 --o o-- 30 gnd + free (43) PB11 31 --o o-- 32 PC0 uart2.tx (2500800.serial:64) + free (44) PB12 33 --o o-- 34 gnd + free (38) PB6 35 --o o-- 36 PB2 uart4.tx (2501000.serial:34) + free (113) PD17 37 --o o-- 38 PB3 uart4.rx (2501000.serial:35) + gnd 39 --o o-- 40 PB4 uart5.tx (2501400.serial:36) Other gpio outputs of interest: -- PD18: Blue Status Led - gpio (2000000.pinctrl:114) diff --git a/alt-trees/serial/mqpro-serial.dts b/alt-trees/serial/mqpro-serial.dts index 033a996..5db323d 100644 --- a/alt-trees/serial/mqpro-serial.dts +++ b/alt-trees/serial/mqpro-serial.dts @@ -211,11 +211,109 @@ pins = "PB4", "PB5"; function = "uart5"; }; + + /omit-if-no-ref/ + pwm0_pb5_pin: pwm0-pb5-pin { + pins = "PB5"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pb12_pin: pwm0-pb12-pin { + pins = "PB12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pg12_pin: pwm0-pg12-pin { + pins = "PG12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm1_pb6_pin: pwm1-pb6-pin { + pins = "PB6"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm1_pd17_pin: pwm1-pd17-pin { + pins = "PD17"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm2_pb11_pin: pwm2-pb11-pin { + pins = "PB11"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm2_pg13_pin: pwm2-pg13-pin { + pins = "PG13"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm3_pb0_pin: pwm3-pb0-pin { + pins = "PB0"; + function = "pwm3"; + }; + + /omit-if-no-ref/ + pwm4_pb1_pin: pwm4-pb1-pin { + pins = "PB1"; + function = "pwm4"; + }; + + /omit-if-no-ref/ + pwm5_pb8_pin: pwm5-pb8-pin { + pins = "PB8"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm5_pd21_pin: pwm5-pd21-pin { + pins = "PD21"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm6_pb9_pin: pwm6-pb9-pin { + pins = "PB9"; + function = "pwm6"; + }; + + /omit-if-no-ref/ + pwm7_pb10_pin: pwm7-pb10-pin { + pins = "PB10"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pd22_pin: pwm7-pd22-pin { + pins = "PD22"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pe16_pin: pwm7-pe16-pin { + pins = "PE16"; + function = "pwm7"; + }; }; -/* Disabled +/* disabled +&pwm { + pinctrl-0 = <&pwm0_pb12_pin>, <&pwm1_pb6_pin>, <&pwm2_pb11_pin>, <&pwm4_pb1_pin>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + +/* disabled &spi1 { - pinctrl-0 = <&spi1_pd_pins>; // conflicts uart3 + pinctrl-0 = <&spi1_pd_pins>; // can conflict uart3 pinctrl-names = "default"; status = "okay"; }; @@ -227,9 +325,9 @@ status = "okay"; }; -/* Disabled +/* disabled &i2c1 { - pinctrl-0 = <&i2c1_pb4_pins>; // conflicts uart5 + pinctrl-0 = <&i2c1_pb4_pins>; // can conflict uart5 pinctrl-names = "default"; status = "okay"; }; @@ -244,7 +342,7 @@ */ &i2c2 { - pinctrl-0 = <&i2c2_pc0_pins>; // conflicts uart2 + pinctrl-0 = <&i2c2_pc0_pins>; // can conflict uart2 pinctrl-names = "default"; status = "okay"; }; @@ -288,7 +386,7 @@ status = "okay"; }; -/* Disabled +/* disabled &uart3 { pinctrl-0 = <&uart3_pb6_pins>; pinctrl-names = "default"; diff --git a/alt-trees/spi_i2c/README.md b/alt-trees/spi-i2c/README.md similarity index 53% rename from alt-trees/spi_i2c/README.md rename to alt-trees/spi-i2c/README.md index cdae384..3d39722 100644 --- a/alt-trees/spi_i2c/README.md +++ b/alt-trees/spi-i2c/README.md @@ -2,27 +2,27 @@ MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) Gpio Header: - func des pin pin des func - 3v3 1 --o o-- 2 5v - i2c0.sda (2502000.i2c:205) PG13 3 --o o-- 4 5v - i2c0.sck (2502000.i2c:204) PG12 5 --o o-- 6 gnd - uart3.rx (2500c00.serial:39 PB7 7 --o o-- 8 PB8 uart0.tx (2500000.serial:40) - gnd 9 --o o-- 10 PB9 uart0.rx (2500000.serial:41) - free (117) PD21 11 --o o-- 12 PB5 i2c1.sda (2502400.i2c:37) - free (118) PD22 13 --o o-- 14 gnd - i2c2.sck (2502800.i2c:32) PB0 15 --o o-- 16 PB1 i2c2.sda (2502800.i2c:33) - 3v3 17 --o o-- 18 PD14 spi1.hold (4026000.spi:110) - spi1.mosi (4026000.spi:108) PD12 19 --o o-- 20 gnd - spi1.miso (4026000.spi:109) PD13 21 --o o-- 22 PC1 uart2.rx (2500800.serial:65) - spi1.clk (4026000.spi:107) PD11 23 --o o-- 24 PD10 spi1.cs (4026000.spi:106) - gnd 25 --o o-- 26 PD15 spi1.wp (4026000.spi:111) - i2c3.sda (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3.sck (2502c00.i2c:144) - free (42) PB10 29 --o o-- 30 gnd - free (43) PB11 31 --o o-- 32 PC0 uart2.tx (2500800.serial:64) - free (44) PB12 33 --o o-- 34 gnd - uart3.tx (2500c00.serial:38) PB6 35 --o o-- 36 PB2 uart4.tx (2501000.serial:34) - free (113) PD17 37 --o o-- 38 PB3 uart4.rx (2501000.serial:35) - gnd 39 --o o-- 40 PB4 i2c1.sck (2502400.i2c:36) + func des pin pin des func + 3v3 1 --o o-- 2 5v + i2c0.sda (2502000.i2c:205) PG13 3 --o o-- 4 5v + i2c0.sck (2502000.i2c:204) PG12 5 --o o-- 6 gnd + uart3.rx (2500c00.serial:39 PB7 7 --o o-- 8 PB8 uart0.tx (2500000.serial:40) + gnd 9 --o o-- 10 PB9 uart0.rx (2500000.serial:41) + free (117) PD21 11 --o o-- 12 PB5 i2c1.sda (2502400.i2c:37) + free (118) PD22 13 --o o-- 14 gnd + i2c2.sck (2502800.i2c:32) PB0 15 --o o-- 16 PB1 i2c2.sda (2502800.i2c:33) + 3v3 17 --o o-- 18 PD14 spi1.hold (4026000.spi:110) + spi1.mosi (4026000.spi:108) PD12 19 --o o-- 20 gnd + spi1.miso (4026000.spi:109) PD13 21 --o o-- 22 PC1 uart2.rx (2500800.serial:65) + spi1.clk (4026000.spi:107) PD11 23 --o o-- 24 PD10 spi1.cs (4026000.spi:106) + gnd 25 --o o-- 26 PD15 spi1.wp (4026000.spi:111) + i2c3.sda (2502c00.i2c:145) PE17 27 --o o-- 28 PE16 i2c3.sck (2502c00.i2c:144) + free (42) PB10 29 --o o-- 30 gnd + free (43) PB11 31 --o o-- 32 PC0 uart2.tx (2500800.serial:64) + free (44) PB12 33 --o o-- 34 gnd + uart3.tx (2500c00.serial:38) PB6 35 --o o-- 36 PB2 uart4.tx (2501000.serial:34) + free (113) PD17 37 --o o-- 38 PB3 uart4.rx (2501000.serial:35) + gnd 39 --o o-- 40 PB4 i2c1.sck (2502400.i2c:36) Other gpio outputs of interest: -- PD18: Blue Status Led - gpio (2000000.pinctrl:114) diff --git a/alt-trees/spi_i2c/mqpro-spi-i2c.dts b/alt-trees/spi-i2c/mqpro-spi-i2c.dts similarity index 73% rename from alt-trees/spi_i2c/mqpro-spi-i2c.dts rename to alt-trees/spi-i2c/mqpro-spi-i2c.dts index a03ea4e..9ed03cf 100644 --- a/alt-trees/spi_i2c/mqpro-spi-i2c.dts +++ b/alt-trees/spi-i2c/mqpro-spi-i2c.dts @@ -211,10 +211,108 @@ pins = "PB4", "PB5"; function = "uart5"; }; + + /omit-if-no-ref/ + pwm0_pb5_pin: pwm0-pb5-pin { + pins = "PB5"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pb12_pin: pwm0-pb12-pin { + pins = "PB12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm0_pg12_pin: pwm0-pg12-pin { + pins = "PG12"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm1_pb6_pin: pwm1-pb6-pin { + pins = "PB6"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm1_pd17_pin: pwm1-pd17-pin { + pins = "PD17"; + function = "pwm1"; + }; + + /omit-if-no-ref/ + pwm2_pb11_pin: pwm2-pb11-pin { + pins = "PB11"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm2_pg13_pin: pwm2-pg13-pin { + pins = "PG13"; + function = "pwm2"; + }; + + /omit-if-no-ref/ + pwm3_pb0_pin: pwm3-pb0-pin { + pins = "PB0"; + function = "pwm3"; + }; + + /omit-if-no-ref/ + pwm4_pb1_pin: pwm4-pb1-pin { + pins = "PB1"; + function = "pwm4"; + }; + + /omit-if-no-ref/ + pwm5_pb8_pin: pwm5-pb8-pin { + pins = "PB8"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm5_pd21_pin: pwm5-pd21-pin { + pins = "PD21"; + function = "pwm5"; + }; + + /omit-if-no-ref/ + pwm6_pb9_pin: pwm6-pb9-pin { + pins = "PB9"; + function = "pwm6"; + }; + + /omit-if-no-ref/ + pwm7_pb10_pin: pwm7-pb10-pin { + pins = "PB10"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pd22_pin: pwm7-pd22-pin { + pins = "PD22"; + function = "pwm7"; + }; + + /omit-if-no-ref/ + pwm7_pe16_pin: pwm7-pe16-pin { + pins = "PE16"; + function = "pwm7"; + }; }; +/* disabled +&pwm { + pinctrl-0 = <&pwm0_pb12_pin>, <&pwm1_pb6_pin>, <&pwm2_pb11_pin>, <&pwm4_pb1_pin>; + pinctrl-names = "default"; + status = "okay"; +}; +*/ + &spi1 { - pinctrl-0 = <&spi1_pd_pins>; // conflicts uart3 + pinctrl-0 = <&spi1_pd_pins>; // can conflict uart3 pinctrl-names = "default"; status = "okay"; }; @@ -226,7 +324,7 @@ }; &i2c1 { - pinctrl-0 = <&i2c1_pb4_pins>; // conflicts uart5 + pinctrl-0 = <&i2c1_pb4_pins>; // can conflict uart5 pinctrl-names = "default"; status = "okay"; }; @@ -239,7 +337,7 @@ /* disabled &i2c2 { - pinctrl-0 = <&i2c2_pc0_pins>; // conflicts uart2 + pinctrl-0 = <&i2c2_pc0_pins>; // can conflict uart2 pinctrl-names = "default"; status = "okay"; }; @@ -277,7 +375,7 @@ status = "okay"; }; -/* Disabled +/* disabled &uart3 { uart-has-rtscts; pinctrl-0 = <&uart3_pd10_pins>, <&uart3_pd13_rts_cts_pins>; // conflicts spi1 @@ -298,7 +396,7 @@ status = "okay"; }; -/* Disabled +/* disabled &uart5 { pinctrl-0 = <&uart5_pb4_pins>; // conflicts i2c1 pinctrl-names = "default"; diff --git a/build-trees/README.md b/build-trees/README.md index f27c8ab..9144535 100644 --- a/build-trees/README.md +++ b/build-trees/README.md @@ -1,6 +1,6 @@ # Building and installing custom device trees. -This folder contains a `make-trees` script that can build device tree source (`.dts`) files against the correct upstream headers and device tree includes. +This folder contains a `make_dtbs` script that can build device tree source (`.dts`) files against the correct upstream headers and device tree includes. ## Preparation / requirements @@ -34,9 +34,10 @@ You should see a load of new (source) repos being updated, it is slow, let it fi ### Get the linux sources This should be done as a normal user -- Note that the command used here `apt source` will download the sources to the current working folder, not a fixed location, and is intended to be run as a normal user. +- Note that the command used here `apt source` will download the sources to the current working folder, not a fixed location +- It is run as a normal user, not root. -We download the sources into the [sources](../sources) repo in this folder: +We download the sources into the [sources](../sources) folder: ```text $ cd source $ apt source linux-riscv @@ -50,17 +51,19 @@ You can re-run the `apt source` command in this folder and it will only download ------------------------------------------- # Building the device tree(s) -Build the sources as a normal user (the same user used to fetch the sources above), in this folder. +Run the build as a normal user (the same user used to fetch the sources above). +- Put your custom `.dts` in this folder. +- This folder also contains the necesscary softlinks to the include files in the source tree we just downloaded. #### Terms * `.dts` is a top-level Device Tree Source file. -* `.dtsi` is a include file for the `.dts` +* `.dtsi` is an include file for the `.dts` * `.dtb` is the binary compiled device tree, this is what we are building here, and is supplied to the kernel at boot time. ## device tree sources -By default the standard `sun20i-d1-mangopi-mq-pro.dts` file from the Ubuntu source is linked here. +For convenience, the default `sun20i-d1-mangopi-mq-pro.dts` file from the Ubuntu source is also linked here. -Rather than modifying the default tree you should copy it to a custom name, eg 'my-project-mqpro.dts'. Or you can copy in examples from the [alt-trees](../alt-trees/) folder. +Rather than modifying the default tree you should copy it to a custom name, eg 'my-project.dts'. Or you can copy in examples from the [alt-trees](../alt-trees/) folder. A full-on tutorial for device tree editing is far beyond the scope of both this document and author. * The examples show some simple custom modifications. @@ -69,17 +72,19 @@ A full-on tutorial for device tree editing is far beyond the scope of both this ## Compile the mq-pro dts with the current kernel headers -To compile all the includes and sources simply run `make-trees.sh`. +To compile all the includes and sources simply run `make_dtbs.sh`. This will: -* Create an output folder named after the kernel version, or clean an existing output folder. -* Pre-compile all the source and include files in the current folder into the output folder using the current kernel headers. -* In the output folder it then compiles *all* the `.dts` files present, and prefixes the output `.dtb` files with the kernel version. +* Pre-compile all the source and include files in the current folder into the output folder using the correct kernel headers. +* In the output folder it then compiles *all* the `.dts` files present. ```console -$ ./make_dtb.sh +$ ./make_dtbs.sh +Building for kernels: 6.8.0-41-generic + +Cleaning existing 6.8.0-41-generic build directory + Compiling against headers for 6.8.0-41-generic -Creating new build directory: 6.8.0-41-generic Precompiling all includes in build root into 6.8.0-41-generic build directory sun20i-common-regulators.dtsi -> 6.8.0-41-generic/sun20i-common-regulators.dtsi sun20i-d1.dtsi -> 6.8.0-41-generic/sun20i-d1.dtsi @@ -87,23 +92,30 @@ Precompiling all includes in build root into 6.8.0-41-generic build directory sunxi-d1-t113.dtsi -> 6.8.0-41-generic/sunxi-d1-t113.dtsi sunxi-d1s-t113.dtsi -> 6.8.0-41-generic/sunxi-d1s-t113.dtsi Precompiling all sources in build root into 6.8.0-41-generic build directory - my-project-mqpro.dts -> 6.8.0-41-generic/my-project-mqpro.dts + my-project.dts -> 6.8.0-41-generic/my-project.dts sun20i-d1-mangopi-mq-pro.dts -> 6.8.0-41-generic/sun20i-d1-mangopi-mq-pro.dts Compiling all device tree sources in 6.8.0-41-generic build directory - 6.8.0-41-generic/my-project-mqpro.dts -> 6.8.0-41-generic/6.8.0-41-generic-my-project-mqpro.dtb - 6.8.0-41-generic/sun20i-d1-mangopi-mq-pro.dts -> 6.8.0-41-generic/6.8.0-41-generic-sun20i-d1-mangopi-mq-pro.dtb + 6.8.0-41-generic/my-project.dts -> 6.8.0-41-generic/my-project.dtb + 6.8.0-41-generic/sun20i-d1-mangopi-mq-pro.dts -> 6.8.0-41-generic/sun20i-d1-mangopi-mq-pro.dtb + +Success. Consider running 'flash_latest.sh' to make permanent (see docs) ``` +The `6.8.0-41-generic` folder now has our device tree: `my-project.dtb` +- We also generate the default device tree, this can be ignored. + +The tool builds for *all* the kernels available on the system, not just the running kernel. +- As new kernels are updated the list of 'available' kernels will increase. ----------------------- # Test Installing self-built DTB's +If this is the first time the tree is compiled after modifying it may be a good idea to do a 'quick' test that it boots properly before making it permanent. ### Move dtb into the boot tree -* move the `.dtb` file into the `/boot` folder: eg: `$ sudo mv 6.8.0-41-generic-my-project-mqpro.dtb /boot/dtbs` -* make a soft link in `/boot` to this: `$ sudo ln -s dtbs/6.8.0-41-generic-my-project-mqpro.dtb /boot/dtb-mqpro` +* move the `.dtb` file into the `/boot` folder: eg: `$ sudo mv 6.8.0-41-generic/my-project.dtb /boot/dtbs` +* make a soft link in `/boot` to this: `$ sudo ln -s dtbs/my-project.dtb /boot/dtb-mqpro` ### Set up Grub to test boot the new DTB -Initially we will test the new dtb: * backup the grub config: `$ sudo cp /etc/grub/grub.cfg /etc/grub/grub.cfg.mybackup` * `$ sudo vi /etc/grub/grub.cfg` (or use nano if you prefer) * Find the 1st `menuentry` section (the default Ubuntu one) and edit the `devicetree` line to look like: @@ -112,64 +124,77 @@ devicetree /boot/dtb-mqpro ``` * Reboot (`$ sudo reboot`) * If the reboot fails you can either attach a serial adapter to the GPIO pins and select the fallback kernel from the advanced options menu, and then restore the grub config backup once logged in. - Or (if no serial available) remove the SD card, mount it on another computer and restore the file there. + Or (if no serial available) remove the SD card, mount it on another (unix) computer and restore the grub config there. -After rebooting you can run **list-pins.py** (see below) to verify the new mappings. - -If you have errors rebooting (maybe a corrupt file if you rebuilt it etc..) you need to either boot using a USB serial adapter on the console pins and select the recovery image, or, in grub, edit the command and revert to the generic `/boot/dtb`. -As a last resort you may have to remove the SD card, mount the `/boot` partition and edit `grub/grub.cfg` there. -* !! The 'default' dtb supplied by ubuntu should always be softlinked as `/boot/dtb`, so putting `devicetree /boot/dtb` in grub in place of the custom `.dtb` should work and is predictable (no version numbers etc). - -## Examining the DTB pin mappings with `list-pins.py` -In the [tools](../tools) folder there is a python script called `list-pins.py`. - -To run the pin list tool you need to be in the tools directory, then run: -```console -$ python3 list-pins.py MangoPi-MQ-Pro -``` -* The script requires root acces (via sudo) to read the pin maps. -* Running the script produces the same map I use in this documentation. -* The data used to assemble the `.gpio` map files identifies which interface a pin is attached to, but not it's specific function for the interface. - * eg it can say 'pinX and pinY are mapped to UART2', but cannot identify which pin is the TX and which is the RX; a limitation of the data, my apologies.. - * You therefore need to reference the [D1 pin mapping table](../reference/d1-pins.pdf) to get the exact functions for pins when running this for yourself. -* The README files uploaded for alternate device trees *have been manually edited* to note full pin function for convenience. +After rebooting you can run **list-pins.py** to verify the new mappings. +* See the README in the [tools](../tools) folder for usage. ### Cleanup test Once you are happy with the test you should make the change permanent as described below. * Before you do the permanent install you *must* restore the backup copy of the grub config: `$ sudo mv /etc/grub/grub.cfg.mybackup /etc/grub/grub.cfg` -* Once that is done you can also clean up any test `.dtb` files you manually placed in `/boot/`, and the softlink to them. -* *Do not remove the files without restoring the grub config, it will leave the system unbootable!* - +* Once that is done you can also clean up the `.dtb` file you manually placed in `/boot/`, and the softlink to it. + * *Do not remove the device tree file without restoring the grub config, it will leave the system unbootable!* + ---------------------------------------------------- # Making Permanent: -We can use [flash-kernel](https://github.com/ubports/flash-kernel) to permanently apply our custom device tree. *Flash-kernel* allows an 'override' device tree to be specified that will be used in place of the tree provided by the linux firmware package. +We can use [flash-kernel](https://github.com/ubports/flash-kernel) to permanently apply our custom device tree. +* *Flash-kernel* normally searches in the linux firmware library to select the matching kernel version of the `.dtb` file for the machine (as specified in the database). +* But if a file of the same name is found in the `dtbs` override directory this will be used instead. -*Flash-kernel* normally searches in the linux firmware library to select the matching kernel version of the `.dtb` file for the machine (as specified in the database). But if a file of the same name is found in the `dtbs` override directory this will be used instead. - -If we soft-link our custom `.dtb` file from this directory and re-run `flash-kernel` it will be installed to the `/boot/dtbs/` tree and used at next boot. -- As with all the device tree tests above an error here might produce an unbootable machine! +## Configure `flash-kernel` for the cusom device tree file +Similar to the way we reconfigured *flash-kernel* to use the MQ Pro device tree in the install guide, we can also configure it to use our custom kernel. +Add a new entry to `/etc/flash-kernel/db`: ```text -$ cd /etc/flash-kernel/dtbs/ -$ sudo ln -s /home//MQ-Pro-IO/build-trees/6.8.0-41-generic/6.8.0-41-generic-my-project-mqpro.dtb sun20i-d1-mangopi-mq-pro.dtb +# Custom project entry +Machine: My Project +Kernel-Flavors: any +DTB-Id: custom/my-project.dtb +Boot-Script-Path: /boot/boot.scr +U-Boot-Script-Name: bootscr.uboot-generic +Required-Packages: u-boot-tools ``` -In this example I am soft linking directly to the `.dtb` I built. +Note that we specify `custom` in the DTB-Id instead of 'allwinner', this helps keep our trees apart from the vanilla (Ubuntu) ones in the boot tree. -Run `flash-kernel` again: you will see the overide being applied. +Edit `/etc/flash-kernel/machine` to match the machine name in the definition: ```console -$ sudo flash-kernel -Using DTB: allwinner/sun20i-d1-mangopi-mq-pro.dtb -Installing /etc/flash-kernel/dtbs/sun20i-d1-mangopi-mq-pro.dtb into /boot/dtbs/6.8.0-41-generic/allwinner/sun20i-d1-mangopi-mq-pro.dtb -Taking backup of sun20i-d1-mangopi-mq-pro.dtb. -Installing new sun20i-d1-mangopi-mq-pro.dtb. +$ sudo mv /etc/flash-kernel/machine /etc/flash-kernel/machine.vanilla +$ sudo sh -c "echo 'My Project' > /etc/flash-kernel/machine" +``` +Running *flash-kernel* immediately after this will fail since it cannot yet find the `.dtb` file specified in the database. +- We need to copy the `.dtb` to `/etc/flash-kernel/dtbs` first. + +## Copying and flashing the device tree file +Run `flash_latest.sh`, this will ask you to confirm which kernel version you want to copy from. +- It defaults to the current running kernel. +- When upgrading this allows you to precompile and install the correct DTB in advance before rebooting into the new kernel. + +```console +$ ./flash_latest.sh + +Available kernels: + [1] 6.8.0-41-generic - currently running kernel +Which kernel to link? [1]: + +Cleaning '/etc/flash-kernel/dtbs/' and copying in device tree binaries from '6.8.0-41-generic/' + /home/owen/MQ-Pro-IO/build-trees/6.8.0-41-generic/my-project.dtb --> /etc/flash-kernel/dtbs/my-project.dtb + /home/owen/MQ-Pro-IO/build-trees/6.8.0-41-generic/sun20i-d1-mangopi-mq-pro.dtb --> /etc/flash-kernel/dtbs/sun20i-d1-mangopi-mq-pro.dtb +Run 'flash-kernel' to apply device tree? [Y]: + +Using DTB: custom/my-project.dtb +Installing /etc/flash-kernel/dtbs/my-project.dtb into /boot/dtbs/6.8.0-41-generic/custom/my-project.dtb +Taking backup of my-project.dtb. +Installing new my-project.dtb. System running in EFI mode, skipping. + +If flash-kernel was successful and configured properly the new device tree will be used after reboot ``` After this, reboot to use the new device tree. -A *flash-kernel* installs a full copy of the `.dtb` into the `/boot/` area, so deleting or moving the build folder will not 'break' bootup, but it *will* break kernel image rebuilds when `dpkg` tries to re-run the *flash-kernel* command and the softlink target has disappeared. Be warned! +It is good practice to update the dtb when new kernels become available. But Ubuntu 24.04.1 is a LTS release, and the DTB should be stable going forward so you may not find it necesscary. -It is good practice to keep the build repo and (periodically) update the dtb when new kernels becme available. But Ubuntu 24.04.1 is a LTS release, and the DTB should be stable going forward so you may not find it necesscary. +To Update, re-fetch the latest sources (see above), then re-run `make_dtbs.sh` and `flash_latest.sh`. -------------------------------------------------------------------------- @@ -181,4 +206,3 @@ It is good practice to keep the build repo and (periodically) update the dtb whe Device Tree that is used in the official armbian image? - https://github.com/smaeul/u-boot/tree/329e94f16ff84f9cf9341f8dfdff7af1b1e6ee9a/arch/riscv/dts - diff --git a/build-trees/flash_latest.sh b/build-trees/flash_latest.sh new file mode 100755 index 0000000..b166429 --- /dev/null +++ b/build-trees/flash_latest.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# Allows the user to choose a kernel version and copies .dtb files to /etc/flash-kernel +# - defaults to current highest available kernel version +# + +cdir=`pwd` +versions=`dpkg --list | grep linux-image-[0-9].* | cut -d" " -s -f 3 | sed s/^linux-image-// | sort -V` +current=`/usr/bin/uname -r` +out=/etc/flash-kernel/dtbs + +echo -e "\nAvailable kernels:" +option=0 +declare -a klist +for ver in $versions ; do + option=$((option+1)) + klist[$option]=$ver + echo -n " [$option] $ver" + if [ $ver == $current ] ; then + echo " - currently running kernel" + else + echo + fi +done + +read -p "Which kernel to link? [$option]: " choice +if [ -z "$choice" ] ; then choice=$option ; fi +echo + +revision=${klist[$choice]} +if [ -z "$revision" ] ; then + echo "No valid kernel selected, exiting." + exit +fi + +if [ -d "$revision" ]; then + echo -e "Cleaning '$out/' and copying in device tree binaries from '$revision/'" + sudo rm -f $out/*.dtb $out/origin* +else + echo "No builds found for selected kernel version: $revision" + echo " Try running ./make_trees.sh to generate them" + exit 1 +fi + +for file in `cd "$revision" ; ls *.dtb`; do + echo " $cdir/$revision/$file --> $out/$file" + sudo cp $cdir/$revision/$file $out +done + +# Add a link to the output folder.. +sudo ln -s $cdir/$revision $out/origin:$revision + +echo +read -p "Run 'flash-kernel' to apply device tree? [Y]: " choice +if [[ "$choice" == [Yy]* ]] || [ -z "$choice" ] ; then + sudo flash-kernel + echo -e "\nIf flash-kernel was successful and configured properly the new device tree will be used after reboot" +else + echo "The new device tree will be used the next time flash-kernel is run" +fi +# fin diff --git a/build-trees/make_dtb.sh b/build-trees/make_dtb.sh deleted file mode 100755 index b1536a7..0000000 --- a/build-trees/make_dtb.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Takes a list of dts files for the specified architecture and emits appropriate compiled dtb files for use in customised deviceTree setups. -# - -dtc=/usr/bin/dtc -revision=`/usr/bin/uname -r` -# alt=../alt-trees -- disabled auto building of all alt trees, better to do individually - -echo "Compiling against headers for $revision" - -if [ -d "$revision" ]; then - echo "Cleaning and Using existing build directory" - rm $revision/*.dts $revision/*.dtsi $revision/*.dtb -else - echo "Creating new build directory: $revision" - mkdir "$revision" -fi - -#echo "Copying custom dts sources to build root" -#for dts in `ls -d $alt/*/*.dts`; do -# echo "$dts" -# cp $dts . -#done - -echo "Precompiling all includes in build root into $revision build directory" -for file in `ls *.dtsi`; do - echo " $file -> $revision/${file##*/}" - cpp -I/usr/src/linux-headers-$revision/include/ -nostdinc -undef -x assembler-with-cpp $file > $revision/${file##*/} -done - -echo "Precompiling all sources in build root into $revision build directory" -for file in `ls *.dts`; do - echo " $file -> $revision/${file##*/}" - cpp -I/usr/src/linux-headers-$revision/include/ -nostdinc -undef -x assembler-with-cpp $file > $revision/${file##*/} -done - -echo "Compiling all device tree sources in $revision build directory" -cd $revision -for file in `ls *.dts`; do - out=${file/.dts/.dtb} - echo " $revision/$file -> $revision/$revision-$out" - $dtc $file > $revision-$out -done diff --git a/build-trees/make_dtbs.sh b/build-trees/make_dtbs.sh new file mode 100755 index 0000000..11e820a --- /dev/null +++ b/build-trees/make_dtbs.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# Takes a list of dts files for the specified architecture and emits appropriate compiled dtb files for use in customised deviceTree setups. +# + +dtc=/usr/bin/dtc + +cdir=`pwd` +versions=`dpkg --list | grep linux-image-[0-9].* | cut -d" " -s -f 3 | sed s/^linux-image-// | sort -V` + +echo -ne "\nBuilding for kernels: " +echo `echo $versions | sed "s/ /, /g"` +echo + +# Disabled auto building of all alt trees, better to do individually +#alt=../alt-trees +#echo "Linking alt dts sources to build root" +#for dts in `ls -d $alt/*/*.dts`; do +# echo "$dts" +# ln -s "$dts" . +#done + +# Ensure sure build roots exist and are clean +for revision in $versions ; do + if [ -d "$cdir/$revision" ]; then + echo "Cleaning existing $revision build directory" + rm -f $revision/*.dts $revision/*.dtsi $revision/*.dtb + else + echo "Creating new build directory: $revision" + mkdir $revision + fi +done + +# Compile for each revision +for revision in $versions ; do + cd $cdir + echo -e "\nCompiling against headers for $revision" + echo "Precompiling all includes in build root into $revision build directory" + for file in `ls *.dtsi`; do + echo " $file -> $revision/${file##*/}" + cpp -I/usr/src/linux-headers-$revision/include/ -nostdinc -undef -x assembler-with-cpp $file > $revision/${file##*/} + if [ ! -s "$revision/${file##*/}" ] ; then + rm "$revision/${file##*/}" + echo "**** ERROR ****" + echo "Precompile failed for include: $revision/${file##*/}" + exit 1 + fi + done + + echo "Precompiling all sources in build root into $revision build directory" + for file in `ls *.dts`; do + echo " $file -> $revision/${file##*/}" + cpp -I/usr/src/linux-headers-$revision/include/ -nostdinc -undef -x assembler-with-cpp $file > $revision/${file##*/} + if [ ! -s "$revision/${file##*/}" ] ; then + rm "$revision/${file##*/}" + echo "**** ERROR ****" + echo "Precompile failed for source: $revision/${file##*/}" + exit 1 + fi + done + + echo "Compiling all device tree sources in $revision build directory" + cd $revision + for file in `ls *.dts`; do + out=${file/.dts/.dtb} + echo " $revision/$file -> $revision/$out" + $dtc $file > $out + if [ ! -s "$out" ] ; then + rm "$out" + echo "**** ERROR ****" + echo "Compile failed for: $out" + exit 1 + fi + done +done + +echo -e "\nSuccess. Consider running 'flash_latest.sh' to make permanent (see docs)" diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 0000000..0f35d79 --- /dev/null +++ b/tools/README.md @@ -0,0 +1,49 @@ +## `list-pins.py` +This is a tool that displays a ascii-art 'map' of the current pinmux assignments on the GPIO header + +To run the pin list tool you need to be in the tools directory, then run: +```console +$ python3 list-pins.py MangoPi-MQ-Pro +``` +* The script requires root acces (via sudo) to read the pin maps. +* Running the script produces the same map I use in this documentation. +* The data used to assemble the `.gpio` map files identifies which interface a pin is attached to, but not it's specific function for the interface. + * eg it can say 'pinX and pinY are mapped to UART2', but cannot identify which pin is the TX and which is the RX; a limitation of the data, my apologies.. + * You therefore need to reference the [D1 pin mapping table](../reference/d1-pins.pdf) to get the exact functions for pins when running this for yourself. + + +### Default output +This is the default output for the MQ-Pro with the default device tree: +``` + MangoPI MQ Pro GPIO header (dtb name: MangoPi MQ Pro) + +Gpio Header: + func des pin pin des func + 3v3 1 --o o-- 2 5v + free (205) PG13 3 --o o-- 4 5v + free (204) PG12 5 --o o-- 6 gnd + free (39) PB7 7 --o o-- 8 PB8 uart0 (2500000.serial:40) + gnd 9 --o o-- 10 PB9 uart0 (2500000.serial:41) + free (117) PD21 11 --o o-- 12 PB5 free (37) + free (118) PD22 13 --o o-- 14 gnd + free (32) PB0 15 --o o-- 16 PB1 free (33) + 3v3 17 --o o-- 18 PD14 free (110) + free (108) PD12 19 --o o-- 20 gnd + free (109) PD13 21 --o o-- 22 PC1 free (65) + free (107) PD11 23 --o o-- 24 PD10 free (106) + gnd 25 --o o-- 26 PD15 free (111) + free (145) PE17 27 --o o-- 28 PE16 free (144) + free (42) PB10 29 --o o-- 30 gnd + free (43) PB11 31 --o o-- 32 PC0 free (64) + free (44) PB12 33 --o o-- 34 gnd + free (38) PB6 35 --o o-- 36 PB2 free (34) + free (113) PD17 37 --o o-- 38 PB3 free (35) + gnd 39 --o o-- 40 PB4 free (36) + +Other gpio outputs of interest: +-- PD18: Blue Status Led - gpio (2000000.pinctrl:114) + +Notes: +- I2C pins 3,5,27 and 28 (PG13, PG12, PE17 and PE16) have 10K pullup resistors to 3v3 +- The Status LED (PD18) is common with the LED_PWM pin on the DSI/LVDS output +``` diff --git a/tools/list-pins.py b/tools/list-pins.py index b1b6ae2..7d3b97a 100644 --- a/tools/list-pins.py +++ b/tools/list-pins.py @@ -1,7 +1,7 @@ from subprocess import run,PIPE from importlib import import_module from sys import path,argv -path.append('maps') +from pathlib import Path ''' Gathers the pinmux table and parses it's output to a more human form, with pin designator included @@ -13,7 +13,12 @@ if len(argv) == 2: model = argv[1] else: model = dtname + +source_path = Path(__file__).resolve() +source_dir = source_path.parent +path.append(str(source_dir) + '/maps') board = import_module(model.replace(' ','-')) + muxindex = [pin[0] for pin in board.gpio] for pin in board.gpio: pin.append('')