Now you can download a copy of these docs so you can use them offline! Download now
AnalogModule.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "AnalogModule.h" 00008 #include "Synchronized.h" 00009 #include "Timer.h" 00010 #include "WPIErrors.h" 00011 #include "NetworkCommunication/AICalibration.h" 00012 00013 const long AnalogModule::kTimebase; 00014 const long AnalogModule::kDefaultOversampleBits; 00015 const long AnalogModule::kDefaultAverageBits; 00016 const float AnalogModule::kDefaultSampleRate; 00017 SEM_ID AnalogModule::m_registerWindowSemaphore = NULL; 00018 00028 AnalogModule* AnalogModule::GetInstance(UINT8 moduleNumber) 00029 { 00030 if (CheckAnalogModule(moduleNumber)) 00031 { 00032 return (AnalogModule*)GetModule(nLoadOut::kModuleType_Analog, moduleNumber); 00033 } 00034 00035 // If this wasn't caught before now, make sure we say what's wrong before we crash 00036 char buf[64]; 00037 snprintf(buf, 64, "Analog Module %d", moduleNumber); 00038 wpi_setGlobalWPIErrorWithContext(ModuleIndexOutOfRange, buf); 00039 00040 return NULL; 00041 } 00042 00054 AnalogModule::AnalogModule(UINT8 moduleNumber) 00055 : Module(nLoadOut::kModuleType_Analog, moduleNumber) 00056 , m_module (NULL) 00057 , m_sampleRateSet (false) 00058 , m_numChannelsToActivate (0) 00059 { 00060 AddToSingletonList(); 00061 tRioStatusCode localStatus = NiFpga_Status_Success; 00062 m_module = tAI::create(m_moduleNumber - 1, &localStatus); 00063 wpi_setError(localStatus); 00064 SetNumChannelsToActivate(kAnalogChannels); 00065 SetSampleRate(kDefaultSampleRate); 00066 00067 for (UINT32 i = 0; i < kAnalogChannels; i++) 00068 { 00069 m_module->writeScanList(i, i, &localStatus); 00070 wpi_setError(localStatus); 00071 SetAverageBits(i + 1, kDefaultAverageBits); 00072 SetOversampleBits(i + 1, kDefaultOversampleBits); 00073 } 00074 00075 if (m_registerWindowSemaphore == NULL) 00076 { 00077 // Needs to be global since the protected resource spans both module singletons. 00078 m_registerWindowSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); 00079 } 00080 } 00081 00085 AnalogModule::~AnalogModule() 00086 { 00087 delete m_module; 00088 } 00089 00097 void AnalogModule::SetSampleRate(float samplesPerSecond) 00098 { 00099 // TODO: This will change when variable size scan lists are implemented. 00100 // TODO: Need float comparison with epsilon. 00101 //wpi_assert(!sampleRateSet || GetSampleRate() == samplesPerSecond); 00102 m_sampleRateSet = true; 00103 00104 // Compute the convert rate 00105 UINT32 ticksPerSample = (UINT32)((float)kTimebase / samplesPerSecond); 00106 UINT32 ticksPerConversion = ticksPerSample / GetNumChannelsToActivate(); 00107 // ticksPerConversion must be at least 80 00108 if (ticksPerConversion < 80) 00109 { 00110 wpi_setWPIError(SampleRateTooHigh); 00111 ticksPerConversion = 80; 00112 } 00113 00114 // Atomically set the scan size and the convert rate so that the sample rate is constant 00115 tAI::tConfig config; 00116 config.ScanSize = GetNumChannelsToActivate(); 00117 config.ConvertRate = ticksPerConversion; 00118 tRioStatusCode localStatus = NiFpga_Status_Success; 00119 m_module->writeConfig(config, &localStatus); 00120 wpi_setError(localStatus); 00121 00122 // Indicate that the scan size has been commited to hardware. 00123 SetNumChannelsToActivate(0); 00124 } 00125 00134 float AnalogModule::GetSampleRate() 00135 { 00136 tRioStatusCode localStatus = NiFpga_Status_Success; 00137 UINT32 ticksPerConversion = m_module->readLoopTiming(&localStatus); 00138 wpi_setError(localStatus); 00139 UINT32 ticksPerSample = ticksPerConversion * GetNumActiveChannels(); 00140 return (float)kTimebase / (float)ticksPerSample; 00141 } 00142 00148 UINT32 AnalogModule::GetNumActiveChannels() 00149 { 00150 tRioStatusCode localStatus = NiFpga_Status_Success; 00151 UINT32 scanSize = m_module->readConfig_ScanSize(&localStatus); 00152 wpi_setError(localStatus); 00153 if (scanSize == 0) 00154 return 8; 00155 return scanSize; 00156 } 00157 00169 UINT32 AnalogModule::GetNumChannelsToActivate() 00170 { 00171 if(m_numChannelsToActivate == 0) return GetNumActiveChannels(); 00172 return m_numChannelsToActivate; 00173 } 00174 00183 void AnalogModule::SetNumChannelsToActivate(UINT32 channels) 00184 { 00185 m_numChannelsToActivate = channels; 00186 } 00187 00198 void AnalogModule::SetAverageBits(UINT32 channel, UINT32 bits) 00199 { 00200 tRioStatusCode localStatus = NiFpga_Status_Success; 00201 m_module->writeAverageBits(channel - 1, bits, &localStatus); 00202 wpi_setError(localStatus); 00203 } 00204 00214 UINT32 AnalogModule::GetAverageBits(UINT32 channel) 00215 { 00216 tRioStatusCode localStatus = NiFpga_Status_Success; 00217 UINT32 result = m_module->readAverageBits(channel - 1, &localStatus); 00218 wpi_setError(localStatus); 00219 return result; 00220 } 00221 00232 void AnalogModule::SetOversampleBits(UINT32 channel, UINT32 bits) 00233 { 00234 tRioStatusCode localStatus = NiFpga_Status_Success; 00235 m_module->writeOversampleBits(channel - 1, bits, &localStatus); 00236 wpi_setError(localStatus); 00237 } 00238 00248 UINT32 AnalogModule::GetOversampleBits(UINT32 channel) 00249 { 00250 tRioStatusCode localStatus = NiFpga_Status_Success; 00251 UINT32 result = m_module->readOversampleBits(channel - 1, &localStatus); 00252 wpi_setError(localStatus); 00253 return result; 00254 } 00255 00264 INT16 AnalogModule::GetValue(UINT32 channel) 00265 { 00266 INT16 value; 00267 CheckAnalogChannel(channel); 00268 00269 tAI::tReadSelect readSelect; 00270 readSelect.Channel = channel - 1; 00271 readSelect.Module = m_moduleNumber - 1; 00272 readSelect.Averaged = false; 00273 tRioStatusCode localStatus = NiFpga_Status_Success; 00274 00275 { 00276 Synchronized sync(m_registerWindowSemaphore); 00277 m_module->writeReadSelect(readSelect, &localStatus); 00278 m_module->strobeLatchOutput(&localStatus); 00279 value = (INT16) m_module->readOutput(&localStatus); 00280 } 00281 00282 wpi_setError(localStatus); 00283 return value; 00284 } 00285 00298 INT32 AnalogModule::GetAverageValue(UINT32 channel) 00299 { 00300 INT32 value; 00301 CheckAnalogChannel(channel); 00302 00303 tAI::tReadSelect readSelect; 00304 readSelect.Channel = channel - 1; 00305 readSelect.Module = m_moduleNumber - 1; 00306 readSelect.Averaged = true; 00307 tRioStatusCode localStatus = NiFpga_Status_Success; 00308 00309 { 00310 Synchronized sync(m_registerWindowSemaphore); 00311 m_module->writeReadSelect(readSelect, &localStatus); 00312 m_module->strobeLatchOutput(&localStatus); 00313 value = m_module->readOutput(&localStatus); 00314 } 00315 00316 wpi_setError(localStatus); 00317 return value; 00318 } 00319 00332 INT32 AnalogModule::VoltsToValue(INT32 channel, float voltage) 00333 { 00334 if (voltage > 10.0) 00335 { 00336 voltage = 10.0; 00337 wpi_setWPIError(VoltageOutOfRange); 00338 } 00339 if (voltage < -10.0) 00340 { 00341 voltage = -10.0; 00342 wpi_setWPIError(VoltageOutOfRange); 00343 } 00344 UINT32 LSBWeight = GetLSBWeight(channel); 00345 INT32 offset = GetOffset(channel); 00346 INT32 value = (INT32) ((voltage + offset * 1.0e-9) / (LSBWeight * 1.0e-9)); 00347 return value; 00348 } 00349 00358 float AnalogModule::GetVoltage(UINT32 channel) 00359 { 00360 INT16 value = GetValue(channel); 00361 UINT32 LSBWeight = GetLSBWeight(channel); 00362 INT32 offset = GetOffset(channel); 00363 float voltage = LSBWeight * 1.0e-9 * value - offset * 1.0e-9; 00364 return voltage; 00365 } 00366 00377 float AnalogModule::GetAverageVoltage(UINT32 channel) 00378 { 00379 INT32 value = GetAverageValue(channel); 00380 UINT32 LSBWeight = GetLSBWeight(channel); 00381 INT32 offset = GetOffset(channel); 00382 UINT32 oversampleBits = GetOversampleBits(channel); 00383 float voltage = ((LSBWeight * 1.0e-9 * value) / (float)(1 << oversampleBits)) - offset * 1.0e-9; 00384 return voltage; 00385 } 00386 00397 UINT32 AnalogModule::GetLSBWeight(UINT32 channel) 00398 { 00399 tRioStatusCode localStatus = NiFpga_Status_Success; 00400 UINT32 lsbWeight = FRC_NetworkCommunication_nAICalibration_getLSBWeight(m_module->getSystemIndex(), channel - 1, (INT32*)&localStatus); 00401 wpi_setError(localStatus); 00402 return lsbWeight; 00403 } 00404 00415 INT32 AnalogModule::GetOffset(UINT32 channel) 00416 { 00417 tRioStatusCode localStatus = NiFpga_Status_Success; 00418 INT32 offset = FRC_NetworkCommunication_nAICalibration_getOffset(m_module->getSystemIndex(), channel - 1, (INT32*)&localStatus); 00419 wpi_setError(localStatus); 00420 return offset; 00421 } 00422 00423
Generated on Thu Jan 12 2012 22:35:17 for WPILibC++ by
1.7.1