Now you can download a copy of these docs so you can use them offline! Download now
PWM.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 "PWM.h" 00008 00009 #include "DigitalModule.h" 00010 #include "Resource.h" 00011 #include "Utility.h" 00012 #include "WPIErrors.h" 00013 00014 const UINT32 PWM::kDefaultPwmPeriod; 00015 const UINT32 PWM::kDefaultMinPwmHigh; 00016 const INT32 PWM::kPwmDisabled; 00017 static Resource *allocated = NULL; 00018 00026 void PWM::InitPWM(UINT8 moduleNumber, UINT32 channel) 00027 { 00028 char buf[64]; 00029 Resource::CreateResourceObject(&allocated, tDIO::kNumSystems * kPwmChannels); 00030 if (!CheckPWMModule(moduleNumber)) 00031 { 00032 snprintf(buf, 64, "Digital Module %d", moduleNumber); 00033 wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf); 00034 return; 00035 } 00036 if (!CheckPWMChannel(channel)) 00037 { 00038 snprintf(buf, 64, "PWM Channel %d", channel); 00039 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf); 00040 return; 00041 } 00042 00043 snprintf(buf, 64, "PWM %d (Module: %d)", channel, moduleNumber); 00044 if (allocated->Allocate((moduleNumber - 1) * kPwmChannels + channel - 1, buf) == ~0ul) 00045 { 00046 CloneError(allocated); 00047 return; 00048 } 00049 m_channel = channel; 00050 m_module = DigitalModule::GetInstance(moduleNumber); 00051 m_module->SetPWM(m_channel, kPwmDisabled); 00052 m_eliminateDeadband = false; 00053 } 00054 00062 PWM::PWM(UINT8 moduleNumber, UINT32 channel) 00063 : m_module(NULL) 00064 { 00065 InitPWM(moduleNumber, channel); 00066 } 00067 00076 PWM::PWM(UINT32 channel) 00077 : m_module(NULL) 00078 { 00079 InitPWM(GetDefaultDigitalModule(), channel); 00080 } 00081 00087 PWM::~PWM() 00088 { 00089 if (m_module) 00090 { 00091 m_module->SetPWM(m_channel, kPwmDisabled); 00092 allocated->Free((m_module->GetNumber() - 1) * kPwmChannels + m_channel - 1); 00093 } 00094 } 00095 00102 void PWM::EnableDeadbandElimination(bool eliminateDeadband) 00103 { 00104 if (StatusIsFatal()) return; 00105 m_eliminateDeadband = eliminateDeadband; 00106 } 00107 00118 void PWM::SetBounds(INT32 max, INT32 deadbandMax, INT32 center, INT32 deadbandMin, INT32 min) 00119 { 00120 if (StatusIsFatal()) return; 00121 m_maxPwm = max; 00122 m_deadbandMaxPwm = deadbandMax; 00123 m_centerPwm = center; 00124 m_deadbandMinPwm = deadbandMin; 00125 m_minPwm = min; 00126 } 00127 00128 UINT32 PWM::GetModuleNumber() 00129 { 00130 return m_module->GetNumber(); 00131 } 00132 00143 void PWM::SetPosition(float pos) 00144 { 00145 if (StatusIsFatal()) return; 00146 if (pos < 0.0) 00147 { 00148 pos = 0.0; 00149 } 00150 else if (pos > 1.0) 00151 { 00152 pos = 1.0; 00153 } 00154 00155 INT32 rawValue; 00156 // note, need to perform the multiplication below as floating point before converting to int 00157 rawValue = (INT32)( (pos * (float) GetFullRangeScaleFactor()) + GetMinNegativePwm()); 00158 00159 wpi_assert((rawValue >= GetMinNegativePwm()) && (rawValue <= GetMaxPositivePwm())); 00160 wpi_assert(rawValue != kPwmDisabled); 00161 00162 // send the computed pwm value to the FPGA 00163 SetRaw((UINT8)rawValue); 00164 } 00165 00176 float PWM::GetPosition() 00177 { 00178 if (StatusIsFatal()) return 0.0; 00179 INT32 value = GetRaw(); 00180 if (value < GetMinNegativePwm()) 00181 { 00182 return 0.0; 00183 } 00184 else if (value > GetMaxPositivePwm()) 00185 { 00186 return 1.0; 00187 } 00188 else 00189 { 00190 return (float)(value - GetMinNegativePwm()) / (float)GetFullRangeScaleFactor(); 00191 } 00192 } 00193 00207 void PWM::SetSpeed(float speed) 00208 { 00209 if (StatusIsFatal()) return; 00210 // clamp speed to be in the range 1.0 >= speed >= -1.0 00211 if (speed < -1.0) 00212 { 00213 speed = -1.0; 00214 } 00215 else if (speed > 1.0) 00216 { 00217 speed = 1.0; 00218 } 00219 00220 // calculate the desired output pwm value by scaling the speed appropriately 00221 INT32 rawValue; 00222 if (speed == 0.0) 00223 { 00224 rawValue = GetCenterPwm(); 00225 } 00226 else if (speed > 0.0) 00227 { 00228 rawValue = (INT32)(speed * ((float)GetPositiveScaleFactor()) + 00229 ((float) GetMinPositivePwm()) + 0.5); 00230 } 00231 else 00232 { 00233 rawValue = (INT32)(speed * ((float)GetNegativeScaleFactor()) + 00234 ((float) GetMaxNegativePwm()) + 0.5); 00235 } 00236 00237 // the above should result in a pwm_value in the valid range 00238 wpi_assert((rawValue >= GetMinNegativePwm()) && (rawValue <= GetMaxPositivePwm())); 00239 wpi_assert(rawValue != kPwmDisabled); 00240 00241 // send the computed pwm value to the FPGA 00242 SetRaw((UINT8)rawValue); 00243 } 00244 00257 float PWM::GetSpeed() 00258 { 00259 if (StatusIsFatal()) return 0.0; 00260 INT32 value = GetRaw(); 00261 if (value > GetMaxPositivePwm()) 00262 { 00263 return 1.0; 00264 } 00265 else if (value < GetMinNegativePwm()) 00266 { 00267 return -1.0; 00268 } 00269 else if (value > GetMinPositivePwm()) 00270 { 00271 return (float)(value - GetMinPositivePwm()) / (float)GetPositiveScaleFactor(); 00272 } 00273 else if (value < GetMaxNegativePwm()) 00274 { 00275 return (float)(value - GetMaxNegativePwm()) / (float)GetNegativeScaleFactor(); 00276 } 00277 else 00278 { 00279 return 0.0; 00280 } 00281 } 00282 00290 void PWM::SetRaw(UINT8 value) 00291 { 00292 if (StatusIsFatal()) return; 00293 m_module->SetPWM(m_channel, value); 00294 } 00295 00303 UINT8 PWM::GetRaw() 00304 { 00305 if (StatusIsFatal()) return 0; 00306 return m_module->GetPWM(m_channel); 00307 } 00308 00314 void PWM::SetPeriodMultiplier(PeriodMultiplier mult) 00315 { 00316 if (StatusIsFatal()) return; 00317 switch(mult) 00318 { 00319 case kPeriodMultiplier_4X: 00320 m_module->SetPWMPeriodScale(m_channel, 3); // Squelch 3 out of 4 outputs 00321 break; 00322 case kPeriodMultiplier_2X: 00323 m_module->SetPWMPeriodScale(m_channel, 1); // Squelch 1 out of 2 outputs 00324 break; 00325 case kPeriodMultiplier_1X: 00326 m_module->SetPWMPeriodScale(m_channel, 0); // Don't squelch any outputs 00327 break; 00328 default: 00329 wpi_assert(false); 00330 } 00331 }
Generated on Thu Jan 12 2012 22:35:23 for WPILibC++ by
1.7.1