All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.harctoolbox.harchardware.ir.Tira Maven / Gradle / Ivy

There is a newer version: 2.4.1
Show newest version
/*
Copyright (C) 2013 Bengt Martensson.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at
your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see http://www.gnu.org/licenses/.
*/

package org.harctoolbox.harchardware.ir;

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import org.harctoolbox.harchardware.IHarcHardware;
import org.harctoolbox.ircore.InvalidArgumentException;
import org.harctoolbox.ircore.IrSignal;
import org.harctoolbox.ircore.Pronto;

/**
 * This is not ready for deployment.
 */
/*public*/ class Tira implements IHarcHardware, IRawIrSender {

    public static final String defaultPortName = "/dev/ttyUSB0";
    private static final int baudRate = 9600;//115200;//9600;
    private static final int flowControl = SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT;// SerialPort.FLOWCONTROL_NONE;
    private static final int bufsize = 255;

    private static final double oscillatorFrequency = 48000000;
    private static final double period = 21.3333; // microseconds
    private static final byte dutyCycle = 0; // semantically: don't care

    private final static boolean transmitNotifyEnabled = true;
    private final static boolean transmitByteCountReportEnabled = true;
    private final static boolean transmitHandshakeEnabled = true;

    private final static byte cmdReset = 0x00; // Reset (returns to remote decoder mode)
    // 0x01 RESERVED for SUMP RUN
    // 0x02 RESERVED for SUMP ID
    private final static byte cmdTransmit = 0x03; // Transmit (FW v07+)
    // 0x04 Frequency report (reserved for future hardware)
    // 0x05 Setup sample timer (FW v07+)
    private final static byte cmdSetFrequency = 0x06; // Setup frequency modulation timer (FW v07+)
    private final static byte cmdLedMuteOn = 0x10; // LED mute on (FW v07+)
    private final static byte cmdLedMuteOff = 0x11; // LED mute off (FW v07+)
    private final static byte cmdLedOn = 0x12; // LED on (FW v07+)
    private final static byte cmdLedOff = 0x13; // LED off (FW v07+)
    // 0x23 Settings descriptor report (FW v20+)
    private final static byte cmdTransmitByteCountReport = 0x24; // Enable transmit byte count report (FW v20+)
    private final static byte cmdTransmitNotify = 0x25; // Enable transmit notify on complete (FW v20+)
    private final static byte cmdTransmitHandshake = 0x26; // Enable transmit handshake (FW v20+)
    // 0x30 IO write
    // 0x31 IO direction
    // 0x32 IO read
    // 0x40 UART setup
    // 0x41 UART close
    // 0x42 UART write

    private final static byte cmdSamplingMode = (byte) 's';
    private final static byte cmdSelfTest = (byte) 't';
    private final static byte cmdVersion = (byte) 'v';
    private final static byte cmdBootloaderMode = (byte) '$';
    private final static byte endOfData = (byte) 0xff;
    private final static int transmitByteCountToken = 't';
    private final static int transmitCompleteSuccess = 'C';
    private final static int transmitCompleteFailure = 'F';
    /**
     * Not supported due to hardware restrictions.
     * @param transmitter
     * @return
     */
    //@Override
    //public boolean stopIr(Transmitter transmitter) {
    //    throw new UnsupportedOperationException("Not supported due to hardware restrictions.");
    //}

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try (Tira tira = new Tira()) {
            System.out.println(tira.getVersion());
            //String result = toy.selftest();
            //System.out.println(result);
            //toy.setLed(true);
            //toy.setLedMute(false);
            //boolean success = toy.transmit(36000, data);
            //IrSignal signal = new IrSignal("../IrpMaster/data/IrpProtocols.ini", "nec1", "D=122 F=26");
            //boolean success = toy.sendIr(signal, 10, null);
            //System.out.println(success);
            //w.listen();
        } catch (NoSuchPortException ex) {
            System.err.println("Port for IRToy " + defaultPortName + " was not found");
        } catch (PortInUseException ex) {
            System.err.println("Port for IRToy in use");
        } catch (UnsupportedCommOperationException | IOException | InterruptedException ex) {
            System.err.println("xxx" + ex.getMessage());
            //ex.printStackTrace();
        }
    }
    private CommPort commPort;
    private String portName;

    private OutputStream out;
    private InputStream in;

    //private String protocolVersion;
    private String version;

    //private boolean verbosity;
    //private int debug;
    /* public */ Tira() throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, IOException, InterruptedException  {
        this(defaultPortName);
    }

    /*public*/ Tira(String portName) throws NoSuchPortException, PortInUseException, UnsupportedCommOperationException, IOException, InterruptedException {
        this.portName = portName;
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        commPort = portIdentifier.open(this.getClass().getName(), 2000);

        if (commPort instanceof gnu.io.SerialPort) {
            SerialPort serialPort = (SerialPort) commPort;
            serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

            serialPort.setFlowControlMode(flowControl);

            out = serialPort.getOutputStream();
            in = serialPort.getInputStream();

            //reset();
            send(new byte[] {(byte)'I', (byte)'V'});
            Thread.sleep(50);
            version = readString();
            //System.err.println(version);
            //version = readString();
            //System.err.println(version);
            //version = readString();
            //System.err.println(version);

        }
    }

    public final void reset() throws IOException, InterruptedException {
        send(new byte[]{cmdReset, cmdReset, cmdReset, cmdReset, cmdReset});
        Thread.sleep(100);
    }

    private void send(byte[] buf) throws IOException {
        out.write(buf);
        out.flush();
    }

    private void send(byte[] buf, int offset, int length) throws IOException {
        out.write(buf, offset, length);
        out.flush();
    }

    private void send(byte b) throws IOException {
        out.write(b);
        out.flush();
    }

    private byte[] toByteArray(int[] data) {
        byte[] buf = new byte[2*data.length + 2];
        for (int i = 0; i < data.length; i++) {
            int periods = (int)Math.round(data[i]/period);
            buf[2*i] = (byte)(periods / 256);
            buf[2*i+1] = (byte) (periods % 256);
        }
        buf[2*data.length] = endOfData;
        buf[2*data.length+1] = endOfData;
        return buf;
    }

    private boolean transmit(double frequency, int[] data) throws IOException {
        if (frequency > 0)
            setFrequency(frequency);
        return transmit(data);
    }

    private boolean transmit(int[] data) throws IOException {
        send(cmdTransmit);
        byte[] buf = toByteArray(data);

        if (transmitHandshakeEnabled) {
            int bytesSent = 0;
            while (bytesSent < buf.length) {
                int noBytes = readByte();
                int toSend = Math.min(noBytes, buf.length - bytesSent);
                send(buf, bytesSent, toSend);
                bytesSent += toSend;
            }

        }
        readByte();

        if (transmitByteCountReportEnabled) {
            int token = readByte();
            if (token != transmitByteCountToken)
                return false;
            int msb = readByte();
            int lsb = readByte();
            int bytesSent = 256*msb + lsb;
            if (bytesSent != data.length*2+2)
                return false;
        }

        if (transmitNotifyEnabled) {
            int token = readByte();
            if (token != transmitCompleteSuccess)
                return false;
        }
        return true;
    }

    private String readString() throws IOException {
        byte[] buf = new byte[bufsize];
        int length = in.read(buf);
        return new String(buf, 0, length, Charset.forName("US-ASCII"));
    }

    private int readByte() throws IOException {
        return in.read();
    }

    public String selftest() throws IOException, InterruptedException {
        reset();
        send(cmdSelfTest);
        byte[] buf = new byte[4];
        for (int i = 0; i < 4; i++)
            buf[i] = (byte) readByte();

        return new String(buf, Charset.forName("US-ASCII"));
    }

    public void bootloaderMode() throws IOException, InterruptedException {
        reset();
        send(cmdBootloaderMode);
    }

    @Override
    public void close() {
        try {
            out.flush();
            out.close();
            in.close();
            Thread.sleep(1000);
            commPort.close();
        } catch (IOException | InterruptedException ex) {
            System.err.println(ex.getMessage());
        }
    }

    //public String getProtocolVersion() {
    //    return protocolVersion;
    //}

    public String getPortName() {
        return portName;
    }

    public void setLedMute(boolean status) throws IOException {
        send(status ? cmdLedMuteOn : cmdLedMuteOff);
    }

    public void setLed(boolean status) throws IOException {
        send(status ? cmdLedOn : cmdLedOff);
    }

    private void setFrequency(double frequency) throws IOException {
        byte pr2 = (byte) Math.round(oscillatorFrequency/(16*frequency) - 1);
        byte[] buf = new byte[3];
        buf[0] = cmdSetFrequency;
        buf[1] = pr2;
        buf[2] = dutyCycle;
        send(buf);
    }

