├── blink ├── arduino ├── tmp │ ├── main │ ├── Wire.o │ ├── main.o │ ├── i2cio.o │ ├── i2cio16.o │ ├── wiring.o │ ├── Peripherals.o │ ├── main.cpp │ ├── makefile.bak │ ├── makefile~ │ └── makefile ├── libraries │ ├── Peripherals │ │ ├── Peripherals.h │ │ ├── i2cio.h │ │ ├── i2cio16.h │ │ ├── Peripherals.cpp │ │ ├── i2cio.cpp │ │ └── i2cio16.cpp │ ├── includes.h~ │ ├── includes.h │ ├── Wire │ │ ├── Wire.h │ │ └── Wire.cpp │ └── cores │ │ ├── wiring.h │ │ └── wiring.cpp └── build └── blink.pde /blink: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/blink -------------------------------------------------------------------------------- /arduino/tmp/main: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/main -------------------------------------------------------------------------------- /arduino/tmp/Wire.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/Wire.o -------------------------------------------------------------------------------- /arduino/tmp/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/main.o -------------------------------------------------------------------------------- /arduino/tmp/i2cio.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/i2cio.o -------------------------------------------------------------------------------- /arduino/tmp/i2cio16.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/i2cio16.o -------------------------------------------------------------------------------- /arduino/tmp/wiring.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/wiring.o -------------------------------------------------------------------------------- /arduino/tmp/Peripherals.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SandboxElectronics/RasPiDeck/master/arduino/tmp/Peripherals.o -------------------------------------------------------------------------------- /blink.pde: -------------------------------------------------------------------------------- 1 | #define LED_PIN (3) 2 | void setup(void) 3 | { 4 | pinMode(LED_PIN, OUTPUT); 5 | RasPiDeckGPIO5v(LED_PIN); 6 | } 7 | 8 | void loop(void) 9 | { 10 | digitalWrite(LED_PIN, 1); 11 | delay(300); 12 | digitalWrite(LED_PIN, 0); 13 | delay(300); 14 | } 15 | -------------------------------------------------------------------------------- /arduino/tmp/main.cpp: -------------------------------------------------------------------------------- 1 | #include "../libraries/includes.h" 2 | #define LED_PIN (3) 3 | void setup(void) 4 | { 5 | pinMode(LED_PIN, OUTPUT); 6 | RasPiDeckGPIO5v(LED_PIN); 7 | } 8 | 9 | void loop(void) 10 | { 11 | digitalWrite(LED_PIN, 1); 12 | delay(300); 13 | digitalWrite(LED_PIN, 0); 14 | delay(300); 15 | } 16 | -------------------------------------------------------------------------------- /arduino/libraries/Peripherals/Peripherals.h: -------------------------------------------------------------------------------- 1 | #ifndef _H_PERIPHERALS_ 2 | #define _H_PERIPHERALS_ 3 | 4 | 5 | 6 | void RasPiDeckPeripheralsReset(void); 7 | void RasPiDeckSPI3v3(void); 8 | void RasPiDeckSPI5v(void); 9 | void RasPiDeckI2C3v3(void); 10 | void RasPiDeckI2C5v(void); 11 | void RasPiDeckSPIEnable(void); 12 | void RasPiDeckSPIDisable(void); 13 | void RasPiDeckI2CEnable(void); 14 | void RasPiDeckI2CDisable(void); 15 | void RasPiDeckReference5v(void); 16 | void RasPiDeckReferenceExt(void); 17 | void RasPiDeckGPIO5v(int pin); 18 | void RasPiDeckGPIO3v3(int pin); 19 | 20 | #endif 21 | 22 | -------------------------------------------------------------------------------- /arduino/libraries/Peripherals/i2cio.h: -------------------------------------------------------------------------------- 1 | #ifndef _H_I2CIO_ 2 | #define _H_I2CIO_ 3 | 4 | #define RASPIDECK_I2CIO_REG_CFG (0X03) 5 | #define RASPIDECK_I2CIO_REG_IN (0X00) 6 | #define RASPIDECK_I2CIO_REG_OUT (0X01) 7 | #define RASPIDECK_I2CIO_REG_INV (0X02) 8 | #define RASPIDECK_I2CIO_ADDR (0x25) 9 | 10 | 11 | 12 | void RasPiDeckI2CIOSetPinMode(uint8_t pin, uint8_t io_mode); 13 | void RasPiDeckI2CIOSetPinStatus(uint8_t pin, uint8_t pin_status); 14 | uint8_t RasPiDeckI2CIOGetPinStatus(uint8_t pin); 15 | void RasPiDeckI2CIOSetPortStatus(uint8_t port_status); 16 | void RasPiDeckI2CIOSetPortMode(uint8_t port_mode); 17 | uint8_t RasPiDeckI2CIOGetPortStatus(void); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /arduino/tmp/makefile.bak: -------------------------------------------------------------------------------- 1 | #DIR OUT are passed from shell command 2 | 3 | LIB_DIR = $(DIR)/libraries 4 | TMP = $(DIR)/tmp 5 | HDR = $(LIB_DIR)/includes.h 6 | EXE = $(TMP)/main 7 | OBJS = $(TMP)/main.o $(TMP)/wiring.o $(TMP)/Wire.o 8 | CC = g++ 9 | DEBUG = -g 10 | CFLAGS = -c 11 | LFLAGS = -lrt -lpthread 12 | 13 | $(TMP)/main: $(OBJS) $(HDR) 14 | $(CC) $(LFLAGS) $(OBJS) -o $(TMP)/main 15 | cp $(TMP)/main $(OUT) 16 | 17 | $(TMP)/main.o: $(TMP)/main.cpp $(HDR) 18 | $(CC) $(CFLAGS) $(TMP)/main.cpp -o $(TMP)/main.o 19 | 20 | $(TMP)/wiring.o: $(LIB_DIR)/cores/wiring.cpp $(LIB_DIR)/cores/wiring.h $(HDR) 21 | $(CC) $(CFLAGS) $(LIB_DIR)/cores/wiring.cpp -o $(TMP)/wiring.o 22 | 23 | $(TMP)/Wire.o: $(LIB_DIR)/Wire/Wire.cpp $(LIB_DIR)/Wire/Wire.h $(HDR) 24 | $(CC) $(CFLAGS) $(LIB_DIR)/Wire/Wire.cpp -o $(TMP)/Wire.o 25 | 26 | clean: 27 | \rm $(TMP)/*.o $(TMP)/main 28 | -------------------------------------------------------------------------------- /arduino/libraries/Peripherals/i2cio16.h: -------------------------------------------------------------------------------- 1 | #ifndef _H_I2CIO16_ 2 | #define _H_I2CIO16_ 3 | 4 | #define RASPIDECK_I2CIO16_REG_IN0 (0x00) 5 | #define RASPIDECK_I2CIO16_REG_IN1 (0X01) 6 | #define RASPIDECK_I2CIO16_REG_OUT0 (0X02) 7 | #define RASPIDECK_I2CIO16_REG_OUT1 (0X03) 8 | #define RASPIDECK_I2CIO16_REG_INV0 (0X04) 9 | #define RASPIDECK_I2CIO16_REG_INV1 (0X05) 10 | #define RASPIDECK_I2CIO16_REG_CFG0 (0X06) 11 | #define RASPIDECK_I2CIO16_REG_CFG1 (0X07) 12 | 13 | #define RASPIDECK_I2CIO16_ADDR (0x20) 14 | 15 | 16 | 17 | void RasPiDeckI2CIO16SetPinMode(uint8_t pin, uint8_t io_mode); 18 | void RasPiDeckI2CIO16SetPinStatus(uint8_t pin, uint8_t pin_status); 19 | uint8_t RasPiDeckI216CIOGetPinStatus(uint8_t pin); 20 | void RasPiDeckI2CIO16SetPortStatus(uint8_t port_number, uint8_t port_status); 21 | void RasPiDeckI2CIO16SetPortMode(uint8_t port_number,uint8_t port_mode); 22 | uint8_t RasPiDeckI2CIO16GetPortStatus(uint8_t port_number); 23 | uint8_t RasPiDeckI2CIO16ReadRegister(uint8_t command, uint8_t *i2c_buf); 24 | void RasPiDeckI2CIO16WriteRegister(uint8_t command, uint8_t *i2c_buf); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /arduino/tmp/makefile~: -------------------------------------------------------------------------------- 1 | #DIR OUT are passed from shell command 2 | 3 | LIB_DIR = $(DIR)/libraries 4 | TMP = $(DIR)/tmp 5 | HDR = $(LIB_DIR)/includes.h 6 | EXE = $(TMP)/main 7 | OBJS = $(TMP)/main.o $(TMP)/i2cio.o $(TMP)/i2cio16.o $(TMP)/wiring.o $(TMP)/Wire.o 8 | CC = g++ 9 | DEBUG = -g 10 | CFLAGS = -c 11 | LFLAGS = -lrt -lpthread 12 | 13 | $(TMP)/main: $(OBJS) $(HDR) 14 | $(CC) $(LFLAGS) $(OBJS) -o $(TMP)/main 15 | cp $(TMP)/main $(OUT) 16 | 17 | $(TMP)/main.o: $(TMP)/main.cpp $(HDR) 18 | $(CC) $(CFLAGS) $(DEBUG) $(TMP)/main.cpp -o $(TMP)/main.o 19 | 20 | $(TMP)/i2cio.o: $(LIB_DIR)/Peripherals/i2cio.cpp $(LIB_DIR)/Peripherals/i2cio.h $(HDR) 21 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Peripherals/i2cio.cpp -o $(TMP)/i2cio.o 22 | 23 | $(TMP)/i2cio16.o: $(LIB_DIR)/Peripherals/i2cio16.cpp $(LIB_DIR)/Peripherals/i2cio16.h $(HDR) 24 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Peripherals/i2cio16.cpp -o $(TMP)/i2cio16.o 25 | 26 | $(TMP)/wiring.o: $(LIB_DIR)/cores/wiring.cpp $(LIB_DIR)/cores/wiring.h $(HDR) 27 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/cores/wiring.cpp -o $(TMP)/wiring.o 28 | 29 | $(TMP)/Wire.o: $(LIB_DIR)/Wire/Wire.cpp $(LIB_DIR)/Wire/Wire.h $(HDR) 30 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Wire/Wire.cpp -o $(TMP)/Wire.o 31 | 32 | 33 | 34 | 35 | clean: 36 | \rm $(TMP)/*.o $(TMP)/main 37 | -------------------------------------------------------------------------------- /arduino/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | usage="Typical usage: build " 4 | 5 | if [[ $1 != -* ]]; then 6 | i=$1 7 | shift 1 8 | fi 9 | 10 | while getopts :i:d:o:h flag 11 | do 12 | case $flag in 13 | i)i=$OPTARG;; 14 | d)d=$OPTARG;; 15 | o)o=$OPTARG;; 16 | h)echo $usage; exit;; 17 | *)echo "Invalid option -$OPTARG."; echo $usage; exit;; 18 | esac 19 | done 20 | 21 | shift $(($OPTIND-1)) 22 | 23 | if [[ -z $d ]]; then 24 | d=arduino 25 | fi 26 | 27 | if [[ -z $i ]]; then 28 | if [[ $# == 1 ]]; then 29 | i=$1 30 | else 31 | echo $usage; exit 32 | fi 33 | else 34 | if [[ $# != 0 ]]; then 35 | echo "Invalid syntax."; echo $usage; exit 36 | fi 37 | fi 38 | 39 | if [[ -z $i ]]; then 40 | echo "Please specify the source file by -i " 41 | else 42 | regex_ino="(.*)\.ino$" 43 | regex_pde="(.*)\.pde$" 44 | regex_cpp="(.*)\.cpp$" 45 | 46 | if [ -e $i ]; then 47 | if [[ $i =~ $regex_ino ]] || [[ $i =~ $regex_pde ]] || [[ $i =~ $regex_cpp ]]; then 48 | if [ ! -d $d/tmp ]; then 49 | mkdir $d/tmp 50 | fi 51 | 52 | echo "#include \"../libraries/includes.h\"" > $d/tmp/main.cpp 53 | cat $i >> $d/tmp/main.cpp 54 | 55 | if [ -z $o ]; then 56 | o=${BASH_REMATCH[1]} 57 | fi 58 | 59 | make -f $d/tmp/makefile DIR=$d OUT=$o 60 | else 61 | echo "File extension not supported. Supported file extensions are .cpp .ino .pde" 62 | fi 63 | else 64 | echo "File does not exist." 65 | fi 66 | fi 67 | -------------------------------------------------------------------------------- /arduino/tmp/makefile: -------------------------------------------------------------------------------- 1 | #DIR OUT are passed from shell command 2 | 3 | LIB_DIR = $(DIR)/libraries 4 | TMP = $(DIR)/tmp 5 | HDR = $(LIB_DIR)/includes.h 6 | EXE = $(TMP)/main 7 | OBJS = $(TMP)/main.o $(TMP)/i2cio.o $(TMP)/i2cio16.o $(TMP)/wiring.o $(TMP)/Wire.o $(TMP)/Peripherals.o 8 | CC = g++ 9 | DEBUG = -g 10 | CFLAGS = -c 11 | LFLAGS = -lrt -lpthread 12 | 13 | $(TMP)/main: $(OBJS) $(HDR) 14 | $(CC) $(LFLAGS) $(OBJS) -o $(TMP)/main 15 | cp $(TMP)/main $(OUT) 16 | 17 | $(TMP)/main.o: $(TMP)/main.cpp $(HDR) 18 | $(CC) $(CFLAGS) $(DEBUG) $(TMP)/main.cpp -o $(TMP)/main.o 19 | 20 | $(TMP)/Peripherals.o: $(LIB_DIR)/Peripherals/Peripherals.cpp $(LIB_DIR)/Peripherals/Peripherals.h $(HDR) 21 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Peripherals/Peripherals.cpp -o $(TMP)/Peripherals.o 22 | 23 | $(TMP)/i2cio.o: $(LIB_DIR)/Peripherals/i2cio.cpp $(LIB_DIR)/Peripherals/i2cio.h $(HDR) 24 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Peripherals/i2cio.cpp -o $(TMP)/i2cio.o 25 | 26 | $(TMP)/i2cio16.o: $(LIB_DIR)/Peripherals/i2cio16.cpp $(LIB_DIR)/Peripherals/i2cio16.h $(HDR) 27 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Peripherals/i2cio16.cpp -o $(TMP)/i2cio16.o 28 | 29 | $(TMP)/wiring.o: $(LIB_DIR)/cores/wiring.cpp $(LIB_DIR)/cores/wiring.h $(HDR) 30 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/cores/wiring.cpp -o $(TMP)/wiring.o 31 | 32 | $(TMP)/Wire.o: $(LIB_DIR)/Wire/Wire.cpp $(LIB_DIR)/Wire/Wire.h $(HDR) 33 | $(CC) $(CFLAGS) $(DEBUG) $(LIB_DIR)/Wire/Wire.cpp -o $(TMP)/Wire.o 34 | 35 | clean: 36 | \rm $(TMP)/*.o $(TMP)/main 37 | -------------------------------------------------------------------------------- /arduino/libraries/Peripherals/Peripherals.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../includes.h" 3 | 4 | 5 | 6 | void RasPiDeckPeripheralsReset(void) 7 | { 8 | digitalWrite(PL, 0); 9 | pinMode(PL,OUTPUT); 10 | 11 | Wire.begin(); 12 | RasPiDeckI2CIOSetPortStatus(0xff);//Set the output register of PCA9554 to its POR status 13 | RasPiDeckI2CIOSetPortMode(0x3F); 14 | RasPiDeckI2CIO16SetPortStatus(0,0xff);//Set the port 0 output register of PCA9555 to its POR status 15 | RasPiDeckI2CIO16SetPortStatus(1,0xff);//Set the port 1 output register of PCA9555 to its POR status 16 | RasPiDeckI2CIO16SetPortMode(0,0); //Set port 0 of PCA9555 to output 17 | RasPiDeckI2CIO16SetPortMode(1,0); //Set port 1 of PCA9555 to output 18 | 19 | 20 | } 21 | 22 | void RasPiDeckSPI3v3(void) 23 | { 24 | RasPiDeckI2CIO16SetPinStatus(15, 1); 25 | } 26 | 27 | void RasPiDeckSPI5v(void) 28 | { 29 | RasPiDeckI2CIO16SetPinStatus(15, 0); 30 | } 31 | 32 | void RasPiDeckI2C3v3(void) 33 | { 34 | RasPiDeckI2CIO16SetPinStatus(14, 1); 35 | } 36 | 37 | void RasPiDeckI2C5v(void) 38 | { 39 | RasPiDeckI2CIO16SetPinStatus(14, 0); 40 | } 41 | 42 | void RasPiDeckSPIEnable(void) 43 | { 44 | digitalWrite(PL,1); 45 | } 46 | 47 | void RasPiDeckSPIDisable(void) 48 | { 49 | digitalWrite(PL,0); 50 | } 51 | 52 | void RasPiDeckI2CEnable(void) 53 | { 54 | RasPiDeckI2CIOSetPinStatus(6,1); 55 | } 56 | 57 | void RasPiDeckI2CDisable(void) 58 | { 59 | RasPiDeckI2CIOSetPinStatus(6,0); 60 | } 61 | 62 | void RasPiDeckReference5v(void) 63 | { 64 | RasPiDeckI2CIOSetPinStatus(7,0); 65 | } 66 | 67 | void RasPiDeckReferenceExt(void) 68 | { 69 | RasPiDeckI2CIOSetPinStatus(7,1); 70 | } 71 | 72 | void RasPiDeckGPIO5v(int pin) 73 | { 74 | if (pin<=7) { 75 | RasPiDeckI2CIO16SetPinStatus(7-pin,0); //write 0 to enable 5V output 76 | } else { 77 | RasPiDeckI2CIO16SetPinStatus(pin,0); 78 | } 79 | } 80 | 81 | void RasPiDeckGPIO3v3(int pin) 82 | { 83 | if (pin<=7) { 84 | RasPiDeckI2CIO16SetPinStatus(7-pin,1); //write 1 to disable 5V output 85 | } else { 86 | RasPiDeckI2CIO16SetPinStatus(pin, 1); 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /arduino/libraries/Peripherals/i2cio.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "../includes.h" 3 | 4 | 5 | uint8_t RasPiDeckI2CIOReadRegister(uint8_t command) 6 | { 7 | uint8_t value; 8 | 9 | Wire.beginTransmission( RASPIDECK_I2CIO_ADDR ); 10 | Wire.write(command); 11 | Wire.endTransmission(); 12 | Wire.requestFrom(RASPIDECK_I2CIO_ADDR,1); 13 | value = Wire.read(); 14 | 15 | return value; 16 | } 17 | 18 | void RasPiDeckI2CIOWriteRegister(uint8_t command, uint8_t value) 19 | { 20 | 21 | Wire.beginTransmission(RASPIDECK_I2CIO_ADDR); 22 | Wire.write(command); 23 | Wire.write(value); 24 | Wire.endTransmission(); 25 | 26 | } 27 | 28 | void RasPiDeckI2CIOSetPinMode(uint8_t pin, uint8_t io_mode) 29 | { 30 | uint8_t reg_val; 31 | 32 | reg_val = RasPiDeckI2CIOReadRegister(RASPIDECK_I2CIO_REG_CFG); 33 | 34 | if (io_mode == INPUT) { 35 | reg_val |= (0x01<. 17 | * 18 | * Version 1.5 (For Raspberry Pi Rev2) 19 | * Author: Anartz Nuin Jiménez 20 | */ 21 | 22 | #ifndef INCLUDES_HEADER 23 | #define INCLUDES_HEADER 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "cores/wiring.h" 50 | #include "Wire/Wire.h" 51 | #include "Peripherals/i2cio.h" 52 | #include "Peripherals/i2cio16.h" 53 | 54 | #define BIT_0 (1 << 0) 55 | #define BIT_1 (1 << 1) 56 | #define BIT_2 (1 << 2) 57 | #define BIT_3 (1 << 3) 58 | #define BIT_4 (1 << 4) 59 | #define BIT_5 (1 << 5) 60 | #define BIT_6 (1 << 6) 61 | #define BIT_7 (1 << 7) 62 | #define BIT_8 (1 << 8) 63 | #define BIT_9 (1 << 9) 64 | #define BIT_10 (1 << 10) 65 | #define BIT_11 (1 << 11) 66 | #define BIT_12 (1 << 12) 67 | #define BIT_13 (1 << 13) 68 | #define BIT_14 (1 << 14) 69 | #define BIT_15 (1 << 15) 70 | #define BIT_16 (1 << 16) 71 | #define BIT_17 (1 << 17) 72 | #define BIT_18 (1 << 18) 73 | #define BIT_19 (1 << 19) 74 | #define BIT_20 (1 << 20) 75 | #define BIT_21 (1 << 21) 76 | #define BIT_22 (1 << 22) 77 | #define BIT_23 (1 << 23) 78 | #define BIT_24 (1 << 24) 79 | #define BIT_25 (1 << 25) 80 | #define BIT_26 (1 << 26) 81 | #define BIT_27 (1 << 27) 82 | #define BIT_28 (1 << 28) 83 | #define BIT_29 (1 << 29) 84 | #define BIT_30 (1 << 30) 85 | #define BIT_31 (1 << 31) 86 | 87 | /* 88 | * Arduino Pin Definition 89 | */ 90 | 91 | #define SS 10 92 | #define MOSI 11 93 | #define MISO 12 94 | #define SCK 13 95 | 96 | #define SDA 18 97 | #define SCL 19 98 | 99 | #define A0 14 100 | #define A1 15 101 | #define A2 16 102 | #define A3 17 103 | #define A4 18 104 | #define A5 19 105 | #define A6 20 106 | #define A7 21 107 | #define PL (0xFF) 108 | 109 | #endif // INCLUDES_HEADER 110 | -------------------------------------------------------------------------------- /arduino/libraries/includes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Libelium Comunicaciones Distribuidas S.L. 3 | * http://www.libelium.com 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * Version 1.5 (For Raspberry Pi Rev2) 19 | * Author: Anartz Nuin Jiménez 20 | */ 21 | 22 | #ifndef INCLUDES_HEADER 23 | #define INCLUDES_HEADER 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "cores/wiring.h" 50 | #include "Wire/Wire.h" 51 | #include "Peripherals/i2cio.h" 52 | #include "Peripherals/i2cio16.h" 53 | #include "Peripherals/Peripherals.h" 54 | 55 | #define BIT_0 (1 << 0) 56 | #define BIT_1 (1 << 1) 57 | #define BIT_2 (1 << 2) 58 | #define BIT_3 (1 << 3) 59 | #define BIT_4 (1 << 4) 60 | #define BIT_5 (1 << 5) 61 | #define BIT_6 (1 << 6) 62 | #define BIT_7 (1 << 7) 63 | #define BIT_8 (1 << 8) 64 | #define BIT_9 (1 << 9) 65 | #define BIT_10 (1 << 10) 66 | #define BIT_11 (1 << 11) 67 | #define BIT_12 (1 << 12) 68 | #define BIT_13 (1 << 13) 69 | #define BIT_14 (1 << 14) 70 | #define BIT_15 (1 << 15) 71 | #define BIT_16 (1 << 16) 72 | #define BIT_17 (1 << 17) 73 | #define BIT_18 (1 << 18) 74 | #define BIT_19 (1 << 19) 75 | #define BIT_20 (1 << 20) 76 | #define BIT_21 (1 << 21) 77 | #define BIT_22 (1 << 22) 78 | #define BIT_23 (1 << 23) 79 | #define BIT_24 (1 << 24) 80 | #define BIT_25 (1 << 25) 81 | #define BIT_26 (1 << 26) 82 | #define BIT_27 (1 << 27) 83 | #define BIT_28 (1 << 28) 84 | #define BIT_29 (1 << 29) 85 | #define BIT_30 (1 << 30) 86 | #define BIT_31 (1 << 31) 87 | 88 | /* 89 | * Arduino Pin Definition 90 | */ 91 | 92 | #define SS 10 93 | #define MOSI 11 94 | #define MISO 12 95 | #define SCK 13 96 | 97 | #define SDA 18 98 | #define SCL 19 99 | 100 | #define A0 14 101 | #define A1 15 102 | #define A2 16 103 | #define A3 17 104 | #define A4 18 105 | #define A5 19 106 | #define A6 20 107 | #define A7 21 108 | #define PL (0xFF) 109 | 110 | #endif // INCLUDES_HEADER 111 | -------------------------------------------------------------------------------- /arduino/libraries/Peripherals/i2cio16.cpp: -------------------------------------------------------------------------------- 1 | //#define PIN_UNDER_TEST (2) 2 | 3 | //#include "stdio.h" 4 | #include "../includes.h" 5 | 6 | 7 | /* 8 | void setup() 9 | 10 | { 11 | Wire.begin(); 12 | 13 | RasPiDeckI2CIO16SetPortStatus(0,0xff); 14 | RasPiDeckI2CIO16SetPortStatus(1,0xff); 15 | 16 | 17 | RasPiDeckI2CIO16SetPortMode(0,0x00); 18 | RasPiDeckI2CIO16SetPortMode(1,0x00); 19 | 20 | RasPiDeckI2CIO16SetPinStatus(14, 0); 21 | 22 | pinMode(14,OUTPUT); 23 | digitalWrite(14,0); 24 | } 25 | 26 | void loop() 27 | { 28 | 29 | uint8_t i; 30 | 31 | i++; 32 | 33 | 34 | if (i&0x01) { 35 | RasPiDeckI2CIO16SetPinStatus(7, 1 ); 36 | } else { 37 | RasPiDeckI2CIO16SetPinStatus(7, 0); 38 | } 39 | 40 | } 41 | */ 42 | uint8_t RasPiDeckI2CIO16ReadRegister(uint8_t command, uint8_t *i2c_buf) 43 | { 44 | uint8_t value; 45 | Wire.beginTransmission( RASPIDECK_I2CIO16_ADDR ); 46 | Wire.write(command); 47 | Wire.endTransmission(); 48 | // printf ("Available data: %d\n", Wire.requestFrom(RASPIDECK_I2CIO16_ADDR,2)); 49 | 50 | i2c_buf[0] = (uint8_t)Wire.read(); 51 | i2c_buf[1] = (uint8_t)Wire.read(); 52 | 53 | // printf("READING from device 0x%02x,register 0x%02x, value 0x%02x:0x%02x\n",RASPIDECK_I2CIO16_ADDR, command,i2c_buf[0],i2c_buf[1]); 54 | return value; 55 | } 56 | 57 | void RasPiDeckI2CIO16WriteRegister(uint8_t command, uint8_t *i2c_buf) 58 | { 59 | 60 | Wire.beginTransmission(RASPIDECK_I2CIO16_ADDR); 61 | Wire.write(command); 62 | Wire.write(i2c_buf[0]); 63 | Wire.write(i2c_buf[1]); 64 | 65 | Wire.endTransmission(); 66 | //printf("WRITING to device 0x%02x,register 0x%02x, value 0x%02x:0x%02x\n",RASPIDECK_I2CIO16_ADDR, command,i2c_buf[0],i2c_buf[1]); 67 | 68 | } 69 | 70 | void RasPiDeckI2CIO16SetPinMode(uint8_t pin, uint8_t io_mode) 71 | { 72 | uint8_t port_reg=RASPIDECK_I2CIO16_REG_CFG0; 73 | uint8_t buf[2]; 74 | 75 | if (pin > 7) { 76 | port_reg = RASPIDECK_I2CIO16_REG_CFG1; 77 | } 78 | 79 | RasPiDeckI2CIO16ReadRegister(port_reg,buf); 80 | 81 | if (io_mode == INPUT) { 82 | buf[0] |= (0x01<<(pin%8)); 83 | } else { 84 | buf[0] &= (uint8_t)~(0x01<<(pin%8)); 85 | } 86 | 87 | RasPiDeckI2CIO16WriteRegister(port_reg, buf); 88 | 89 | return; 90 | 91 | } 92 | 93 | void RasPiDeckI2CIO16SetPinStatus(uint8_t pin, uint8_t pin_status) 94 | { 95 | uint8_t buf[2]; 96 | 97 | if (pin > 7) { 98 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_IN1,buf); 99 | } else { 100 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_IN0,buf); 101 | } 102 | 103 | 104 | if (pin_status != 0) { 105 | buf[0] |= (0x01<<(pin%8)); 106 | } else { 107 | buf[0] &= (uint8_t)~(0x01<<(pin%8)); 108 | } 109 | 110 | if (pin > 7) { 111 | RasPiDeckI2CIO16WriteRegister(RASPIDECK_I2CIO16_REG_OUT1, buf); 112 | } else { 113 | RasPiDeckI2CIO16WriteRegister(RASPIDECK_I2CIO16_REG_OUT0, buf); 114 | } 115 | 116 | return; 117 | } 118 | 119 | uint8_t RasPiDeckI2CIO16GetPinStatus(uint8_t pin) 120 | { 121 | uint8_t buf[2]; 122 | uint8_t port_reg=RASPIDECK_I2CIO16_REG_IN0; 123 | 124 | 125 | if (pin > 7) { 126 | port_reg = RASPIDECK_I2CIO16_REG_IN1; 127 | } 128 | 129 | RasPiDeckI2CIO16ReadRegister(port_reg,buf); 130 | 131 | 132 | if (buf[0]&(0x01<<(pin%8)) != 0) { 133 | return 1; 134 | } 135 | return 0; 136 | } 137 | 138 | 139 | 140 | void RasPiDeckI2CIO16SetPortMode(uint8_t port_number, uint8_t io_mode) //0:output 1:input 141 | { 142 | uint8_t buf[2]; 143 | 144 | if ( port_number == 0) { 145 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_CFG0, buf); 146 | buf[0] = io_mode; 147 | RasPiDeckI2CIO16WriteRegister(RASPIDECK_I2CIO16_REG_CFG0,buf); 148 | } else { 149 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_CFG1, buf); 150 | buf[0] = io_mode; 151 | RasPiDeckI2CIO16WriteRegister(RASPIDECK_I2CIO16_REG_CFG1,buf); 152 | 153 | } 154 | return; 155 | 156 | } 157 | 158 | void RasPiDeckI2CIO16SetPortStatus(uint8_t port_number, uint8_t port_status) 159 | { 160 | 161 | uint8_t buf[2]; 162 | 163 | if ( port_number == 0) { 164 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_IN0, buf); 165 | buf[0] = port_status; 166 | RasPiDeckI2CIO16WriteRegister(RASPIDECK_I2CIO16_REG_OUT0,buf); 167 | } else { 168 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_IN1, buf); 169 | buf[0] = port_status; 170 | RasPiDeckI2CIO16WriteRegister(RASPIDECK_I2CIO16_REG_OUT1,buf); 171 | 172 | } 173 | 174 | return; 175 | 176 | } 177 | 178 | 179 | uint8_t RasPiDeckI2CIO16GetPortStatus(uint8_t port_number) 180 | { 181 | uint8_t buf[2]; 182 | if ( port_number == 0) { 183 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_IN0, buf); 184 | } else { 185 | RasPiDeckI2CIO16ReadRegister(RASPIDECK_I2CIO16_REG_IN1, buf); 186 | } 187 | 188 | return buf[0]; 189 | 190 | } 191 | 192 | -------------------------------------------------------------------------------- /arduino/libraries/Wire/Wire.h: -------------------------------------------------------------------------------- 1 | #ifndef WIRE_HEADER 2 | #define WIRE_HEADER 3 | 4 | #define BCM2835_BSC1_BASE (0x20804000) 5 | 6 | // Defines for I2C 7 | // GPIO register offsets from BCM2835_BSC*_BASE. 8 | // Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map 9 | #define BCM2835_BSC_C 0x0000 ///< BSC Master Control 10 | #define BCM2835_BSC_S 0x0004 ///< BSC Master Status 11 | #define BCM2835_BSC_DLEN 0x0008 ///< BSC Master Data Length 12 | #define BCM2835_BSC_A 0x000c ///< BSC Master Slave Address 13 | #define BCM2835_BSC_FIFO 0x0010 ///< BSC Master Data FIFO 14 | #define BCM2835_BSC_DIV 0x0014 ///< BSC Master Clock Divider 15 | #define BCM2835_BSC_DEL 0x0018 ///< BSC Master Data Delay 16 | #define BCM2835_BSC_CLKT 0x001c ///< BSC Master Clock Stretch Timeout 17 | 18 | // Register masks for BSC_C 19 | #define BCM2835_BSC_C_I2CEN 0x00008000 ///< I2C Enable, 0 = disabled, 1 = enabled 20 | #define BCM2835_BSC_C_INTR 0x00000400 ///< Interrupt on RX 21 | #define BCM2835_BSC_C_INTT 0x00000200 ///< Interrupt on TX 22 | #define BCM2835_BSC_C_INTD 0x00000100 ///< Interrupt on DONE 23 | #define BCM2835_BSC_C_ST 0x00000080 ///< Start transfer, 1 = Start a new transfer 24 | #define BCM2835_BSC_C_CLEAR_1 0x00000020 ///< Clear FIFO Clear 25 | #define BCM2835_BSC_C_CLEAR_2 0x00000010 ///< Clear FIFO Clear 26 | #define BCM2835_BSC_C_READ 0x00000001 ///< Read transfer 27 | 28 | // Register masks for BSC_S 29 | #define BCM2835_BSC_S_CLKT 0x00000200 ///< Clock stretch timeout 30 | #define BCM2835_BSC_S_ERR 0x00000100 ///< ACK error 31 | #define BCM2835_BSC_S_RXF 0x00000080 ///< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full 32 | #define BCM2835_BSC_S_TXE 0x00000040 ///< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full 33 | #define BCM2835_BSC_S_RXD 0x00000020 ///< RXD FIFO contains data 34 | #define BCM2835_BSC_S_TXD 0x00000010 ///< TXD FIFO can accept data 35 | #define BCM2835_BSC_S_RXR 0x00000008 ///< RXR FIFO needs reading (full) 36 | #define BCM2835_BSC_S_TXW 0x00000004 ///< TXW FIFO needs writing (full) 37 | #define BCM2835_BSC_S_DONE 0x00000002 ///< Transfer DONE 38 | #define BCM2835_BSC_S_TA 0x00000001 ///< Transfer Active 39 | 40 | #define BCM2835_BSC_FIFO_SIZE 16 ///< BSC FIFO size 41 | #define BCM2835_CORE_CLK_HZ 250000000 ///< 250 MHz 42 | 43 | #define BSC_C_I2CEN BIT_15 44 | #define BSC_C_INTR BIT_10 45 | #define BSC_C_INTT BIT_9 46 | #define BSC_C_INTD BIT_8 47 | #define BSC_C_ST BIT_7 48 | #define BSC_C_CLEAR BIT_4 49 | #define BSC_C_READ BIT_0 50 | 51 | #define START_READ BSC_C_I2CEN | BSC_C_ST | BSC_C_CLEAR | BSC_C_READ 52 | #define START_WRITE BSC_C_I2CEN | BSC_C_ST 53 | 54 | #define BSC_S_CLKT BIT_9 55 | #define BSC_S_ERR BIT_8 56 | #define BSC_S_RXF BIT_7 57 | #define BSC_S_TXE BIT_6 58 | #define BSC_S_RXD BIT_5 59 | #define BSC_S_TXD BIT_4 60 | #define BSC_S_RXR BIT_3 61 | #define BSC_S_TXW BIT_2 62 | #define BSC_S_DONE BIT_1 63 | #define BSC_S_TA BIT_0 64 | 65 | #define CLEAR_STATUS BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE 66 | 67 | #define BUFFER_LENGTH 32 68 | 69 | /// \brief bcm2835I2CClockDivider 70 | /// Specifies the divider used to generate the I2C clock from the system clock. 71 | /// Clock divided is based on nominal base clock rate of 250MHz 72 | typedef enum 73 | { 74 | BCM2835_I2C_CLOCK_DIVIDER_2500 = 2500, ///< 2500 = 10us = 100 kHz 75 | BCM2835_I2C_CLOCK_DIVIDER_626 = 626, ///< 622 = 2.504us = 399.3610 kHz 76 | BCM2835_I2C_CLOCK_DIVIDER_150 = 150, ///< 150 = 60ns = 1.666 MHz (default at reset) 77 | BCM2835_I2C_CLOCK_DIVIDER_148 = 148, ///< 148 = 59ns = 1.689 MHz 78 | } bcm2835I2CClockDivider; 79 | 80 | /// \brief bcm2835I2CReasonCodes 81 | /// Specifies the reason codes for the bcm2835_i2c_write and bcm2835_i2c_read functions. 82 | typedef enum 83 | { 84 | BCM2835_I2C_REASON_OK = 0x00, ///< Success 85 | BCM2835_I2C_REASON_ERROR_NACK = 0x01, ///< Received a NACK 86 | BCM2835_I2C_REASON_ERROR_CLKT = 0x02, ///< Received Clock Stretch Timeout 87 | BCM2835_I2C_REASON_ERROR_DATA = 0x04, ///< Not all data is sent / received 88 | } bcm2835I2CReasonCodes; 89 | 90 | typedef enum 91 | { 92 | RPI_V2_GPIO_P1_03 = 2, ///< Version 2, Pin P1-03 93 | RPI_V2_GPIO_P1_05 = 3, ///< Version 2, Pin P1-05 94 | }RPiGPIOPin; 95 | 96 | /* WirePi Class 97 | * Class that provides the functionality of arduino Wire library 98 | */ 99 | class WirePi{ 100 | private: 101 | volatile uint32_t* reg_dlen; 102 | volatile uint32_t* reg_fifo; 103 | volatile uint32_t* reg_stat; 104 | volatile uint32_t* reg_ctrl; 105 | volatile uint32_t* reg_addr; 106 | 107 | uint8_t rxBuffer[BUFFER_LENGTH]; 108 | uint8_t rxBufferIndex; 109 | uint8_t rxBufferLength; 110 | 111 | uint8_t txAddress; 112 | uint8_t txBuffer[BUFFER_LENGTH]; 113 | uint8_t txBufferIndex; 114 | uint8_t txBufferLength; 115 | 116 | int memfd; 117 | int map_peripheral (struct bcm2835_peripheral *p); 118 | void unmap_peripheral (struct bcm2835_peripheral *p); 119 | public: 120 | WirePi(); 121 | void begin(); 122 | void beginTransmission (uint8_t address); 123 | void beginTransmission (int address); 124 | size_t write (uint8_t data); 125 | size_t write (const uint8_t *data, size_t quantity); 126 | uint8_t endTransmission (uint8_t sendStop); 127 | uint8_t endTransmission (void); 128 | uint8_t requestFrom (uint8_t address, uint8_t quantity); 129 | int available (void); 130 | int read (void); 131 | int peek (void); 132 | }; 133 | 134 | extern WirePi Wire; 135 | 136 | #endif // WIRE_HEADER 137 | -------------------------------------------------------------------------------- /arduino/libraries/Wire/Wire.cpp: -------------------------------------------------------------------------------- 1 | #include "../includes.h" 2 | 3 | volatile uint32_t *bcm2835_bsc1; 4 | 5 | extern timeval start_program; 6 | extern struct bcm2835_peripheral gpio; 7 | 8 | /****************** 9 | * Public methods * 10 | ******************/ 11 | 12 | //Constructor 13 | WirePi::WirePi(){ 14 | if(map_peripheral(&gpio) == -1) { 15 | printf("Failed to map the physical GPIO registers into the virtual memory space.\n"); 16 | } 17 | 18 | memfd = -1; 19 | 20 | // Open the master /dev/memory device 21 | if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) { 22 | fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n", 23 | strerror(errno)) ; 24 | exit(1); 25 | } 26 | 27 | bcm2835_bsc1 = mapmem("bsc1", BLOCK_SIZE, memfd, BCM2835_BSC1_BASE); 28 | if (bcm2835_bsc1 == MAP_FAILED) { 29 | exit(1); 30 | } 31 | 32 | // start timer 33 | gettimeofday(&start_program, NULL); 34 | 35 | reg_dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; 36 | reg_fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; 37 | reg_stat = bcm2835_bsc1 + BCM2835_BSC_S/4; 38 | reg_ctrl = bcm2835_bsc1 + BCM2835_BSC_C/4; 39 | reg_addr = bcm2835_bsc1 + BCM2835_BSC_A/4; 40 | } 41 | 42 | //Initiate the Wire library and join the I2C bus. 43 | void WirePi::begin() { 44 | rxBufferIndex = 0; 45 | rxBufferLength = 0; 46 | 47 | txBufferIndex = 0; 48 | txBufferLength = 0; 49 | 50 | // Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them 51 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); // SDA 52 | bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); // SCL 53 | 54 | // Enable I2C Operation 55 | bcm2835_peri_write_nb(reg_ctrl, BCM2835_BSC_C_I2CEN); 56 | } 57 | 58 | //Begin a transmission to the I2C slave device with the given address 59 | void WirePi::beginTransmission (uint8_t address) { 60 | // set address of targeted slave 61 | txAddress = address; 62 | // reset tx buffer iterator vars 63 | txBufferIndex = 0; 64 | txBufferLength = 0; 65 | } 66 | 67 | 68 | void WirePi::beginTransmission (int address) { 69 | beginTransmission((uint8_t)address); 70 | } 71 | 72 | 73 | uint8_t WirePi::endTransmission (uint8_t sendStop) { 74 | // Wait until I2C is ready, become master receiver 75 | while ((bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_TA)); 76 | 77 | // Set Slave Address 78 | bcm2835_peri_write_nb(reg_addr, txAddress); 79 | // Clear FIFO 80 | bcm2835_peri_set_bits(reg_ctrl, BCM2835_BSC_C_CLEAR_1, BCM2835_BSC_C_CLEAR_1); 81 | // Clear Status 82 | bcm2835_peri_write_nb(reg_stat, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); 83 | // Set Data Length 84 | bcm2835_peri_write_nb(reg_dlen, txBufferLength); 85 | 86 | // pre populate FIFO with max buffer 87 | txBufferIndex = 0; 88 | while (txBufferIndex != txBufferLength) { 89 | if (bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_TXD) { 90 | bcm2835_peri_write_nb(reg_fifo, txBuffer[txBufferIndex]); 91 | txBufferIndex++; 92 | 93 | if (txBufferIndex < BCM2835_BSC_FIFO_SIZE) { 94 | if (txBufferIndex == txBufferLength) { 95 | // Enable I2C opertation and start transfer 96 | bcm2835_peri_write_nb(reg_ctrl, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); 97 | } 98 | } else if (txBufferIndex == BCM2835_BSC_FIFO_SIZE) { 99 | // Enable I2C opertation and start transfer 100 | bcm2835_peri_write_nb(reg_ctrl, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); 101 | } 102 | } 103 | } 104 | 105 | // Transfer is over when BCM2835_BSC_S_DONE 106 | while(!(bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_DONE)); 107 | 108 | // Received an Error 109 | if (bcm2835_peri_read(reg_stat) & BCM2835_BSC_S_ERR) { 110 | return 4; 111 | } 112 | 113 | // Received Clock Stretch Timeout 114 | else if (bcm2835_peri_read(reg_stat) & BCM2835_BSC_S_CLKT) { 115 | return 4; 116 | } 117 | 118 | // reset tx buffer iterator vars 119 | txBufferIndex = 0; 120 | txBufferLength = 0; 121 | return 0; 122 | } 123 | 124 | 125 | uint8_t WirePi::endTransmission (void) { 126 | return endTransmission(true); 127 | } 128 | 129 | 130 | size_t WirePi::write (uint8_t data) { 131 | // don't bother if buffer is full 132 | if (txBufferLength >= BUFFER_LENGTH) { 133 | return 0; 134 | } 135 | // put byte in tx buffer 136 | txBuffer[txBufferIndex] = data; 137 | ++txBufferIndex; 138 | // update amount in buffer 139 | txBufferLength = txBufferIndex; 140 | 141 | return 1; 142 | } 143 | 144 | 145 | size_t WirePi::write (const uint8_t *data, size_t quantity) { 146 | for(size_t i = 0; i < quantity; ++i){ 147 | write(data[i]); 148 | } 149 | 150 | return quantity; 151 | } 152 | 153 | 154 | uint8_t WirePi::requestFrom (uint8_t address, uint8_t quantity){ 155 | if (quantity > BUFFER_LENGTH) { 156 | quantity = BUFFER_LENGTH; 157 | } 158 | 159 | // Wait until I2C is ready, become master receiver 160 | while ((bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_TA)){/* printf("DEBUG INFO:I2C busy\n");*/ }; 161 | 162 | // Set Slave Address 163 | bcm2835_peri_write_nb(reg_addr, address); 164 | // Clear Status Flags 165 | bcm2835_peri_write_nb(reg_stat, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); 166 | // Set Data Length 167 | bcm2835_peri_write_nb(reg_dlen, quantity); 168 | // Start Read 169 | bcm2835_peri_write_nb(reg_ctrl, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_CLEAR_1 | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ); 170 | 171 | // Reset rxBuffer Index 172 | rxBufferIndex = 0; 173 | rxBufferLength = 0; 174 | // Wait for transfer to complete 175 | while (!(bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_DONE)) { 176 | // Empty the FIFO as it is populated 177 | while (bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_RXD) { 178 | rxBuffer[rxBufferIndex] = (uint8_t)bcm2835_peri_read_nb(reg_fifo); 179 | rxBufferIndex++; 180 | rxBufferLength++; 181 | } 182 | } 183 | 184 | // Empty the FIFO after all I2C transfer has been DONE 185 | while (bcm2835_peri_read_nb(reg_stat) & BCM2835_BSC_S_RXD) { 186 | rxBuffer[rxBufferIndex] = (uint8_t)bcm2835_peri_read_nb(reg_fifo); 187 | rxBufferIndex++; 188 | rxBufferLength++; 189 | } 190 | 191 | // Received an ERR 192 | if (bcm2835_peri_read(reg_stat) & BCM2835_BSC_S_ERR) { 193 | printf("Error Occured\n"); 194 | } 195 | 196 | // Clock Stretch Timeout 197 | else if (bcm2835_peri_read(reg_stat) & BCM2835_BSC_S_CLKT) { 198 | printf("Slave Timeout\n"); 199 | } 200 | 201 | rxBufferIndex = 0; 202 | // printf ("DEBUG INFO: rxBufferIndex=0x%02x, rxBufferLength=0x%02x\n", rxBufferIndex, rxBufferLength); 203 | return rxBufferLength; 204 | } 205 | 206 | 207 | int WirePi::available(){ 208 | return rxBufferLength - rxBufferIndex; 209 | } 210 | 211 | 212 | int WirePi::read(){ 213 | int value = -1; 214 | 215 | // get each successive byte on each call 216 | if(rxBufferIndex < rxBufferLength){ 217 | value = rxBuffer[rxBufferIndex]; 218 | rxBufferIndex++; 219 | } 220 | 221 | return value; 222 | } 223 | 224 | 225 | int WirePi::peek(void) 226 | { 227 | int value = -1; 228 | 229 | if(rxBufferIndex < rxBufferLength){ 230 | value = rxBuffer[rxBufferIndex]; 231 | } 232 | 233 | return value; 234 | } 235 | 236 | 237 | /******************* 238 | * Private methods * 239 | *******************/ 240 | 241 | // Exposes the physical address defined in the passed structure using mmap on /dev/mem 242 | int WirePi::map_peripheral(struct bcm2835_peripheral *p) { 243 | // Open /dev/mem 244 | if ((p->mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) { 245 | printf("Failed to open /dev/mem, try checking permissions.\n"); 246 | return -1; 247 | } 248 | 249 | p->map = mmap( 250 | NULL, 251 | BLOCK_SIZE, 252 | PROT_READ|PROT_WRITE, 253 | MAP_SHARED, 254 | p->mem_fd, // File descriptor to physical memory virtual file '/dev/mem' 255 | p->addr_p // Address in physical map that we want this memory block to expose 256 | ); 257 | 258 | if (p->map == MAP_FAILED) { 259 | perror("mmap"); 260 | return -1; 261 | } 262 | 263 | p->addr = (volatile unsigned int *)p->map; 264 | 265 | return 0; 266 | } 267 | 268 | void WirePi::unmap_peripheral(struct bcm2835_peripheral *p) { 269 | munmap(p->map, BLOCK_SIZE); 270 | unistd::close(p->mem_fd); 271 | } 272 | 273 | -------------------------------------------------------------------------------- /arduino/libraries/cores/wiring.h: -------------------------------------------------------------------------------- 1 | #ifndef WIRING_HEADER 2 | #define WIRING_HEADER 3 | 4 | #define SERIAL_IO_ADDR 0x20 5 | 6 | #define IOBASE 0x20000000 7 | 8 | 9 | #define GPIO_BASE (IOBASE + 0x200000) 10 | #define BCM2835_SPI0_BASE (IOBASE + 0x204000) 11 | 12 | 13 | 14 | #define GPFSEL0 *(gpio.addr + 0) 15 | #define GPFSEL1 *(gpio.addr + 1) 16 | #define GPFSEL2 *(gpio.addr + 2) 17 | #define GPFSEL3 *(gpio.addr + 3) 18 | #define GPFSEL4 *(gpio.addr + 4) 19 | #define GPFSEL5 *(gpio.addr + 5) 20 | 21 | // Reserved @ word offset 6 22 | #define GPSET0 *(gpio.addr + 7) 23 | #define GPSET1 *(gpio.addr + 8) 24 | // Reserved @ word offset 9 25 | #define GPCLR0 *(gpio.addr + 10) 26 | #define GPCLR1 *(gpio.addr + 11) 27 | // Reserved @ word offset 12 28 | #define GPLEV0 *(gpio.addr + 13) 29 | #define GPLEV1 *(gpio.addr + 14) 30 | 31 | 32 | 33 | 34 | 35 | #define PAGESIZE 4096 36 | #define BLOCK_SIZE 4096 37 | 38 | 39 | /// Defines for SPI 40 | /// GPIO register offsets from BCM2835_SPI0_BASE. 41 | /// Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map 42 | #define BCM2835_SPI0_CS 0x0000 ///< SPI Master Control and Status 43 | #define BCM2835_SPI0_FIFO 0x0004 ///< SPI Master TX and RX FIFOs 44 | #define BCM2835_SPI0_CLK 0x0008 ///< SPI Master Clock Divider 45 | #define BCM2835_SPI0_DLEN 0x000c ///< SPI Master Data Length 46 | #define BCM2835_SPI0_LTOH 0x0010 ///< SPI LOSSI mode TOH 47 | #define BCM2835_SPI0_DC 0x0014 ///< SPI DMA DREQ Controls 48 | 49 | // Register masks for SPI0_CS 50 | #define BCM2835_SPI0_CS_LEN_LONG 0x02000000 ///< Enable Long data word in Lossi mode if DMA_LEN is set 51 | #define BCM2835_SPI0_CS_DMA_LEN 0x01000000 ///< Enable DMA mode in Lossi mode 52 | #define BCM2835_SPI0_CS_CSPOL2 0x00800000 ///< Chip Select 2 Polarity 53 | #define BCM2835_SPI0_CS_CSPOL1 0x00400000 ///< Chip Select 1 Polarity 54 | #define BCM2835_SPI0_CS_CSPOL0 0x00200000 ///< Chip Select 0 Polarity 55 | #define BCM2835_SPI0_CS_RXF 0x00100000 ///< RXF - RX FIFO Full 56 | #define BCM2835_SPI0_CS_RXR 0x00080000 ///< RXR RX FIFO needs Reading ( full) 57 | #define BCM2835_SPI0_CS_TXD 0x00040000 ///< TXD TX FIFO can accept Data 58 | #define BCM2835_SPI0_CS_RXD 0x00020000 ///< RXD RX FIFO contains Data 59 | #define BCM2835_SPI0_CS_DONE 0x00010000 ///< Done transfer Done 60 | #define BCM2835_SPI0_CS_TE_EN 0x00008000 ///< Unused 61 | #define BCM2835_SPI0_CS_LMONO 0x00004000 ///< Unused 62 | #define BCM2835_SPI0_CS_LEN 0x00002000 ///< LEN LoSSI enable 63 | #define BCM2835_SPI0_CS_REN 0x00001000 ///< REN Read Enable 64 | #define BCM2835_SPI0_CS_ADCS 0x00000800 ///< ADCS Automatically Deassert Chip Select 65 | #define BCM2835_SPI0_CS_INTR 0x00000400 ///< INTR Interrupt on RXR 66 | #define BCM2835_SPI0_CS_INTD 0x00000200 ///< INTD Interrupt on Done 67 | #define BCM2835_SPI0_CS_DMAEN 0x00000100 ///< DMAEN DMA Enable 68 | #define BCM2835_SPI0_CS_TA 0x00000080 ///< Transfer Active 69 | #define BCM2835_SPI0_CS_CSPOL 0x00000040 ///< Chip Select Polarity 70 | #define BCM2835_SPI0_CS_CLEAR 0x00000030 ///< Clear FIFO Clear RX and TX 71 | #define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 ///< Clear FIFO Clear RX 72 | #define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 ///< Clear FIFO Clear TX 73 | #define BCM2835_SPI0_CS_CPOL 0x00000008 ///< Clock Polarity 74 | #define BCM2835_SPI0_CS_CPHA 0x00000004 ///< Clock Phase 75 | #define BCM2835_SPI0_CS_CS 0x00000003 ///< Chip Select 76 | 77 | #define BCM2835_GPFSEL0 0x0000 ///< GPIO Function Select 0 78 | 79 | #define BCM2835_GPEDS0 0x0040 ///< GPIO Pin Event Detect Status 0 80 | #define BCM2835_GPREN0 0x004c ///< GPIO Pin Rising Edge Detect Enable 0 81 | #define BCM2835_GPFEN0 0x0048 ///< GPIO Pin Falling Edge Detect Enable 0 82 | #define BCM2835_GPHEN0 0x0064 ///< GPIO Pin High Detect Enable 0 83 | #define BCM2835_GPLEN0 0x0070 ///< GPIO Pin Low Detect Enable 0 84 | 85 | #define CS 10 86 | #define MOSI 11 87 | #define MISO 12 88 | #define SCK 13 89 | 90 | 91 | static int REV = 0; 92 | 93 | /// \brief bcm2835SPIBitOrder 94 | /// Specifies the SPI data bit ordering 95 | typedef enum 96 | { 97 | LSBFIRST = 0, ///< LSB First 98 | MSBFIRST = 1 ///< MSB First 99 | }bcm2835SPIBitOrder; 100 | 101 | /// \brief bcm2835SPIMode 102 | /// Specify the SPI data mode 103 | typedef enum 104 | { 105 | SPI_MODE0 = 0, ///< CPOL = 0, CPHA = 0 106 | SPI_MODE1 = 1, ///< CPOL = 0, CPHA = 1 107 | SPI_MODE2 = 2, ///< CPOL = 1, CPHA = 0 108 | SPI_MODE3 = 3, ///< CPOL = 1, CPHA = 1 109 | }bcm2835SPIMode; 110 | 111 | /// \brief bcm2835SPIChipSelect 112 | /// Specify the SPI chip select pin(s) 113 | typedef enum 114 | { 115 | SPI_CS0 = 0, ///< Chip Select 0 116 | SPI_CS1 = 1, ///< Chip Select 1 117 | SPI_CS2 = 2, ///< Chip Select 2 (ie pins CS1 and CS2 are asserted) 118 | SPI_CS_NONE = 3, ///< No CS, control it yourself 119 | } bcm2835SPIChipSelect; 120 | 121 | /// \brief bcm2835SPIClockDivider 122 | /// Specifies the divider used to generate the SPI clock from the system clock. 123 | /// Figures below give the divider, clock period and clock frequency. 124 | typedef enum 125 | { 126 | SPI_CLOCK_DIV65536 = 0, ///< 65536 = 256us = 4kHz 127 | SPI_CLOCK_DIV32768 = 32768, ///< 32768 = 126us = 8kHz 128 | SPI_CLOCK_DIV16384 = 16384, ///< 16384 = 64us = 15.625kHz 129 | SPI_CLOCK_DIV8192 = 8192, ///< 8192 = 32us = 31.25kHz 130 | SPI_CLOCK_DIV4096 = 4096, ///< 4096 = 16us = 62.5kHz 131 | SPI_CLOCK_DIV2048 = 2048, ///< 2048 = 8us = 125kHz 132 | SPI_CLOCK_DIV1024 = 1024, ///< 1024 = 4us = 250kHz 133 | SPI_CLOCK_DIV512 = 512, ///< 512 = 2us = 500kHz 134 | SPI_CLOCK_DIV256 = 256, ///< 256 = 1us = 1MHz 135 | SPI_CLOCK_DIV128 = 128, ///< 128 = 500ns = = 2MHz 136 | SPI_CLOCK_DIV64 = 64, ///< 64 = 250ns = 4MHz 137 | SPI_CLOCK_DIV32 = 32, ///< 32 = 125ns = 8MHz 138 | SPI_CLOCK_DIV16 = 16, ///< 16 = 50ns = 20MHz 139 | SPI_CLOCK_DIV8 = 8, ///< 8 = 25ns = 40MHz 140 | SPI_CLOCK_DIV4 = 4, ///< 4 = 12.5ns 80MHz 141 | SPI_CLOCK_DIV2 = 2, ///< 2 = 6.25ns = 160MHz 142 | SPI_CLOCK_DIV1 = 1, ///< 0 = 256us = 4kHz 143 | } bcm2835SPIClockDivider; 144 | 145 | typedef enum 146 | { 147 | BCM2835_GPIO_FSEL_INPT = 0b000, ///< Input 148 | BCM2835_GPIO_FSEL_OUTP = 0b001, ///< Output 149 | BCM2835_GPIO_FSEL_ALT0 = 0b100, ///< Alternate function 0 150 | BCM2835_GPIO_FSEL_ALT1 = 0b101, ///< Alternate function 1 151 | BCM2835_GPIO_FSEL_ALT2 = 0b110, ///< Alternate function 2 152 | BCM2835_GPIO_FSEL_ALT3 = 0b111, ///< Alternate function 3 153 | BCM2835_GPIO_FSEL_ALT4 = 0b011, ///< Alternate function 4 154 | BCM2835_GPIO_FSEL_ALT5 = 0b010, ///< Alternate function 5 155 | BCM2835_GPIO_FSEL_MASK = 0b111 ///< Function select bits mask 156 | } bcm2835FunctionSelect; 157 | 158 | 159 | namespace unistd { 160 | //All functions of unistd.h must be called like this: unistd::the_function() 161 | #include 162 | } 163 | 164 | 165 | enum Representation{ 166 | BIN, 167 | OCT, 168 | DEC, 169 | HEX, 170 | BYTE 171 | }; 172 | 173 | typedef enum { 174 | INPUT, 175 | OUTPUT 176 | }Pinmode; 177 | 178 | typedef enum { 179 | LOW = 0, 180 | HIGH = 1, 181 | RISING = 2, 182 | FALLING = 3, 183 | BOTH = 4 184 | }Digivalue; 185 | 186 | typedef bool boolean; 187 | typedef unsigned char byte; 188 | 189 | struct bcm2835_peripheral { 190 | unsigned long addr_p; 191 | int mem_fd; 192 | void *map; 193 | volatile unsigned int *addr; 194 | }; 195 | 196 | struct ThreadArg{ 197 | void (*func)(); 198 | int pin; 199 | }; 200 | 201 | 202 | 203 | /* SerialPi Class 204 | * Class that provides the functionality of arduino Serial library 205 | */ 206 | class SerialPi { 207 | 208 | private: 209 | int sd,status; 210 | const char *serialPort; 211 | unsigned char c; 212 | struct termios options; 213 | int speed; 214 | long timeOut; 215 | timespec time1, time2; 216 | timespec timeDiff(timespec start, timespec end); 217 | char * int2bin(int i); 218 | char * int2hex(int i); 219 | char * int2oct(int i); 220 | 221 | public: 222 | 223 | SerialPi(); 224 | void begin(int serialSpeed); 225 | int available(); 226 | char read(); 227 | int readBytes(char message[], int size); 228 | int readBytesUntil(char character,char buffer[],int length); 229 | bool find(const char *target); 230 | bool findUntil(const char *target, const char *terminal); 231 | long parseInt(); 232 | float parseFloat(); 233 | char peek(); 234 | void print(const char *message); 235 | void print(char message); 236 | void print(unsigned char i,Representation rep); 237 | void print(float f, int precission); 238 | void println(const char *message); 239 | void println(char message); 240 | void println(int i, Representation rep); 241 | void println(float f, int precission); 242 | int write(unsigned char message); 243 | int write(const char *message); 244 | int write (char *message, int size); 245 | void flush(); 246 | void setTimeout(long millis); 247 | void end(); 248 | }; 249 | 250 | class SPIPi{ 251 | public: 252 | SPIPi(); 253 | void begin(); 254 | void end(); 255 | void setBitOrder(uint8_t order); 256 | void setClockDivider(uint16_t divider); 257 | void setDataMode(uint8_t mode); 258 | void chipSelect(uint8_t cs); 259 | void setChipSelectPolarity(uint8_t cs, uint8_t active); 260 | uint8_t transfer(uint8_t value); 261 | void transfernb(char* tbuf, char* rbuf, uint32_t len); 262 | }; 263 | 264 | /* Some useful arduino functions */ 265 | void pinMode(int pin, Pinmode mode); 266 | //void pinEn5v(int pin); 267 | //void pinDis5v(int pin); 268 | void digitalWrite(int pin, int value); 269 | int digitalRead(int pin); 270 | int analogRead (int pin); 271 | void delay(long millis); 272 | void delayMicroseconds(long micros); 273 | uint8_t shiftIn (uint8_t dPin, uint8_t cPin, bcm2835SPIBitOrder order); 274 | void shiftOut (uint8_t dPin, uint8_t cPin, bcm2835SPIBitOrder order, uint8_t val); 275 | void attachInterrupt(int p,void (*f)(), Digivalue m); 276 | void detachInterrupt(int p); 277 | void setup(); 278 | void loop(); 279 | long millis(); 280 | 281 | /* Helper functions */ 282 | int getBoardRev(); 283 | uint32_t *mapmem(const char *msg, size_t size, int fd, off_t off); 284 | void setBoardRev(int rev); 285 | int raspberryPinNumber(int arduinoPin); 286 | pthread_t *getThreadIdFromPin(int pin); 287 | uint32_t bcm2835_peri_read(volatile uint32_t* paddr); 288 | uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr); 289 | void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value); 290 | void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value); 291 | void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask); 292 | void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode); 293 | void * threadFunction(void *args); 294 | 295 | extern SerialPi Serial; 296 | extern SPIPi SPI; 297 | 298 | #endif // WIRING_HEADER 299 | -------------------------------------------------------------------------------- /arduino/libraries/cores/wiring.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 Libelium Comunicaciones Distribuidas S.L. 3 | * http://www.libelium.com 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * Version 1.5 19 | * Author: Anartz Nuin Jiménez 20 | */ 21 | 22 | #include "../includes.h" 23 | 24 | struct bcm2835_peripheral gpio = {GPIO_BASE}; 25 | struct bcm2835_peripheral bsc_rev1 = {IOBASE + 0X205000}; 26 | struct bcm2835_peripheral bsc_rev2 = {IOBASE + 0X804000}; 27 | struct bcm2835_peripheral bsc0; 28 | 29 | 30 | void *spi0 = MAP_FAILED; 31 | static uint8_t *spi0Mem = NULL; 32 | 33 | pthread_t idThread2; 34 | pthread_t idThread3; 35 | pthread_t idThread4; 36 | pthread_t idThread5; 37 | pthread_t idThread6; 38 | pthread_t idThread7; 39 | pthread_t idThread8; 40 | pthread_t idThread9; 41 | pthread_t idThread10; 42 | pthread_t idThread11; 43 | pthread_t idThread12; 44 | pthread_t idThread13; 45 | 46 | timeval start_program, end_point; 47 | 48 | 49 | /********************************* 50 | * * 51 | * SerialPi Class implementation * 52 | * ----------------------------- * 53 | *********************************/ 54 | 55 | /****************** 56 | * Public methods * 57 | ******************/ 58 | 59 | //Constructor 60 | SerialPi::SerialPi(){ 61 | REV = getBoardRev(); 62 | serialPort="/dev/ttyAMA0"; 63 | timeOut = 1000; 64 | } 65 | 66 | //Sets the data rate in bits per second (baud) for serial data transmission 67 | void SerialPi::begin(int serialSpeed){ 68 | 69 | switch(serialSpeed){ 70 | case 50: speed = B50 ; break ; 71 | case 75: speed = B75 ; break ; 72 | case 110: speed = B110 ; break ; 73 | case 134: speed = B134 ; break ; 74 | case 150: speed = B150 ; break ; 75 | case 200: speed = B200 ; break ; 76 | case 300: speed = B300 ; break ; 77 | case 600: speed = B600 ; break ; 78 | case 1200: speed = B1200 ; break ; 79 | case 1800: speed = B1800 ; break ; 80 | case 2400: speed = B2400 ; break ; 81 | case 9600: speed = B9600 ; break ; 82 | case 19200: speed = B19200 ; break ; 83 | case 38400: speed = B38400 ; break ; 84 | case 57600: speed = B57600 ; break ; 85 | case 115200: speed = B115200 ; break ; 86 | default: speed = B230400 ; break ; 87 | 88 | } 89 | 90 | 91 | if ((sd = open(serialPort, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1){ 92 | fprintf(stderr,"Unable to open the serial port %s - \n", serialPort); 93 | exit(-1); 94 | } 95 | 96 | fcntl (sd, F_SETFL, O_RDWR) ; 97 | 98 | tcgetattr(sd, &options); 99 | cfmakeraw(&options); 100 | cfsetispeed (&options, speed); 101 | cfsetospeed (&options, speed); 102 | 103 | options.c_cflag |= (CLOCAL | CREAD); 104 | options.c_cflag &= ~PARENB; 105 | options.c_cflag &= ~CSTOPB; 106 | options.c_cflag &= ~CSIZE; 107 | options.c_cflag |= CS8; 108 | options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 109 | options.c_oflag &= ~OPOST; 110 | 111 | tcsetattr (sd, TCSANOW, &options); 112 | 113 | ioctl (sd, TIOCMGET, &status); 114 | 115 | status |= TIOCM_DTR; 116 | status |= TIOCM_RTS; 117 | 118 | ioctl (sd, TIOCMSET, &status); 119 | 120 | unistd::usleep (10000); 121 | 122 | } 123 | 124 | //Prints data to the serial port as human-readable ASCII text. 125 | void SerialPi::print(const char *message){ 126 | unistd::write(sd,message,strlen(message)); 127 | } 128 | 129 | //Prints data to the serial port as human-readable ASCII text. 130 | void SerialPi::print (char message){ 131 | unistd::write(sd,&message,1); 132 | } 133 | 134 | /*Prints data to the serial port as human-readable ASCII text. 135 | * It can print the message in many format representations such as: 136 | * Binary, Octal, Decimal, Hexadecimal and as a BYTE. */ 137 | void SerialPi::print(unsigned char i,Representation rep){ 138 | char * message; 139 | switch(rep){ 140 | 141 | case BIN: 142 | message = int2bin(i); 143 | unistd::write(sd,message,strlen(message)); 144 | break; 145 | case OCT: 146 | message = int2oct(i); 147 | unistd::write(sd,message,strlen(message)); 148 | break; 149 | case DEC: 150 | sprintf(message,"%d",i); 151 | unistd::write(sd,message,strlen(message)); 152 | break; 153 | case HEX: 154 | message = int2hex(i); 155 | unistd::write(sd,message,strlen(message)); 156 | break; 157 | case BYTE: 158 | unistd::write(sd,&i,1); 159 | break; 160 | 161 | } 162 | } 163 | 164 | /* Prints data to the serial port as human-readable ASCII text. 165 | * precission is used to limit the number of decimals. 166 | */ 167 | void SerialPi::print(float f, int precission){ 168 | /* 169 | const char *str1="%."; 170 | char * str2; 171 | char * str3; 172 | char * message; 173 | sprintf(str2,"%df",precission); 174 | asprintf(&str3,"%s%s",str1,str2); 175 | sprintf(message,str3,f); 176 | */ 177 | char message[10]; 178 | sprintf(message, "%.1f", f ); 179 | unistd::write(sd,message,strlen(message)); 180 | } 181 | 182 | /* Prints data to the serial port as human-readable ASCII text followed 183 | * by a carriage retrun character '\r' and a newline character '\n' */ 184 | void SerialPi::println(const char *message){ 185 | const char *newline="\r\n"; 186 | char * msg = NULL; 187 | asprintf(&msg,"%s%s",message,newline); 188 | unistd::write(sd,msg,strlen(msg)); 189 | } 190 | 191 | /* Prints data to the serial port as human-readable ASCII text followed 192 | * by a carriage retrun character '\r' and a newline character '\n' */ 193 | void SerialPi::println(char message){ 194 | const char *newline="\r\n"; 195 | char * msg = NULL; 196 | asprintf(&msg,"%s%s",&message,newline); 197 | unistd::write(sd,msg,strlen(msg)); 198 | } 199 | 200 | /* Prints data to the serial port as human-readable ASCII text followed 201 | * by a carriage retrun character '\r' and a newline character '\n' */ 202 | void SerialPi::println(int i, Representation rep){ 203 | char * message; 204 | switch(rep){ 205 | 206 | case BIN: 207 | message = int2bin(i); 208 | break; 209 | case OCT: 210 | message = int2oct(i); 211 | break; 212 | case DEC: 213 | sprintf(message,"%d",i); 214 | break; 215 | case HEX: 216 | message = int2hex(i); 217 | break; 218 | 219 | } 220 | 221 | const char *newline="\r\n"; 222 | char * msg = NULL; 223 | asprintf(&msg,"%s%s",message,newline); 224 | unistd::write(sd,msg,strlen(msg)); 225 | } 226 | 227 | /* Prints data to the serial port as human-readable ASCII text followed 228 | * by a carriage retrun character '\r' and a newline character '\n' */ 229 | void SerialPi::println(float f, int precission){ 230 | const char *str1="%."; 231 | char * str2; 232 | char * str3; 233 | char * message; 234 | sprintf(str2,"%df",precission); 235 | asprintf(&str3,"%s%s",str1,str2); 236 | sprintf(message,str3,f); 237 | 238 | const char *newline="\r\n"; 239 | char * msg = NULL; 240 | asprintf(&msg,"%s%s",message,newline); 241 | unistd::write(sd,msg,strlen(msg)); 242 | } 243 | 244 | /* Writes binary data to the serial port. This data is sent as a byte 245 | * Returns: number of bytes written */ 246 | int SerialPi::write(unsigned char message){ 247 | unistd::write(sd,&message,1); 248 | return 1; 249 | } 250 | 251 | /* Writes binary data to the serial port. This data is sent as a series 252 | * of bytes 253 | * Returns: number of bytes written */ 254 | int SerialPi::write(const char *message){ 255 | int len = strlen(message); 256 | unistd::write(sd,&message,len); 257 | return len; 258 | } 259 | 260 | /* Writes binary data to the serial port. This data is sent as a series 261 | * of bytes placed in an buffer. It needs the length of the buffer 262 | * Returns: number of bytes written */ 263 | int SerialPi::write(char *message, int size){ 264 | unistd::write(sd,message,size); 265 | return size; 266 | } 267 | 268 | /* Get the numberof bytes (characters) available for reading from 269 | * the serial port. 270 | * Return: number of bytes avalable to read */ 271 | int SerialPi::available(){ 272 | int nbytes = 0; 273 | if (ioctl(sd, FIONREAD, &nbytes) < 0) { 274 | fprintf(stderr, "Failed to get byte count on serial.\n"); 275 | exit(-1); 276 | } 277 | return nbytes; 278 | } 279 | 280 | /* Reads 1 byte of incoming serial data 281 | * Returns: first byte of incoming serial data available */ 282 | char SerialPi::read() { 283 | unistd::read(sd,&c,1); 284 | return c; 285 | } 286 | 287 | /* Reads characters from th serial port into a buffer. The function 288 | * terminates if the determined length has been read, or it times out 289 | * Returns: number of bytes readed */ 290 | int SerialPi::readBytes(char message[], int size){ 291 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 292 | int count; 293 | for (count=0;counttimeOut) break; 298 | } 299 | return count; 300 | } 301 | 302 | /* Reads characters from the serial buffer into an array. 303 | * The function terminates if the terminator character is detected, 304 | * the determined length has been read, or it times out. 305 | * Returns: number of characters read into the buffer. */ 306 | int SerialPi::readBytesUntil(char character,char buffer[],int length){ 307 | char lastReaded = character +1; //Just to make lastReaded != character 308 | int count=0; 309 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 310 | while(count != length && lastReaded != character){ 311 | if(available()) unistd::read(sd,&buffer[count],1); 312 | lastReaded = buffer[count]; 313 | count ++; 314 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); 315 | timespec t = timeDiff(time1,time2); 316 | if((t.tv_nsec/1000)>timeOut) break; 317 | } 318 | 319 | return count; 320 | } 321 | 322 | 323 | bool SerialPi::find(const char *target){ 324 | findUntil(target,NULL); 325 | } 326 | 327 | /* Reads data from the serial buffer until a target string of given length 328 | * or terminator string is found. 329 | * Returns: true if the target string is found, false if it times out */ 330 | bool SerialPi::findUntil(const char *target, const char *terminal){ 331 | int index = 0; 332 | int termIndex = 0; 333 | int targetLen = strlen(target); 334 | int termLen = strlen(terminal); 335 | char readed; 336 | timespec t; 337 | 338 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1); 339 | 340 | if( *target == 0) 341 | return true; // return true if target is a null string 342 | 343 | do{ 344 | if(available()){ 345 | unistd::read(sd,&readed,1); 346 | if(readed != target[index]) 347 | index = 0; // reset index if any char does not match 348 | 349 | if( readed == target[index]){ 350 | if(++index >= targetLen){ // return true if all chars in the target match 351 | return true; 352 | } 353 | } 354 | 355 | if(termLen > 0 && c == terminal[termIndex]){ 356 | if(++termIndex >= termLen) return false; // return false if terminate string found before target string 357 | }else{ 358 | termIndex = 0; 359 | } 360 | } 361 | 362 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2); 363 | t = timeDiff(time1,time2); 364 | 365 | }while((t.tv_nsec/1000)<=timeOut); 366 | 367 | return false; 368 | } 369 | 370 | /* returns the first valid (long) integer value from the current position. 371 | * initial characters that are not digits (or the minus sign) are skipped 372 | * function is terminated by the first character that is not a digit. */ 373 | long SerialPi::parseInt(){ 374 | bool isNegative = false; 375 | long value = 0; 376 | char c; 377 | 378 | //Skip characters until a number or - sign found 379 | do{ 380 | c = peek(); 381 | if (c == '-') break; 382 | if (c >= '0' && c <= '9') break; 383 | unistd::read(sd,&c,1); // discard non-numeric 384 | }while(1); 385 | 386 | do{ 387 | if(c == '-') 388 | isNegative = true; 389 | else if(c >= '0' && c <= '9')// is c a digit? 390 | value = value * 10 + c - '0'; 391 | unistd::read(sd,&c,1); // consume the character we got with peek 392 | c = peek(); 393 | 394 | }while(c >= '0' && c <= '9'); 395 | 396 | if(isNegative) 397 | value = -value; 398 | return value; 399 | } 400 | 401 | float SerialPi::parseFloat(){ 402 | boolean isNegative = false; 403 | boolean isFraction = false; 404 | long value = 0; 405 | char c; 406 | float fraction = 1.0; 407 | 408 | //Skip characters until a number or - sign found 409 | do{ 410 | c = peek(); 411 | if (c == '-') break; 412 | if (c >= '0' && c <= '9') break; 413 | unistd::read(sd,&c,1); // discard non-numeric 414 | }while(1); 415 | 416 | do{ 417 | if(c == '-') 418 | isNegative = true; 419 | else if (c == '.') 420 | isFraction = true; 421 | else if(c >= '0' && c <= '9') { // is c a digit? 422 | value = value * 10 + c - '0'; 423 | if(isFraction) 424 | fraction *= 0.1; 425 | } 426 | unistd::read(sd,&c,1); // consume the character we got with peek 427 | c = peek(); 428 | }while( (c >= '0' && c <= '9') || (c == '.' && isFraction==false)); 429 | 430 | if(isNegative) 431 | value = -value; 432 | if(isFraction) 433 | return value * fraction; 434 | else 435 | return value; 436 | 437 | 438 | } 439 | 440 | // Returns the next byte (character) of incoming serial data without removing it from the internal serial buffer. 441 | char SerialPi::peek(){ 442 | //We obtain a pointer to FILE structure from the file descriptor sd 443 | FILE * f = fdopen(sd,"r+"); 444 | //With a pointer to FILE we can do getc and ungetc 445 | c = getc(f); 446 | ungetc(c, f); 447 | return c; 448 | } 449 | 450 | // Remove any data remaining on the serial buffer 451 | void SerialPi::flush(){ 452 | while(available()){ 453 | unistd::read(sd,&c,1); 454 | } 455 | } 456 | 457 | /* Sets the maximum milliseconds to wait for serial data when using SerialPi::readBytes() 458 | * The default value is set to 1000 */ 459 | void SerialPi::setTimeout(long millis){ 460 | timeOut = millis; 461 | } 462 | 463 | //Disables serial communication 464 | void SerialPi::end(){ 465 | unistd::close(sd); 466 | } 467 | 468 | /******************* 469 | * Private methods * 470 | *******************/ 471 | 472 | //Returns a timespec struct with the time elapsed between start and end timespecs 473 | timespec SerialPi::timeDiff(timespec start, timespec end){ 474 | timespec temp; 475 | if ((end.tv_nsec-start.tv_nsec)<0) { 476 | temp.tv_sec = end.tv_sec-start.tv_sec-1; 477 | temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; 478 | } else { 479 | temp.tv_sec = end.tv_sec-start.tv_sec; 480 | temp.tv_nsec = end.tv_nsec-start.tv_nsec; 481 | } 482 | return temp; 483 | } 484 | 485 | //Returns a binary representation of the integer passed as argument 486 | char * SerialPi::int2bin(int i){ 487 | size_t bits = sizeof(int) * CHAR_BIT; 488 | char * str = (char *)malloc(bits + 1); 489 | int firstCeros = 0; 490 | int size = bits; 491 | if(!str) return NULL; 492 | str[bits] = 0; 493 | 494 | // type punning because signed shift is implementation-defined 495 | unsigned u = *(unsigned *)&i; 496 | for(; bits--; u >>= 1) 497 | str[bits] = u & 1 ? '1' : '0'; 498 | 499 | //Delete first 0's 500 | for (int i=0; i 100){ 704 | struct timespec tim, tim2; 705 | tim.tv_sec = 0; 706 | tim.tv_nsec = micros * 1000; 707 | 708 | if(nanosleep(&tim , &tim2) < 0 ) { 709 | fprintf(stderr,"Nano sleep system call failed \n"); 710 | exit(1); 711 | } 712 | }else{ 713 | struct timeval tNow, tLong, tEnd ; 714 | 715 | gettimeofday (&tNow, NULL) ; 716 | tLong.tv_sec = micros / 1000000 ; 717 | tLong.tv_usec = micros % 1000000 ; 718 | timeradd (&tNow, &tLong, &tEnd) ; 719 | 720 | while (timercmp (&tNow, &tEnd, <)) 721 | gettimeofday (&tNow, NULL) ; 722 | } 723 | } 724 | 725 | uint8_t shiftIn(uint8_t dPin, uint8_t cPin, bcm2835SPIBitOrder order){ 726 | uint8_t value = 0 ; 727 | int8_t i ; 728 | 729 | if (order == MSBFIRST) 730 | for (i = 7 ; i >= 0 ; --i){ 731 | digitalWrite (cPin, HIGH); 732 | value |= digitalRead (dPin) << i; 733 | digitalWrite (cPin, LOW); 734 | } 735 | else 736 | for (i = 0 ; i < 8 ; ++i){ 737 | digitalWrite (cPin, HIGH); 738 | value |= digitalRead (dPin) << i; 739 | digitalWrite (cPin, LOW); 740 | } 741 | 742 | return value; 743 | } 744 | 745 | void shiftOut(uint8_t dPin, uint8_t cPin, bcm2835SPIBitOrder order, uint8_t val){ 746 | int8_t i; 747 | 748 | if (order == MSBFIRST) 749 | for (i = 7 ; i >= 0 ; --i){ 750 | digitalWrite (dPin, val & (1 << i)) ; 751 | digitalWrite (cPin, HIGH) ; 752 | digitalWrite (cPin, LOW) ; 753 | } 754 | else 755 | for (i = 0 ; i < 8 ; ++i){ 756 | digitalWrite (dPin, val & (1 << i)) ; 757 | digitalWrite (cPin, HIGH) ; 758 | digitalWrite (cPin, LOW) ; 759 | } 760 | } 761 | 762 | 763 | // Configures the specified pin to behave either as an input or an output 764 | void pinMode(int pin, Pinmode mode){ 765 | 766 | uint8_t direction; 767 | uint8_t reg; 768 | //uint8_t pin_number; 769 | 770 | //pin_number = pin; 771 | 772 | if ((pin <= 13)||(pin == PL)) { 773 | pin = raspberryPinNumber(pin); 774 | if(mode == OUTPUT){ 775 | switch (pin) { 776 | case 4: GPFSEL0 &= ~(7 << 12); GPFSEL0 |= (1 << 12); break; 777 | case 7: GPFSEL0 &= ~(7 << 21); GPFSEL0 |= (1 << 21); break; 778 | case 8: GPFSEL0 &= ~(7 << 24); GPFSEL0 |= (1 << 24); break; 779 | case 9: GPFSEL0 &= ~(7 << 27); GPFSEL0 |= (1 << 27); break; 780 | case 10: GPFSEL1 &= ~(7 << 0); GPFSEL1 |= (1 << 0); break; 781 | case 11: GPFSEL1 &= ~(7 << 3); GPFSEL1 |= (1 << 3); break; 782 | case 14: GPFSEL1 &= ~(7 << 12); GPFSEL1 |= (1 << 12); break; 783 | case 15: GPFSEL1 &= ~(7 << 15); GPFSEL1 |= (1 << 15); break; 784 | case 17: GPFSEL1 &= ~(7 << 21); GPFSEL1 |= (1 << 21); break; 785 | case 18: GPFSEL1 &= ~(7 << 24); GPFSEL1 |= (1 << 24); break; 786 | case 21: GPFSEL2 &= ~(7 << 3); GPFSEL2 |= (1 << 3); break; 787 | case 27: GPFSEL2 &= ~(7 << 21); GPFSEL2 |= (1 << 21); break; 788 | case 22: GPFSEL2 &= ~(7 << 6); GPFSEL2 |= (1 << 6); break; 789 | case 23: GPFSEL2 &= ~(7 << 9); GPFSEL2 |= (1 << 9); break; 790 | case 24: GPFSEL2 &= ~(7 << 12); GPFSEL2 |= (1 << 12); break; 791 | case 25: GPFSEL2 &= ~(7 << 15); GPFSEL2 |= (1 << 15); break; 792 | } 793 | 794 | } else if (mode == INPUT) { 795 | switch (pin) { 796 | case 4: GPFSEL0 &= ~(7 << 12); break; 797 | case 7: GPFSEL0 &= ~(7 << 21); break; 798 | case 8: GPFSEL0 &= ~(7 << 24); break; 799 | case 9: GPFSEL0 &= ~(7 << 27); break; 800 | case 10: GPFSEL1 &= ~(7 << 0); break; 801 | case 11: GPFSEL1 &= ~(7 << 3); break; 802 | case 14: GPFSEL1 &= ~(7 << 12); break; 803 | case 15: GPFSEL1 &= ~(7 << 15); break; 804 | case 17: GPFSEL1 &= ~(7 << 21); break; 805 | case 18: GPFSEL1 &= ~(7 << 24); break; 806 | case 21: GPFSEL2 &= ~(7 << 3); break; 807 | case 27: GPFSEL2 &= ~(7 << 3); break; 808 | case 22: GPFSEL2 &= ~(7 << 6); break; 809 | case 23: GPFSEL2 &= ~(7 << 9); break; 810 | case 24: GPFSEL2 &= ~(7 << 12); break; 811 | case 25: GPFSEL2 &= ~(7 << 15); break; 812 | } 813 | } 814 | } else if ((pin >= A0) && (pin <= A7)) { 815 | pin = pin-A0; 816 | RasPiDeckI2CIOSetPinMode(pin,mode); 817 | }; 818 | 819 | /* 820 | else if (pin <= 19) { 821 | direction = SerialIO.direction; 822 | 823 | if (mode == INPUT){ 824 | direction |= 1 << (pin-14); 825 | } else if (mode == OUTPUT){ 826 | direction &= ~(1 << (pin-14)); 827 | } 828 | 829 | if (direction != SerialIO.direction) { 830 | SerialIO.direction = direction; 831 | reg = SerialIO.direction & SerialIO.state; 832 | 833 | Wire.beginTransmission(SERIAL_IO_ADDR); 834 | Wire.write(reg); 835 | Wire.endTransmission(); 836 | } 837 | } 838 | */ 839 | } 840 | 841 | // Write a HIGH or a LOW value to a digital pin 842 | void digitalWrite(int pin, int value) 843 | { 844 | uint8_t state; 845 | uint8_t reg; 846 | 847 | if ((pin <= 13)||(pin==PL)) { 848 | // printf("before pin map\n"); 849 | pin = raspberryPinNumber(pin); 850 | // printf("after pin map\n"); 851 | if (value == HIGH){ 852 | switch(pin){ 853 | case 4:GPSET0 = BIT_4;break; 854 | case 7:GPSET0 = BIT_7;break; 855 | case 8:GPSET0 = BIT_8;break; 856 | case 9:GPSET0 = BIT_9;break; 857 | case 10:GPSET0 = BIT_10;break; 858 | case 11:GPSET0 = BIT_11;break; 859 | case 14:GPSET0 = BIT_14;break; 860 | case 15:GPSET0 = BIT_15;break; 861 | case 17:GPSET0 = BIT_17;break; 862 | case 18:GPSET0 = BIT_18;break; 863 | case 21:GPSET0 = BIT_21;break; 864 | case 27:GPSET0 = BIT_27;break; 865 | case 22:GPSET0 = BIT_22;break; 866 | case 23:GPSET0 = BIT_23;break; 867 | case 24:GPSET0 = BIT_24;break; 868 | case 25:GPSET0 = BIT_25;break; 869 | } 870 | } else if(value == LOW){ 871 | switch(pin){ 872 | case 4:GPCLR0 = BIT_4;break; 873 | case 7:GPCLR0 = BIT_7;break; 874 | case 8:GPCLR0 = BIT_8;break; 875 | case 9:GPCLR0 = BIT_9;break; 876 | case 10:GPCLR0 = BIT_10;break; 877 | case 11:GPCLR0 = BIT_11;break; 878 | case 14:GPCLR0 = BIT_14;break; 879 | case 15:GPCLR0 = BIT_15;break; 880 | case 17:GPCLR0 = BIT_17;break; 881 | case 18:GPCLR0 = BIT_18;break; 882 | case 21:GPCLR0 = BIT_21;break; 883 | case 27:GPCLR0 = BIT_27;break; 884 | case 22:GPCLR0 = BIT_22;break; 885 | case 23:GPCLR0 = BIT_23;break; 886 | case 24:GPCLR0 = BIT_24;break; 887 | case 25:GPCLR0 = BIT_25;break; 888 | } 889 | } 890 | delayMicroseconds(1); // Delay to allow any change in state to be reflected in the LEVn, register bit. 891 | } else if ((pin >= A0)&&(pin <= A7)) { 892 | RasPiDeckI2CIOSetPinStatus(pin-A0, value); 893 | } 894 | 895 | /* 896 | else if (pin <= 19) { 897 | state = SerialIO.state; 898 | 899 | if (value == HIGH){ 900 | state |= 1 << (pin-14); 901 | } else if (value == LOW){ 902 | state &= ~(1 << (pin-14)); 903 | } 904 | 905 | if (state != SerialIO.state) { 906 | SerialIO.state = state; 907 | reg = SerialIO.direction & SerialIO.state; 908 | 909 | Wire.beginTransmission(SERIAL_IO_ADDR); 910 | Wire.write(reg); 911 | Wire.endTransmission(); 912 | } 913 | } else if (pin == PL) { // Peripheral Transceiver Enable/Disable 914 | if (value == HIGH){ 915 | GPSET0 = BIT_7; 916 | } else { 917 | GPCLR0 = BIT_7; 918 | } 919 | } 920 | 921 | 922 | */ 923 | } 924 | 925 | 926 | 927 | // Reads the value from a specified digital pin, either HIGH or LOW. 928 | int digitalRead(int pin){ 929 | Digivalue value; 930 | 931 | if ((pin <= 13)||(pin==PL)) { 932 | pin = raspberryPinNumber(pin); 933 | switch (pin) { 934 | case 4: if(GPLEV0 & BIT_4){value = HIGH;} else{value = LOW;};break; 935 | case 7: if(GPLEV0 & BIT_7){value = HIGH;} else{value = LOW;};break; 936 | case 8: if(GPLEV0 & BIT_8){value = HIGH;} else{value = LOW;};break; 937 | case 9: if(GPLEV0 & BIT_9){value = HIGH;} else{value = LOW;};break; 938 | case 10:if(GPLEV0 & BIT_10){value = HIGH;} else{value = LOW;};break; 939 | case 11:if(GPLEV0 & BIT_11){value = HIGH;} else{value = LOW;};break; 940 | case 14:if(GPLEV0 & BIT_14){value = HIGH;} else{value = LOW;};break; 941 | case 15:if(GPLEV0 & BIT_15){value = HIGH;} else{value = LOW;};break; 942 | case 17:if(GPLEV0 & BIT_17){value = HIGH;}else{value = LOW;};break; 943 | case 18:if(GPLEV0 & BIT_18){value = HIGH;}else{value = LOW;};break; 944 | case 21:if(GPLEV0 & BIT_21){value = HIGH;}else{value = LOW;};break; 945 | case 27:if(GPLEV0 & BIT_27){value = HIGH;}else{value = LOW;};break; 946 | case 22:if(GPLEV0 & BIT_22){value = HIGH;}else{value = LOW;};break; 947 | case 23:if(GPLEV0 & BIT_23){value = HIGH;}else{value = LOW;};break; 948 | case 24:if(GPLEV0 & BIT_24){value = HIGH;}else{value = LOW;};break; 949 | case 25:if(GPLEV0 & BIT_25){value = HIGH;}else{value = LOW;};break; 950 | } 951 | 952 | } else if ((pin >= A0)&&(pin <= A7)) { 953 | if ( RasPiDeckI2CIOGetPinStatus((uint8_t)pin-A0) == 0) { 954 | return LOW; 955 | } else { 956 | return HIGH; 957 | } 958 | } 959 | /* 960 | else if (pin <= 19) { 961 | if (Wire.requestFrom(SERIAL_IO_ADDR, 1)) { 962 | reg = Wire.read(); 963 | if (reg & (1 << (pin-14))) { 964 | value = HIGH; 965 | } else { 966 | value = LOW; 967 | } 968 | } 969 | } else if ( pin == PL) { 970 | if(GPLEV0 & BIT_7) { 971 | value = HIGH; 972 | } else{ 973 | value = LOW; 974 | } 975 | } 976 | */ 977 | return value; 978 | } 979 | /* 980 | int analogRead (int pin){ 981 | 982 | int value; 983 | int address; 984 | 985 | if (pin == 0) { 986 | address = 0xDC; 987 | } else if (pin == 1){ 988 | address = 0x9C; 989 | } else if (pin == 2){ 990 | address = 0xCC ; 991 | } else if (pin == 3){ 992 | address = 0x8C; 993 | } else if (pin == 4){ 994 | address = 0xAC; 995 | } else if (pin == 5){ 996 | address = 0xEC; 997 | } else if (pin == 6){ 998 | address = 0xBC; 999 | } else if (pin == 7){ 1000 | address = 0xFC; 1001 | } 1002 | 1003 | 1004 | Wire.begin(); 1005 | Wire.beginTransmission(8); 1006 | Wire.write(byte(address)); 1007 | 1008 | byte val_0 = (byte)Wire.read(); 1009 | byte val_1 = (byte)Wire.read(); 1010 | 1011 | value = int(val_0)*16 + int(val_1>>4); 1012 | value = value * 1023 / 4095; //mapping the value between 0 and 1023 1013 | return value; 1014 | } 1015 | */ 1016 | 1017 | int analogRead(int channel) { 1018 | uint16_t adc_result; 1019 | uint8_t count; 1020 | uint8_t channel_code; 1021 | 1022 | // uint8_t channel; 1023 | 1024 | // for (channel = 0; channel < 8; channel++) { 1025 | switch(channel) { 1026 | case 0: 1027 | channel_code = 0; 1028 | break; 1029 | case 1: 1030 | channel_code = 4; 1031 | break; 1032 | case 2: 1033 | channel_code = 1; 1034 | break; 1035 | case 3: 1036 | channel_code = 5; 1037 | break; 1038 | case 4: 1039 | channel_code = 2; 1040 | break; 1041 | case 5: 1042 | channel_code = 6; 1043 | break; 1044 | case 6: 1045 | channel_code = 3; 1046 | break; 1047 | case 7: 1048 | channel_code = 7; 1049 | break; 1050 | default: 1051 | break; 1052 | } 1053 | 1054 | Wire.beginTransmission(0x48); 1055 | Wire.write((channel_code<<4) + 0x84); 1056 | Wire.endTransmission(); 1057 | 1058 | count = Wire.requestFrom(0x48, 2); // 1059 | // printf("Got %d bytes\n", count); 1060 | 1061 | if (count == 2) { 1062 | adc_result = (uint8_t)Wire.read(); 1063 | adc_result = adc_result << 8; 1064 | adc_result += (uint8_t)Wire.read(); 1065 | 1066 | //printf("channel_%d (0x%02X) = %d (%.5fV)\n", channel, channel * 0x10 + 0x84, adc_result, adc_result * 5.0 / 4095); 1067 | } else { 1068 | //printf("Invalid Data\n"); 1069 | } 1070 | // } 1071 | //printf("==================================\n"); 1072 | // 1073 | // delay(2000); 1074 | return adc_result; 1075 | } 1076 | 1077 | 1078 | void attachInterrupt(int p,void (*f)(), Digivalue m){ 1079 | int GPIOPin = raspberryPinNumber(p); 1080 | pthread_t *threadId = getThreadIdFromPin(p); 1081 | struct ThreadArg *threadArgs = (ThreadArg *)malloc(sizeof(ThreadArg)); 1082 | threadArgs->func = f; 1083 | threadArgs->pin = GPIOPin; 1084 | 1085 | //Export pin for interrupt 1086 | FILE *fp = fopen("/sys/class/gpio/export","w"); 1087 | if (fp == NULL){ 1088 | fprintf(stderr,"Unable to export pin %d for interrupt\n",p); 1089 | exit(1); 1090 | }else{ 1091 | fprintf(fp,"%d",GPIOPin); 1092 | } 1093 | fclose(fp); 1094 | 1095 | //The system to create the file /sys/class/gpio/gpio 1096 | //So we wait a bit 1097 | delay(1); 1098 | 1099 | char * interruptFile = NULL; 1100 | asprintf(&interruptFile, "/sys/class/gpio/gpio%d/edge",GPIOPin); 1101 | 1102 | //Set detection condition 1103 | fp = fopen(interruptFile,"w"); 1104 | if (fp == NULL){ 1105 | fprintf(stderr,"Unable to set detection type on pin %d\n",p); 1106 | exit(1); 1107 | }else{ 1108 | switch(m){ 1109 | case RISING: fprintf(fp,"rising");break; 1110 | case FALLING: fprintf(fp,"falling");break; 1111 | default: fprintf(fp,"both");break; 1112 | } 1113 | 1114 | } 1115 | fclose(fp); 1116 | 1117 | if(*threadId == 0){ 1118 | //Create a thread passing the pin and function 1119 | pthread_create (threadId, NULL, threadFunction, (void *)threadArgs); 1120 | }else{ 1121 | //First cancel the existing thread for that pin 1122 | pthread_cancel(*threadId); 1123 | //Create a thread passing the pin, function and mode 1124 | pthread_create (threadId, NULL, threadFunction, (void *)threadArgs); 1125 | } 1126 | 1127 | } 1128 | 1129 | void detachInterrupt(int p){ 1130 | int GPIOPin = raspberryPinNumber(p); 1131 | 1132 | FILE *fp = fopen("/sys/class/gpio/unexport","w"); 1133 | if (fp == NULL){ 1134 | fprintf(stderr,"Unable to unexport pin %d for interrupt\n",p); 1135 | exit(1); 1136 | }else{ 1137 | fprintf(fp,"%d",GPIOPin); 1138 | } 1139 | fclose(fp); 1140 | 1141 | pthread_t *threadId = getThreadIdFromPin(p); 1142 | pthread_cancel(*threadId); 1143 | } 1144 | 1145 | long millis(){ 1146 | long elapsedTime; 1147 | // stop timer 1148 | gettimeofday(&end_point, NULL); 1149 | 1150 | // compute and print the elapsed time in millisec 1151 | elapsedTime = (end_point.tv_sec - start_program.tv_sec) * 1000.0; // sec to ms 1152 | elapsedTime += (end_point.tv_usec - start_program.tv_usec) / 1000.0; // us to ms 1153 | return elapsedTime; 1154 | } 1155 | 1156 | int main(int argc,char *argv[]) { 1157 | uint8_t i; 1158 | uint8_t skip_reset=0; 1159 | 1160 | for (i=1;ipin; 1339 | 1340 | int GPIO_FN_MAXLEN = 32; 1341 | int RDBUF_LEN = 5; 1342 | 1343 | char fn[GPIO_FN_MAXLEN]; 1344 | int fd,ret; 1345 | struct pollfd pfd; 1346 | char rdbuf [RDBUF_LEN]; 1347 | 1348 | memset(rdbuf, 0x00, RDBUF_LEN); 1349 | memset(fn,0x00,GPIO_FN_MAXLEN); 1350 | 1351 | snprintf(fn, GPIO_FN_MAXLEN-1, "/sys/class/gpio/gpio%d/value",pin); 1352 | fd=open(fn, O_RDONLY); 1353 | if(fd<0){ 1354 | perror(fn); 1355 | exit(1); 1356 | } 1357 | pfd.fd=fd; 1358 | pfd.events=POLLPRI; 1359 | 1360 | ret=unistd::read(fd,rdbuf,RDBUF_LEN-1); 1361 | if(ret<0){ 1362 | perror("Error reading interrupt file\n"); 1363 | exit(1); 1364 | } 1365 | 1366 | while(1){ 1367 | memset(rdbuf, 0x00, RDBUF_LEN); 1368 | unistd::lseek(fd, 0, SEEK_SET); 1369 | ret=poll(&pfd, 1, -1); 1370 | if(ret<0){ 1371 | perror("Error waiting for interrupt\n"); 1372 | unistd::close(fd); 1373 | exit(1); 1374 | } 1375 | if(ret==0){ 1376 | printf("Timeout\n"); 1377 | continue; 1378 | } 1379 | ret=unistd::read(fd,rdbuf,RDBUF_LEN-1); 1380 | if(ret<0){ 1381 | perror("Error reading interrupt file\n"); 1382 | exit(1); 1383 | } 1384 | //Interrupt. We call user function. 1385 | arguments->func(); 1386 | } 1387 | } 1388 | 1389 | SerialPi Serial = SerialPi(); 1390 | WirePi Wire = WirePi(); 1391 | SPIPi SPI = SPIPi(); 1392 | --------------------------------------------------------------------------------