/** * Check a DIO line to see if it is currently generating a pulse. */ bool DigitalModule::IsPulsing(UINT32 channel) { UINT32 mask = 1 << RemapDigitalChannel(channel - 1); UINT16 pulseRegister = m_fpgaDIO->readPulse(&status); wpi_assertCleanStatus(status); return pulseRegister & mask != 0; }
/** * Generate a single pulse. * Write a pulse to the specified digital output channel. There can only be a single pulse going at any time. */ void DigitalModule::Pulse(UINT32 channel, float pulseLength) { UINT32 mask = 1 << RemapDigitalChannel(channel - 1); m_fpgaDIO->writePulseLength((UINT8)(1e9 * pulseLength / (m_fpgaDIO->readLoopTiming(&status) * 25)), &status); m_fpgaDIO->writePulse(mask, &status); wpi_assertCleanStatus(status); }
/** * Check a DIO line to see if it is currently generating a pulse. * * @return A pulse is in progress */ bool DigitalModule::IsPulsing(uint32_t channel) { uint16_t mask = 1 << RemapDigitalChannel(channel - 1); tRioStatusCode localStatus = NiFpga_Status_Success; uint16_t pulseRegister = m_fpgaDIO->readPulse(&localStatus); wpi_setError(localStatus); return (pulseRegister & mask) != 0; }
/** * Generate a single pulse. * Write a pulse to the specified digital output channel. There can only be a single pulse going at any time. * * @param channel The Digital Output channel that the pulse should be output on * @param pulseLength The active length of the pulse (in seconds) */ void DigitalModule::Pulse(uint32_t channel, float pulseLength) { uint16_t mask = 1 << RemapDigitalChannel(channel - 1); tRioStatusCode localStatus = NiFpga_Status_Success; m_fpgaDIO->writePulseLength((uint8_t)(1.0e9 * pulseLength / (m_fpgaDIO->readLoopTiming(&localStatus) * 25)), &localStatus); m_fpgaDIO->writePulse(mask, &localStatus); wpi_setError(localStatus); }
/** * Configure which DO channel the PWM siganl is output on * * @param pwmGenerator The generator index reserved by AllocateDO_PWM() * @param channel The Digital Output channel to output on */ void DigitalModule::SetDO_PWMOutputChannel(uint32_t pwmGenerator, uint32_t channel) { if (pwmGenerator == ~0ul) return; tRioStatusCode localStatus = NiFpga_Status_Success; switch(pwmGenerator) { case 0: m_fpgaDIO->writeDO_PWMConfig_OutputSelect_0(RemapDigitalChannel(channel - 1), &localStatus); break; case 1: m_fpgaDIO->writeDO_PWMConfig_OutputSelect_1(RemapDigitalChannel(channel - 1), &localStatus); break; case 2: m_fpgaDIO->writeDO_PWMConfig_OutputSelect_2(RemapDigitalChannel(channel - 1), &localStatus); break; case 3: m_fpgaDIO->writeDO_PWMConfig_OutputSelect_3(RemapDigitalChannel(channel - 1), &localStatus); break; } wpi_setError(localStatus); }
/** * Write a digital I/O bit to the FPGA. * Set a single value on a digital I/O channel. */ void DigitalModule::SetDIO(UINT32 channel, short value) { status = 0; if (value != 0 && value != 1) { wpi_fatal(NonBinaryDigitalValue); if (value != 0) value = 1; } UINT16 currentDIO = m_fpgaDIO->readDO(&status); if(value == 0) { currentDIO = currentDIO & ~(1 << RemapDigitalChannel(channel - 1)); } else if (value == 1) { currentDIO = currentDIO | (1 << RemapDigitalChannel(channel - 1)); } m_fpgaDIO->writeDO(currentDIO, &status); wpi_assertCleanStatus(status); }
/** * Write a digital I/O bit to the FPGA. * Set a single value on a digital I/O channel. * * @param channel The Digital I/O channel * @param value The state to set the digital channel (if it is configured as an output) */ void DigitalModule::SetDIO(uint32_t channel, short value) { if (value != 0 && value != 1) { wpi_setWPIError(NonBinaryDigitalValue); if (value != 0) value = 1; } tRioStatusCode localStatus = NiFpga_Status_Success; { Synchronized sync(m_digitalSemaphore); uint16_t currentDIO = m_fpgaDIO->readDO(&localStatus); if(value == 0) { currentDIO = currentDIO & ~(1 << RemapDigitalChannel(channel - 1)); } else if (value == 1) { currentDIO = currentDIO | (1 << RemapDigitalChannel(channel - 1)); } m_fpgaDIO->writeDO(currentDIO, &localStatus); } wpi_setError(localStatus); }
/** * 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. */ bool DigitalModule::AllocateDIO(UINT32 channel, bool input) { status = 0; DIOChannels->Allocate(kDigitalChannels * SlotToIndex(m_slot) + channel - 1); UINT32 outputEnable = m_fpgaDIO->readOutputEnable(&status); UINT32 bitToSet = 1 << (RemapDigitalChannel(channel - 1)); UINT32 outputEnableValue; if (input) { outputEnableValue = outputEnable & (~ bitToSet ); // clear the bit for read } else { outputEnableValue = outputEnable | bitToSet; // set the bit for write } m_fpgaDIO->writeOutputEnable(outputEnableValue, &status); wpi_assertCleanStatus(status); return true; }
/** * 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 Digital I/O channel * @param input If true open as input; if false open as output * @return Was successfully allocated */ bool DigitalModule::AllocateDIO(uint32_t channel, bool input) { char buf[64]; sprintf(buf, "DIO %u (Module %d)", channel, m_moduleNumber); if (DIOChannels->Allocate(kDigitalChannels * (m_moduleNumber - 1) + channel - 1, buf) == ~0ul) return false; tRioStatusCode localStatus = NiFpga_Status_Success; { Synchronized sync(m_digitalSemaphore); uint32_t bitToSet = 1 << (RemapDigitalChannel(channel - 1)); uint32_t outputEnable = m_fpgaDIO->readOutputEnable(&localStatus); uint32_t outputEnableValue; if (input) { outputEnableValue = outputEnable & (~bitToSet); // clear the bit for read } else { outputEnableValue = outputEnable | bitToSet; // set the bit for write } m_fpgaDIO->writeOutputEnable(outputEnableValue, &localStatus); } wpi_setError(localStatus); return true; }