1
0
Fork 0
mirror of https://github.com/RobotechLille/cdf2018-principal synced 2024-11-24 00:56:04 +01:00

Added I2C (SRF05 & LCD)

This commit is contained in:
Geoffrey Frogeye 2018-04-29 21:57:29 +02:00
parent 832306706d
commit 0eb11d9fc6
12 changed files with 326 additions and 8 deletions

View file

@ -34,7 +34,7 @@ endif
# RÈGLES DE COMPILATION
# Règle éxecutée par défaut (quand on fait juste `make`)
default: bin/testpin bin/premier bin/local bin/testI2c bin/testLCD
default: bin/testpin bin/premier bin/local bin/testI2c
# Binaires (dont il faut spécifier les objets explicitement)
bin/premier: obj/CF.o obj/movement.o obj/debug.o obj/position.o

55
chef/src/i2c.c Normal file
View file

@ -0,0 +1,55 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiI2C.h>
#include "i2c.h"
pthread_mutex_t sI2C;
void initI2C()
{
pthread_mutex_init(&sI2C, NULL);
}
int openI2C(int8_t address)
{
lockI2C();
int fd = wiringPiI2CSetup(address);
unlockI2C();
if (fd < 0) {
perror("wiringPiI2CSetup");
exit(EXIT_FAILURE);
}
return fd;
}
int8_t readI2C(int fd, int8_t reg)
{
lockI2C();
int8_t res = wiringPiI2CReadReg8(fd, reg);
unlockI2C();
return res;
}
void writeI2C(int fd, int8_t reg, int8_t data)
{
lockI2C();
int res = wiringPiI2CWriteReg8(fd, reg, data);
unlockI2C();
if (res < 0) {
perror("wiringPiI2CWriteReg8");
exit(EXIT_FAILURE);
}
}
void lockI2C()
{
pthread_mutex_lock(&sI2C);
}
void unlockI2C()
{
pthread_mutex_unlock(&sI2C);
}

17
chef/src/i2c.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef __I2C_H__
#define __I2C_H__
#include <stdint.h>
void initI2C();
int openI2C(int8_t address);
int8_t readI2C(int fd, int8_t reg);
void writeI2C(int fd, int8_t reg, int8_t data);
// Get full control over the I2C communication
// Note: Don't use methods from this library
// while in this mode
void lockI2C();
void unlockI2C();
#endif

68
chef/src/lcd.c Normal file
View file

@ -0,0 +1,68 @@
#include "lcd.h"
#include "i2c.h"
#include <wiringPi.h>
#include <wiringPiI2C.h>
int lcdFd;
void initLCD()
{
lcdFd = openI2C(LCD_ADDR);
// TODO More details
sendLCD(0x33, LCD_MODE_CMD); // Initialise
sendLCD(0x32, LCD_MODE_CMD); // Initialise
sendLCD(0x06, LCD_MODE_CMD); // Cursor move direction
sendLCD(0x0C, LCD_MODE_CMD); // Blink Off
sendLCD(0x28, LCD_MODE_CMD); // Data length, number of lines, font size
sendLCD(0x01, LCD_MODE_CMD); // Clear display
delayMicroseconds(500);
}
void clearLCD()
{
sendLCD(0x01, LCD_MODE_CMD);
sendLCD(0x02, LCD_MODE_CMD);
}
void gotoLCD(uint8_t line)
{
sendLCD(line, LCD_MODE_CMD);
}
void charLCD(char c)
{
sendLCD(c, LCD_MODE_CHR);
}
void printLCD(char* s)
{
while (*s != '\0') {
charLCD(*s);
s++;
}
}
void sendLCD(uint8_t bits, uint8_t mode)
{
lockI2C();
// High bits
uint8_t part = mode | (bits & 0xF0) | LCD_BACKLIGHT;
wiringPiI2CReadReg8(lcdFd, part);
toggleEnableLCD(part);
// Low bits
part = mode | ((bits << 4) & 0xF0) | LCD_BACKLIGHT;
wiringPiI2CReadReg8(lcdFd, part);
toggleEnableLCD(part);
unlockI2C();
}
void toggleEnableLCD(uint8_t bits)
{
wiringPiI2CReadReg8(lcdFd, (bits | LCD_MASK_ENABLE));
delayMicroseconds(1);
wiringPiI2CReadReg8(lcdFd, (bits & ~LCD_MASK_ENABLE));
delayMicroseconds(50);
}