/*
    public void listen() throws IOException, UnsupportedCommOperationException {
        int toRead = 7000;
        byte[] data = new byte[toRead];

        RXTXPort serial = (RXTXPort) commPort;
        InputStream in = serial.getInputStream();
        serial.setDTR(true);
        //serial.setRTS(true);
        serial.disableReceiveThreshold();
        //serial.disableReceiveFraming();
        serial.enableReceiveTimeout(5000);
        //serial.setLowLatency();
        serial.disableReceiveFraming();
        System.err.println(serial.getDivisor());

        int bytesRead = 0;
        boolean status = serial.clearCommInput();
        System.err.println(status);
        while (bytesRead < toRead) {

           int x = in.read(data, bytesRead, toRead - bytesRead);
           bytesRead += x;
           //int avail = serial.getInputStream().available();
           System.out.println(x + "\t" + bytesRead + "\t" + data[bytesRead-1]);
        }
    }*/

    @Override
    public String getVersion() {
        return version;
    }

    @Override
    public void setVerbose(boolean verbose) {
    }

    @Override
    public void setDebug(int debug) {
    }

    @Override
    public void setTimeout(int timeout) {
        // ???
    }

    @Override
    public boolean isValid() {
        return commPort != null;
    }

    @Override
    public boolean sendIr(IrSignal code, int count, Transmitter transmitter) throws IOException {
        return transmit(code.getFrequency(), code.toIntArray(count-1));
    }

    public boolean sendCcf(String ccf, int count, Transmitter transmitter) throws IOException, Pronto.NonProntoFormatException, InvalidArgumentException {
        return sendIr(Pronto.parse(ccf), count, transmitter);
    }

    /**
     * Not supported due to hardware restrictions.
     *
     * @param ccf
     * @param transmitter
     * @return
     */
    public boolean sendCcfRepeat(String ccf, Transmitter transmitter) {
        throw new UnsupportedOperationException("Not supported due to hardware restrictions.");
    }


    @Override
    public Transmitter getTransmitter() {
        return null;
    }

    @Override
    public void open() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy