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:
1:8aa5cdb4ab67
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 #include "mbed.h"
Jonathan Austin 1:8aa5cdb4ab67 27 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 28
Jonathan Austin 1:8aa5cdb4ab67 29 #ifndef MICROBIT_DYNAMIC_PWM_H
Jonathan Austin 1:8aa5cdb4ab67 30 #define MICROBIT_DYNAMIC_PWM_H
Jonathan Austin 1:8aa5cdb4ab67 31
Jonathan Austin 1:8aa5cdb4ab67 32 #define NO_PWMS 3
Jonathan Austin 1:8aa5cdb4ab67 33 #define MICROBIT_DEFAULT_PWM_PERIOD 20000
Jonathan Austin 1:8aa5cdb4ab67 34
Jonathan Austin 1:8aa5cdb4ab67 35 enum PwmPersistence
Jonathan Austin 1:8aa5cdb4ab67 36 {
Jonathan Austin 1:8aa5cdb4ab67 37 PWM_PERSISTENCE_TRANSIENT = 1,
Jonathan Austin 1:8aa5cdb4ab67 38 PWM_PERSISTENCE_PERSISTENT = 2,
Jonathan Austin 1:8aa5cdb4ab67 39 };
Jonathan Austin 1:8aa5cdb4ab67 40
Jonathan Austin 1:8aa5cdb4ab67 41 /**
Jonathan Austin 1:8aa5cdb4ab67 42 * Class definition for DynamicPwm.
Jonathan Austin 1:8aa5cdb4ab67 43 *
Jonathan Austin 1:8aa5cdb4ab67 44 * This class addresses a few issues found in the underlying libraries.
Jonathan Austin 1:8aa5cdb4ab67 45 * This provides the ability for a neat, clean swap between PWM channels.
Jonathan Austin 1:8aa5cdb4ab67 46 */
Jonathan Austin 1:8aa5cdb4ab67 47 class DynamicPwm : public PwmOut
Jonathan Austin 1:8aa5cdb4ab67 48 {
Jonathan Austin 1:8aa5cdb4ab67 49 private:
Jonathan Austin 1:8aa5cdb4ab67 50 static DynamicPwm* pwms[NO_PWMS];
Jonathan Austin 1:8aa5cdb4ab67 51 static uint8_t lastUsed;
Jonathan Austin 1:8aa5cdb4ab67 52 static uint16_t sharedPeriod;
Jonathan Austin 1:8aa5cdb4ab67 53 uint8_t flags;
Jonathan Austin 1:8aa5cdb4ab67 54 float lastValue;
Jonathan Austin 1:8aa5cdb4ab67 55
Jonathan Austin 1:8aa5cdb4ab67 56
Jonathan Austin 1:8aa5cdb4ab67 57
Jonathan Austin 1:8aa5cdb4ab67 58 /**
Jonathan Austin 1:8aa5cdb4ab67 59 * An internal constructor used when allocating a new DynamicPwm instance.
Jonathan Austin 1:8aa5cdb4ab67 60 *
Jonathan Austin 1:8aa5cdb4ab67 61 * @param pin the name of the pin for the pwm to target
Jonathan Austin 1:8aa5cdb4ab67 62 *
Jonathan Austin 1:8aa5cdb4ab67 63 * @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 64 * or PWM_PERSISTENCE_TRANSIENT (can be replaced at any point if a channel is required.)
Jonathan Austin 1:8aa5cdb4ab67 65 */
Jonathan Austin 1:8aa5cdb4ab67 66 DynamicPwm(PinName pin, PwmPersistence persistence = PWM_PERSISTENCE_TRANSIENT);
Jonathan Austin 1:8aa5cdb4ab67 67
Jonathan Austin 1:8aa5cdb4ab67 68 public:
Jonathan Austin 1:8aa5cdb4ab67 69
Jonathan Austin 1:8aa5cdb4ab67 70 /**
Jonathan Austin 1:8aa5cdb4ab67 71 * Redirects the pwm channel to point at a different pin.
Jonathan Austin 1:8aa5cdb4ab67 72 *
Jonathan Austin 1:8aa5cdb4ab67 73 * @param pin the desired pin to output a PWM wave.
Jonathan Austin 1:8aa5cdb4ab67 74 *
Jonathan Austin 1:8aa5cdb4ab67 75 * @code
Jonathan Austin 1:8aa5cdb4ab67 76 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 77 * pwm->redirect(p0); // pwm is now produced on p0
Jonathan Austin 1:8aa5cdb4ab67 78 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 79 */
Jonathan Austin 1:8aa5cdb4ab67 80 void redirect(PinName pin);
Jonathan Austin 1:8aa5cdb4ab67 81
Jonathan Austin 1:8aa5cdb4ab67 82
Jonathan Austin 1:8aa5cdb4ab67 83 /**
Jonathan Austin 1:8aa5cdb4ab67 84 * Creates a new DynamicPwm instance, or reuses an existing instance that
Jonathan Austin 1:8aa5cdb4ab67 85 * has a persistence level of PWM_PERSISTENCE_TRANSIENT.
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 * @return a pointer to the first available free pwm channel - or the first one that can be reallocated. If
Jonathan Austin 1:8aa5cdb4ab67 93 * no channels are available, NULL is returned.
Jonathan Austin 1:8aa5cdb4ab67 94 *
Jonathan Austin 1:8aa5cdb4ab67 95 * @code
Jonathan Austin 1:8aa5cdb4ab67 96 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 97 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 98 */
Jonathan Austin 1:8aa5cdb4ab67 99 static DynamicPwm* allocate(PinName pin, PwmPersistence persistence = PWM_PERSISTENCE_TRANSIENT);
Jonathan Austin 1:8aa5cdb4ab67 100
Jonathan Austin 1:8aa5cdb4ab67 101 /**
Jonathan Austin 1:8aa5cdb4ab67 102 * Frees this DynamicPwm instance for reuse.
Jonathan Austin 1:8aa5cdb4ab67 103 *
Jonathan Austin 1:8aa5cdb4ab67 104 * @code
Jonathan Austin 1:8aa5cdb4ab67 105 * DynamicPwm* pwm = DynamicPwm::allocate();
Jonathan Austin 1:8aa5cdb4ab67 106 * pwm->release();
Jonathan Austin 1:8aa5cdb4ab67 107 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 108 */
Jonathan Austin 1:8aa5cdb4ab67 109 void release();
Jonathan Austin 1:8aa5cdb4ab67 110
Jonathan Austin 1:8aa5cdb4ab67 111 /**
Jonathan Austin 1:8aa5cdb4ab67 112 * A lightweight wrapper around the super class' write in order to capture the value
Jonathan Austin 1:8aa5cdb4ab67 113 *
Jonathan Austin 1:8aa5cdb4ab67 114 * @param value the duty cycle percentage in floating point format.
Jonathan Austin 1:8aa5cdb4ab67 115 *
Jonathan Austin 1:8aa5cdb4ab67 116 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range
Jonathan Austin 1:8aa5cdb4ab67 117 *
Jonathan Austin 1:8aa5cdb4ab67 118 * @code
Jonathan Austin 1:8aa5cdb4ab67 119 * DynamicPwm* pwm = DynamicPwm::allocate();
Jonathan Austin 1:8aa5cdb4ab67 120 * pwm->write(0.5);
Jonathan Austin 1:8aa5cdb4ab67 121 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 122 */
Jonathan Austin 1:8aa5cdb4ab67 123 int write(float value);
Jonathan Austin 1:8aa5cdb4ab67 124
Jonathan Austin 1:8aa5cdb4ab67 125 /**
Jonathan Austin 1:8aa5cdb4ab67 126 * Retreives the PinName associated with this DynamicPwm instance.
Jonathan Austin 1:8aa5cdb4ab67 127 *
Jonathan Austin 1:8aa5cdb4ab67 128 * @code
Jonathan Austin 1:8aa5cdb4ab67 129 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 130 *
Jonathan Austin 1:8aa5cdb4ab67 131 * // returns the PinName n.
Jonathan Austin 1:8aa5cdb4ab67 132 * pwm->getPinName();
Jonathan Austin 1:8aa5cdb4ab67 133 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 134 *
Jonathan Austin 1:8aa5cdb4ab67 135 * @note This should be used to check that the DynamicPwm instance has not
Jonathan Austin 1:8aa5cdb4ab67 136 * been reallocated for use in another part of a program.
Jonathan Austin 1:8aa5cdb4ab67 137 */
Jonathan Austin 1:8aa5cdb4ab67 138 PinName getPinName();
Jonathan Austin 1:8aa5cdb4ab67 139
Jonathan Austin 1:8aa5cdb4ab67 140 /**
Jonathan Austin 1:8aa5cdb4ab67 141 * Retreives the last value that has been written to this DynamicPwm instance.
Jonathan Austin 1:8aa5cdb4ab67 142 * in the range 0 - 1023 inclusive.
Jonathan Austin 1:8aa5cdb4ab67 143 *
Jonathan Austin 1:8aa5cdb4ab67 144 * @code
Jonathan Austin 1:8aa5cdb4ab67 145 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 146 * pwm->write(0.5);
Jonathan Austin 1:8aa5cdb4ab67 147 *
Jonathan Austin 1:8aa5cdb4ab67 148 * // will return 512.
Jonathan Austin 1:8aa5cdb4ab67 149 * pwm->getValue();
Jonathan Austin 1:8aa5cdb4ab67 150 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 151 */
Jonathan Austin 1:8aa5cdb4ab67 152 int getValue();
Jonathan Austin 1:8aa5cdb4ab67 153
Jonathan Austin 1:8aa5cdb4ab67 154 /**
Jonathan Austin 1:8aa5cdb4ab67 155 * Retreives the current period in use by the entire PWM module in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 156 *
Jonathan Austin 1:8aa5cdb4ab67 157 * Example:
Jonathan Austin 1:8aa5cdb4ab67 158 * @code
Jonathan Austin 1:8aa5cdb4ab67 159 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 160 * pwm->getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 161 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 162 */
Jonathan Austin 1:8aa5cdb4ab67 163 int getPeriodUs();
Jonathan Austin 1:8aa5cdb4ab67 164
Jonathan Austin 1:8aa5cdb4ab67 165 /**
Jonathan Austin 1:8aa5cdb4ab67 166 * Retreives the current period in use by the entire PWM module in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 167 *
Jonathan Austin 1:8aa5cdb4ab67 168 * Example:
Jonathan Austin 1:8aa5cdb4ab67 169 * @code
Jonathan Austin 1:8aa5cdb4ab67 170 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 171 * pwm->setPeriodUs(20000);
Jonathan Austin 1:8aa5cdb4ab67 172 *
Jonathan Austin 1:8aa5cdb4ab67 173 * // will return 20000
Jonathan Austin 1:8aa5cdb4ab67 174 * pwm->getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 175 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 176 */
Jonathan Austin 1:8aa5cdb4ab67 177 int getPeriod();
Jonathan Austin 1:8aa5cdb4ab67 178
Jonathan Austin 1:8aa5cdb4ab67 179 /**
Jonathan Austin 1:8aa5cdb4ab67 180 * Sets the period used by the WHOLE PWM module.
Jonathan Austin 1:8aa5cdb4ab67 181 *
Jonathan Austin 1:8aa5cdb4ab67 182 * @param period the desired period in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 183 *
Jonathan Austin 1:8aa5cdb4ab67 184 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
Jonathan Austin 1:8aa5cdb4ab67 185 *
Jonathan Austin 1:8aa5cdb4ab67 186 * Example:
Jonathan Austin 1:8aa5cdb4ab67 187 * @code
Jonathan Austin 1:8aa5cdb4ab67 188 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 189 *
Jonathan Austin 1:8aa5cdb4ab67 190 * // period now is 20ms
Jonathan Austin 1:8aa5cdb4ab67 191 * pwm->setPeriodUs(20000);
Jonathan Austin 1:8aa5cdb4ab67 192 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 193 *
Jonathan Austin 1:8aa5cdb4ab67 194 * @note Any changes to the period will AFFECT ALL CHANNELS.
Jonathan Austin 1:8aa5cdb4ab67 195 */
Jonathan Austin 1:8aa5cdb4ab67 196 int setPeriodUs(int period);
Jonathan Austin 1:8aa5cdb4ab67 197
Jonathan Austin 1:8aa5cdb4ab67 198 /**
Jonathan Austin 1:8aa5cdb4ab67 199 * Sets the period used by the WHOLE PWM module. Any changes to the period will AFFECT ALL CHANNELS.
Jonathan Austin 1:8aa5cdb4ab67 200 *
Jonathan Austin 1:8aa5cdb4ab67 201 * @param period the desired period in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 202 *
Jonathan Austin 1:8aa5cdb4ab67 203 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if period is out of range
Jonathan Austin 1:8aa5cdb4ab67 204 *
Jonathan Austin 1:8aa5cdb4ab67 205 * Example:
Jonathan Austin 1:8aa5cdb4ab67 206 * @code
Jonathan Austin 1:8aa5cdb4ab67 207 * DynamicPwm* pwm = DynamicPwm::allocate(PinName n);
Jonathan Austin 1:8aa5cdb4ab67 208 *
Jonathan Austin 1:8aa5cdb4ab67 209 * // period now is 20ms
Jonathan Austin 1:8aa5cdb4ab67 210 * pwm->setPeriod(20);
Jonathan Austin 1:8aa5cdb4ab67 211 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 212 */
Jonathan Austin 1:8aa5cdb4ab67 213 int setPeriod(int period);
Jonathan Austin 1:8aa5cdb4ab67 214 };
Jonathan Austin 1:8aa5cdb4ab67 215
Jonathan Austin 1:8aa5cdb4ab67 216 #endif