fixed drive strength
Fork of mbed-dev by
targets/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/pwmout_api.c@149:156823d33999, 2016-10-28 (annotated)
- Committer:
- <>
- Date:
- Fri Oct 28 11:17:30 2016 +0100
- Revision:
- 149:156823d33999
- Parent:
- targets/hal/TARGET_NORDIC/TARGET_NRF5/TARGET_MCU_NRF52832/pwmout_api.c@144:ef7eb2e8f9f7
- Child:
- 150:02e0a0aed4ec
This updates the lib to the mbed lib v128
NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.
Who changed what in which revision?
User | Revision | Line number | New 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 | |
<> | 144:ef7eb2e8f9f7 | 110 | void pwmout_init(pwmout_t *obj, PinName pin) |
<> | 144:ef7eb2e8f9f7 | 111 | { |
<> | 144:ef7eb2e8f9f7 | 112 | uint32_t i; |
<> | 144:ef7eb2e8f9f7 | 113 | |
<> | 144:ef7eb2e8f9f7 | 114 | for (i = 0; PWM_INSTANCE_COUNT; i++) |
<> | 144:ef7eb2e8f9f7 | 115 | { |
<> | 144:ef7eb2e8f9f7 | 116 | if (m_pwm[i].p_pwm_driver == NULL) // a driver instance not assigned to the obj? |
<> | 144:ef7eb2e8f9f7 | 117 | { |
<> | 144:ef7eb2e8f9f7 | 118 | obj->pin = pin; |
<> | 144:ef7eb2e8f9f7 | 119 | |
<> | 144:ef7eb2e8f9f7 | 120 | obj->pwm_channel = i; |
<> | 144:ef7eb2e8f9f7 | 121 | |
<> | 144:ef7eb2e8f9f7 | 122 | m_pwm[i].p_pwm_driver = (nrf_drv_pwm_t *) &m_pwm_driver[i]; |
<> | 144:ef7eb2e8f9f7 | 123 | m_pwm[i].signal.period_us = 200000; // 0.02 s |
<> | 144:ef7eb2e8f9f7 | 124 | m_pwm[i].signal.duty_us = 100000; |
<> | 144:ef7eb2e8f9f7 | 125 | m_pwm[i].signal.duty = 0.5f; |
<> | 144:ef7eb2e8f9f7 | 126 | |
<> | 144:ef7eb2e8f9f7 | 127 | obj->pwm_struct = &m_pwm[i]; |
<> | 144:ef7eb2e8f9f7 | 128 | |
<> | 144:ef7eb2e8f9f7 | 129 | internal_pwmout_exe(obj, true, true); |
<> | 144:ef7eb2e8f9f7 | 130 | |
<> | 144:ef7eb2e8f9f7 | 131 | break; |
<> | 144:ef7eb2e8f9f7 | 132 | } |
<> | 144:ef7eb2e8f9f7 | 133 | } |
<> | 144:ef7eb2e8f9f7 | 134 | |
<> | 144:ef7eb2e8f9f7 | 135 | MBED_ASSERT(i != PWM_INSTANCE_COUNT); // assert if free instance was not found. |
<> | 144:ef7eb2e8f9f7 | 136 | } |
<> | 144:ef7eb2e8f9f7 | 137 | |
<> | 144:ef7eb2e8f9f7 | 138 | void pwmout_free(pwmout_t *obj) |
<> | 144:ef7eb2e8f9f7 | 139 | { |
<> | 144:ef7eb2e8f9f7 | 140 | nrf_drv_pwm_uninit( (nrf_drv_pwm_t*) obj->pwm_struct ); |
<> | 144:ef7eb2e8f9f7 | 141 | |
<> | 144:ef7eb2e8f9f7 | 142 | m_pwm[obj->pwm_channel].p_pwm_driver = NULL; |
<> | 144:ef7eb2e8f9f7 | 143 | } |
<> | 144:ef7eb2e8f9f7 | 144 | |
<> | 144:ef7eb2e8f9f7 | 145 | void pwmout_write(pwmout_t *obj, float percent) |
<> | 144:ef7eb2e8f9f7 | 146 | { |
<> | 144:ef7eb2e8f9f7 | 147 | |
<> | 144:ef7eb2e8f9f7 | 148 | if (percent < 0) |
<> | 144:ef7eb2e8f9f7 | 149 | { |
<> | 144:ef7eb2e8f9f7 | 150 | percent = 0; |
<> | 144:ef7eb2e8f9f7 | 151 | } |
<> | 144:ef7eb2e8f9f7 | 152 | else if (percent > 1) |
<> | 144:ef7eb2e8f9f7 | 153 | { |
<> | 144:ef7eb2e8f9f7 | 154 | percent = 1; |
<> | 144:ef7eb2e8f9f7 | 155 | } |
<> | 144:ef7eb2e8f9f7 | 156 | |
<> | 144:ef7eb2e8f9f7 | 157 | pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal); |
<> | 144:ef7eb2e8f9f7 | 158 | |
<> | 144:ef7eb2e8f9f7 | 159 | p_pwm_signal->duty = percent; |
<> | 144:ef7eb2e8f9f7 | 160 | |
<> | 144:ef7eb2e8f9f7 | 161 | int us = (((int)p_pwm_signal->period_us) * percent); |
<> | 144:ef7eb2e8f9f7 | 162 | |
<> | 144:ef7eb2e8f9f7 | 163 | pwmout_pulsewidth_us(obj, us); |
<> | 144:ef7eb2e8f9f7 | 164 | } |
<> | 144:ef7eb2e8f9f7 | 165 | |
<> | 144:ef7eb2e8f9f7 | 166 | float pwmout_read(pwmout_t *obj) |
<> | 144:ef7eb2e8f9f7 | 167 | { |
<> | 144:ef7eb2e8f9f7 | 168 | pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal); |
<> | 144:ef7eb2e8f9f7 | 169 | |
<> | 144:ef7eb2e8f9f7 | 170 | return (float)p_pwm_signal->duty_us / (float)p_pwm_signal->period_us; |
<> | 144:ef7eb2e8f9f7 | 171 | } |
<> | 144:ef7eb2e8f9f7 | 172 | |
<> | 144:ef7eb2e8f9f7 | 173 | void pwmout_period(pwmout_t *obj, float seconds) |
<> | 144:ef7eb2e8f9f7 | 174 | { |
<> | 144:ef7eb2e8f9f7 | 175 | // raught saturation < 0, quasi-max> |
<> | 144:ef7eb2e8f9f7 | 176 | if (seconds > MAX_PWM_PERIOD_S) |
<> | 144:ef7eb2e8f9f7 | 177 | { |
<> | 144:ef7eb2e8f9f7 | 178 | seconds = MAX_PWM_PERIOD_S; |
<> | 144:ef7eb2e8f9f7 | 179 | } |
<> | 144:ef7eb2e8f9f7 | 180 | else if (seconds < 0) |
<> | 144:ef7eb2e8f9f7 | 181 | { |
<> | 144:ef7eb2e8f9f7 | 182 | seconds = 0; // f. pwmout_period_us will set period to min. value |
<> | 144:ef7eb2e8f9f7 | 183 | } |
<> | 144:ef7eb2e8f9f7 | 184 | |
<> | 144:ef7eb2e8f9f7 | 185 | int us = seconds * 1000000; |
<> | 144:ef7eb2e8f9f7 | 186 | |
<> | 144:ef7eb2e8f9f7 | 187 | pwmout_period_us(obj, us); |
<> | 144:ef7eb2e8f9f7 | 188 | } |
<> | 144:ef7eb2e8f9f7 | 189 | |
<> | 144:ef7eb2e8f9f7 | 190 | void pwmout_period_ms(pwmout_t *obj, int ms) |
<> | 144:ef7eb2e8f9f7 | 191 | { |
<> | 144:ef7eb2e8f9f7 | 192 | // reught saturation < 0, quasi-max> |
<> | 144:ef7eb2e8f9f7 | 193 | if (ms > MAX_PWM_PERIOD_MS) |
<> | 144:ef7eb2e8f9f7 | 194 | { |
<> | 144:ef7eb2e8f9f7 | 195 | ms = MAX_PWM_PERIOD_MS; |
<> | 144:ef7eb2e8f9f7 | 196 | } |
<> | 144:ef7eb2e8f9f7 | 197 | else if (ms < 0) |
<> | 144:ef7eb2e8f9f7 | 198 | { |
<> | 144:ef7eb2e8f9f7 | 199 | ms = 0; // f. pwmout_period_us will set period to min. value |
<> | 144:ef7eb2e8f9f7 | 200 | } |
<> | 144:ef7eb2e8f9f7 | 201 | |
<> | 144:ef7eb2e8f9f7 | 202 | int us = ms * 1000; |
<> | 144:ef7eb2e8f9f7 | 203 | |
<> | 144:ef7eb2e8f9f7 | 204 | pwmout_period_us(obj, us); |
<> | 144:ef7eb2e8f9f7 | 205 | } |
<> | 144:ef7eb2e8f9f7 | 206 | |
<> | 144:ef7eb2e8f9f7 | 207 | |
<> | 144:ef7eb2e8f9f7 | 208 | void pwmout_period_us(pwmout_t *obj, int us) |
<> | 144:ef7eb2e8f9f7 | 209 | { |
<> | 144:ef7eb2e8f9f7 | 210 | pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal); |
<> | 144:ef7eb2e8f9f7 | 211 | |
<> | 144:ef7eb2e8f9f7 | 212 | // saturation <1, real-max> |
<> | 144:ef7eb2e8f9f7 | 213 | if (us > MAX_PWM_PERIOD_US) |
<> | 144:ef7eb2e8f9f7 | 214 | { |
<> | 144:ef7eb2e8f9f7 | 215 | us = MAX_PWM_PERIOD_US; |
<> | 144:ef7eb2e8f9f7 | 216 | } |
<> | 144:ef7eb2e8f9f7 | 217 | else if (us < 1) |
<> | 144:ef7eb2e8f9f7 | 218 | { |
<> | 144:ef7eb2e8f9f7 | 219 | us = 1; |
<> | 144:ef7eb2e8f9f7 | 220 | } |
<> | 144:ef7eb2e8f9f7 | 221 | |
<> | 144:ef7eb2e8f9f7 | 222 | p_pwm_signal->duty_us = (int)((float)us * p_pwm_signal->duty); |
<> | 144:ef7eb2e8f9f7 | 223 | |
<> | 144:ef7eb2e8f9f7 | 224 | p_pwm_signal->period_us = us; |
<> | 144:ef7eb2e8f9f7 | 225 | |
<> | 144:ef7eb2e8f9f7 | 226 | internal_pwmout_exe(obj, true, false); |
<> | 144:ef7eb2e8f9f7 | 227 | } |
<> | 144:ef7eb2e8f9f7 | 228 | |
<> | 144:ef7eb2e8f9f7 | 229 | void pwmout_pulsewidth(pwmout_t *obj, float seconds) |
<> | 144:ef7eb2e8f9f7 | 230 | { |
<> | 144:ef7eb2e8f9f7 | 231 | // raught saturation < 0, quasi-max> |
<> | 144:ef7eb2e8f9f7 | 232 | if (seconds > MAX_PWM_PERIOD_S) |
<> | 144:ef7eb2e8f9f7 | 233 | { |
<> | 144:ef7eb2e8f9f7 | 234 | seconds = MAX_PWM_PERIOD_S; |
<> | 144:ef7eb2e8f9f7 | 235 | } |
<> | 144:ef7eb2e8f9f7 | 236 | else if (seconds < 0) |
<> | 144:ef7eb2e8f9f7 | 237 | { |
<> | 144:ef7eb2e8f9f7 | 238 | seconds = 0; |
<> | 144:ef7eb2e8f9f7 | 239 | } |
<> | 144:ef7eb2e8f9f7 | 240 | |
<> | 144:ef7eb2e8f9f7 | 241 | int us = seconds * 1000000; |
<> | 144:ef7eb2e8f9f7 | 242 | |
<> | 144:ef7eb2e8f9f7 | 243 | pwmout_pulsewidth_us(obj,us); |
<> | 144:ef7eb2e8f9f7 | 244 | } |
<> | 144:ef7eb2e8f9f7 | 245 | |
<> | 144:ef7eb2e8f9f7 | 246 | void pwmout_pulsewidth_ms(pwmout_t *obj, int ms) |
<> | 144:ef7eb2e8f9f7 | 247 | { |
<> | 144:ef7eb2e8f9f7 | 248 | // raught saturation < 0, quasi-max> |
<> | 144:ef7eb2e8f9f7 | 249 | if (ms > MAX_PWM_PERIOD_MS) |
<> | 144:ef7eb2e8f9f7 | 250 | { |
<> | 144:ef7eb2e8f9f7 | 251 | ms = MAX_PWM_PERIOD_MS; |
<> | 144:ef7eb2e8f9f7 | 252 | } |
<> | 144:ef7eb2e8f9f7 | 253 | else if (ms < 0) |
<> | 144:ef7eb2e8f9f7 | 254 | { |
<> | 144:ef7eb2e8f9f7 | 255 | ms = 0; |
<> | 144:ef7eb2e8f9f7 | 256 | } |
<> | 144:ef7eb2e8f9f7 | 257 | |
<> | 144:ef7eb2e8f9f7 | 258 | int us = ms * 1000; |
<> | 144:ef7eb2e8f9f7 | 259 | |
<> | 144:ef7eb2e8f9f7 | 260 | pwmout_pulsewidth_us(obj, us); |
<> | 144:ef7eb2e8f9f7 | 261 | } |
<> | 144:ef7eb2e8f9f7 | 262 | |
<> | 144:ef7eb2e8f9f7 | 263 | void pwmout_pulsewidth_us(pwmout_t *obj, int us) |
<> | 144:ef7eb2e8f9f7 | 264 | { |
<> | 144:ef7eb2e8f9f7 | 265 | // saturation <0, real-max> |
<> | 144:ef7eb2e8f9f7 | 266 | if (us > MAX_PWM_PERIOD_US) |
<> | 144:ef7eb2e8f9f7 | 267 | { |
<> | 144:ef7eb2e8f9f7 | 268 | us = MAX_PWM_PERIOD_US; |
<> | 144:ef7eb2e8f9f7 | 269 | } |
<> | 144:ef7eb2e8f9f7 | 270 | else if (us < 0) |
<> | 144:ef7eb2e8f9f7 | 271 | { |
<> | 144:ef7eb2e8f9f7 | 272 | us = 0; |
<> | 144:ef7eb2e8f9f7 | 273 | } |
<> | 144:ef7eb2e8f9f7 | 274 | |
<> | 144:ef7eb2e8f9f7 | 275 | pwm_signal_t * p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal); |
<> | 144:ef7eb2e8f9f7 | 276 | |
<> | 144:ef7eb2e8f9f7 | 277 | p_pwm_signal->duty_us = us; |
<> | 144:ef7eb2e8f9f7 | 278 | p_pwm_signal->duty = us / p_pwm_signal->period_us; |
<> | 144:ef7eb2e8f9f7 | 279 | |
<> | 144:ef7eb2e8f9f7 | 280 | internal_pwmout_exe(obj, false, false); |
<> | 144:ef7eb2e8f9f7 | 281 | } |
<> | 144:ef7eb2e8f9f7 | 282 | |
<> | 144:ef7eb2e8f9f7 | 283 | |
<> | 144:ef7eb2e8f9f7 | 284 | |
<> | 144:ef7eb2e8f9f7 | 285 | |
<> | 144:ef7eb2e8f9f7 | 286 | |
<> | 144:ef7eb2e8f9f7 | 287 | |
<> | 144:ef7eb2e8f9f7 | 288 | static ret_code_t pulsewidth_us_set_get(int period_hwu, int duty_hwu, pulsewidth_set_t * p_settings) |
<> | 144:ef7eb2e8f9f7 | 289 | { |
<> | 144:ef7eb2e8f9f7 | 290 | uint16_t div; |
<> | 144:ef7eb2e8f9f7 | 291 | nrf_pwm_clk_t pwm_clk = NRF_PWM_CLK_16MHz; |
<> | 144:ef7eb2e8f9f7 | 292 | |
<> | 144:ef7eb2e8f9f7 | 293 | for(div = 1; div <= 128 ; div <<= 1) // 128 is the maximum of clock prescaler for PWM peripherial |
<> | 144:ef7eb2e8f9f7 | 294 | { |
<> | 144:ef7eb2e8f9f7 | 295 | if (MAX_PWM_COUNTERTOP >= period_hwu) |
<> | 144:ef7eb2e8f9f7 | 296 | { |
<> | 144:ef7eb2e8f9f7 | 297 | p_settings->period_hwu = period_hwu; // unit [us/16 * div] |
<> | 144:ef7eb2e8f9f7 | 298 | p_settings->duty_hwu = duty_hwu; // unit [us/16 * div] |
<> | 144:ef7eb2e8f9f7 | 299 | p_settings->pwm_clk = pwm_clk; |
<> | 144:ef7eb2e8f9f7 | 300 | |
<> | 144:ef7eb2e8f9f7 | 301 | return NRF_SUCCESS; |
<> | 144:ef7eb2e8f9f7 | 302 | } |
<> | 144:ef7eb2e8f9f7 | 303 | |
<> | 144:ef7eb2e8f9f7 | 304 | period_hwu >>= 1; |
<> | 144:ef7eb2e8f9f7 | 305 | duty_hwu >>= 1; |
<> | 144:ef7eb2e8f9f7 | 306 | pwm_clk++; |
<> | 144:ef7eb2e8f9f7 | 307 | } |
<> | 144:ef7eb2e8f9f7 | 308 | |
<> | 144:ef7eb2e8f9f7 | 309 | return NRF_ERROR_INVALID_PARAM; |
<> | 144:ef7eb2e8f9f7 | 310 | } |
<> | 144:ef7eb2e8f9f7 | 311 | |
<> | 144:ef7eb2e8f9f7 | 312 | |
<> | 144:ef7eb2e8f9f7 | 313 | static void internal_pwmout_exe(pwmout_t *obj, bool new_period, bool initialization) |
<> | 144:ef7eb2e8f9f7 | 314 | { |
<> | 144:ef7eb2e8f9f7 | 315 | pulsewidth_set_t pulsewidth_set; |
<> | 144:ef7eb2e8f9f7 | 316 | pwm_signal_t * p_pwm_signal; |
<> | 144:ef7eb2e8f9f7 | 317 | nrf_drv_pwm_t * p_pwm_driver; |
<> | 144:ef7eb2e8f9f7 | 318 | ret_code_t ret_code; |
<> | 144:ef7eb2e8f9f7 | 319 | |
<> | 144:ef7eb2e8f9f7 | 320 | p_pwm_signal = &(((pwm_t*)obj->pwm_struct)->signal); |
<> | 144:ef7eb2e8f9f7 | 321 | |
<> | 144:ef7eb2e8f9f7 | 322 | if (NRF_SUCCESS == pulsewidth_us_set_get(p_pwm_signal->period_us * 16, // base clk for PWM is 16 MHz |
<> | 144:ef7eb2e8f9f7 | 323 | p_pwm_signal->duty_us * 16, // base clk for PWM is 16 MHz |
<> | 144:ef7eb2e8f9f7 | 324 | &pulsewidth_set)) |
<> | 144:ef7eb2e8f9f7 | 325 | { |
<> | 144:ef7eb2e8f9f7 | 326 | p_pwm_driver = (((pwm_t*)obj->pwm_struct)->p_pwm_driver); |
<> | 144:ef7eb2e8f9f7 | 327 | |
<> | 144:ef7eb2e8f9f7 | 328 | const nrf_pwm_sequence_t seq = |
<> | 144:ef7eb2e8f9f7 | 329 | { |
<> | 144:ef7eb2e8f9f7 | 330 | .values.p_common = (nrf_pwm_values_common_t*) (((pwm_t*)obj->pwm_struct)->seq_values), |
<> | 144:ef7eb2e8f9f7 | 331 | .length = 1, |
<> | 144:ef7eb2e8f9f7 | 332 | .repeats = 0, |
<> | 144:ef7eb2e8f9f7 | 333 | .end_delay = 0 |
<> | 144:ef7eb2e8f9f7 | 334 | }; |
<> | 144:ef7eb2e8f9f7 | 335 | |
<> | 144:ef7eb2e8f9f7 | 336 | (((pwm_t*)obj->pwm_struct)->seq_values)[0] = pulsewidth_set.duty_hwu | 0x8000; |
<> | 144:ef7eb2e8f9f7 | 337 | |
<> | 144:ef7eb2e8f9f7 | 338 | if (new_period) |
<> | 144:ef7eb2e8f9f7 | 339 | { |
<> | 144:ef7eb2e8f9f7 | 340 | nrf_drv_pwm_config_t config0 = |
<> | 144:ef7eb2e8f9f7 | 341 | { |
<> | 144:ef7eb2e8f9f7 | 342 | .output_pins = |
<> | 144:ef7eb2e8f9f7 | 343 | { |
<> | 144:ef7eb2e8f9f7 | 344 | obj->pin | NRF_DRV_PWM_PIN_INVERTED, // channel 0 |
<> | 144:ef7eb2e8f9f7 | 345 | NRF_DRV_PWM_PIN_NOT_USED, // channel 1 |
<> | 144:ef7eb2e8f9f7 | 346 | NRF_DRV_PWM_PIN_NOT_USED, // channel 2 |
<> | 144:ef7eb2e8f9f7 | 347 | NRF_DRV_PWM_PIN_NOT_USED, // channel 3 |
<> | 144:ef7eb2e8f9f7 | 348 | }, |
<> | 144:ef7eb2e8f9f7 | 349 | .irq_priority = APP_IRQ_PRIORITY_LOW, |
<> | 144:ef7eb2e8f9f7 | 350 | .base_clock = pulsewidth_set.pwm_clk, |
<> | 144:ef7eb2e8f9f7 | 351 | .count_mode = NRF_PWM_MODE_UP, |
<> | 144:ef7eb2e8f9f7 | 352 | .top_value = pulsewidth_set.period_hwu, |
<> | 144:ef7eb2e8f9f7 | 353 | .load_mode = NRF_PWM_LOAD_COMMON, |
<> | 144:ef7eb2e8f9f7 | 354 | .step_mode = NRF_PWM_STEP_AUTO |
<> | 144:ef7eb2e8f9f7 | 355 | }; |
<> | 144:ef7eb2e8f9f7 | 356 | |
<> | 144:ef7eb2e8f9f7 | 357 | if (!initialization) |
<> | 144:ef7eb2e8f9f7 | 358 | { |
<> | 144:ef7eb2e8f9f7 | 359 | nrf_drv_pwm_uninit(p_pwm_driver); |
<> | 144:ef7eb2e8f9f7 | 360 | } |
<> | 144:ef7eb2e8f9f7 | 361 | |
<> | 144:ef7eb2e8f9f7 | 362 | ret_code = nrf_drv_pwm_init( p_pwm_driver, &config0, NULL); |
<> | 144:ef7eb2e8f9f7 | 363 | |
<> | 144:ef7eb2e8f9f7 | 364 | MBED_ASSERT(ret_code == NRF_SUCCESS); // assert if free instance was not found. |
<> | 144:ef7eb2e8f9f7 | 365 | } |
<> | 144:ef7eb2e8f9f7 | 366 | |
<> | 144:ef7eb2e8f9f7 | 367 | nrf_drv_pwm_simple_playback(p_pwm_driver, &seq, 0, NRF_DRV_PWM_FLAG_LOOP); |
<> | 144:ef7eb2e8f9f7 | 368 | } |
<> | 144:ef7eb2e8f9f7 | 369 | else |
<> | 144:ef7eb2e8f9f7 | 370 | { |
<> | 144:ef7eb2e8f9f7 | 371 | MBED_ASSERT(0); // force assertion |
<> | 144:ef7eb2e8f9f7 | 372 | } |
<> | 144:ef7eb2e8f9f7 | 373 | |
<> | 144:ef7eb2e8f9f7 | 374 | } |
<> | 144:ef7eb2e8f9f7 | 375 | |
<> | 144:ef7eb2e8f9f7 | 376 | #endif // DEVICE_PWMOUT |