BLIT2008-Board mit i2c-tiny-usb-Firmware

Aus BraLUG-Wiki

(Unterschied zwischen Versionen)
Wechseln zu: Navigation, Suche
(Thermo-Board auslesen)
(RTC auslesen)
Zeile 70: Zeile 70:
 
get_part () { i2cget -y "$BUS" "$ADDR" $1 | sed -e 's/^0x//' ; }
 
get_part () { i2cget -y "$BUS" "$ADDR" $1 | sed -e 's/^0x//' ; }
  
ss=`get_part 2`
+
SS=$(get_byte 2)
mm=`get_part 3`
+
MM=$(get_byte 3)
hh=`get_part 4`
+
HH=$(get_byte 4)
dd=`get_part 5`
+
DD=$(get_byte 5)
mo=`get_part 6`
+
MO=$(get_byte 6)
  
 
echo "RTC time: $dd.$mo. $hh:$mm:$ss"
 
echo "RTC time: $dd.$mo. $hh:$mm:$ss"
Zeile 83: Zeile 83:
 
RTC time: 01.01. 03:14:11
 
RTC time: 01.01. 03:14:11
 
</pre>
 
</pre>
 +
 +
===RTC auf aktuelles Datum/Uhrzeit setzen===
 +
Bevor man Datum/Uhrzeit ausliest, sollte man diese natürlich auf die aktuellen Werte setzen. Hier ein entsprechendes Script dazu:
 +
<pre>
 +
#!/bin/sh
 +
 +
I2C_BUS=5
 +
ADDR_RTC=0x51
 +
 +
set_byte () { i2cset -y "$I2C_BUS" "$ADDR_RTC" $1 $((($2/10<<4)+($2%10))) b ; }
 +
 +
set_byte 2 $(date +%S)
 +
set_byte 3 $(date +%M)
 +
set_byte 4 $(date +%H)
 +
set_byte 5 $(date +%d)
 +
set_byte 6 $(date +%m)
 +
 +
</pre>
 +
 +
