001/*
002 * Copyright (C) Photon Vision.
003 *
004 * This program is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package org.photonvision.common.hardware.GPIO.pi;
019
020import org.photonvision.common.hardware.GPIO.GPIOBase;
021import org.photonvision.common.logging.LogGroup;
022import org.photonvision.common.logging.Logger;
023
024public class PigpioPin extends GPIOBase {
025    public static final Logger logger = new Logger(PigpioPin.class, LogGroup.General);
026    private static final PigpioSocket piSocket = new PigpioSocket();
027
028    private final boolean isHardwarePWMPin;
029    private final int pinNo;
030
031    private boolean hasFailedHardwarePWM;
032
033    public PigpioPin(int pinNo) {
034        isHardwarePWMPin = pinNo == 12 || pinNo == 13 || pinNo == 17 || pinNo == 18;
035        this.pinNo = pinNo;
036    }
037
038    @Override
039    public int getPinNumber() {
040        return pinNo;
041    }
042
043    @Override
044    protected void setStateImpl(boolean state) {
045        try {
046            piSocket.gpioWrite(pinNo, state);
047        } catch (PigpioException e) {
048            logger.error("gpioWrite FAIL - " + e.getMessage());
049        }
050    }
051
052    @Override
053    public boolean shutdown() {
054        setState(false);
055        return true;
056    }
057
058    @Override
059    public boolean getStateImpl() {
060        try {
061            return piSocket.gpioRead(pinNo);
062        } catch (PigpioException e) {
063            logger.error("gpioRead FAIL - " + e.getMessage());
064            return false;
065        }
066    }
067
068    @Override
069    protected void blinkImpl(int pulseTimeMillis, int blinks) {
070        try {
071            piSocket.generateAndSendWaveform(pulseTimeMillis, blinks, pinNo);
072        } catch (PigpioException e) {
073            logger.error("Could not set blink - " + e.getMessage());
074        }
075    }
076
077    @Override
078    protected void setBrightnessImpl(int brightness) {
079        if (isHardwarePWMPin) {
080            try {
081                piSocket.hardwarePWM(pinNo, 22000, (int) (1000000 * (brightness / 100.0)));
082            } catch (PigpioException e) {
083                logger.error("Failed to hardPWM - " + e.getMessage());
084            }
085        } else if (!hasFailedHardwarePWM) {
086            logger.warn(
087                    "Specified pin ("
088                            + pinNo
089                            + ") is not capable of hardware PWM - no action will be taken.");
090            hasFailedHardwarePWM = true;
091        }
092    }
093}