protected void initDigitalPort(int channel, boolean input) { m_channel = channel; checkDigitalChannel(m_channel); try { channels.allocate(m_channel); } catch (CheckedAllocationException ex) { throw new AllocationException("Digital input " + m_channel + " is already allocated"); } long port_pointer = DIOJNI.getPort((byte) channel); m_port = DIOJNI.initializeDigitalPort(port_pointer); DIOJNI.allocateDIO(m_port, input); }
/** * Construct an analog output on a specified MXP channel. * * @param channel The channel number to represent. */ public AnalogOutput(final int channel) { m_channel = channel; if (!AnalogJNI.checkAnalogOutputChannel(channel)) { throw new AllocationException("Analog output channel " + m_channel + " cannot be allocated. Channel is not present."); } try { channels.allocate(channel); } catch (CheckedAllocationException e) { throw new AllocationException("Analog output channel " + m_channel + " is already allocated"); } long port_pointer = AnalogJNI.getPort((byte) channel); m_port = AnalogJNI.initializeAnalogOutputPort(port_pointer); LiveWindow.addSensor("AnalogOutput", channel, this); UsageReporting.report(tResourceType.kResourceType_AnalogOutput, channel); }
/** * Request one of the 8 interrupts asynchronously on this digital input. * * @param handler The {@link InterruptHandlerFunction} that contains the * method {@link InterruptHandlerFunction#interruptFired(int, Object)} * that will be called whenever there is an interrupt on this device. * Request interrupts in synchronous mode where the user program * interrupt handler will be called when an interrupt occurs. The * default is interrupt on rising edges only. */ public void requestInterrupts(InterruptHandlerFunction<?> handler) { if (m_interrupt != 0) { throw new AllocationException("The interrupt has already been allocated"); } allocateInterrupts(false); assert (m_interrupt != 0); InterruptJNI.requestInterrupts(m_interrupt, getModuleForRouting(), getChannelForRouting(), getAnalogTriggerForRouting()); setUpSourceEdge(true, false); InterruptJNI.attachInterruptHandler(m_interrupt, handler.function, handler.overridableParameter()); }
/** * Initialize PWMs given a channel. * * This method is private and is the common path for all the constructors for * creating PWM instances. Checks channel value ranges and allocates the * appropriate channel. The allocation is only done to help users ensure that * they don't double assign channels. *$ * @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the * MXP port */ private void initPWM(final int channel) { checkPWMChannel(channel); m_channel = channel; m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel)); if (!PWMJNI.allocatePWMChannel(m_port)) { throw new AllocationException("PWM channel " + channel + " is already allocated"); } PWMJNI.setPWM(m_port, (short) 0); m_eliminateDeadband = false; UsageReporting.report(tResourceType.kResourceType_PWM, channel); }
/** * Common function to implement constructor behavior. */ private synchronized void initSolenoid() { checkSolenoidModule(m_moduleNumber); checkSolenoidChannel(m_channel); try { m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_channel); } catch (CheckedAllocationException e) { throw new AllocationException("Solenoid channel " + m_channel + " on module " + m_moduleNumber + " is already allocated"); } long port = SolenoidJNI.getPortWithModule((byte) m_moduleNumber, (byte) m_channel); m_solenoid_port = SolenoidJNI.initializeSolenoidPort(port); LiveWindow.addActuator("Solenoid", m_moduleNumber, m_channel, this); UsageReporting.report(tResourceType.kResourceType_Solenoid, m_channel, m_moduleNumber); }
/** * Common relay initialization method. This code is common to all Relay * constructors and initializes the relay and reserves all resources that need * to be locked. Initially the relay is set to both lines at 0v. */ private void initRelay() { SensorBase.checkRelayChannel(m_channel); try { if (m_direction == Direction.kBoth || m_direction == Direction.kForward) { relayChannels.allocate(m_channel * 2); UsageReporting.report(tResourceType.kResourceType_Relay, m_channel); } if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) { relayChannels.allocate(m_channel * 2 + 1); UsageReporting.report(tResourceType.kResourceType_Relay, m_channel + 128); } } catch (CheckedAllocationException e) { throw new AllocationException("Relay channel " + m_channel + " is already allocated"); } m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel)); m_safetyHelper = new MotorSafetyHelper(this); m_safetyHelper.setSafetyEnabled(false); LiveWindow.addActuator("Relay", m_channel, this); }
/** * Construct an analog channel. * * @param channel The channel number to represent. 0-3 are on-board 4-7 are on * the MXP port. */ public AnalogInput(final int channel) { m_channel = channel; if (!AnalogJNI.checkAnalogInputChannel(channel)) { throw new AllocationException("Analog input channel " + m_channel + " cannot be allocated. Channel is not present."); } try { channels.allocate(channel); } catch (CheckedAllocationException e) { throw new AllocationException("Analog input channel " + m_channel + " is already allocated"); } long port_pointer = AnalogJNI.getPort((byte) channel); m_port = AnalogJNI.initializeAnalogInputPort(port_pointer); LiveWindow.addSensor("AnalogInput", channel, this); UsageReporting.report(tResourceType.kResourceType_AnalogChannel, channel); }
/** * Construct an analog channel on a specified module. * * @param moduleNumber The digital module to use (1 or 2). * @param channel The channel number to represent. */ public AnalogChannel(final int moduleNumber, final int channel) { m_shouldUseVoltageForPID = false; checkAnalogModule(moduleNumber); checkAnalogChannel(channel); m_channel = channel; m_moduleNumber = moduleNumber; m_module = AnalogModule.getInstance(moduleNumber); try { channels.allocate((moduleNumber - 1) * kAnalogChannels + m_channel - 1); } catch (CheckedAllocationException e) { throw new AllocationException( "Analog channel " + m_channel + " on module " + m_moduleNumber + " is already allocated"); } if (channel == 1 || channel == 2) { m_accumulator = new tAccumulator((byte) (channel - 1)); m_accumulatorOffset = 0; } else { m_accumulator = null; } LiveWindow.addSensor("Analog", moduleNumber, channel, this); UsageReporting.report(UsageReporting.kResourceType_AnalogChannel, channel, m_moduleNumber-1); }
private void initCounter(final Mode mode) { m_allocatedUpSource = false; m_allocatedDownSource = false; try { m_index = counters.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("No counters left to be allocated"); } m_counter = new tCounter(m_index); m_counter.writeConfig_Mode(mode.value); m_upSource = null; m_downSource = null; m_counter.writeTimerConfig_AverageSize(1); UsageReporting.report(UsageReporting.kResourceType_Counter, m_index, mode.value); }
/** * Initialize PWMs given an module and channel. * * This method is private and is the common path for all the constructors for creating PWM * instances. Checks module and channel value ranges and allocates the appropriate channel. * The allocation is only done to help users ensure that they don't double assign channels. */ private void initPWM(final int moduleNumber, final int channel) { checkPWMModule(moduleNumber); checkPWMChannel(channel); try { allocated.allocate((moduleNumber - 1) * kPwmChannels + channel - 1); } catch (CheckedAllocationException e) { throw new AllocationException( "PWM channel " + channel + " on module " + moduleNumber + " is already allocated"); } m_channel = channel; m_module = DigitalModule.getInstance(moduleNumber); m_module.setPWM(m_channel, kPwmDisabled); m_eliminateDeadband = false; UsageReporting.report(UsageReporting.kResourceType_PWM, channel, moduleNumber-1); }
/** * Common relay initialization method. * This code is common to all Relay constructors and initializes the relay and reserves * all resources that need to be locked. Initially the relay is set to both lines at 0v. * @param moduleNumber The number of the digital module to use. */ private void initRelay(final int moduleNumber) { SensorBase.checkRelayModule(moduleNumber); SensorBase.checkRelayChannel(m_channel); try { if (m_direction == Direction.kBoth || m_direction == Direction.kForward) { relayChannels.allocate(((moduleNumber - 1) * kRelayChannels + m_channel - 1) * 2); UsageReporting.report(UsageReporting.kResourceType_Relay, m_channel, moduleNumber-1); } if (m_direction == Direction.kBoth || m_direction == Direction.kReverse) { relayChannels.allocate(((moduleNumber - 1) * kRelayChannels + m_channel - 1) * 2 + 1); UsageReporting.report(UsageReporting.kResourceType_Relay, m_channel+128, moduleNumber-1); } } catch (CheckedAllocationException e) { throw new AllocationException("Relay channel " + m_channel + " on module " + moduleNumber + " is already allocated"); } m_module = DigitalModule.getInstance(moduleNumber); m_module.setRelayForward(m_channel, false); m_module.setRelayReverse(m_channel, false); LiveWindow.addActuator("Relay", moduleNumber, m_channel, this); }
/** * Allocate Digital I/O channels. * Allocate channels so that they are not accidently reused. Also the direction is set at the * time of the allocation. * * @param channel The channel to allocate. * @param input Indicates whether the I/O pin is an input (true) or an output (false). * @return True if the I/O pin was allocated, false otherwise. */ public boolean allocateDIO(final int channel, final boolean input) { try { DIOChannels.allocate((kDigitalChannels * (m_moduleNumber - 1) + channel - 1)); } catch (CheckedAllocationException e) { throw new AllocationException( "Digital channel " + channel + " on module " + m_moduleNumber + " is already allocated"); } final int outputEnable = m_fpgaDIO.readOutputEnable(); final int bitToSet = 1 << (DigitalModule.remapDigitalChannel((channel - 1))); short outputEnableValue; if (input) { outputEnableValue = (short) (outputEnable & (~bitToSet)); } else { outputEnableValue = (short) (outputEnable | bitToSet); } m_fpgaDIO.writeOutputEnable(outputEnableValue); return true; }
/** * Request interrupts asynchronously on this digital input. * @param handler The address of the interrupt handler function of type tInterruptHandler that * will be called whenever there is an interrupt on the digitial input port. * Request interrupts in synchronus mode where the user program interrupt handler will be * called when an interrupt occurs. * The default is interrupt on rising edges only. * @param param argument to pass to the handler */ public void requestInterrupts(/*tInterruptHandler*/Object handler, Object param) { //TODO: add interrupt support try { m_interruptIndex = interrupts.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("No interrupts are left to be allocated"); } allocateInterrupts(false); m_interrupt.writeConfig_WaitForAck(false); m_interrupt.writeConfig_Source_AnalogTrigger(getAnalogTriggerForRouting()); m_interrupt.writeConfig_Source_Channel((byte) getChannelForRouting()); m_interrupt.writeConfig_Source_Module((byte) getModuleForRouting()); setUpSourceEdge(true, false); //TODO: m_manager.registerHandler(handler, param); }
private void initCounter(final Mode mode) { m_allocatedUpSource = false; m_allocatedDownSource = false; try { m_index = counters.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("No counters left to be allocated"); } m_upSource = null; m_downSource = null; //UsageReporting.report(UsageReporting.kResourceType_Counter, m_index, mode.value); }
/** * Construct an analog channel on a specified module. * * @param moduleNumber The digital module to use (1 or 2). * @param channel The channel number to represent. */ public AnalogChannel(final int moduleNumber, final int channel) { checkAnalogModule(moduleNumber); checkAnalogChannel(channel); m_channel = channel; m_moduleNumber = moduleNumber; m_module = AnalogModule.getInstance(moduleNumber); try { channels.allocate((moduleNumber - 1) * kAnalogChannels + m_channel - 1); } catch (CheckedAllocationException e) { throw new AllocationException( "Analog channel " + m_channel + " on module " + m_moduleNumber + " is already allocated"); } if (channel == 1 || channel == 2) { m_accumulator = new tAccumulator((byte) (channel - 1)); m_accumulatorOffset = 0; } else { m_accumulator = null; } LiveWindow.addSensor("Analog", moduleNumber, channel, this); UsageReporting.report(UsageReporting.kResourceType_AnalogChannel, channel, m_moduleNumber-1); }
/** * Set the index source for the encoder. When this source rises, the encoder count automatically * resets. * * @param channel A DIO channel to set as the encoder index * @param type The state that will cause the encoder to reset */ public void setIndexSource(int channel, IndexingType type) { if (m_allocatedI) { throw new AllocationException("Digital Input for Indexing already allocated"); } m_indexSource = new DigitalInput(channel); m_allocatedI = true; setIndexSource(m_indexSource, type); }
/** * Initialize the accumulator. */ public void initAccumulator() { if (!isAccumulatorChannel()) { throw new AllocationException("Accumulators are only available on slot " + kAccumulatorSlot + " on channels " + kAccumulatorChannels[0] + ", " + kAccumulatorChannels[1]); } m_accumulatorOffset = 0; AnalogJNI.initAccumulator(m_port); }
/** * Request one of the 8 interrupts synchronously on this digital input. * Request interrupts in synchronous mode where the user program will have to * explicitly wait for the interrupt to occur using {@link #waitForInterrupt}. * The default is interrupt on rising edges only. */ public void requestInterrupts() { if (m_interrupt != 0) { throw new AllocationException("The interrupt has already been allocated"); } allocateInterrupts(true); assert (m_interrupt != 0); InterruptJNI.requestInterrupts(m_interrupt, getModuleForRouting(), getChannelForRouting(), getAnalogTriggerForRouting()); setUpSourceEdge(true, false); }
/** * Allocate the interrupt * * @param watcher true if the interrupt should be in synchronous mode where * the user program will have to explicitly wait for the interrupt to * occur. */ protected void allocateInterrupts(boolean watcher) { try { m_interruptIndex = interrupts.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("No interrupts are left to be allocated"); } m_isSynchronousInterrupt = watcher; m_interrupt = InterruptJNI.initializeInterrupts(m_interruptIndex, watcher); }
/** * Initialize the accumulator. */ public void initAccumulator() { if (!isAccumulatorChannel()) { throw new AllocationException( "Accumulators are only available on slot " + kAccumulatorSlot + " on channels " + kAccumulatorChannels[0] + "," + kAccumulatorChannels[1]); } m_accumulatorOffset = 0; setAccumulatorCenter(0); resetAccumulator(); }
/** * Initialize an analog trigger from a module number and channel. * This is the common code for the two constructors that use a module number and channel. * @param moduleNumber The number of the analog module to create this trigger on. * @param channel the port to use for the analog trigger */ protected void initTrigger(final int moduleNumber, final int channel) { m_channel = channel; m_analogModule = AnalogModule.getInstance(moduleNumber); try { m_index = triggers.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("No analog triggers are available to allocate"); } m_trigger = new tAnalogTrigger((byte) m_index); m_trigger.writeSourceSelect_Channel((byte) (m_channel - 1)); m_trigger.writeSourceSelect_Module((byte) moduleNumber - 1); UsageReporting.report(UsageReporting.kResourceType_AnalogTrigger, channel, moduleNumber-1); }
/** * Common initialization code for Encoders. * This code allocates resources for Encoders and is common to all constructors. * @param reverseDirection If true, counts down instead of up (this is all relative) * @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is * selected, then an encoder FPGA object is used and the returned counts will be 4x the encoder * spec'd value since all rising and falling edges are counted. If 1X or 2X are selected then * a counter object will be used and the returned value will either exactly match the spec'd count * or be double (2x) the spec'd count. */ private void initEncoder(boolean reverseDirection) { switch (m_encodingType.value) { case EncodingType.k4X_val: try { m_index = quadEncoders.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("There are no encoders left to allocate"); } m_encoder = new tEncoder(m_index); m_encoder.writeConfig_ASource_Module(m_aSource.getModuleForRouting()); m_encoder.writeConfig_ASource_Channel(m_aSource.getChannelForRouting()); m_encoder.writeConfig_ASource_AnalogTrigger(m_aSource.getAnalogTriggerForRouting()); m_encoder.writeConfig_BSource_Module(m_bSource.getModuleForRouting()); m_encoder.writeConfig_BSource_Channel(m_bSource.getChannelForRouting()); m_encoder.writeConfig_BSource_AnalogTrigger(m_bSource.getAnalogTriggerForRouting()); m_encoder.strobeReset(); m_encoder.writeConfig_Reverse(reverseDirection); m_encoder.writeTimerConfig_AverageSize(1); if (m_indexSource != null) { m_encoder.writeConfig_IndexSource_Module(m_indexSource.getModuleForRouting()); m_encoder.writeConfig_IndexSource_Channel(m_indexSource.getChannelForRouting()); m_encoder.writeConfig_IndexSource_AnalogTrigger(m_indexSource.getAnalogTriggerForRouting()); m_encoder.writeConfig_IndexActiveHigh(true); } m_counter = null; break; case EncodingType.k2X_val: case EncodingType.k1X_val: m_counter = new Counter(m_encodingType, m_aSource, m_bSource, reverseDirection); break; } m_distancePerPulse = 1.0; UsageReporting.report(UsageReporting.kResourceType_Encoder, m_index, m_encodingType.value); LiveWindow.addSensor("Encoder", m_aSource.getModuleForRouting(), m_aSource.getChannelForRouting(), this); }
/** * Common function to implement constructor behavior. */ private synchronized void initSolenoid() { checkSolenoidModule(m_moduleNumber); checkSolenoidChannel(m_channel); try { m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_channel - 1); } catch (CheckedAllocationException e) { throw new AllocationException( "Solenoid channel " + m_channel + " on module " + m_moduleNumber + " is already allocated"); } LiveWindow.addActuator("Solenoid", m_moduleNumber, m_channel, this); UsageReporting.report(UsageReporting.kResourceType_Solenoid, m_channel, m_moduleNumber - 1); }
/** * Allocate a DO PWM Generator. * Allocate PWM generators so that they are not accidently reused. */ public int allocateDO_PWM() { try { return DO_PWMGenerators[m_moduleNumber - 1].allocate(); } catch (CheckedAllocationException e) { throw new AllocationException( "No Digital Output PWM Generators on module " + m_moduleNumber + " remaining"); } }
/** * Request interrupts synchronously on this digital input. * Request interrupts in synchronus mode where the user program will have to explicitly * wait for the interrupt to occur. * The default is interrupt on rising edges only. */ public void requestInterrupts() { try { m_interruptIndex = interrupts.allocate(); } catch (CheckedAllocationException e) { throw new AllocationException("No interrupts are left to be allocated"); } allocateInterrupts(true); m_interrupt.writeConfig_Source_AnalogTrigger(getAnalogTriggerForRouting()); m_interrupt.writeConfig_Source_Channel((byte) getChannelForRouting()); m_interrupt.writeConfig_Source_Module((byte) getModuleForRouting()); setUpSourceEdge(true, false); }
/** * Common function to implement constructor behavior. */ private synchronized void initSolenoid() { checkSolenoidModule(m_moduleNumber); checkSolenoidChannel(m_channel); try { m_allocated.allocate((m_moduleNumber - 1) * kSolenoidChannels + m_channel - 1); } catch (CheckedAllocationException e) { throw new AllocationException( "Solenoid channel " + m_channel + " on module " + m_moduleNumber + " is already allocated"); } LiveWindow.addSensor("Solenoid", m_moduleNumber, m_channel, this); UsageReporting.report(UsageReporting.kResourceType_Solenoid, m_channel, m_moduleNumber - 1); }
/** * Free an allocated resource. After a resource is no longer needed, for example a destructor is * called for a channel assignment class, Free will release the resource value so it can be reused * somewhere else in the program. * * @param index The index of the resource to free. */ public void free(final int index) { if (m_numAllocated[index] == false) { throw new AllocationException("No resource available to be freed"); } m_numAllocated[index] = false; }