mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Mon Nov 10 07:45:06 2014 +0000
Revision:
395:bfce16e86ea4
Parent:
340:28d1f895c6fe
Synchronized with git revision 8adfd82aa1bf8859ec08537ee7bcd4aaaec1769b

Full URL: https://github.com/mbedmicro/mbed/commit/8adfd82aa1bf8859ec08537ee7bcd4aaaec1769b/

Targets: LPC176X - Add repeater pinmode

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 85:e1a8e879a6a9 1 /* mbed Microcontroller Library
mbed_official 104:a6a92e2e5a92 2 * Copyright (c) 2013 Nordic Semiconductor
mbed_official 85:e1a8e879a6a9 3 *
mbed_official 85:e1a8e879a6a9 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 85:e1a8e879a6a9 5 * you may not use this file except in compliance with the License.
mbed_official 85:e1a8e879a6a9 6 * You may obtain a copy of the License at
mbed_official 85:e1a8e879a6a9 7 *
mbed_official 85:e1a8e879a6a9 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 85:e1a8e879a6a9 9 *
mbed_official 85:e1a8e879a6a9 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 85:e1a8e879a6a9 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 85:e1a8e879a6a9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 85:e1a8e879a6a9 13 * See the License for the specific language governing permissions and
mbed_official 85:e1a8e879a6a9 14 * limitations under the License.
mbed_official 85:e1a8e879a6a9 15 */
mbed_official 227:7bd0639b8911 16 #include "mbed_assert.h"
mbed_official 85:e1a8e879a6a9 17 #include "pwmout_api.h"
mbed_official 85:e1a8e879a6a9 18 #include "cmsis.h"
mbed_official 85:e1a8e879a6a9 19 #include "pinmap.h"
mbed_official 285:31249416b6f9 20 #include "mbed_error.h"
mbed_official 85:e1a8e879a6a9 21
mbed_official 229:9bd26d142f33 22 #define NO_PWMS 3
mbed_official 300:55638feb26a4 23 #define TIMER_PRECISION 4 //4us ticks
mbed_official 229:9bd26d142f33 24 #define TIMER_PRESCALER 6 //4us ticks = 16Mhz/(2**6)
mbed_official 85:e1a8e879a6a9 25 static const PinMap PinMap_PWM[] = {
mbed_official 85:e1a8e879a6a9 26 {p0, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 27 {p1, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 28 {p2, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 29 {p3, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 30 {p4, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 31 {p5, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 32 {p6, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 33 {p7, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 34 {p8, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 35 {p9, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 36 {p10, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 37 {p11, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 38 {p12, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 39 {p13, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 40 {p14, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 41 {p15, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 42 {p16, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 43 {p17, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 44 {p18, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 45 {p19, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 46 {p20, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 47 {p21, PWM_1, 1},
mbed_official 227:7bd0639b8911 48 {p22, PWM_1, 1},
mbed_official 227:7bd0639b8911 49 {p23, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 50 {p24, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 51 {p25, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 52 {p28, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 53 {p29, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 54 {p30, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 55 {NC, NC, 0}
mbed_official 85:e1a8e879a6a9 56 };
mbed_official 85:e1a8e879a6a9 57
mbed_official 85:e1a8e879a6a9 58 static NRF_TIMER_Type *Timers[1] = {
mbed_official 227:7bd0639b8911 59 NRF_TIMER2
mbed_official 85:e1a8e879a6a9 60 };
mbed_official 85:e1a8e879a6a9 61
mbed_official 300:55638feb26a4 62 uint16_t PERIOD = 20000 / TIMER_PRECISION; //20ms
mbed_official 300:55638feb26a4 63 uint8_t PWM_taken[NO_PWMS] = {0, 0, 0};
mbed_official 300:55638feb26a4 64 uint16_t PULSE_WIDTH[NO_PWMS] = {1, 1, 1}; //set to 1 instead of 0
mbed_official 300:55638feb26a4 65 uint16_t ACTUAL_PULSE[NO_PWMS] = {0, 0, 0};
mbed_official 85:e1a8e879a6a9 66
mbed_official 85:e1a8e879a6a9 67
mbed_official 85:e1a8e879a6a9 68 /** @brief Function for handling timer 2 peripheral interrupts.
mbed_official 85:e1a8e879a6a9 69 */
mbed_official 300:55638feb26a4 70 #ifdef __cplusplus
mbed_official 85:e1a8e879a6a9 71 extern "C" {
mbed_official 300:55638feb26a4 72 #endif
mbed_official 85:e1a8e879a6a9 73 void TIMER2_IRQHandler(void)
mbed_official 85:e1a8e879a6a9 74 {
mbed_official 229:9bd26d142f33 75 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 300:55638feb26a4 76 NRF_TIMER2->CC[3] = PERIOD;
mbed_official 300:55638feb26a4 77
mbed_official 300:55638feb26a4 78 if (PWM_taken[0]) {
mbed_official 300:55638feb26a4 79 NRF_TIMER2->CC[0] = PULSE_WIDTH[0];
mbed_official 229:9bd26d142f33 80 }
mbed_official 300:55638feb26a4 81 if (PWM_taken[1]) {
mbed_official 300:55638feb26a4 82 NRF_TIMER2->CC[1] = PULSE_WIDTH[1];
mbed_official 229:9bd26d142f33 83 }
mbed_official 300:55638feb26a4 84 if (PWM_taken[2]) {
mbed_official 300:55638feb26a4 85 NRF_TIMER2->CC[2] = PULSE_WIDTH[2];
mbed_official 229:9bd26d142f33 86 }
mbed_official 300:55638feb26a4 87
mbed_official 229:9bd26d142f33 88 NRF_TIMER2->TASKS_START = 1;
mbed_official 300:55638feb26a4 89 }
mbed_official 85:e1a8e879a6a9 90
mbed_official 85:e1a8e879a6a9 91 #ifdef __cplusplus
mbed_official 85:e1a8e879a6a9 92 }
mbed_official 300:55638feb26a4 93 #endif
mbed_official 85:e1a8e879a6a9 94 /** @brief Function for initializing the Timer peripherals.
mbed_official 85:e1a8e879a6a9 95 */
mbed_official 85:e1a8e879a6a9 96 void timer_init(uint8_t pwmChoice)
mbed_official 85:e1a8e879a6a9 97 {
mbed_official 229:9bd26d142f33 98 NRF_TIMER_Type *timer = Timers[0];
mbed_official 229:9bd26d142f33 99 timer->TASKS_STOP = 0;
mbed_official 300:55638feb26a4 100
mbed_official 300:55638feb26a4 101 if (pwmChoice == 0) {
mbed_official 85:e1a8e879a6a9 102 timer->POWER = 0;
mbed_official 300:55638feb26a4 103 timer->POWER = 1;
mbed_official 300:55638feb26a4 104 timer->MODE = TIMER_MODE_MODE_Timer;
mbed_official 85:e1a8e879a6a9 105 timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
mbed_official 300:55638feb26a4 106 timer->PRESCALER = TIMER_PRESCALER;
mbed_official 229:9bd26d142f33 107 timer->CC[3] = PERIOD;
mbed_official 85:e1a8e879a6a9 108 }
mbed_official 300:55638feb26a4 109
mbed_official 229:9bd26d142f33 110 timer->CC[pwmChoice] = PULSE_WIDTH[pwmChoice];
mbed_official 300:55638feb26a4 111
mbed_official 85:e1a8e879a6a9 112 //high priority application interrupt
mbed_official 85:e1a8e879a6a9 113 NVIC_SetPriority(TIMER2_IRQn, 1);
mbed_official 85:e1a8e879a6a9 114 NVIC_EnableIRQ(TIMER2_IRQn);
mbed_official 300:55638feb26a4 115
mbed_official 85:e1a8e879a6a9 116 timer->TASKS_START = 0x01;
mbed_official 85:e1a8e879a6a9 117 }
mbed_official 300:55638feb26a4 118
mbed_official 85:e1a8e879a6a9 119 /** @brief Function for initializing the GPIO Tasks/Events peripheral.
mbed_official 85:e1a8e879a6a9 120 */
mbed_official 300:55638feb26a4 121 void gpiote_init(PinName pin, uint8_t channel_number)
mbed_official 85:e1a8e879a6a9 122 {
mbed_official 85:e1a8e879a6a9 123 // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
mbed_official 85:e1a8e879a6a9 124 NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
mbed_official 85:e1a8e879a6a9 125 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
mbed_official 85:e1a8e879a6a9 126 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
mbed_official 85:e1a8e879a6a9 127 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
mbed_official 85:e1a8e879a6a9 128 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
mbed_official 85:e1a8e879a6a9 129 NRF_GPIO->OUTCLR = (1UL << pin);
mbed_official 85:e1a8e879a6a9 130 // Configure GPIOTE channel 0 to toggle the PWM pin state
mbed_official 85:e1a8e879a6a9 131 // @note Only one GPIOTE task can be connected to an output pin.
mbed_official 85:e1a8e879a6a9 132 /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
mbed_official 300:55638feb26a4 133 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 300:55638feb26a4 134 (31UL << GPIOTE_CONFIG_PSEL_Pos) |
mbed_official 85:e1a8e879a6a9 135 (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 300:55638feb26a4 136 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
mbed_official 300:55638feb26a4 137 __NOP();
mbed_official 85:e1a8e879a6a9 138 __NOP();
mbed_official 85:e1a8e879a6a9 139 __NOP();
mbed_official 85:e1a8e879a6a9 140 /* Launch the task to take the GPIOTE channel output to the desired level */
mbed_official 85:e1a8e879a6a9 141 NRF_GPIOTE->TASKS_OUT[channel_number] = 1;
mbed_official 300:55638feb26a4 142
mbed_official 300:55638feb26a4 143 /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
mbed_official 85:e1a8e879a6a9 144 If it does not, the channel output inheritance sets the proper level. */
mbed_official 300:55638feb26a4 145 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 300:55638feb26a4 146 ((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
mbed_official 300:55638feb26a4 147 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
mbed_official 300:55638feb26a4 148 ((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos); // ((uint32_t)GPIOTE_CONFIG_OUTINIT_High <<
mbed_official 300:55638feb26a4 149 // GPIOTE_CONFIG_OUTINIT_Pos);//
mbed_official 85:e1a8e879a6a9 150
mbed_official 85:e1a8e879a6a9 151 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
mbed_official 85:e1a8e879a6a9 152 __NOP();
mbed_official 85:e1a8e879a6a9 153 __NOP();
mbed_official 300:55638feb26a4 154 __NOP();
mbed_official 85:e1a8e879a6a9 155 }
mbed_official 300:55638feb26a4 156
mbed_official 85:e1a8e879a6a9 157 /** @brief Function for initializing the Programmable Peripheral Interconnect peripheral.
mbed_official 85:e1a8e879a6a9 158 */
mbed_official 85:e1a8e879a6a9 159 static void ppi_init(uint8_t pwm)
mbed_official 85:e1a8e879a6a9 160 {
mbed_official 300:55638feb26a4 161 //using ppi channels 0-7 (only 0-7 are available)
mbed_official 300:55638feb26a4 162 uint8_t channel_number = 2 * pwm;
mbed_official 300:55638feb26a4 163 NRF_TIMER_Type *timer = Timers[0];
mbed_official 300:55638feb26a4 164
mbed_official 85:e1a8e879a6a9 165 // Configure PPI channel 0 to toggle ADVERTISING_LED_PIN_NO on every TIMER1 COMPARE[0] match
mbed_official 85:e1a8e879a6a9 166 NRF_PPI->CH[channel_number].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
mbed_official 300:55638feb26a4 167 NRF_PPI->CH[channel_number + 1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
mbed_official 300:55638feb26a4 168 NRF_PPI->CH[channel_number].EEP = (uint32_t)&timer->EVENTS_COMPARE[pwm];
mbed_official 300:55638feb26a4 169 NRF_PPI->CH[channel_number + 1].EEP = (uint32_t)&timer->EVENTS_COMPARE[3];
mbed_official 300:55638feb26a4 170
mbed_official 85:e1a8e879a6a9 171 // Enable PPI channels.
mbed_official 300:55638feb26a4 172 NRF_PPI->CHEN |= (1 << channel_number) |
mbed_official 300:55638feb26a4 173 (1 << (channel_number + 1));
mbed_official 85:e1a8e879a6a9 174 }
mbed_official 85:e1a8e879a6a9 175
mbed_official 300:55638feb26a4 176 void setModulation(pwmout_t *obj, uint8_t toggle, uint8_t high)
mbed_official 85:e1a8e879a6a9 177 {
mbed_official 300:55638feb26a4 178 if (high) {
mbed_official 85:e1a8e879a6a9 179 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 300:55638feb26a4 180 if (toggle) {
mbed_official 300:55638feb26a4 181 NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 300:55638feb26a4 182 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 300:55638feb26a4 183 } else {
mbed_official 300:55638feb26a4 184 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 300:55638feb26a4 185 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 186 }
mbed_official 300:55638feb26a4 187 } else {
mbed_official 85:e1a8e879a6a9 188 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 300:55638feb26a4 189
mbed_official 300:55638feb26a4 190 if (toggle) {
mbed_official 300:55638feb26a4 191 NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 300:55638feb26a4 192 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 300:55638feb26a4 193 } else {
mbed_official 300:55638feb26a4 194 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 300:55638feb26a4 195 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 196 }
mbed_official 85:e1a8e879a6a9 197 }
mbed_official 85:e1a8e879a6a9 198 }
mbed_official 300:55638feb26a4 199
mbed_official 300:55638feb26a4 200 void pwmout_init(pwmout_t *obj, PinName pin)
mbed_official 300:55638feb26a4 201 {
mbed_official 85:e1a8e879a6a9 202 // determine the channel
mbed_official 85:e1a8e879a6a9 203 uint8_t pwmOutSuccess = 0;
mbed_official 300:55638feb26a4 204 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
mbed_official 300:55638feb26a4 205
mbed_official 227:7bd0639b8911 206 MBED_ASSERT(pwm != (PWMName)NC);
mbed_official 300:55638feb26a4 207
mbed_official 300:55638feb26a4 208 if (PWM_taken[(uint8_t)pwm]) {
mbed_official 300:55638feb26a4 209 for (uint8_t i = 1; !pwmOutSuccess && (i<NO_PWMS); i++) {
mbed_official 300:55638feb26a4 210 if (!PWM_taken[i]) {
mbed_official 85:e1a8e879a6a9 211 pwm = (PWMName)i;
mbed_official 85:e1a8e879a6a9 212 PWM_taken[i] = 1;
mbed_official 85:e1a8e879a6a9 213 pwmOutSuccess = 1;
mbed_official 85:e1a8e879a6a9 214 }
mbed_official 85:e1a8e879a6a9 215 }
mbed_official 300:55638feb26a4 216 } else {
mbed_official 85:e1a8e879a6a9 217 pwmOutSuccess = 1;
mbed_official 85:e1a8e879a6a9 218 PWM_taken[(uint8_t)pwm] = 1;
mbed_official 85:e1a8e879a6a9 219 }
mbed_official 300:55638feb26a4 220
mbed_official 300:55638feb26a4 221 if (!pwmOutSuccess) {
mbed_official 85:e1a8e879a6a9 222 error("PwmOut pin mapping failed. All available PWM channels are in use.");
mbed_official 85:e1a8e879a6a9 223 }
mbed_official 300:55638feb26a4 224
mbed_official 85:e1a8e879a6a9 225 obj->pwm = pwm;
mbed_official 85:e1a8e879a6a9 226 obj->pin = pin;
mbed_official 300:55638feb26a4 227
mbed_official 300:55638feb26a4 228 gpiote_init(pin, (uint8_t)pwm);
mbed_official 85:e1a8e879a6a9 229 ppi_init((uint8_t)pwm);
mbed_official 300:55638feb26a4 230
mbed_official 300:55638feb26a4 231 if (pwm == 0) {
mbed_official 85:e1a8e879a6a9 232 NRF_POWER->TASKS_CONSTLAT = 1;
mbed_official 85:e1a8e879a6a9 233 }
mbed_official 300:55638feb26a4 234
mbed_official 85:e1a8e879a6a9 235 timer_init((uint8_t)pwm);
mbed_official 300:55638feb26a4 236
mbed_official 85:e1a8e879a6a9 237 //default to 20ms: standard for servos, and fine for e.g. brightness control
mbed_official 85:e1a8e879a6a9 238 pwmout_period_ms(obj, 20);
mbed_official 85:e1a8e879a6a9 239 pwmout_write (obj, 0);
mbed_official 85:e1a8e879a6a9 240 }
mbed_official 85:e1a8e879a6a9 241
mbed_official 300:55638feb26a4 242 void pwmout_free(pwmout_t *obj)
mbed_official 300:55638feb26a4 243 {
mbed_official 340:28d1f895c6fe 244 MBED_ASSERT(obj->pwm != (PWMName)NC);
mbed_official 340:28d1f895c6fe 245 PWM_taken[obj->pwm] = 0;
mbed_official 340:28d1f895c6fe 246 pwmout_write(obj, 0);
mbed_official 85:e1a8e879a6a9 247 }
mbed_official 85:e1a8e879a6a9 248
mbed_official 300:55638feb26a4 249 void pwmout_write(pwmout_t *obj, float value)
mbed_official 300:55638feb26a4 250 {
mbed_official 85:e1a8e879a6a9 251 uint16_t oldPulseWidth;
mbed_official 300:55638feb26a4 252
mbed_official 229:9bd26d142f33 253 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 300:55638feb26a4 254 NRF_TIMER2->TASKS_STOP = 1;
mbed_official 300:55638feb26a4 255
mbed_official 85:e1a8e879a6a9 256 if (value < 0.0f) {
mbed_official 85:e1a8e879a6a9 257 value = 0.0;
mbed_official 85:e1a8e879a6a9 258 } else if (value > 1.0f) {
mbed_official 85:e1a8e879a6a9 259 value = 1.0;
mbed_official 85:e1a8e879a6a9 260 }
mbed_official 300:55638feb26a4 261
mbed_official 300:55638feb26a4 262 oldPulseWidth = ACTUAL_PULSE[obj->pwm];
mbed_official 300:55638feb26a4 263 ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = value * PERIOD;
mbed_official 300:55638feb26a4 264
mbed_official 300:55638feb26a4 265 if (PULSE_WIDTH[obj->pwm] == 0) {
mbed_official 300:55638feb26a4 266 PULSE_WIDTH[obj->pwm] = 1;
mbed_official 300:55638feb26a4 267 setModulation(obj, 0, 0);
mbed_official 300:55638feb26a4 268 } else if (PULSE_WIDTH[obj->pwm] == PERIOD) {
mbed_official 300:55638feb26a4 269 PULSE_WIDTH[obj->pwm] = PERIOD - 1;
mbed_official 300:55638feb26a4 270 setModulation(obj, 0, 1);
mbed_official 300:55638feb26a4 271 } else if ((oldPulseWidth == 0) || (oldPulseWidth == PERIOD)) {
mbed_official 300:55638feb26a4 272 setModulation(obj, 1, oldPulseWidth == PERIOD);
mbed_official 85:e1a8e879a6a9 273 }
mbed_official 300:55638feb26a4 274
mbed_official 300:55638feb26a4 275 NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
mbed_official 300:55638feb26a4 276 NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
mbed_official 229:9bd26d142f33 277 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 278 }
mbed_official 85:e1a8e879a6a9 279
mbed_official 300:55638feb26a4 280 float pwmout_read(pwmout_t *obj)
mbed_official 300:55638feb26a4 281 {
mbed_official 300:55638feb26a4 282 return ((float)PULSE_WIDTH[obj->pwm] / (float)PERIOD);
mbed_official 85:e1a8e879a6a9 283 }
mbed_official 85:e1a8e879a6a9 284
mbed_official 300:55638feb26a4 285 void pwmout_period(pwmout_t *obj, float seconds)
mbed_official 300:55638feb26a4 286 {
mbed_official 85:e1a8e879a6a9 287 pwmout_period_us(obj, seconds * 1000000.0f);
mbed_official 85:e1a8e879a6a9 288 }
mbed_official 85:e1a8e879a6a9 289
mbed_official 300:55638feb26a4 290 void pwmout_period_ms(pwmout_t *obj, int ms)
mbed_official 300:55638feb26a4 291 {
mbed_official 85:e1a8e879a6a9 292 pwmout_period_us(obj, ms * 1000);
mbed_official 85:e1a8e879a6a9 293 }
mbed_official 85:e1a8e879a6a9 294
mbed_official 85:e1a8e879a6a9 295 // Set the PWM period, keeping the duty cycle the same.
mbed_official 300:55638feb26a4 296 void pwmout_period_us(pwmout_t *obj, int us)
mbed_official 300:55638feb26a4 297 {
mbed_official 300:55638feb26a4 298 uint32_t periodInTicks = us / TIMER_PRECISION;
mbed_official 300:55638feb26a4 299
mbed_official 229:9bd26d142f33 300 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 300:55638feb26a4 301 NRF_TIMER2->TASKS_STOP = 1;
mbed_official 300:55638feb26a4 302
mbed_official 300:55638feb26a4 303 if (periodInTicks>((1 << 16) - 1)) {
mbed_official 300:55638feb26a4 304 PERIOD = (1 << 16) - 1; //131ms
mbed_official 300:55638feb26a4 305 } else if (periodInTicks<5) {
mbed_official 300:55638feb26a4 306 PERIOD = 5;
mbed_official 300:55638feb26a4 307 } else {
mbed_official 300:55638feb26a4 308 PERIOD = periodInTicks;
mbed_official 85:e1a8e879a6a9 309 }
mbed_official 300:55638feb26a4 310 NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
mbed_official 300:55638feb26a4 311 NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
mbed_official 300:55638feb26a4 312 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 313 }
mbed_official 85:e1a8e879a6a9 314
mbed_official 300:55638feb26a4 315 void pwmout_pulsewidth(pwmout_t *obj, float seconds)
mbed_official 300:55638feb26a4 316 {
mbed_official 85:e1a8e879a6a9 317 pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
mbed_official 85:e1a8e879a6a9 318 }
mbed_official 85:e1a8e879a6a9 319
mbed_official 300:55638feb26a4 320 void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
mbed_official 300:55638feb26a4 321 {
mbed_official 85:e1a8e879a6a9 322 pwmout_pulsewidth_us(obj, ms * 1000);
mbed_official 85:e1a8e879a6a9 323 }
mbed_official 85:e1a8e879a6a9 324
mbed_official 300:55638feb26a4 325 void pwmout_pulsewidth_us(pwmout_t *obj, int us)
mbed_official 300:55638feb26a4 326 {
mbed_official 300:55638feb26a4 327 uint32_t pulseInTicks = us / TIMER_PRECISION;
mbed_official 85:e1a8e879a6a9 328 uint16_t oldPulseWidth = ACTUAL_PULSE[obj->pwm];
mbed_official 300:55638feb26a4 329
mbed_official 229:9bd26d142f33 330 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 300:55638feb26a4 331 NRF_TIMER2->TASKS_STOP = 1;
mbed_official 300:55638feb26a4 332
mbed_official 85:e1a8e879a6a9 333 ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = pulseInTicks;
mbed_official 300:55638feb26a4 334
mbed_official 300:55638feb26a4 335 if (PULSE_WIDTH[obj->pwm] == 0) {
mbed_official 85:e1a8e879a6a9 336 PULSE_WIDTH[obj->pwm] = 1;
mbed_official 300:55638feb26a4 337 setModulation(obj, 0, 0);
mbed_official 300:55638feb26a4 338 } else if (PULSE_WIDTH[obj->pwm] == PERIOD) {
mbed_official 300:55638feb26a4 339 PULSE_WIDTH[obj->pwm] = PERIOD - 1;
mbed_official 300:55638feb26a4 340 setModulation(obj, 0, 1);
mbed_official 300:55638feb26a4 341 } else if ((oldPulseWidth == 0) || (oldPulseWidth == PERIOD)) {
mbed_official 300:55638feb26a4 342 setModulation(obj, 1, oldPulseWidth == PERIOD);
mbed_official 85:e1a8e879a6a9 343 }
mbed_official 300:55638feb26a4 344 NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
mbed_official 300:55638feb26a4 345 NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
mbed_official 300:55638feb26a4 346 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 347 }