31
chef/src/lcd.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef __LCD_H_
#define __LCD_H_
#include "stdint.h"
#define LCD_ADDR 0x27
#define LCD_MODE_CHR 1
#define LCD_MODE_CMD 0
#define LCD_LINE_1 0x80 // 1st line
#define LCD_LINE_2 0xC0 // 2nd line
#define LCD_BACKLIGHT_ON 0x08
#define LCD_BACKLIGHT_OFF 0x08
#define LCD_BACKLIGHT LCD_BACKLIGHT_ON
#define LCD_MASK_ENABLE 0x04 // Enable bit
// Public
void initLCD();
void clearLCD();
void gotoLCD(uint8_t line);
void charLCD(char c);
void printLCD(char* s);
// Private
void sendLCD(uint8_t bits, uint8_t mode);
void toggleEnableLCD(uint8_t bits);
#endif

44
chef/src/srf08.c Normal file
View file

@ -0,0 +1,44 @@
#include <unistd.h>
#include "i2c.h"
#include "srf08.h"
int openSRF08(int address)
{
int fd = openI2C(address);
writeI2C(fd, SRF08_REGISTER_WRITE_MAX_GAIN, SRF08_DEFAULT_MAX_GAIN);
writeI2C(fd, SRF08_REGISTER_WRITE_RANGE, SRF08_DEFAULT_RANGE);
return fd;
}
uint8_t revSRF08(int fd)
{
return readI2C(fd, SRF08_REGISTER_READ_REVISION);
}
void startSRF08(int fd)
{
writeI2C(fd, SRF08_REGISTER_WRITE_COMMAND, SRF08_COMMAND_RANGING_US);
}
void waitSRF08(int fd)
{
while (revSRF08(fd) == 0xFF) {
sleep(0);
}
}
float getSRF08(int fd)
{
int8_t high = readI2C(fd, SRF08_REGISTER_READ_ECHO_1_HIGH) - SRF08_VALUES_OFFSET;
int8_t low = readI2C(fd, SRF08_REGISTER_READ_ECHO_1_LOW) - SRF08_VALUES_OFFSET;
int total = high * SRF08_VALUES_OFFSET + low;
return total * SOUNDSPEED_MM_P_US;
}
float readSRF08(int fd)
{
startSRF08(fd);
waitSRF08(fd);
return getSRF08(fd);
}

33
chef/src/srf08.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef __SRF08_H__
#define __SRF08_H__
#include <stdint.h>
int openSRF08(int address);
uint8_t revSRF08(int fd);
void startSRF08(int fd);
void waitSRF08(int fd);
// In mm
float getSRF08(int fd);
float readSRF08(int fd);
#define SRF08_REGISTER_READ_REVISION 0x00
#define SRF08_REGISTER_READ_ECHO_1_HIGH 0x02
#define SRF08_REGISTER_READ_ECHO_1_LOW 0x03
#define SRF08_REGISTER_WRITE_COMMAND 0x00
#define SRF08_REGISTER_WRITE_MAX_GAIN 0x01
#define SRF08_REGISTER_WRITE_RANGE 0x02
#define SRF08_COMMAND_RANGING_IN 0x50
#define SRF08_COMMAND_RANGING_CM 0x51
#define SRF08_COMMAND_RANGING_US 0x52
#define SRF08_DEFAULT_MAX_GAIN 0x1F
#define SRF08_DEFAULT_RANGE 0xFF
#define SRF08_VALUES_OFFSET 0x80
#define SOUNDSPEED_MM_P_US 0.3312
#endif

