/** * Create a new instance of an digital module. * Create an instance of the digital module object. Initialize all the parameters * to reasonable values on start. * Setting a global value on an digital module can be done only once unless subsequent * values are set the previously set value. * Digital modules are a singleton, so the constructor is never called outside of this class. */ DigitalModule::DigitalModule(UINT32 slot) : Module(slot) , m_fpgaDIO (NULL) { Resource::CreateResourceObject(&DIOChannels, tDIO::kNumSystems * kDigitalChannels); m_fpgaDIO = new tDIO(SlotToIndex(m_slot), &status); // Make sure that the 9403 IONode has had a chance to initialize before continuing. while(m_fpgaDIO->readLoopTiming(&status) == 0) taskDelay(1); if (m_fpgaDIO->readLoopTiming(&status) != kExpectedLoopTiming) { wpi_fatal(LoopTimingError); printf("DIO LoopTiming: %d, expecting: %d\n", m_fpgaDIO->readLoopTiming(&status), kExpectedLoopTiming); } m_fpgaDIO->writePWMConfig_Period(PWM::kDefaultPwmPeriod, &status); m_fpgaDIO->writePWMConfig_MinHigh(PWM::kDefaultMinPwmHigh, &status); // Ensure that PWM output values are set to OFF for (UINT32 pwm_index = 1; pwm_index <= kPwmChannels; pwm_index++) { SetPWM(pwm_index, PWM::kPwmDisabled); SetPWMPeriodScale(pwm_index, 3); // Set all to 4x by default. } // Turn off all relay outputs. m_fpgaDIO->writeSlowValue_RelayFwd(0, &status); m_fpgaDIO->writeSlowValue_RelayRev(0, &status); // Create a semaphore to protect changes to the relay values m_relaySemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); AddToSingletonList(); }
/** * Create a new instance of an digital module. * Create an instance of the digital module object. Initialize all the parameters * to reasonable values on start. * Setting a global value on an digital module can be done only once unless subsequent * values are set the previously set value. * Digital modules are a singleton, so the constructor is never called outside of this class. * * @param moduleNumber The digital module to create (1 or 2). */ DigitalModule::DigitalModule(uint8_t moduleNumber) : Module(nLoadOut::kModuleType_Digital, moduleNumber) , m_fpgaDIO (NULL) { Resource::CreateResourceObject(&DIOChannels, tDIO::kNumSystems * kDigitalChannels); Resource::CreateResourceObject(&DO_PWMGenerators[m_moduleNumber - 1], tDIO::kNumDO_PWMDutyCycleElements); tRioStatusCode localStatus = NiFpga_Status_Success; m_fpgaDIO = tDIO::create(m_moduleNumber - 1, &localStatus); wpi_setError(localStatus); // Make sure that the 9403 IONode has had a chance to initialize before continuing. while(m_fpgaDIO->readLoopTiming(&localStatus) == 0) sleep_ms(1);//taskDelay(1); if (m_fpgaDIO->readLoopTiming(&localStatus) != kExpectedLoopTiming) { char err[128]; sprintf(err, "DIO LoopTiming: %d, expecting: %u\n", m_fpgaDIO->readLoopTiming(&localStatus), kExpectedLoopTiming); wpi_setWPIErrorWithContext(LoopTimingError, err); } //Calculate the length, in ms, of one DIO loop double loopTime = m_fpgaDIO->readLoopTiming(&localStatus)/(kSystemClockTicksPerMicrosecond*1e3); m_fpgaDIO->writePWMConfig_Period((uint16_t) (PWM::kDefaultPwmPeriod/loopTime + .5), &localStatus); m_fpgaDIO->writePWMConfig_MinHigh((uint16_t) ((PWM::kDefaultPwmCenter-PWM::kDefaultPwmStepsDown*loopTime)/loopTime + .5), &localStatus); // Ensure that PWM output values are set to OFF for (uint32_t pwm_index = 1; pwm_index <= kPwmChannels; pwm_index++) { SetPWM(pwm_index, PWM::kPwmDisabled); SetPWMPeriodScale(pwm_index, 3); // Set all to 4x by default. } // Turn off all relay outputs. m_fpgaDIO->writeSlowValue_RelayFwd(0, &localStatus); m_fpgaDIO->writeSlowValue_RelayRev(0, &localStatus); wpi_setError(localStatus); // Create a semaphore to protect changes to the digital output values // m_digitalSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); // Create a semaphore to protect changes to the relay values // m_relaySemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); // Create a semaphore to protect changes to the DO PWM config // m_doPwmSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); AddToSingletonList(); }