/*---------------------------------------------------------------------------
 * Copyright (C) EMAC.inc
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *---------------------------------------------------------------------------
 */

/**
 * This class is a thin wrapper over a parallel port native library for
 * a SOM400EM PLD's GPIO lines
 */
public class PAR400EM {
    // SPI config state
    private int shadow;

    /* Load native library in static intializer */
    static {
        try {
            System.loadLibrary("par400em.tlib");
        } catch (UnsatisfiedLinkError ule) {
            System.out.println("Unable to load/initialize library:" +
                               ule.getMessage());
            throw ule;
        }
    }



    /**
     * Construct an parallel object
     *
     */
    public PAR400EM() {
        this.shadow = 0;
        PAROpen(0);
    }


    /**
     * Write a byte of data to the output port, PORTY
     * This port is currently only 5 bits wide, MSBs 7,6, and 5 have no
     * effect. Data written to the port is stored in a shadow variable,
     * which can be retrieved by using the getshadow method
     *
     * @param data The byte of data to write to the port.
     * @return 0
     * @see getshadow
     */
    public int write(int data) {
        // Bounds check array access (easier here than in native)
        this.shadow = data;
        return PARWrite(data);
    }

    /**
     * Read a byte of data from the input port, PORTX
     * This port is currently only 5 bits wide, MSBs 7,6, and 5 are masked
     * to zero by the native method
     *
     * @return the byte that was read
     */

    public synchronized int read() {
            // Bounds check array access (easier here than in native)
            return PARRead(0);
        }


    /**
     * Return the current state of the output port
     * @return the last byte written to the output port
     */
    public int getshadow() {
        return shadow;
    }



    // *** Native PAR read and write methods. not meant to be directly callable

private static native int PARWrite(int data);

private static native int PARRead(int unused);

private static native int PAROpen(int unused);

}