50
chef/src/testI2c.c Normal file
View file

@ -0,0 +1,50 @@
/* Teste si une broche est connecté à une autre */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPiI2C.h>
#include "srf08.h"
#include "i2c.h"
#include "lcd.h"
int main(int argc, char* argv[])
{
(void)argc;
(void)argv;
initI2C();
// Adresse du SRF05
uint8_t address = atoi(argv[1]);
printf("Connecting to %d (0x%x)\n", address, address);
initLCD();
clearLCD();
gotoLCD(LCD_LINE_1);
printLCD("Distance");
int front = openSRF08(address);
char line[16];
float l = 0;
for (;;) {
startSRF08(front);
gotoLCD(LCD_LINE_2);
printf("l = %3f\n", l);
sprintf(line, "%f mm", l);
printLCD(line);
printLCD(" ");
waitSRF08(front);
l = getSRF08(front);
}
}

View file

@ -0,0 +1 @@
CONFIG_RX=y

View file

@ -0,0 +1,10 @@
#!/bin/sh
>> "${BINARIES_DIR}/rpi-firmware/config.txt"
cat << __EOF__ >> "${BINARIES_DIR}/rpi-firmware/config.txt"
# activates I2C connectivity
dtparam=i2c_arm=on,i2c_arm_baudrate=1000000
__EOF__

View file

@ -6,11 +6,15 @@
start() {
printf "Starting hardware handling: "
modprobe pl2303 # USB↔Serial cable
modprobe i2c-bcm2708 # I2C
modprobe i2c-dev # I2C
echo "OK"
}
stop() {
printf "Stopping hardware handling: "
rmmod i2c-dev # I2C
rmmod i2c-bcm2708 # I2C
rmmod pl2303 # USB↔Serial cable
echo "OK"
}

View file

@ -49,16 +49,16 @@ BR2_CCACHE=y
BR2_TARGET_GENERIC_HOSTNAME="principal"
BR2_TARGET_GENERIC_ISSUE="Robotech - CdF 2018 - Robot principal"
# Configuration noyau supplémentaire
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/linux-extra.conf"
# TODO Not working
# Paquets nécessaires
BR2_PACKAGE_CHEF=y
# Fichiers supplémentaires
BR2_ROOTFS_OVERLAY="${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/rootfs_overlay/"
BR2_ROOTFS_POST_BUILD_SCRIPT="board/raspberrypi3/post-build.sh ${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/post-build.sh"
BR2_ROOTFS_POST_BUILD_SCRIPT="${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/post-build.sh board/raspberrypi3/post-build.sh"
BR2_ROOTFS_POST_IMAGE_SCRIPT="${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/post-image.sh board/raspberrypi3/post-image.sh"
BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/busybox-extra.conf"
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_CDF_PATH}/board/robotech/cdfprincipal/linux-extra.conf"
# TODO Doesn't work
# Ne pas activer la connexion ethernet par défaut
BR2_SYSTEM_DHCP=""
@ -72,6 +72,7 @@ BR2_PACKAGE_WPA_SUPPLICANT=y
# Pour upgrader à chaud
BR2_PACKAGE_DROPBEAR=y
BR2_PACKAGE_RSYNC=y
BR2_PACKAGE_PPPD=y
# Pour faire plaisir à Geoffrey
BR2_PACKAGE_HTOP=y
@ -85,3 +86,7 @@ BR2_PACKAGE_AVRDUDE=y
# Pour uploader sur le FPGA
BR2_PACKAGE_MERCPCL=y
# Communication I2C
BR2_PACKAGE_BUSYBOX_SHOW_OTHERS=y
BR2_PACKAGE_I2C_TOOLS=y