Kleine Besonderheit des PCF8583: die Werte sind im [http://de.wikipedia.org/wiki/Binary_Coded_Decimal BCD]-Format anzugeben.
  
 
===RTC beschreiben===
 
===RTC beschreiben===

Version vom 10. Februar 2012, 22:21 Uhr


Statt das Rad neu zu erfinden, kann man sich für I²C auf dem BLIT2008-Board auch die Linux-Kernel-Unterstützung für ein ähnliches Projekt zunutze machen. Die Firmware für das i2c-tiny-usb-Board läuft mit minimalen Änderungen auch und man hat die Treiber- und Software-Unterstützung von Linux als Bonus.

Inhaltsverzeichnis

Firmware

Da die Firmware schon für den Mega8 vorgesehen ist, war die Portierung auf das Board mehr als einfach. Folgende Schritte sollten funktionieren:

  • Beschaffen und Entpacken der Firmware (http://www.harbaum.org/till/i2c_tiny_usb/i2c_tiny_usb-2007-06-07.zip)
  • In das Firmware-Verzeichnis wechseln: „cd i2c_tiny_usb/firmware/
  • Anpassen der usbtiny.h, Ändern des Ports auf PORT_D und Ändern des D+-Pins auf 2 (Patch)
  • Bauen mit „make -f Makefile-usbtiny.mega8
  • Hochladen auf den Mikrocontroller z.B. mit „avrusbboot main.hex

Kerneltreiber

Der benötigte Kerneltreiber namens i2c-tiny-usb ist ungefähr seit Version 2.6.22 im Linux-Kernel. Man benötigt folgende Konfigurationsoptionen (sollte im Distributionskernel dabei sein):

CONFIG_I2C
CONFIG_I2C_CHARDEV
CONFIG_I2C_TINY_USB

Geladen werden müssen i2c_tiny_usb und i2c_dev.

i2c-tools

Zum grundlegenden Test, zum Debugging und zum Skripten eignen sich die I2C-Tools, bei Debian auch im Paket i2c-tools verfügbar.

Liste der verfügbaren Busse:

# i2cdetect -l
i2c-5	i2c       	i2c-tiny-usb at bus 005 device 004	I2C adapter
i2c-0	i2c       	radeonfb monid                  	I2C adapter
i2c-1	i2c       	radeonfb dvi                    	I2C adapter
i2c-2	i2c       	radeonfb vga                    	I2C adapter
i2c-3	i2c       	radeonfb crt2                   	I2C adapter
i2c-4	smbus     	SMBus Via Pro adapter at e800   	SMBus adapter
  • Die Nummer des I²C-Busses ist die 5 in i2c-5, nicht die 5 in „at bus 005“ (USB-Bus-Nummer)

Slave-Chips am Bus finden:

# i2cdetect 5
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-5.
I will probe address range 0x03-0x77.
Continue? [Y/n] 
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
  • i2cdetect verwendet eine etwas andere Darstellung für die Adressen. Im AVR-Code würde man Aread = 2 * n + 1 und Awrite = 2 * n + 0 verwenden, 0x51 ist also Adresse 0xA2 (schreiben) und 0xA3 (lesen).
  • Die Warnung sollte man durchaus ernst nehmen und das Kommando nicht unreflektiert auf den anderen Bussen ausführen. Ist man sich sicher, den richtigen Bus erwischt zu haben (in diesem Fall 5), dann kann man auch i2cdetect -y 5 benutzen, um die Nachfrage abzuschalten.

RTC auslesen

In Anlehnung an Uwes Beispiele hier ein Script, um die RTC-Zeit auszulesen. Gegebenfalls sind wieder Bus-Nummer und Adresse anzupassen.

get_rtc_time.sh:

#!/bin/sh

BUS=5
ADDR=0x51

get_part () { i2cget -y "$BUS" "$ADDR" $1 | sed -e 's/^0x//' ; }

SS=$(get_byte 2)
MM=$(get_byte 3)
HH=$(get_byte 4)
DD=$(get_byte 5)
MO=$(get_byte 6)

echo "RTC time: $dd.$mo. $hh:$mm:$ss"
# ./get_rtc_time.sh
RTC time: 01.01. 03:14:11

RTC auf aktuelles Datum/Uhrzeit setzen

Bevor man Datum/Uhrzeit ausliest, sollte man diese natürlich auf die aktuellen Werte setzen. Hier ein entsprechendes Script dazu:

#!/bin/sh

I2C_BUS=5
ADDR_RTC=0x51

set_byte () { i2cset -y "$I2C_BUS" "$ADDR_RTC" $1 $((($2/10<<4)+($2%10))) b ; }

set_byte 2 $(date +%S)
set_byte 3 $(date +%M)
set_byte 4 $(date +%H)
set_byte 5 $(date +%d)
set_byte 6 $(date +%m)

Kleine Besonderheit des PCF8583: die Werte sind im BCD-Format anzugeben.

RTC beschreiben

Der umgekehrte Weg geht natürlich auch! Mittels des Kommandos i2cset kann ein I²C-Chip beschrieben werden, wenn er es zulässt. Der PCF8583, welcher auf dem RTC-Board verwendet wird, erlaubt dies. Zum einen kann Datum/Uhrzeit auf einen Wert vorinitialisiert werden, zum anderen gibt es in dem Schaltkreis 240 Byte RAM zur freien Verfügung. Im folgenden Beispiel wird eine solche Speicherzelle beschrieben:

Erst mal schauen, was derzeit in der Speicherzelle (Adresse: 0x11) steht:

# i2cget -y 2 0x51 0x11
0x00

Einen neuen Wert schreiben:

# i2cset -y 2 0x51 0x11 0xbc b
Value 0xbc written, readback matched

Nochmals auslesen:

# i2cget -y 2 0x51 0x11
0xbc


In diesem Beispiel war das BLIT-Board über I²C-Bus 2 zu erreichen und das RTC-Board hatte die Adresse 0x51. Der genaue Syntax von i2cget und i2cset ist der jeweiligen Manpage zu entnehmen.

Thermo-Board auslesen

Und natürlich das entsprechende Script für das Thermo-Board darf nicht fehlen. Auch hier sind wieder Bus-Nummer und Adresse entsprechend anzupassen (bei mir war es halt der Bus 2...!). Als Shell wird bash vorausgesetzt.

get_temperature.sh:

#!/bin/bash
#
# Kodierung der Temperatur im LM75
# --------------------------------
#
#   High-Byte          Low-Byte
# 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0
# x 1 1 1 1 1 1 1   x x x x x x x x 
# |                 | |...........|
# |                 | |
# |                 | +-- Temperatur (Vorkomma): Bit 0...6
# |                 +---- Vorzeichen: 1 -> Temperatur < 0°C
# +---------------------- Nachkommastelle: 0 -> ,0°C; 1 -> ,5°C
#

I2C_BUS=2
ADDR_LM75=0x49

# Temperatur auslesen
val=$((16#$(i2cget -y "$I2C_BUS" "$ADDR_LM75" 0 w | sed -e 's/^0x//')))

lb=$(($val & $((2#11111111))))
hb=$(($val>>8))

# Vorzeichen interpretieren
if [ $(($lb & $((2#10000000)))) -eq 0 ] 
then sign="+"
else sign="-"
fi

# Vorzeichenbit rauskanten
lb=$(($lb & $((2#01111111))))

# Nachkomma interpretieren
if [ $hb -ge 128 ] 
then dec=5
else dec=0
fi

echo "$sign$lb,$dec°C"
# ./get_temperature.sh
+23,5 °C

SAA1064 (7-Segment-Anzeige) beschreiben

Das Beschreiben 7-Segment-Anzeige auf Basis eines I²C-IC SAA1064 funktioniert ebenfalls ohne Probleme.

Initialisieren des SAA1064 (I²C-Bus 0; Adresse 0x38):

i2cset -y 0 0x38 0x00 0x77

Es wird das Register 0 im SAA1064 mit mit der Bitfolge 01110111 gesetzt. Die einzelnen Bits des Register 0 haben in Kurzform folgende Bedeutung (die genaue Bedeutung sollte man Datenblatt nachlesen):

// SAA1064 Control-Register (Adresse 0)
// Bit	7	6	5	4	3	2	1	0
//	|	|	|	|	|	|	|	|
//	|	|	|	|	|	|	|	---- 0: Digit 1,2; 1: Digit 1...4
//	|	|	|	|	|	|	-------- 0/1: Digit 1,3 aus/an
//	|	|	|	|	|	------------ 0/1: Digit 2,4 aus/an
//	|	|	|	|	---------------- 1: Testmode, alle Segmente an
//	|	|	|	-------------------- 1: plus 3mA
//	|	|	------------------------ 1: plus 6mA
//	|	---------------------------- 1: plus 12mA
//	-------------------------------- nicht belegt


Mit einem

i2cset -y 0 0x38 0x01 0xff

schaltet man alle Segmente des 1.Digit an. Die 0x01 steht für das 1.Digit (für das 4.Digit würde dann z.B. hier eine 0x04 stehen). Das letzte Parameter bildet die anzusteuernden Segmente des Digits ab

// Bit:     7 6 5 4 3 2 1 0
// Segment: p g f e d c b a
//
//  -a-
// |f  |b
//  -g-
// |e  |c
//  -d- .p

lm_sensors

Selbstverständlich kann man die ganze Geschichte auch in lm-sensors einbinden, wenn die I²C-Slave-Schaltkreise unterstützt würden. Beim Thermo-Board mit seinem LM75-Chip ist dies der Fall :-)!

Die Installation von lm-sensors auf dem Rechner erfolgt entweder über das Paketsystem der jeweiligen Distribution oder das Übersetzen/Installieren der Originalquellen.

Die Konfiguration von lm-sensors erledigt man sinnvollerweise mit dem mitgelieferten Setup-Script:

# sudo sensors-detect

Sämtliche Fragen können bedenkenlos mit Ja (Yes) beantwortet werden. Die entscheidende Stelle der Ausgaben sollte ungefähr so aussehen:

...
Next adapter: i2c-tiny-usb at bus 002 device 007 (i2c-2)
Do you want to scan it? (YES/no/selectively): 
Client found at address 0x49
Probing for `National Semiconductor LM75'...                Success!
    (confidence 6, driver `lm75')
Probing for `Dallas Semiconductor DS75'...                  No
Probing for `National Semiconductor LM77'...                No
Probing for `Dallas Semiconductor DS1621'...                No
Probing for `National Semiconductor LM92'...                No
Probing for `National Semiconductor LM76'...                No
Probing for `Maxim MAX6633/MAX6634/MAX6635'...              No
Client found at address 0x51
Probing for `Analog Devices ADM1033'...                     No
Probing for `Analog Devices ADM1034'...                     No
Probing for `SPD EEPROM'...                                 No
Probing for `EDID EEPROM'...                                No
...

Nach einem Reboot des Rechners oder manuellem Laden des lm75-Kernelmoduls sollte lm-sensors auch die Thermo-Zusatzbaugruppe des BLIT-Boards mit eingebunden haben:

# sensors
k8temp-pci-00c3
Adapter: PCI adapter
Core0 Temp:
             +26°C
Core1 Temp:
             +31°C

lm75-i2c-2-49
Adapter: i2c-tiny-usb at bus 002 device 007
temp:      +22.0°C  (high = +80.0°C, hyst = +75.0°C)  

Zur Visualisierung der gemessenen Temperatur können die verschiedensten Tools verwendet werden. Bei einer Gnome-Oberfläche bietet sich da das Panel-Applet sensors-applet an. Als "desktop-neutrales" Tools wären z.B. xsensors oder GkrellM zu erwähnen.

'Persönliche Werkzeuge