1-Wire

From linux-sunxi.org
Jump to navigation Jump to search

One Wire

1-Wire is a device communications bus system designed by Dallas Semiconductor that provides low-speed data, signaling, and power over a single signal. 1-Wire is similar in concept to I²C, but with lower data rates and longer range. It is typically used to communicate with small inexpensive devices such as digital thermometers and weather instruments. A network of 1-Wire devices with an associated master device is called a MicroLan.

1-Wire support for Mainline kernel

To communicate with 1-wire devices it is recommended to use w1-gpio driver as most of the Allwinner SoCs lack hardware controller (only present on A31 and A80).

Device Tree

First add the device definition in your devices devicetree (assuming 1-wire device is connected to PD2 pin):

onewire_device {
   compatible = "w1-gpio";
   gpios = <&pio 3 2 GPIO_ACTIVE_HIGH>; /* PD2 */
   pinctrl-names = "default";
   pinctrl-0 = <&my_w1_pin>;
};

And then define the pins under &pio label:

&pio {
   ...

   my_w1_pin: my_w1_pin@0 {
     allwinner,pins = "PD2";
     allwinner,function = "gpio_in";
     allwinner,drive = <SUN4I_PINCTRL_10_MA>;
     allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
   };

   ...
};

After rebuilding your dts/dtb and rebooting, check whether it's enabled

cat /sys/kernel/debug/pinctrl/1c20800.pinctrl/pinmux-pins |grep PD2

The pin is properly configured if you have an output like

pin ?? (PD2): w1.7 1c20800.pinctrl:?? function gpio_out group PD2

Linux kernel 3.4

Edit the script.fex file and set the gpio pin for 1-wire bus


[gpio_para]
gpio_used = 1
gpio_num = 67
gpio_pin_1 = port:PG03<1><default><default><1>
....
gpio_pin_66 = port:PB10<1><default><default><1>

[w1_para]
gpio = 66

Connect the data pin of devices to gpio pin PB10 and in sys folder you have

/sys/bus/w1/devices/
28-000004bfae30
28-000004c022c5

what are connect 2 DS18B20 devices

cat /sys/bus/w1/devices/28-000004bfae30/w1_slave
45 01 4b 46 7f ff 0b 10 84 : crc=84 YES
45 01 4b 46 7f ff 0b 10 84 t=20312

the temp is 20.312 °C

Linux kernel 4.14

You don't have to edit the fex-file, but the /boot/armbianEnv.txt and add the lines:

overlays=w1-gpio
param_w1_pin=PB10             # desired pin
param_w1_pin_int_pullup=1     # internal pullup-resistor: 1=on, 0=off

Connect the data pin of devices to gpio pin PB10 and proceed like Kernel 3.4 with

/sys/bus/w1/devices/
28-000004bfae30
28-000004c022c5

and

cat /sys/bus/w1/devices/28-000004bfae30/w1_slave
45 01 4b 46 7f ff 0b 10 84 : crc=84 YES
45 01 4b 46 7f ff 0b 10 84 t=20312

Read Data Sensor

simple bash script for read 1-wire temp sensor


#!/bin/bash

file="/sys/bus/w1/devices/28-000004bfae30/w1_slave"
function find(){
 [[ "$1" =~ "$2" ]] && true || false
}

while :
do
	DATE=$(date +"%d-%m-%Y-%H:%M:%S")
	#read device
	CRC=false
	while read curline; do
		#check crc
		if( find "$curline" "crc" && find "$curline" "YES" ) then
			CRC=true
			DEVICE=`echo $curline|cut -d':' -f 1`	
		fi
		if($CRC && find "$curline" "t=") then
		TEMP=`echo $curline|cut -d'=' -f 2`
		echo $DEVICE ";" $DATE ";" `echo "scale=3;$TEMP/1000"|bc -l` 
		fi
	done <$file
sleep 10
done