No Changes

Dependencies:   BLE_API mbed-dev-bin nRF51822

Dependents:   microbit

Fork of microbit-dal by Lancaster University

Committer:
Asimov
Date:
Fri Jan 13 21:14:06 2017 +0000
Revision:
75:ae9a17da71af
Parent:
3:d86a4ddc1867
No Changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for DynamicPwm.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * This class addresses a few issues found in the underlying libraries.
Jonathan Austin 1:8aa5cdb4ab67 30 * This provides the ability for a neat, clean swap between PWM channels.
Jonathan Austin 1:8aa5cdb4ab67 31 */
Jonathan Austin 1:8aa5cdb4ab67 32
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 34 #include "DynamicPwm.h"
Jonathan Austin 1:8aa5cdb4ab67 35 #include "MicroBitPin.h"
Jonathan Austin 1:8aa5cdb4ab67 36 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 37
LancasterUniversity 3:d86a4ddc1867 38 DynamicPwm* DynamicPwm::pwms[NO_PWMS] = { NULL, NULL, NULL };
Jonathan Austin 1:8aa5cdb4ab67 39
Jonathan Austin 1:8aa5cdb4ab67 40 uint8_t DynamicPwm::lastUsed = NO_PWMS+1; //set it to out of range i.e. 4 so we know it hasn't been used yet.
Jonathan Austin 1:8aa5cdb4ab67 41
Jonathan Austin 1:8aa5cdb4ab67 42 uint16_t DynamicPwm::sharedPeriod = 0; //set the shared period to an unknown state
Jonathan Austin 1:8aa5cdb4ab67 43
Jonathan Austin 1:8aa5cdb4ab67 44 /**
Jonathan Austin 1:8aa5cdb4ab67 45 * Reassigns an already operational PWM channel to the given pin.
Jonathan Austin 1:8aa5cdb4ab67 46 *
Jonathan Austin 1:8aa5cdb4ab67 47 * @param pin The desired pin to begin a PWM wave.
Jonathan Austin 1:8aa5cdb4ab67 48 *
Jonathan Austin 1:8aa5cdb4ab67 49 * @param oldPin The pin to stop running a PWM wave.
Jonathan Austin 1:8aa5cdb4ab67 50 *
Jonathan Austin 1:8aa5cdb4ab67 51 * @param channel_number The GPIOTE channel being used to drive this PWM channel
Jonathan Austin 1:8aa5cdb4ab67 52 *
Jonathan Austin 1:8aa5cdb4ab67 53 * TODO: Merge into mbed, at a later date.
Jonathan Austin 1:8aa5cdb4ab67 54 */
Jonathan Austin 1:8aa5cdb4ab67 55 void gpiote_reinit(PinName pin, PinName oldPin, uint8_t channel_number)
Jonathan Austin 1:8aa5cdb4ab67 56 {
Jonathan Austin 1:8aa5cdb4ab67 57 // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
Jonathan Austin 1:8aa5cdb4ab67 58 NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
Jonathan Austin 1:8aa5cdb4ab67 59 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
Jonathan Austin 1:8aa5cdb4ab67 60 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
Jonathan Austin 1:8aa5cdb4ab67 61 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
Jonathan Austin 1:8aa5cdb4ab67 62 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
Jonathan Austin 1:8aa5cdb4ab67 63
Jonathan Austin 1:8aa5cdb4ab67 64 NRF_GPIO->OUTCLR = (1 << oldPin);
Jonathan Austin 1:8aa5cdb4ab67 65 NRF_GPIO->OUTCLR = (1 << pin);
Jonathan Austin 1:8aa5cdb4ab67 66
Jonathan Austin 1:8aa5cdb4ab67 67 /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
Jonathan Austin 1:8aa5cdb4ab67 68 If it does not, the channel output inheritance sets the proper level. */
Jonathan Austin 1:8aa5cdb4ab67 69
Jonathan Austin 1:8aa5cdb4ab67 70 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 71 ((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 72 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
Jonathan Austin 1:8aa5cdb4ab67 73 ((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos); // ((uint32_t)GPIOTE_CONFIG_OUTINIT_High <<
Jonathan Austin 1:8aa5cdb4ab67 74 // GPIOTE_CONFIG_OUTINIT_Pos);//
Jonathan Austin 1:8aa5cdb4ab67 75
Jonathan Austin 1:8aa5cdb4ab67 76 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
Jonathan Austin 1:8aa5cdb4ab67 77 __NOP();
Jonathan Austin 1:8aa5cdb4ab67 78 __NOP();
Jonathan Austin 1:8aa5cdb4ab67 79 __NOP();
Jonathan Austin 1:8aa5cdb4ab67 80
Jonathan Austin 1:8aa5cdb4ab67 81 NRF_TIMER2->CC[channel_number] = 0;
Jonathan Austin 1:8aa5cdb4ab67 82 }
Jonathan Austin 1:8aa5cdb4ab67 83
Jonathan Austin 1:8aa5cdb4ab67 84 /**
Jonathan Austin 1:8aa5cdb4ab67 85 * An internal constructor used when allocating a new DynamicPwm instance.
Jonathan Austin 1:8aa5cdb4ab67 86 *
Jonathan Austin 1:8aa5cdb4ab67 87 * @param pin the name of the pin for the pwm to target
Jonathan Austin 1:8aa5cdb4ab67 88 *
Jonathan Austin 1:8aa5cdb4ab67 89 * @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
Jonathan Austin 1:8aa5cdb4ab67 90 * or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
Jonathan Austin 1:8aa5cdb4ab67 91 */
Jonathan Austin 1:8aa5cdb4ab67 92 DynamicPwm::DynamicPwm(PinName pin, PwmPersistence persistence) : PwmOut(pin)
Jonathan Austin 1:8aa5cdb4ab67 93 {
Jonathan Austin 1:8aa5cdb4ab67 94 this->flags = persistence;
Jonathan Austin 1:8aa5cdb4ab67 95 }
Jonathan Austin 1:8aa5cdb4ab67 96
Jonathan Austin 1:8aa5cdb4ab67 97 /**
Jonathan Austin 1:8aa5cdb4ab67 98 * Redirects the pwm channel to point at a different pin.
Jonathan Austin 1:8aa5cdb4ab67 99 *
Jonathan Austin 1:8aa5cdb4ab67 100 * @param pin the desired pin to output a PWM wave.
Jonathan Austin 1:8aa5cdb4ab67 101 *
Jonathan Austin 1:8aa5cdb4ab67 102 * @code
Jonathan Austin 1:8aa5cdb4ab67 103 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 104 * pwm->redirect(p0); // pwm is now produced on p0
Jonathan Austin 1:8aa5cdb4ab67 105 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 106 */
Jonathan Austin 1:8aa5cdb4ab67 107 void DynamicPwm::redirect(PinName pin)
Jonathan Austin 1:8aa5cdb4ab67 108 {
Jonathan Austin 1:8aa5cdb4ab67 109 gpiote_reinit(pin, _pwm.pin, (uint8_t)_pwm.pwm);
Jonathan Austin 1:8aa5cdb4ab67 110 this->_pwm.pin = pin;
Jonathan Austin 1:8aa5cdb4ab67 111 }
Jonathan Austin 1:8aa5cdb4ab67 112
Jonathan Austin 1:8aa5cdb4ab67 113 /**
Jonathan Austin 1:8aa5cdb4ab67 114 * Creates a new DynamicPwm instance, or reuses an existing instance that
Jonathan Austin 1:8aa5cdb4ab67 115 * has a persistence level of PWM_PERSISTENCE_TRANSIENT.
Jonathan Austin 1:8aa5cdb4ab67 116 *
Jonathan Austin 1:8aa5cdb4ab67 117 * @param pin the name of the pin for the pwm to target
Jonathan Austin 1:8aa5cdb4ab67 118 *
Jonathan Austin 1:8aa5cdb4ab67 119 * @param persistance the level of persistence for this pin PWM_PERSISTENCE_PERSISTENT (can not be replaced until freed, should only be used for system services really.)
Jonathan Austin 1:8aa5cdb4ab67 120 * or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
Jonathan Austin 1:8aa5cdb4ab67 121 *
Jonathan Austin 1:8aa5cdb4ab67 122 * @return a pointer to the first available free pwm channel - or the first one that can be reallocated. If
Jonathan Austin 1:8aa5cdb4ab67 123 * no channels are available, NULL is returned.
Jonathan Austin 1:8aa5cdb4ab67 124 *
Jonathan Austin 1:8aa5cdb4ab67 125 * @code
Jonathan Austin 1:8aa5cdb4ab67 126 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 127 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 128 */
Jonathan Austin 1:8aa5cdb4ab67 129 DynamicPwm* DynamicPwm::allocate(PinName pin, PwmPersistence persistence)
Jonathan Austin 1:8aa5cdb4ab67 130 {
Jonathan Austin 1:8aa5cdb4ab67 131 //try to find a blank spot first
Jonathan Austin 1:8aa5cdb4ab67 132 for(int i = 0; i < NO_PWMS; i++)
Jonathan Austin 1:8aa5cdb4ab67 133 {
Jonathan Austin 1:8aa5cdb4ab67 134 if(pwms[i] == NULL)
Jonathan Austin 1:8aa5cdb4ab67 135 {
Jonathan Austin 1:8aa5cdb4ab67 136 lastUsed = i;
Jonathan Austin 1:8aa5cdb4ab67 137 pwms[i] = new DynamicPwm(pin, persistence);
Jonathan Austin 1:8aa5cdb4ab67 138 return pwms[i];
Jonathan Austin 1:8aa5cdb4ab67 139 }
Jonathan Austin 1:8aa5cdb4ab67 140 }
Jonathan Austin 1:8aa5cdb4ab67 141
Jonathan Austin 1:8aa5cdb4ab67 142 //no blank spot.. try to find a transient PWM
Jonathan Austin 1:8aa5cdb4ab67 143 int channelIterator = (lastUsed + 1 > NO_PWMS - 1) ? 0 : lastUsed + 1;
Jonathan Austin 1:8aa5cdb4ab67 144
Jonathan Austin 1:8aa5cdb4ab67 145 while(channelIterator != lastUsed)
Jonathan Austin 1:8aa5cdb4ab67 146 {
Jonathan Austin 1:8aa5cdb4ab67 147 if(pwms[channelIterator]->flags & PWM_PERSISTENCE_TRANSIENT)
Jonathan Austin 1:8aa5cdb4ab67 148 {
Jonathan Austin 1:8aa5cdb4ab67 149 lastUsed = channelIterator;
Jonathan Austin 1:8aa5cdb4ab67 150 pwms[channelIterator]->flags = persistence;
Jonathan Austin 1:8aa5cdb4ab67 151 pwms[channelIterator]->redirect(pin);
Jonathan Austin 1:8aa5cdb4ab67 152 return pwms[channelIterator];
Jonathan Austin 1:8aa5cdb4ab67 153 }
Jonathan Austin 1:8aa5cdb4ab67 154
Jonathan Austin 1:8aa5cdb4ab67 155 channelIterator = (channelIterator + 1 > NO_PWMS - 1) ? 0 : channelIterator + 1;
Jonathan Austin 1:8aa5cdb4ab67 156 }
Jonathan Austin 1:8aa5cdb4ab67 157
Jonathan Austin 1:8aa5cdb4ab67 158 //if we haven't found a free one, we must try to allocate the last used...
Jonathan Austin 1:8aa5cdb4ab67 159 if(pwms[lastUsed]->flags & PWM_PERSISTENCE_TRANSIENT)
Jonathan Austin 1:8aa5cdb4ab67 160 {
Jonathan Austin 1:8aa5cdb4ab67 161 pwms[lastUsed]->flags = persistence;
Jonathan Austin 1:8aa5cdb4ab67 162 pwms[lastUsed]->redirect(pin);
Jonathan Austin 1:8aa5cdb4ab67 163 return pwms[lastUsed];
Jonathan Austin 1:8aa5cdb4ab67 164 }
Jonathan Austin 1:8aa5cdb4ab67 165
Jonathan Austin 1:8aa5cdb4ab67 166 //well if we have no transient channels - we can't give any away! :( return null
Jonathan Austin 1:8aa5cdb4ab67 167 return (DynamicPwm*)NULL;
Jonathan Austin 1:8aa5cdb4ab67 168 }
Jonathan Austin 1:8aa5cdb4ab67 169
Jonathan Austin 1:8aa5cdb4ab67 170 /**
Jonathan Austin 1:8aa5cdb4ab67 171 * Frees this DynamicPwm instance for reuse.
Jonathan Austin 1:8aa5cdb4ab67 172 *
Jonathan Austin 1:8aa5cdb4ab67 173 * @code
Jonathan Austin 1:8aa5cdb4ab67 174 * DynamicPwm* pwm = DynamicPwm::allocate();
Jonathan Austin 1:8aa5cdb4ab67 175 * pwm->release();
Jonathan Austin 1:8aa5cdb4ab67 176 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 177 */
Jonathan Austin 1:8aa5cdb4ab67 178 void DynamicPwm::release()
Jonathan Austin 1:8aa5cdb4ab67 179 {
Jonathan Austin 1:8aa5cdb4ab67 180 //free the pwm instance.
Jonathan Austin 1:8aa5cdb4ab67 181 NRF_GPIOTE->CONFIG[(uint8_t) _pwm.pwm] = 0;
Jonathan Austin 1:8aa5cdb4ab67 182 pwmout_free(&_pwm);
Jonathan Austin 1:8aa5cdb4ab67 183 this->flags = PWM_PERSISTENCE_TRANSIENT;
Jonathan Austin 1:8aa5cdb4ab67 184
Jonathan Austin 1:8aa5cdb4ab67 185 //set the pointer to this object to null...
Jonathan Austin 1:8aa5cdb4ab67 186 for(int i =0; i < NO_PWMS; i++)
Jonathan Austin 1:8aa5cdb4ab67 187 if(pwms[i] == this)
Jonathan Austin 1:8aa5cdb4ab67 188 {
Jonathan Austin 1:8aa5cdb4ab67 189 delete pwms[i];
Jonathan Austin 1:8aa5cdb4ab67 190 pwms[i] = NULL;
Jonathan Austin 1:8aa5cdb4ab67 191 }
Jonathan Austin 1:8aa5cdb4ab67 192 }
Jonathan Austin 1:8aa5cdb4ab67 193
Jonathan Austin 1:8aa5cdb4ab67 194 /**
Jonathan Austin 1:8aa5cdb4ab67 195 * A lightweight wrapper around the super class' write in order to capture the value
Jonathan Austin 1:8aa5cdb4ab67 196 *
Jonathan Austin 1:8aa5cdb4ab67 197 * @param value the duty cycle percentage in floating point format.
Jonathan Austin 1:8aa5cdb4ab67 198 *
Jonathan Austin 1:8aa5cdb4ab67 199 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range
Jonathan Austin 1:8aa5cdb4ab67 200 *
Jonathan Austin 1:8aa5cdb4ab67 201 * @code
Jonathan Austin 1:8aa5cdb4ab67 202 * DynamicPwm* pwm = DynamicPwm::allocate();
Jonathan Austin 1:8aa5cdb4ab67 203 * pwm->write(0.5);
Jonathan Austin 1:8aa5cdb4ab67 204 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 205 */
Jonathan Austin 1:8aa5cdb4ab67 206 int DynamicPwm::write(float value){
Jonathan Austin 1:8aa5cdb4ab67 207
Jonathan Austin 1:8aa5cdb4ab67 208 if(value < 0)
Jonathan Austin 1:8aa5cdb4ab67 209 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 210
Jonathan Austin 1:8aa5cdb4ab67 211 PwmOut::write(value);
Jonathan Austin 1:8aa5cdb4ab67 212 lastValue = value;
Jonathan Austin 1:8aa5cdb4ab67 213
Jonathan Austin 1:8aa5cdb4ab67 214 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 215 }
Jonathan Austin 1:8aa5cdb4ab67 216
Jonathan Austin 1:8aa5cdb4ab67 217 /**
Jonathan Austin 1:8aa5cdb4ab67 218 * Retreives the PinName associated with this DynamicPwm instance.
Jonathan Austin 1:8aa5cdb4ab67 219 *
Jonathan Austin 1:8aa5cdb4ab67 220 * @code
Jonathan Austin 1:8aa5cdb4ab67 221 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 222 *
Jonathan Austin 1:8aa5cdb4ab67 223 * // returns the PinName n.
Jonathan Austin 1:8aa5cdb4ab67 224 * pwm->getPinName();
Jonathan Austin 1:8aa5cdb4ab67 225 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 226 *
Jonathan Austin 1:8aa5cdb4ab67 227 * @note This should be used to check that the DynamicPwm instance has not
Jonathan Austin 1:8aa5cdb4ab67 228 * been reallocated for use in another part of a program.
Jonathan Austin 1:8aa5cdb4ab67 229 */
Jonathan Austin 1:8aa5cdb4ab67 230 PinName DynamicPwm::getPinName()
Jonathan Austin 1:8aa5cdb4ab67 231 {
Jonathan Austin 1:8aa5cdb4ab67 232 return _pwm.pin;
Jonathan Austin 1:8aa5cdb4ab67 233 }
Jonathan Austin 1:8aa5cdb4ab67 234
Jonathan Austin 1:8aa5cdb4ab67 235 /**
Jonathan Austin 1:8aa5cdb4ab67 236 * Retreives the last value that has been written to this DynamicPwm instance.
Jonathan Austin 1:8aa5cdb4ab67 237 * in the range 0 - 1023 inclusive.
Jonathan Austin 1:8aa5cdb4ab67 238 *
Jonathan Austin 1:8aa5cdb4ab67 239 * @code
Jonathan Austin 1:8aa5cdb4ab67 240 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 241 * pwm->write(0.5);
Jonathan Austin 1:8aa5cdb4ab67 242 *
Jonathan Austin 1:8aa5cdb4ab67 243 * // will return 512.
Jonathan Austin 1:8aa5cdb4ab67 244 * pwm->getValue();
Jonathan Austin 1:8aa5cdb4ab67 245 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 246 */
Jonathan Austin 1:8aa5cdb4ab67 247 int DynamicPwm::getValue()
Jonathan Austin 1:8aa5cdb4ab67 248 {
Jonathan Austin 1:8aa5cdb4ab67 249 return (float)lastValue * float(MICROBIT_PIN_MAX_OUTPUT);
Jonathan Austin 1:8aa5cdb4ab67 250 }
Jonathan Austin 1:8aa5cdb4ab67 251
Jonathan Austin 1:8aa5cdb4ab67 252 /**
Jonathan Austin 1:8aa5cdb4ab67 253 * Retreives the current period in use by the entire PWM module in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 254 *
Jonathan Austin 1:8aa5cdb4ab67 255 * Example:
Jonathan Austin 1:8aa5cdb4ab67 256 * @code
Jonathan Austin 1:8aa5cdb4ab67 257 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 258 * pwm->getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 259 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 260 */
Jonathan Austin 1:8aa5cdb4ab67 261 int DynamicPwm::getPeriodUs()
Jonathan Austin 1:8aa5cdb4ab67 262 {
Jonathan Austin 1:8aa5cdb4ab67 263 return sharedPeriod;
Jonathan Austin 1:8aa5cdb4ab67 264 }
Jonathan Austin 1:8aa5cdb4ab67 265
Jonathan Austin 1:8aa5cdb4ab67 266 /**
Jonathan Austin 1:8aa5cdb4ab67 267 * Retreives the current period in use by the entire PWM module in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 268 *
Jonathan Austin 1:8aa5cdb4ab67 269 * Example:
Jonathan Austin 1:8aa5cdb4ab67 270 * @code
Jonathan Austin 1:8aa5cdb4ab67 271 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 272 * pwm->setPeriodUs(20000);
Jonathan Austin 1:8aa5cdb4ab67 273 *
Jonathan Austin 1:8aa5cdb4ab67 274 * // will return 20000
Jonathan Austin 1:8aa5cdb4ab67 275 * pwm->getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 276 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 277 */
Jonathan Austin 1:8aa5cdb4ab67 278 int DynamicPwm::getPeriod()
Jonathan Austin 1:8aa5cdb4ab67 279 {
Jonathan Austin 1:8aa5cdb4ab67 280 return getPeriodUs() / 1000;
Jonathan Austin 1:8aa5cdb4ab67 281 }
Jonathan Austin 1:8aa5cdb4ab67 282
Jonathan Austin 1:8aa5cdb4ab67 283 /**
Jonathan Austin 1:8aa5cdb4ab67 284 * Sets the period used by the WHOLE PWM module.
Jonathan Austin 1:8aa5cdb4ab67 285 *
Jonathan Austin 1:8aa5cdb4ab67 286 * @param period the desired period in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 287 *
Jonathan Austin 1:8aa5cdb4ab67 288 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
Jonathan Austin 1:8aa5cdb4ab67 289 *
Jonathan Austin 1:8aa5cdb4ab67 290 * Example:
Jonathan Austin 1:8aa5cdb4ab67 291 * @code
Jonathan Austin 1:8aa5cdb4ab67 292 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 293 *
Jonathan Austin 1:8aa5cdb4ab67 294 * // period now is 20ms
Jonathan Austin 1:8aa5cdb4ab67 295 * pwm->setPeriodUs(20000);
Jonathan Austin 1:8aa5cdb4ab67 296 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 297 *
Jonathan Austin 1:8aa5cdb4ab67 298 * @note Any changes to the period will AFFECT ALL CHANNELS.
Jonathan Austin 1:8aa5cdb4ab67 299 */
Jonathan Austin 1:8aa5cdb4ab67 300 int DynamicPwm::setPeriodUs(int period)
Jonathan Austin 1:8aa5cdb4ab67 301 {
Jonathan Austin 1:8aa5cdb4ab67 302 if(period < 0)
Jonathan Austin 1:8aa5cdb4ab67 303 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 304
Jonathan Austin 1:8aa5cdb4ab67 305 //#HACK this forces mbed to update the pulse width calculation.
Jonathan Austin 1:8aa5cdb4ab67 306 period_us(period);
Jonathan Austin 1:8aa5cdb4ab67 307 write(lastValue);
Jonathan Austin 1:8aa5cdb4ab67 308 sharedPeriod = period;
Jonathan Austin 1:8aa5cdb4ab67 309
Jonathan Austin 1:8aa5cdb4ab67 310 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 311 }
Jonathan Austin 1:8aa5cdb4ab67 312
Jonathan Austin 1:8aa5cdb4ab67 313 /**
Jonathan Austin 1:8aa5cdb4ab67 314 * Sets the period used by the WHOLE PWM module. Any changes to the period will AFFECT ALL CHANNELS.
Jonathan Austin 1:8aa5cdb4ab67 315 *
Jonathan Austin 1:8aa5cdb4ab67 316 * @param period the desired period in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 317 *
Jonathan Austin 1:8aa5cdb4ab67 318 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
Jonathan Austin 1:8aa5cdb4ab67 319 *
Jonathan Austin 1:8aa5cdb4ab67 320 * Example:
Jonathan Austin 1:8aa5cdb4ab67 321 * @code
Jonathan Austin 1:8aa5cdb4ab67 322 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 323 *
Jonathan Austin 1:8aa5cdb4ab67 324 * // period now is 20ms
Jonathan Austin 1:8aa5cdb4ab67 325 * pwm->setPeriod(20);
Jonathan Austin 1:8aa5cdb4ab67 326 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 327 */
Jonathan Austin 1:8aa5cdb4ab67 328 int DynamicPwm::setPeriod(int period)
Jonathan Austin 1:8aa5cdb4ab67 329 {
Jonathan Austin 1:8aa5cdb4ab67 330 return setPeriodUs(period * 1000);
LancasterUniversity 3:d86a4ddc1867 331 }