001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2008-2012. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.wpilibj;
009
010import java.nio.ByteBuffer;
011import java.nio.ByteOrder;
012
013import edu.wpi.first.wpilibj.hal.DIOJNI;
014import edu.wpi.first.wpilibj.hal.HALUtil;
015import edu.wpi.first.wpilibj.util.AllocationException;
016import edu.wpi.first.wpilibj.util.CheckedAllocationException;
017
018/**
019 * DigitalSource Interface. The DigitalSource represents all the possible inputs
020 * for a counter or a quadrature encoder. The source may be either a digital
021 * input or an analog input. If the caller just provides a channel, then a
022 * digital input will be constructed and freed when finished for the source. The
023 * source can either be a digital input or analog trigger but not both.
024 */
025public abstract class DigitalSource extends InterruptableSensorBase {
026
027        protected static Resource channels = new Resource(kDigitalChannels);
028        protected ByteBuffer m_port;
029        protected int m_channel;
030
031        protected void initDigitalPort(int channel, boolean input) {
032
033                m_channel = channel;
034
035                checkDigitalChannel(m_channel); // XXX: Replace with
036                                                                                // HALLibrary.checkDigitalChannel when
037                                                                                // implemented
038
039                try {
040                        channels.allocate(m_channel);
041                } catch (CheckedAllocationException ex) {
042                        throw new AllocationException("Digital input " + m_channel
043                                        + " is already allocated");
044                }
045
046                ByteBuffer port_pointer = DIOJNI.getPort((byte) channel);
047                ByteBuffer status = ByteBuffer.allocateDirect(4);
048                // set the byte order
049                status.order(ByteOrder.LITTLE_ENDIAN);
050                m_port = DIOJNI.initializeDigitalPort(port_pointer, status.asIntBuffer());
051                HALUtil.checkStatus(status.asIntBuffer());
052                DIOJNI.allocateDIO(m_port, (byte) (input ? 1 : 0), status.asIntBuffer());
053                HALUtil.checkStatus(status.asIntBuffer());
054        }
055
056        @Override
057        public void free() {
058                channels.free(m_channel);
059                ByteBuffer status = ByteBuffer.allocateDirect(4);
060                // set the byte order
061                status.order(ByteOrder.LITTLE_ENDIAN);
062                DIOJNI.freeDIO(m_port, status.asIntBuffer());
063                HALUtil.checkStatus(status.asIntBuffer());
064                m_channel = 0;
065        }
066
067        /**
068         * Get the channel routing number
069         *
070         * @return channel routing number
071         */
072        @Override
073        public int getChannelForRouting() {
074                return m_channel;
075        }
076
077        /**
078         * Get the module routing number
079         *
080         * @return 0
081         */
082        @Override
083        public byte getModuleForRouting() {
084                return 0;
085        }
086
087        /**
088         * Is this an analog trigger
089         * @return true if this is an analog trigger
090         */
091        @Override
092        public boolean getAnalogTriggerForRouting() {
093                return false;
094        }
095}