Master SIAME | Université Toulouse 3

Internet of things and System on Chip

Master SIAME | Université Toulouse 3

Internet of things and System on Chip

User Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

embedded:logiciel:i2c [2015/08/26 20:37] (current)
Line 1: Line 1:
 +====== I2C ======
 +
 +===== En ligne de commande =====
 +
 +Pour obtenir la liste des ports I2C disponible:
 +
 +<code sh>
 +i2cdetect -y -l
 +</​code>​
 +
 +Pour liste les périphériques disponibles sur le bus (//PORT// est le numéro du port I2C) :
 +
 +<code sh>
 +i2cdetect -y -r PORT
 +</​code>​
 +
 +Pour écrire dans un registre I2C //REG// la valeur //VAL// du périphérique PER (//REG//, //VAL// et //PER// en hexadécimal) :
 +<code sh>
 +i2cset -y PORT PER REG VAL
 +</​code>​
 +
 +Pour lire un registre //REG// de 8-bits:
 +<code sh>
 +i2cget -y PORT PER REG
 +</​code>​
 +
 +Pour lire un registre //REG// de 16-bits:
 +<code sh>
 +i2cget -y PORT PER REG w
 +</​code>​
 +
 +Références :
 +  *  [[http://​elinux.org/​Interfacing_with_I2C_Devices|périphériques /dev]]
 +  * [[https://​i2c.wiki.kernel.org/​index.php/​Main_Page|documentation du noyau]].
 +
 +
 +===== En C =====
 +
 +Bien qu'il existe une API spécifique pour accéder à l'I2C, (1) elle n'est pas disponible sur notre version de Linux et (2) l'I2C étant basé sur des flux, il est pratiquement aussi rapide de passer par le système de fichier.
 +
 +Notre micro-contrôleur possède plusieurs bus I2C et nous utiliserons le bus 1 qui est correspond au fichier ''/​dev/​i2c-3''​ (logique, non ;)).
 +
 +Avant tout, il faut inclure les en-têtes nécessaires :
 +<code c>
 +#include <​linux/​i2c.h>​
 +#include <​sys/​ioctl.h>​
 +#include <​linux/​i2c-dev.h>​
 +#define MPU6050_ADDR 0x68
 +</​code>​
 +
 +Pour y accéder, il faut l'​ouvrir :
 +<code c>
 + int fd = open(PATH, O_RDWR);
 + if(fd < 0)
 + error();
 +</​code>​
 +
 +
 +Sélectionner le périphérique avec lequel on veut communiquer :
 +<code c>
 + if(ioctl(fd,​ I2C_SLAVE, MPU6050_ADDR) < 0)
 + error();
 +</​code>​
 +
 +
 +Puis utiliser ''​write''​ pour envoyer des commandes :
 +<code c>
 + uint8_t buf[] = { REGISTER_ADDR,​ SET_VALUE };
 + if(write(fd,​ buf, sizeof(buf)) != sizeof(buf))
 + error();
 +</​code>​
 +
 +Et ''​read''​ pour lire les réponses :
 +<code c>
 + char buf[2];
 + if(read(fd,​ ptr, sizeof(buf)) != sizeof(buf))
 + error();
 +</​code>​
 +
 +**ATTENTION** Les valeurs 16-bits lues sur l'​IMU-6050 sont en big-endian alors que notre processeur fonctionne en little-endian.
 +
 +Références :
 +  * http://​www.unixgarden.com/​index.php/​gnu-linux-magazine-hs/​un-capteur-de-temperature-sur-bus-i2c|article général]]
 +  * https://​www.kernel.org/​doc/​htmldocs/​device-drivers/​i2c.html