001package com.pi4j.io.i2c.impl; 002 003/* 004 * #%L 005 * ********************************************************************** 006 * ORGANIZATION : Pi4J 007 * PROJECT : Pi4J :: Java Library (Core) 008 * FILENAME : I2CBusImplBananaPi.java 009 * 010 * This file is part of the Pi4J project. More information about 011 * this project can be found here: http://www.pi4j.com/ 012 * ********************************************************************** 013 * %% 014 * Copyright (C) 2012 - 2015 Pi4J 015 * %% 016 * This program is free software: you can redistribute it and/or modify 017 * it under the terms of the GNU Lesser General Public License as 018 * published by the Free Software Foundation, either version 3 of the 019 * License, or (at your option) any later version. 020 * 021 * This program is distributed in the hope that it will be useful, 022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 024 * GNU General Lesser Public License for more details. 025 * 026 * You should have received a copy of the GNU General Lesser Public 027 * License along with this program. If not, see 028 * <http://www.gnu.org/licenses/lgpl-3.0.html>. 029 * #L% 030 */ 031 032import com.pi4j.io.i2c.I2CBus; 033import com.pi4j.jni.I2C; 034 035import java.io.IOException; 036import java.util.concurrent.locks.Lock; 037import java.util.concurrent.locks.ReentrantLock; 038 039/** 040 * This is implementation of i2c bus. This class keeps underlying linux file descriptor of 041 * particular bus. As all reads and writes from/to i2c bus are blocked I/Os current implementation uses only 042 * one file per bus for all devices. Device implementations use this class file handle. 043 * 044 * @author Daniel Sendula 045 * 046 */ 047public class I2CBusImplBananaPi extends I2CBusImpl { 048 049 /** Singleton instance of bus 0 */ 050 private static I2CBus bus0 = null; 051 052 /** Singleton instance of bus 1 */ 053 private static I2CBus bus1 = null; 054 055 /** Singleton instance of bus 1 */ 056 private static I2CBus bus2 = null; 057 058 /** Singleton instance of bus 1 */ 059 private static I2CBus bus3 = null; 060 061 /** 062 * to lock the creation/destruction of the bus singletons 063 */ 064 private final static Lock lock = new ReentrantLock(true); 065 066 /** 067 * Factory method that returns bus implementation. 068 * 069 * @param busNumber bus number 070 * @return appropriate bus implementation 071 * @throws IOException thrown in case there is a problem opening bus file or bus number is not 0 or 1. 072 */ 073 public static I2CBus getBus(int busNumber) throws IOException { 074 I2CBus bus; 075 lock.lock(); 076 if (busNumber == 0) { 077 bus = bus0; 078 if (bus == null) { 079 bus = new I2CBusImplBananaPi("/dev/i2c-0"); 080 bus0 = bus; 081 } 082 } else if (busNumber == 1) { 083 bus = bus1; 084 if (bus == null) { 085 bus = new I2CBusImplBananaPi("/dev/i2c-1"); 086 bus1 = bus; 087 } 088 } else if (busNumber == 2) { 089 bus = bus2; 090 if (bus == null) { 091 bus = new I2CBusImplBananaPi("/dev/i2c-2"); 092 bus2 = bus; 093 } 094 } else if (busNumber == 3) { 095 bus = bus3; 096 if (bus == null) { 097 bus = new I2CBusImplBananaPi("/dev/i2c-3"); 098 bus3 = bus; 099 } 100 } else { 101 throw new IOException("Unknown bus number " + busNumber); 102 } 103 lock.unlock(); 104 return bus; 105 } 106 107 /** 108 * Constructor of i2c bus implementation. 109 * 110 * @param filename file name of device to be opened. 111 * 112 * @throws IOException thrown in case that file cannot be opened 113 */ 114 public I2CBusImplBananaPi(String filename) throws IOException { 115 super(filename); 116 } 117 118 /** 119 * Closes this i2c bus 120 * 121 * @throws IOException never in this implementation 122 */ 123 @Override 124 public void close() throws IOException { 125 lock.lock(); 126 I2C.i2cClose(fd); 127 /* after closing the fd, we must "forget" the singleton bus instance, otherwise further request to this bus will 128 * always fail 129 */ 130 if (this == bus0) { 131 bus0 = null; 132 } else if (this == bus1) { 133 bus1 = null; 134 } else if (this == bus2) { 135 bus2 = null; 136 } else if (this == bus3) { 137 bus3 = null; 138 } 139 lock.unlock(); 140 } 141}