MikroElektronika Click Boards
Using MIKROE Click Boards on embeddedTS Platforms
What Are Click Boards™?
Click boards™ are a standardized format introduced by MikroElektronika (MIKROE) that conform to their mikroBUS™ interface. The mikroBUS interface is intended to standardize a physical and electrical interface for add-on boards. The standard specifies the physical layout of the mikroBUS pinout, the communication and power supply pins used, the size and shape of the add-on boards, the positioning of the mikroBUS socket on the mainboard, and finally, the silkscreen marking conventions for both the add-on boards and sockets. mikroBUS pinout is comprised of three groups of communication buses (SPI, UART, and I2C), six additional pins (PWM, Interrupt, Analog input, Reset, and Chip select), and two power groups (+3.3 V and +5 V).
The Click board standard conforms to the above mikroBUS standard while also defining the physical envelope of Click boards.
MIKROE currently offers 1,700+ official Click boards, as well as openly defines both the mikroBUS and Click board standards to allow others to create devices that can function within the ecosystem.
Which embeddedTS Platforms Support Click Boards™?
Currently, our TS-7250-V3 platform is our only shipping platform that offers a socket specifically for MIKROE Click boards™.
We have platforms in the pipeline that will include mikroBUS™ support, and on existing platforms it is possible to create a compatible interface for many Click boards using just GPIO. This is because the Linux kernel can support creating many interfaces, SPI, I2C, and even PWM (with some limitations) using GPIO resources rather than specific peripherals.
Which Click Boards™ Are Supported?
This is difficult to answer thanks to the immense lineup of devices that MIKROE offers. In general, nearly every Click board™ can be used; however if the Click board uses a controller that Linux does not have a driver for, it would be up to the user to either create a driver or interact with the controller from userspace. The best compatibility can be obtained by looking for devices that are listed with support in click_info.csv
file from MIKROE's click_id Github repository: https://github.com/MikroElektronika/click_id/blob/main/click_info.csv
Devices listed above are known working and will either ship with a populated ClickID manifest on the Click board (more on ClickID and manifests later) and/or will have manifest sources available in the aforementioned Github repository.
A list of Click boards with ClickID that ship with a populated manifest on to them and are ready for full auto-detection support can be found on MIKROE's website: https://www.mikroe.com/click?feature*=clickid-manifest,clickid-manifest
Outside of Click boards listed in either location above, support for individual Click boards can be evaluated by examining the controller and interface used by the Click board, and referencing Linux driver support for that specific controller.
Interfacing Click Boards™ with Linux
Manual Devicetree Setup
Devices on non-discoverable busses such as UART, SPI, I2C are connected to the kernel via devicetree: https://www.kernel.org/doc/html/latest/devicetree/usage-model.html
The devicetree model allows for a compile-time description of what devices are connected in the system and where they can be found.
Currently, using a manual devicetree setup for connecting a Click board™ to the kernel is going to offer the widest support at the expense of Click boards not being plug-and-play. Testing new devices requires taking the time to modify the devicetree to describe the hardware that is connected.
Tested Examples on the TS-7250-V3
Below are devicetree patch examples from a handful of Click boards™ that we have tested on the TS-7250-V3. The examples are based on our linux-6.6.y kernel but should apply easily to newer kernels as well. Backporting these to the linux-5.10.y kernel is also possible, but the devicetree locations have changed between 5.10 and 6.6.
Ambient 2 Click
The Ambient 2 Click is based on an OPT3001 ambient light sensor which measures illuminance of the visible light spectrum in lux
.
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
index bc4dc1b04fae9..683c66301111f 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
@@ -739,6 +739,13 @@ mikro_i2c: mikro_i2c@188 {
clock-names = "i2c-oc-clk";
reg-io-width = <1>;
reg-shift = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ light-sensor@44 {
+ compatible = "ti,opt3001";
+ reg = <0x44>;
+ };
};
mikro_pwm: mikro_pwm@1a8 {
diff --git a/arch/arm/configs/tsimx6ul_defconfig b/arch/arm/configs/tsimx6ul_defconfig
index 956896ab6048f..5973dbba3478a 100644
--- a/arch/arm/configs/tsimx6ul_defconfig
+++ b/arch/arm/configs/tsimx6ul_defconfig
@@ -843,6 +843,7 @@ CONFIG_VF610_ADC=y
CONFIG_INV_MPU6050_I2C=m
CONFIG_IIO_ST_LSM6DSX=m
CONFIG_SENSORS_ISL29018=y
+CONFIG_OPT3001=m
CONFIG_AK8975=m
CONFIG_MAG3110=y
CONFIG_IIO_ST_MAGN_3AXIS=m
Once loaded, the ambient measured light can be read from the corresponding IIO device, for example:
root@tsimx6ul:~# cat /sys/bus/iio/devices/iio\:device5/in_illuminance_input
87.240000 # Value while in the middle of the room
root@tsimx6ul:~# cat /sys/bus/iio/devices/iio\:device5/in_illuminance_input
248.960000 # Value with some light directed at the sensor
root@tsimx6ul:~# cat /sys/bus/iio/devices/iio\:device5/in_illuminance_input
2.410000 # Value with the lens covered
root@tsimx6ul:~# cat /sys/bus/iio/devices/iio\:device5/in_illuminance_input
83865.600000 # Value with high-power flashlight pointed directly at the sensor
ISO ADC 6 Click
The ISO ADC 6 Click offers 8 to 15 channels of isolated ADC using an AD7124-8 controller.
Note: | Some additional wiring is needed, and a small modification is required when using this Click board™ with the TS-7250-V3. Please read the following carefully. |
As this device contains an isolation barrier, the GND2
and VIN
pins on the external pin header need to be connected to ground and 3.3 V otherwise the actual ADC device will not receive power. These can be wired to the same ground and 3.3 V that is available on the TS-7250-V3, but are designed to be connected to a remote source to provide digital isolation via the Click board's ADuM341E isolator.
Additionally, the AD7124-8 uses the SPI POCI (peripheral-out, controller-in) data pin to signal an interrupt to the host. The POCI pin on the TS-7250-V3's mikroBUS™ socket is not capable of interrupt handling, and a jumper needs to be soldered between the pin labeled SDO
and what is normally the mikroBUS INT
pin as shown in the photo below.
The devicetree setup uses 15 pseudo-single-ended unipolar ADC channels, using pin A15
as the common ground for all other channels. It is possible to configure any number of channels between 8 and 15 as differential pairs, in unipolar or bipolar operation.
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
index 48e38bd6a948..6690b95c0d78 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
@@ -79,6 +79,13 @@ vref_adc_2v5: adc {
regulator-max-microvolt = <2500000>;
};
+ ad7124_refout: ad7124-vref {
+ compatible = "regulator-fixed";
+ regulator-name = "AD7124_VREF";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
an_3p3v: an_3p3v {
compatible = "voltage-divider";
io-channels = <&supervisor_adc 0>;
@@ -106,6 +113,14 @@ an_8v_48v: an_8v_48v {
#io-channel-cells = <0>;
};
+ /* Fixed clock used for forcing the internal clock on the ADC */
+ ad7124_clk: fixed-clk@0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <614400>;
+ clock-accuracy = <50000000>; // +- 5%
+ };
+
/*
* At the time of writing, there is a locking bug when using AFE channels
* that can be consumed within the kernel. The hwmon device is disabled
@@ -716,10 +731,100 @@ opencores_spi1: spi@120 {
opencores-spi,idx = <0>;
opencores-spi,num-chipselects = <1>;
- mikrobus: spi@0 {
- compatible = "technologic,spi-header";
- spi-max-frequency = <19800000>;
+ /* The following is set up for ISO ADC 6 Click
+ * This assumes A15 is common ground for all
+ * channels, pseudo differential mode. It also
+ * requires VIN connected to 3.3 V, but there isn't
+ * a clean way to do that on the board, which
+ * makes sense as it is meant to be isolated.
+ */
+ ad7124: adc@0 {
+ compatible = "adi,ad7124-8";
reg = <0>;
+ spi-max-frequency = <1000000>;
+ clocks = <&ad7124_clk>;
+ clock-names = "mclk";
+ refin1-supply = <&ad7124_refout>;
+ interrupt-parent = <&fpga_intc>;
+ interrupts = <18 IRQ_TYPE_EDGE_FALLING>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ channel@0 {
+ reg = <0>;
+ diff-channels = <0 15>;
+ };
+
+ channel@1 {
+ reg = <1>;
+ diff-channels = <1 15>;
+ };
+
+ channel@2 {
+ reg = <2>;
+ diff-channels = <2 15>;
+ };
+
+ channel@3 {
+ reg = <3>;
+ diff-channels = <3 15>;
+ };
+
+ channel@4 {
+ reg = <4>;
+ diff-channels = <4 15>;
+ };
+
+ channel@5 {
+ reg = <5>;
+ diff-channels = <5 15>;
+ };
+
+ channel@6 {
+ reg = <6>;
+ diff-channels = <6 15>;
+ };
+
+ channel@7 {
+ reg = <7>;
+ diff-channels = <7 15>;
+ };
+
+ channel@8 {
+ reg = <8>;
+ diff-channels = <8 15>;
+ };
+
+ channel@9 {
+ reg = <9>;
+ diff-channels = <9 15>;
+ };
+
+ channel@10 {
+ reg = <10>;
+ diff-channels = <10 15>;
+ };
+
+ channel@11 {
+ reg = <11>;
+ diff-channels = <11 15>;
+ };
+
+ channel@12 {
+ reg = <12>;
+ diff-channels = <12 15>;
+ };
+
+ channel@13 {
+ reg = <13>;
+ diff-channels = <13 15>;
+ };
+
+ channel@14 {
+ reg = <14>;
+ diff-channels = <14 15>;
+ };
};
};
diff --git a/arch/arm/configs/tsimx6ul_defconfig b/arch/arm/configs/tsimx6ul_defconfig
index fb4aea96e3ea..b8e670ccc247 100644
--- a/arch/arm/configs/tsimx6ul_defconfig
+++ b/arch/arm/configs/tsimx6ul_defconfig
@@ -846,6 +846,7 @@ CONFIG_COMMON_CLK_PWM=y
CONFIG_IMX_GPCV2_PM_DOMAINS=y
CONFIG_IIO=y
CONFIG_MMA8452=y
+CONFIG_AD7124=m
CONFIG_TS_SIMPLEADC=y
CONFIG_TS_SUPERVISOR_ADC=y
CONFIG_VF610_ADC=y
diff --git a/drivers/irqchip/irq-ts71xxweim.c b/drivers/irqchip/irq-ts71xxweim.c
index a08ac179ae78..3d57683d4aa2 100644
--- a/drivers/irqchip/irq-ts71xxweim.c
+++ b/drivers/irqchip/irq-ts71xxweim.c
@@ -48,9 +48,11 @@ static int tsweim_intc_set_type(struct irq_data *d, unsigned int flow_type)
switch (flow_type) {
case IRQ_TYPE_LEVEL_LOW:
+ case IRQ_TYPE_EDGE_FALLING:
polarity |= bit;
break;
case IRQ_TYPE_LEVEL_HIGH:
+ case IRQ_TYPE_EDGE_RISING:
polarity &= ~bit;
break;
default:
Once connected to the system, the channels can be read using iio_attr
, for example:
root@tsimx6ul:~# iio_attr -c ad7124-8 voltage0-voltage15
dev 'ad7124-8', channel 'voltage0-voltage15' (input), attr 'filter_low_pass_3db_frequency', value '3'
dev 'ad7124-8', channel 'voltage0-voltage15' (input), attr 'offset', value '0'
dev 'ad7124-8', channel 'voltage0-voltage15' (input), attr 'raw', value '0'
dev 'ad7124-8', channel 'voltage0-voltage15' (input), attr 'sampling_frequency', value '10'
dev 'ad7124-8', channel 'voltage0-voltage15' (input), attr 'scale', value '0.000149011'
dev 'ad7124-8', channel 'voltage0-voltage15' (input), attr 'scale_available', value '0.000001164 0.000002328 0.000004656 0.000009313 0.000018626 0.000037252 0.000074505 0.000149011 0.000298023'
Relay 5 Click
The Relay 5 Click is based on a PCA9538 GPIO controller with 3x J1031C3VDC.15S relays. The relays are able to switch up to 125 VAC / 60 VDC at 2 A and are compatible with both 3.3 V and 5 V sources.
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
index bc4dc1b04fae9..e859e6c28c661 100644
--- a/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
+++ b/arch/arm/boot/dts/nxp/imx/imx6ul-ts7250v3.dtsi
@@ -739,6 +739,16 @@ mikro_i2c: mikro_i2c@188 {
clock-names = "i2c-oc-clk";
reg-io-width = <1>;
reg-shift = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@70 {
+ compatible = "nxp,pca9538";
+ reg = <0x70>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-line-names = "RELAY5CLICK_REL1", "RELAY5CLICK_REL2", "RELAY5CLICK_REL3";
+ };
};
mikro_pwm: mikro_pwm@1a8 {
Once loaded, the named relays can be looked up and used:
root@tsimx6ul:~# gpiofind RELAY5CLICK_REL1
gpiochip12 0
root@tsimx6ul:~# gpioset 12 0=1 # Energize relay 1
Dynamically Attaching Click Boards™ at Runtime
There is currently experimental support for dynamically attaching Click boards™ at runtime, and even being able to dynamically discover them. A driver for the mikroBUS™ interface is in development that allows for describing the bus interface and connecting it to the Greybus system. This allows for compiled manifest files to be loaded at runtime with no manual modification needed.
This is further expanded by MIKROE's ClickID system which puts a small EEPROM on compatible units that can be probed at runtime and can contain the compiled manifest description that is automatically loaded. These systems combined allow for Plug-and-Play support of various Click boards.
WARNING: | Note that the dynamic system allows for Plug-and-Play, but Click boards are not hot-swappable! When switching between Click boards, be sure to remove power from the device first in order to prevent damage to the Click board or the platform they are connected to. |
Kernel Configuration
As this support is experimental, we are keeping an up-to-date copy of it in our linux-lts Github repository that is based on our linux-6.6.y kernel with patches applied over top of it.
Compiling this is as simple as re-building the TS-7250-V3 kernel, using the linux-6.6.y branch with mikroBUS™ support instead of the default branch.
Once this kernel is built and installed, a compatible Click board™ can be installed to the mikroBUS socket and the unit booted.
Note that kernel configurations may need to be changed to add specific device support. For example, the Ambient 2 Click above uses the opt3001
driver that is not normally a part of our kernel config. In order to support this device at runtime, the kernel still needs to have this driver available as a module or built-in.
Loading Manifests
Manifest source files are maintained by MIKROE: https://github.com/MikroElektronika/click_id. The following can be used to obtain and compile existing sources. It is possible to not only create manifest files to support existing devices that may not yet have full support, but manifest files can also be created for custom Click boards™.
# The following can be performed on the TS-7250-V3 directly, or a recent Debian based distribution on a Linux workstation.
# If building on the TS-7250-V3 it can take a few minutes to get all of the manifest files compiled.
# If building on a desktop workstation, the resulting binary files can be copied to the TS-7250-V3.
# Install prerequisites
apt-get update && apt-get install -y python-is-python3
# Clone repository and build manifest files
git clone https://github.com/MikroElektronika/click_id
cd click_id
make && make install
Ambient 2 Click Manifest
For the example below, the kernel booted is from the mikrobus-support-6.6
branch as described above and also includes the opt3001
driver as a kernel module.
root@tsimx6ul:~# cat /lib/firmware/mikrobus/AMBIENT-2-CLICK.mnfb > /sys/bus/mikrobus/devices/mikrobus-0/new_device
[ 236.866400] mikrobus_manifest:mikrobus_manifest_attach_device: parsed device 1, driver=opt3001
[ 236.866458] mikrobus_manifest:mikrobus_manifest_parse: Ambient 2 Click manifest parsed with 1 devices
[ 236.891522] mikrobus mikrobus-0: registering device : opt3001
[ 236.904125] mikrobus mikrobus-0: error -22: could not get irq 1 # This can be ignored
[ 237.387365] opt3001 4-0044: Found TI OPT3001
And it will function the same was as if the Click board™ were described manually in the devicetree.
Relay 5 Click Manifest
Note: | At the time of writing this, the Relay 5 Click is not officially supported via manifest, the referenced files are ones we have created and are working on getting added to the main repository of manifests. |
For the example below, the kernel booted is from the mikrobus-support-6.6
branch as described above with no configuration or devicetree changes.
root@tsimx6ul:~# cat /lib/firmware/mikrobus/RELAY-5-CLICK.mnfb > /sys/bus/mikrobus/devices/mikrobus-0/new_device
[ 294.550610] mikrobus_manifest:mikrobus_manifest_attach_device: parsed device 1, driver=pca9538
[ 294.550812] mikrobus_manifest:mikrobus_manifest_parse: Relay 5 Click manifest parsed with 1 devices
[ 294.575973] mikrobus mikrobus-0: registering device : pca9538
[ 294.587583] pca953x 4-0070: supply vcc not found, using dummy regulator
[ 294.608866] pca953x 4-0070: using no AI
And now the relays can be accessed over GPIO nearly the same as if they were described manually in the devicetree. The manifest system does not allow for devicetree properties with string values, so the GPIO are unnamed but can be found by querying gpiodetect
to find the newly created device:
root@tsimx6ul:~# gpiodetect |grep 0070 # 0070 is the address of the I2C GPIO device
gpiochip12 [4-0070] (8 lines)
root@tsimx6ul:~# gpioset 12 0=1 # Energize relay 1
Using ClickID
ClickID takes this one step further and allows for querying the Click board™ over 1-Wire and reading information as well as a loadable manifest directly from the Click board itself. This allows for compatible Click boards to simply work without any user intervention needed provided the device is supported by a Linux kernel driver and the driver is available as a kernel built-in or a loadable module.
Note that not all Click boards that offer ClickID have a manifest programmed in to them. See information from MIKROE as they roll out new units and work on compatibility.
If the booted kernel has been configured to support the mikroBUS™ interface, then ClickID support is included in that. Simply attach a compatible Click board to the system and power it on.
Ambient 2 Click ClickID
Once booted, the following can be seen in kernel logs:
[ 35.531089] mikrobus:mikrobus_port_register: registering port mikrobus-0
[ 35.531374] mikrobus mikrobus-0: mikrobus port 0 eeprom empty probing default eeprom
[ 35.791297] w1_master_driver w1_bus_master1: Attaching one wire slave cc.057000001e1c crc 24
[ 38.003732] mikrobus_manifest:mikrobus_manifest_attach_device: parsed device 1, driver=opt3001
[ 38.003770] mikrobus_manifest:mikrobus_manifest_parse: Ambient 2 Click manifest parsed with 1 devices
[ 38.003849] mikrobus mikrobus-0: registering device : opt3001
[ 38.003876] mikrobus mikrobus-0: error -22: could not get irq 1 # This can be ignored
[ 43.907989] opt3001 4-0044: Found TI OPT3001
And that is it! The light sensor is connected to the system and its driver loaded like it were described manually in the devicetree.
Relay 5 Click ClickID
Note: | At the time of writing this, shipping Relay 5 Click units do not contain a valid manifest file. Additionally as noted above, the Relay 5 Click is not officially supported via manifest, the referenced files are ones we have created and are working on getting added to the main repository of manifests. |
In order to support the Relay 5 Click via ClickID, we first needed to boot the platform with the Click board™ installed, write the binary manifest file to the ClickID EEPROM, and reboot the unit in order for the Relay 5 Click to automatically detect.
root@tsimx6ul:~# dmesg
...
[ 33.505826] w1_master_driver w1_bus_master1: Attaching one wire slave cc.05700000dc1b crc 00
[ 34.705709] mikrobus_manifest:mikrobus_manifest_header_validate: short manifest (12 < 4)
[ 34.705770] mikrobus mikrobus-0: error -22: invalid manifest size -22
root@tsimx6ul:~# dd if=/lib/firmware/mikrobus/RELAY-5-CLICK.mnfb of=/sys/bus/w1/devices/w1_bus_master1-<unique ID>/mikrobus_manifest
[ 95.314827] mikrobus_id: writing manifest size = 132 bytes
[ 95.543580] mikrobus_id: manifest written bytes: 160
root@tsimx6ul:~# reboot
Once rebooted, the following can be seen in kernel logs:
[ 34.419628] mikrobus:mikrobus_port_register: registering port mikrobus-0
[ 34.419914] mikrobus mikrobus-0: mikrobus port 0 eeprom empty probing default eeprom
[ 34.680502] w1_master_driver w1_bus_master1: Attaching one wire slave cc.05700000dc1b crc 00
[ 37.808361] mikrobus_manifest:mikrobus_manifest_attach_device: parsed device 1, driver=pca9538
[ 37.808396] mikrobus_manifest:mikrobus_manifest_parse: Relay 5 Click manifest parsed with 1 devices
[ 37.808474] mikrobus mikrobus-0: registering device : pca9538
[ 37.811613] pca953x 4-0070: supply vcc not found, using dummy regulator
[ 37.827415] pca953x 4-0070: using no AI
root@tsimx6ul:~# gpiodetect |grep 0070 # 0070 is the address of the I2C GPIO device
gpiochip12 [4-0070] (8 lines)
root@tsimx6ul:~# gpioset 12 0=1 # Energize relay 1
And just like the Ambient 2 Click, the driver is automatically loaded and the relay GPIO are made available to the system.