fixed drive strength

Dependents:   capstone_i2c

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Tue Nov 08 17:45:16 2016 +0000
Revision:
150:02e0a0aed4ec
Parent:
149:156823d33999
This updates the lib to the mbed lib v129

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2013 Nordic Semiconductor ASA
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * 1. Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * 2. Redistributions in binary form, except as embedded into a Nordic Semiconductor ASA
<> 144:ef7eb2e8f9f7 12 * integrated circuit in a product or a software update for such product, must reproduce
<> 144:ef7eb2e8f9f7 13 * the above copyright notice, this list of conditions and the following disclaimer in
<> 144:ef7eb2e8f9f7 14 * the documentation and/or other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 15 *
<> 144:ef7eb2e8f9f7 16 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its contributors may be
<> 144:ef7eb2e8f9f7 17 * used to endorse or promote products derived from this software without specific prior
<> 144:ef7eb2e8f9f7 18 * written permission.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * 4. This software, with or without modification, must only be used with a
<> 144:ef7eb2e8f9f7 21 * Nordic Semiconductor ASA integrated circuit.
<> 144:ef7eb2e8f9f7 22 *
<> 144:ef7eb2e8f9f7 23 * 5. Any software provided in binary or object form under this license must not be reverse
<> 144:ef7eb2e8f9f7 24 * engineered, decompiled, modified and/or disassembled.
<> 144:ef7eb2e8f9f7 25 *
<> 144:ef7eb2e8f9f7 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 30 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 33 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 36 *
<> 144:ef7eb2e8f9f7 37 */
<> 144:ef7eb2e8f9f7 38
<> 144:ef7eb2e8f9f7 39 #include "mbed_assert.h"
<> 144:ef7eb2e8f9f7 40 #include "mbed_error.h"
<> 144:ef7eb2e8f9f7 41 #include "pwmout_api.h"
<> 144:ef7eb2e8f9f7 42 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 43 #include "pinmap.h"
<> 144:ef7eb2e8f9f7 44
<> 144:ef7eb2e8f9f7 45 #if DEVICE_PWMOUT
<> 144:ef7eb2e8f9f7 46
<> 144:ef7eb2e8f9f7 47 #include "app_util_platform.h"
<> 144:ef7eb2e8f9f7 48 #include "nrf_drv_pwm.h"
<> 144:ef7eb2e8f9f7 49
<> 144:ef7eb2e8f9f7 50 #define MAX_PWM_COUNTERTOP (0x7FFF) // 0x7FFF is the max of COUNTERTOP value for the PWM peripherial of the nRF52.
<> 144:ef7eb2e8f9f7 51 #define MAX_PWM_PERIOD_US (MAX_PWM_COUNTERTOP * 8) // PWM hw is driven by 16 MHz clock, hence the tick is 1_us/16,
<> 144:ef7eb2e8f9f7 52 // and 128 is the max prescaler value.
<> 144:ef7eb2e8f9f7 53 #define MAX_PWM_PERIOD_MS ((MAX_PWM_PERIOD_US / 1000) + 1) // approximations advance
<> 144:ef7eb2e8f9f7 54 #define MAX_PWM_PERIOD_S ((MAX_PWM_PERIOD_US / 1000000) + 1) // approximations advance
<> 144:ef7eb2e8f9f7 55
<> 144:ef7eb2e8f9f7 56
<> 144:ef7eb2e8f9f7 57 #define PWM_INSTANCE_COUNT (PWM_COUNT) // import from the nrf_drv_config.h file
<> 144:ef7eb2e8f9f7 58
<> 144:ef7eb2e8f9f7 59 ///> instances of nRF52 PWM driver
<> 144:ef7eb2e8f9f7 60 static const nrf_drv_pwm_t m_pwm_driver[PWM_INSTANCE_COUNT] =
<> 144:ef7eb2e8f9f7 61 {
<> 144:ef7eb2e8f9f7 62 #if PWM0_ENABLED
<> 144:ef7eb2e8f9f7 63 NRF_DRV_PWM_INSTANCE(0),
<> 144:ef7eb2e8f9f7 64 #endif
<> 144:ef7eb2e8f9f7 65 #if PWM1_ENABLED
<> 144:ef7eb2e8f9f7 66 NRF_DRV_PWM_INSTANCE(1),
<> 144:ef7eb2e8f9f7 67 #endif
<> 144:ef7eb2e8f9f7 68 #if PWM2_ENABLED
<> 144:ef7eb2e8f9f7 69 NRF_DRV_PWM_INSTANCE(2)
<> 144:ef7eb2e8f9f7 70 #endif
<> 144:ef7eb2e8f9f7 71 };
<> 144:ef7eb2e8f9f7 72
<> 144:ef7eb2e8f9f7 73 typedef struct
<> 144:ef7eb2e8f9f7 74 {
<> 144:ef7eb2e8f9f7 75 uint32_t period_us;
<> 144:ef7eb2e8f9f7 76 uint32_t duty_us;
<> 144:ef7eb2e8f9f7 77 float duty;
<> 144:ef7eb2e8f9f7 78 } pwm_signal_t; /// PWM signal description type
<> 144:ef7eb2e8f9f7 79
<> 144:ef7eb2e8f9f7 80 typedef struct
<> 144:ef7eb2e8f9f7 81 {
<> 144:ef7eb2e8f9f7 82 nrf_drv_pwm_t * p_pwm_driver;
<> 144:ef7eb2e8f9f7 83 pwm_signal_t signal;
<> 144:ef7eb2e8f9f7 84 volatile nrf_pwm_values_common_t seq_values[1];
<> 144:ef7eb2e8f9f7 85 } pwm_t; /// internal PWM instance support type
<> 144:ef7eb2e8f9f7 86
<> 144:ef7eb2e8f9f7 87 static pwm_t m_pwm[PWM_INSTANCE_COUNT] =
<> 144:ef7eb2e8f9f7 88 {
<> 144:ef7eb2e8f9f7 89 #if PWM0_ENABLED
<> 144:ef7eb2e8f9f7 90 {.p_pwm_driver = NULL},
<> 144:ef7eb2e8f9f7 91 #endif
<> 144:ef7eb2e8f9f7 92 #if PWM1_ENABLED
<> 144:ef7eb2e8f9f7 93 {.p_pwm_driver = NULL},
<> 144:ef7eb2e8f9f7 94 #endif
<> 144:ef7eb2e8f9f7 95 #if PWM2_ENABLED
<> 144:ef7eb2e8f9f7 96 {.p_pwm_driver = NULL}
<> 144:ef7eb2e8f9f7 97 #endif
<> 144:ef7eb2e8f9f7 98 }; /// Array of internal PWM instances.
<> 144:ef7eb2e8f9f7 99
<> 144:ef7eb2e8f9f7 100 typedef struct
<> 144:ef7eb2e8f9f7 101 {
<> 144:ef7eb2e8f9f7 102 uint16_t period_hwu; // unit related to pwm_clk
<> 144:ef7eb2e8f9f7 103 uint16_t duty_hwu; // unit related to pwm_clk
<> 144:ef7eb2e8f9f7 104 nrf_pwm_clk_t pwm_clk;
<> 144:ef7eb2e8f9f7 105 } pulsewidth_set_t; /// helper type for timing calculations
<> 144:ef7eb2e8f9f7 106
<> 144:ef7eb2e8f9f7 107
<> 144:ef7eb2e8f9f7 108 static void internal_pwmout_exe(pwmout_t *obj, bool new_period, bool initialization);
<> 144:ef7eb2e8f9f7 109
<> 150:02e0a0aed4ec 110 // extern PWM nIRQ handler implementations
<> 150:02e0a0aed4ec 111 void PWM0_IRQHandler(void);
<> 150:02e0a0aed4ec 112 void PWM1_IRQHandler(void);
<> 150:02e0a0aed4ec 113 void PWM2_IRQHandler(void);
<> 150:02e0a0aed4ec 114
<> 150:02e0a0aed4ec 115 static const peripheral_handler_desc_t pwm_handlers[PWM_INSTANCE_COUNT] =
<> 150:02e0a0aed4ec 116 {
<> 150:02e0a0aed4ec 117 {
<> 150:02e0a0aed4ec 118 PWM0_IRQn,
<> 150:02e0a0aed4ec 119 (uint32_t)PWM0_IRQHandler
<> 150:02e0a0aed4ec 120 },
<> 150:02e0a0aed4ec 121 {
<> 150:02e0a0aed4ec 122 PWM1_IRQn,
<> 150:02e0a0aed4ec 123 (uint32_t)PWM1_IRQHandler
<> 150:02e0a0aed4ec 124 },
<> 150:02e0a0aed4ec 125 {
<> 150:02e0a0aed4ec 126 PWM2_IRQn,
<> 150:02e0a0aed4ec 127 (uint32_t)PWM2_IRQHandler
<> 150:02e0a0aed4ec 128 }
<> 150:02e0a0aed4ec 129 };
<> 150:02e0a0aed4ec 130
<> 144:ef7eb2e8f9f7 131 void pwmout_init(pwmout_t *obj, PinName pin)
<> 144:ef7eb2e8f9f7 132 {
<> 144:ef7eb2e8f9f7 133 uint32_t i;
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135 for (i = 0; PWM_INSTANCE_COUNT; i++)
<> 144:ef7eb2e8f9f7 136 {
<> 144:ef7eb2e8f9f7 137 if (m_pwm[i].p_pwm_driver == NULL) // a driver instance not assigned to the obj?
<> 144:ef7eb2e8f9f7 138 {
<> 150:02e0a0aed4ec 139 NVIC_SetVector(pwm_handlers[i].IRQn, pwm_handlers[i].vector);
<> 150:02e0a0aed4ec 140
<> 144:ef7eb2e8f9f7 141 obj->pin = pin;
<> 144:ef7eb2e8f9f7 142
<> 144:ef7eb2e8f9f7 143 obj->pwm_channel = i;
<> 144:ef7eb2e8f9f7 144
<> 144:ef7eb2e8f9f7 145 m_pwm[i].p_pwm_driver = (nrf_drv_pwm_t *) &m_pwm_driver[i];
<> 144:ef7eb2e8f9f7 146 m_pwm[i].signal.period_us = 200000; // 0.02 s
<> 144:ef7eb2e8f9f7 147 m_pwm[i].signal.duty_us = 100000;
<> 144:ef7eb2e8f9f7 148 m_pwm[i].signal.duty = 0.5f;
<> 144:ef7eb2e8f9f7 149
<> 144:ef7eb2e8f9f7 150 obj->pwm_struct = &m_pwm[i];
<> 144:ef7eb2e8f9f7 151
<> 144:ef7eb2e8f9f7 152 internal_pwmout_exe(obj, true, true);
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 break;
<> 144:ef7eb2e8f9f7 155 }
<> 144:ef7eb2e8f9f7 156 }
<> 144:ef7eb2e8f9f7 157
<> 144:ef7eb2e8f9f7 158 MBED_ASSERT(i != PWM_INSTANCE_COUNT); // assert if free instance was not found.
<> 144:ef7eb2e8f9f7 159 }
<> 144:ef7eb2e8f9f7 160
<> 144:ef7eb2e8f9f7 161 void pwmout_free(pwmout_t *obj)
<> 144:ef7eb2e8f9f7 162 {
<> 144:ef7eb2e8f9f7 163 nrf_drv_pwm_uninit( (nrf_drv_pwm_t*) obj->pwm_struct );
<> 144:ef7eb2e8f9f7 164
<> 144:ef7eb2e8f9f7 165 m_pwm[obj->pwm_channel].p_pwm_driver = NULL;
<> 144:ef7eb2e8f9f7 166 }
<> 144:ef7eb2e8f9f7 167
<> 144:ef7eb2e8f9f7 168 void pwmout_write(pwmout_t *obj, float percent)
<> 144:ef7eb2e8f9f7 169 {
<> 144:ef7eb2e8f9f7 170
<> 144:ef7eb2e8f9f7 171 if (percent < 0)
<> 144:ef7eb2e8f9f7 172 {
<> 144:ef7eb2e8f9f7 173 percent = 0;
<> 144:ef7eb2e8f9f7 174 }
<> 144:ef7eb2e8f9f7 175 else if (percent > 1)
<> 144:ef7eb2e8f9f7 176 {
<> 144:ef7eb2e8f9f7 177 percent = 1;
<> 144:ef7eb2e8f9f7 178 }
<> 144:ef7eb2e8f9f7 179
<> 144:ef7eb2e8f9f7 180 pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
<> 144:ef7eb2e8f9f7 181
<> 144:ef7eb2e8f9f7 182 p_pwm_signal->duty = percent;
<> 144:ef7eb2e8f9f7 183
<> 144:ef7eb2e8f9f7 184 int us = (((int)p_pwm_signal->period_us) * percent);
<> 144:ef7eb2e8f9f7 185
<> 144:ef7eb2e8f9f7 186 pwmout_pulsewidth_us(obj, us);
<> 144:ef7eb2e8f9f7 187 }
<> 144:ef7eb2e8f9f7 188
<> 144:ef7eb2e8f9f7 189 float pwmout_read(pwmout_t *obj)
<> 144:ef7eb2e8f9f7 190 {
<> 144:ef7eb2e8f9f7 191 pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
<> 144:ef7eb2e8f9f7 192
<> 144:ef7eb2e8f9f7 193 return (float)p_pwm_signal->duty_us / (float)p_pwm_signal->period_us;
<> 144:ef7eb2e8f9f7 194 }
<> 144:ef7eb2e8f9f7 195
<> 144:ef7eb2e8f9f7 196 void pwmout_period(pwmout_t *obj, float seconds)
<> 144:ef7eb2e8f9f7 197 {
<> 144:ef7eb2e8f9f7 198 // raught saturation < 0, quasi-max>
<> 144:ef7eb2e8f9f7 199 if (seconds > MAX_PWM_PERIOD_S)
<> 144:ef7eb2e8f9f7 200 {
<> 144:ef7eb2e8f9f7 201 seconds = MAX_PWM_PERIOD_S;
<> 144:ef7eb2e8f9f7 202 }
<> 144:ef7eb2e8f9f7 203 else if (seconds < 0)
<> 144:ef7eb2e8f9f7 204 {
<> 144:ef7eb2e8f9f7 205 seconds = 0; // f. pwmout_period_us will set period to min. value
<> 144:ef7eb2e8f9f7 206 }
<> 144:ef7eb2e8f9f7 207
<> 144:ef7eb2e8f9f7 208 int us = seconds * 1000000;
<> 144:ef7eb2e8f9f7 209
<> 144:ef7eb2e8f9f7 210 pwmout_period_us(obj, us);
<> 144:ef7eb2e8f9f7 211 }
<> 144:ef7eb2e8f9f7 212
<> 144:ef7eb2e8f9f7 213 void pwmout_period_ms(pwmout_t *obj, int ms)
<> 144:ef7eb2e8f9f7 214 {
<> 144:ef7eb2e8f9f7 215 // reught saturation < 0, quasi-max>
<> 144:ef7eb2e8f9f7 216 if (ms > MAX_PWM_PERIOD_MS)
<> 144:ef7eb2e8f9f7 217 {
<> 144:ef7eb2e8f9f7 218 ms = MAX_PWM_PERIOD_MS;
<> 144:ef7eb2e8f9f7 219 }
<> 144:ef7eb2e8f9f7 220 else if (ms < 0)
<> 144:ef7eb2e8f9f7 221 {
<> 144:ef7eb2e8f9f7 222 ms = 0; // f. pwmout_period_us will set period to min. value
<> 144:ef7eb2e8f9f7 223 }
<> 144:ef7eb2e8f9f7 224
<> 144:ef7eb2e8f9f7 225 int us = ms * 1000;
<> 144:ef7eb2e8f9f7 226
<> 144:ef7eb2e8f9f7 227 pwmout_period_us(obj, us);
<> 144:ef7eb2e8f9f7 228 }
<> 144:ef7eb2e8f9f7 229
<> 144:ef7eb2e8f9f7 230
<> 144:ef7eb2e8f9f7 231 void pwmout_period_us(pwmout_t *obj, int us)
<> 144:ef7eb2e8f9f7 232 {
<> 144:ef7eb2e8f9f7 233 pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
<> 144:ef7eb2e8f9f7 234
<> 144:ef7eb2e8f9f7 235 // saturation <1, real-max>
<> 144:ef7eb2e8f9f7 236 if (us > MAX_PWM_PERIOD_US)
<> 144:ef7eb2e8f9f7 237 {
<> 144:ef7eb2e8f9f7 238 us = MAX_PWM_PERIOD_US;
<> 144:ef7eb2e8f9f7 239 }
<> 144:ef7eb2e8f9f7 240 else if (us < 1)
<> 144:ef7eb2e8f9f7 241 {
<> 144:ef7eb2e8f9f7 242 us = 1;
<> 144:ef7eb2e8f9f7 243 }
<> 144:ef7eb2e8f9f7 244
<> 144:ef7eb2e8f9f7 245 p_pwm_signal->duty_us = (int)((float)us * p_pwm_signal->duty);
<> 144:ef7eb2e8f9f7 246
<> 144:ef7eb2e8f9f7 247 p_pwm_signal->period_us = us;
<> 144:ef7eb2e8f9f7 248
<> 144:ef7eb2e8f9f7 249 internal_pwmout_exe(obj, true, false);
<> 144:ef7eb2e8f9f7 250 }
<> 144:ef7eb2e8f9f7 251
<> 144:ef7eb2e8f9f7 252 void pwmout_pulsewidth(pwmout_t *obj, float seconds)
<> 144:ef7eb2e8f9f7 253 {
<> 144:ef7eb2e8f9f7 254 // raught saturation < 0, quasi-max>
<> 144:ef7eb2e8f9f7 255 if (seconds > MAX_PWM_PERIOD_S)
<> 144:ef7eb2e8f9f7 256 {
<> 144:ef7eb2e8f9f7 257 seconds = MAX_PWM_PERIOD_S;
<> 144:ef7eb2e8f9f7 258 }
<> 144:ef7eb2e8f9f7 259 else if (seconds < 0)
<> 144:ef7eb2e8f9f7 260 {
<> 144:ef7eb2e8f9f7 261 seconds = 0;
<> 144:ef7eb2e8f9f7 262 }
<> 144:ef7eb2e8f9f7 263
<> 144:ef7eb2e8f9f7 264 int us = seconds * 1000000;
<> 144:ef7eb2e8f9f7 265
<> 144:ef7eb2e8f9f7 266 pwmout_pulsewidth_us(obj,us);
<> 144:ef7eb2e8f9f7 267 }
<> 144:ef7eb2e8f9f7 268
<> 144:ef7eb2e8f9f7 269 void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
<> 144:ef7eb2e8f9f7 270 {
<> 144:ef7eb2e8f9f7 271 // raught saturation < 0, quasi-max>
<> 144:ef7eb2e8f9f7 272 if (ms > MAX_PWM_PERIOD_MS)
<> 144:ef7eb2e8f9f7 273 {
<> 144:ef7eb2e8f9f7 274 ms = MAX_PWM_PERIOD_MS;
<> 144:ef7eb2e8f9f7 275 }
<> 144:ef7eb2e8f9f7 276 else if (ms < 0)
<> 144:ef7eb2e8f9f7 277 {
<> 144:ef7eb2e8f9f7 278 ms = 0;
<> 144:ef7eb2e8f9f7 279 }
<> 144:ef7eb2e8f9f7 280
<> 144:ef7eb2e8f9f7 281 int us = ms * 1000;
<> 144:ef7eb2e8f9f7 282
<> 144:ef7eb2e8f9f7 283 pwmout_pulsewidth_us(obj, us);
<> 144:ef7eb2e8f9f7 284 }
<> 144:ef7eb2e8f9f7 285
<> 144:ef7eb2e8f9f7 286 void pwmout_pulsewidth_us(pwmout_t *obj, int us)
<> 144:ef7eb2e8f9f7 287 {
<> 144:ef7eb2e8f9f7 288 // saturation <0, real-max>
<> 144:ef7eb2e8f9f7 289 if (us > MAX_PWM_PERIOD_US)
<> 144:ef7eb2e8f9f7 290 {
<> 144:ef7eb2e8f9f7 291 us = MAX_PWM_PERIOD_US;
<> 144:ef7eb2e8f9f7 292 }
<> 144:ef7eb2e8f9f7 293 else if (us < 0)
<> 144:ef7eb2e8f9f7 294 {
<> 144:ef7eb2e8f9f7 295 us = 0;
<> 144:ef7eb2e8f9f7 296 }
<> 144:ef7eb2e8f9f7 297
<> 144:ef7eb2e8f9f7 298 pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
<> 144:ef7eb2e8f9f7 299
<> 144:ef7eb2e8f9f7 300 p_pwm_signal->duty_us = us;
<> 144:ef7eb2e8f9f7 301 p_pwm_signal->duty = us / p_pwm_signal->period_us;
<> 144:ef7eb2e8f9f7 302
<> 144:ef7eb2e8f9f7 303 internal_pwmout_exe(obj, false, false);
<> 144:ef7eb2e8f9f7 304 }
<> 144:ef7eb2e8f9f7 305
<> 144:ef7eb2e8f9f7 306
<> 144:ef7eb2e8f9f7 307
<> 144:ef7eb2e8f9f7 308
<> 144:ef7eb2e8f9f7 309
<> 144:ef7eb2e8f9f7 310
<> 144:ef7eb2e8f9f7 311 static ret_code_t pulsewidth_us_set_get(int period_hwu, int duty_hwu, pulsewidth_set_t * p_settings)
<> 144:ef7eb2e8f9f7 312 {
<> 144:ef7eb2e8f9f7 313 uint16_t div;
<> 144:ef7eb2e8f9f7 314 nrf_pwm_clk_t pwm_clk = NRF_PWM_CLK_16MHz;
<> 144:ef7eb2e8f9f7 315
<> 144:ef7eb2e8f9f7 316 for(div = 1; div <= 128 ; div <<= 1) // 128 is the maximum of clock prescaler for PWM peripherial
<> 144:ef7eb2e8f9f7 317 {
<> 144:ef7eb2e8f9f7 318 if (MAX_PWM_COUNTERTOP >= period_hwu)
<> 144:ef7eb2e8f9f7 319 {
<> 144:ef7eb2e8f9f7 320 p_settings->period_hwu = period_hwu; // unit [us/16 * div]
<> 144:ef7eb2e8f9f7 321 p_settings->duty_hwu = duty_hwu; // unit [us/16 * div]
<> 144:ef7eb2e8f9f7 322 p_settings->pwm_clk = pwm_clk;
<> 144:ef7eb2e8f9f7 323
<> 144:ef7eb2e8f9f7 324 return NRF_SUCCESS;
<> 144:ef7eb2e8f9f7 325 }
<> 144:ef7eb2e8f9f7 326
<> 144:ef7eb2e8f9f7 327 period_hwu >>= 1;
<> 144:ef7eb2e8f9f7 328 duty_hwu >>= 1;
<> 144:ef7eb2e8f9f7 329 pwm_clk++;
<> 144:ef7eb2e8f9f7 330 }
<> 144:ef7eb2e8f9f7 331
<> 144:ef7eb2e8f9f7 332 return NRF_ERROR_INVALID_PARAM;
<> 144:ef7eb2e8f9f7 333 }
<> 144:ef7eb2e8f9f7 334
<> 144:ef7eb2e8f9f7 335
<> 144:ef7eb2e8f9f7 336 static void internal_pwmout_exe(pwmout_t *obj, bool new_period, bool initialization)
<> 144:ef7eb2e8f9f7 337 {
<> 144:ef7eb2e8f9f7 338 pulsewidth_set_t pulsewidth_set;
<> 144:ef7eb2e8f9f7 339 pwm_signal_t * p_pwm_signal;
<> 144:ef7eb2e8f9f7 340 nrf_drv_pwm_t * p_pwm_driver;
<> 144:ef7eb2e8f9f7 341 ret_code_t ret_code;
<> 144:ef7eb2e8f9f7 342
<> 144:ef7eb2e8f9f7 343 p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal);
<> 144:ef7eb2e8f9f7 344
<> 144:ef7eb2e8f9f7 345 if (NRF_SUCCESS == pulsewidth_us_set_get(p_pwm_signal->period_us * 16, // base clk for PWM is 16 MHz
<> 144:ef7eb2e8f9f7 346 p_pwm_signal->duty_us * 16, // base clk for PWM is 16 MHz
<> 144:ef7eb2e8f9f7 347 &pulsewidth_set))
<> 144:ef7eb2e8f9f7 348 {
<> 144:ef7eb2e8f9f7 349 p_pwm_driver = (((pwm_t*)obj->pwm_struct)->p_pwm_driver);
<> 144:ef7eb2e8f9f7 350
<> 144:ef7eb2e8f9f7 351 const nrf_pwm_sequence_t seq =
<> 144:ef7eb2e8f9f7 352 {
<> 144:ef7eb2e8f9f7 353 .values.p_common = (nrf_pwm_values_common_t*) (((pwm_t*)obj->pwm_struct)->seq_values),
<> 144:ef7eb2e8f9f7 354 .length = 1,
<> 144:ef7eb2e8f9f7 355 .repeats = 0,
<> 144:ef7eb2e8f9f7 356 .end_delay = 0
<> 144:ef7eb2e8f9f7 357 };
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359 (((pwm_t*)obj->pwm_struct)->seq_values)[0] = pulsewidth_set.duty_hwu | 0x8000;
<> 144:ef7eb2e8f9f7 360
<> 144:ef7eb2e8f9f7 361 if (new_period)
<> 144:ef7eb2e8f9f7 362 {
<> 144:ef7eb2e8f9f7 363 nrf_drv_pwm_config_t config0 =
<> 144:ef7eb2e8f9f7 364 {
<> 144:ef7eb2e8f9f7 365 .output_pins =
<> 144:ef7eb2e8f9f7 366 {
<> 144:ef7eb2e8f9f7 367 obj->pin | NRF_DRV_PWM_PIN_INVERTED, // channel 0
<> 144:ef7eb2e8f9f7 368 NRF_DRV_PWM_PIN_NOT_USED, // channel 1
<> 144:ef7eb2e8f9f7 369 NRF_DRV_PWM_PIN_NOT_USED, // channel 2
<> 144:ef7eb2e8f9f7 370 NRF_DRV_PWM_PIN_NOT_USED, // channel 3
<> 144:ef7eb2e8f9f7 371 },
<> 150:02e0a0aed4ec 372 .irq_priority = PWM0_CONFIG_IRQ_PRIORITY,
<> 144:ef7eb2e8f9f7 373 .base_clock = pulsewidth_set.pwm_clk,
<> 144:ef7eb2e8f9f7 374 .count_mode = NRF_PWM_MODE_UP,
<> 144:ef7eb2e8f9f7 375 .top_value = pulsewidth_set.period_hwu,
<> 144:ef7eb2e8f9f7 376 .load_mode = NRF_PWM_LOAD_COMMON,
<> 144:ef7eb2e8f9f7 377 .step_mode = NRF_PWM_STEP_AUTO
<> 144:ef7eb2e8f9f7 378 };
<> 144:ef7eb2e8f9f7 379
<> 144:ef7eb2e8f9f7 380 if (!initialization)
<> 144:ef7eb2e8f9f7 381 {
<> 144:ef7eb2e8f9f7 382 nrf_drv_pwm_uninit(p_pwm_driver);
<> 144:ef7eb2e8f9f7 383 }
<> 144:ef7eb2e8f9f7 384
<> 144:ef7eb2e8f9f7 385 ret_code = nrf_drv_pwm_init( p_pwm_driver, &config0, NULL);
<> 144:ef7eb2e8f9f7 386
<> 144:ef7eb2e8f9f7 387 MBED_ASSERT(ret_code == NRF_SUCCESS); // assert if free instance was not found.
<> 144:ef7eb2e8f9f7 388 }
<> 144:ef7eb2e8f9f7 389
<> 144:ef7eb2e8f9f7 390 nrf_drv_pwm_simple_playback(p_pwm_driver, &seq, 0, NRF_DRV_PWM_FLAG_LOOP);
<> 144:ef7eb2e8f9f7 391 }
<> 144:ef7eb2e8f9f7 392 else
<> 144:ef7eb2e8f9f7 393 {
<> 144:ef7eb2e8f9f7 394 MBED_ASSERT(0); // force assertion
<> 144:ef7eb2e8f9f7 395 }
<> 144:ef7eb2e8f9f7 396
<> 144:ef7eb2e8f9f7 397 }
<> 144:ef7eb2e8f9f7 398
<> 144:ef7eb2e8f9f7 399 #endif // DEVICE_PWMOUT