mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Thu Jun 12 14:45:07 2014 +0100
Revision:
229:9bd26d142f33
Parent:
227:7bd0639b8911
Child:
250:a49055e7a707
Synchronized with git revision fb13a684ae512b82e9e0bc1734e0375b017708ec

Full URL: https://github.com/mbedmicro/mbed/commit/fb13a684ae512b82e9e0bc1734e0375b017708ec/

[NRF] PWM issue solved when Softdevice is running

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 85:e1a8e879a6a9 20 #include "error.h"
mbed_official 85:e1a8e879a6a9 21
mbed_official 229:9bd26d142f33 22 #define NO_PWMS 3
mbed_official 229:9bd26d142f33 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 229:9bd26d142f33 62 uint16_t PERIOD = 20000/TIMER_PRECISION;//20ms
mbed_official 229:9bd26d142f33 63 uint8_t PWM_taken[NO_PWMS] = {0,0,0};
mbed_official 229:9bd26d142f33 64 uint16_t PULSE_WIDTH[NO_PWMS] = {1,1,1};//set to 1 instead of 0
mbed_official 229:9bd26d142f33 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 85:e1a8e879a6a9 70 #ifdef __cplusplus
mbed_official 85:e1a8e879a6a9 71 extern "C" {
mbed_official 229:9bd26d142f33 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 229:9bd26d142f33 76 NRF_TIMER2->CC[3] = PERIOD;
mbed_official 85:e1a8e879a6a9 77
mbed_official 229:9bd26d142f33 78 if(PWM_taken[0]){
mbed_official 229:9bd26d142f33 79 NRF_TIMER2->CC[0] = PULSE_WIDTH[0];
mbed_official 229:9bd26d142f33 80 }
mbed_official 229:9bd26d142f33 81 if(PWM_taken[1]){
mbed_official 229:9bd26d142f33 82 NRF_TIMER2->CC[1] = PULSE_WIDTH[1];
mbed_official 229:9bd26d142f33 83 }
mbed_official 229:9bd26d142f33 84 if(PWM_taken[2]){
mbed_official 229:9bd26d142f33 85 NRF_TIMER2->CC[2] = PULSE_WIDTH[2];
mbed_official 229:9bd26d142f33 86 }
mbed_official 229:9bd26d142f33 87
mbed_official 229:9bd26d142f33 88 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 89
mbed_official 85:e1a8e879a6a9 90 }
mbed_official 85:e1a8e879a6a9 91 #ifdef __cplusplus
mbed_official 85:e1a8e879a6a9 92 }
mbed_official 229:9bd26d142f33 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 229:9bd26d142f33 100
mbed_official 229:9bd26d142f33 101 if(pwmChoice == 0){
mbed_official 85:e1a8e879a6a9 102 timer->POWER = 0;
mbed_official 229:9bd26d142f33 103 timer->POWER = 1;
mbed_official 229:9bd26d142f33 104 timer->MODE = TIMER_MODE_MODE_Timer;
mbed_official 85:e1a8e879a6a9 105 timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
mbed_official 229:9bd26d142f33 106 timer->PRESCALER = TIMER_PRESCALER;
mbed_official 229:9bd26d142f33 107 timer->CC[3] = PERIOD;
mbed_official 85:e1a8e879a6a9 108 }
mbed_official 85:e1a8e879a6a9 109
mbed_official 229:9bd26d142f33 110 timer->CC[pwmChoice] = PULSE_WIDTH[pwmChoice];
mbed_official 229:9bd26d142f33 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 85:e1a8e879a6a9 115
mbed_official 85:e1a8e879a6a9 116 timer->TASKS_START = 0x01;
mbed_official 85:e1a8e879a6a9 117 }
mbed_official 85:e1a8e879a6a9 118 /** @brief Function for initializing the GPIO Tasks/Events peripheral.
mbed_official 85:e1a8e879a6a9 119 */
mbed_official 85:e1a8e879a6a9 120 void gpiote_init(PinName pin,uint8_t channel_number)
mbed_official 85:e1a8e879a6a9 121 {
mbed_official 85:e1a8e879a6a9 122 // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
mbed_official 85:e1a8e879a6a9 123 NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
mbed_official 85:e1a8e879a6a9 124 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
mbed_official 85:e1a8e879a6a9 125 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
mbed_official 85:e1a8e879a6a9 126 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
mbed_official 85:e1a8e879a6a9 127 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
mbed_official 85:e1a8e879a6a9 128 NRF_GPIO->OUTCLR = (1UL << pin);
mbed_official 85:e1a8e879a6a9 129 // Configure GPIOTE channel 0 to toggle the PWM pin state
mbed_official 85:e1a8e879a6a9 130 // @note Only one GPIOTE task can be connected to an output pin.
mbed_official 85:e1a8e879a6a9 131 /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
mbed_official 85:e1a8e879a6a9 132 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 133 (31UL << GPIOTE_CONFIG_PSEL_Pos) |
mbed_official 85:e1a8e879a6a9 134 (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 135 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
mbed_official 85:e1a8e879a6a9 136 __NOP();
mbed_official 85:e1a8e879a6a9 137 __NOP();
mbed_official 229:9bd26d142f33 138 __NOP();
mbed_official 85:e1a8e879a6a9 139 /* Launch the task to take the GPIOTE channel output to the desired level */
mbed_official 85:e1a8e879a6a9 140 NRF_GPIOTE->TASKS_OUT[channel_number] = 1;
mbed_official 85:e1a8e879a6a9 141
mbed_official 229:9bd26d142f33 142 /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
mbed_official 85:e1a8e879a6a9 143 If it does not, the channel output inheritance sets the proper level. */
mbed_official 85:e1a8e879a6a9 144 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 145 ((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
mbed_official 85:e1a8e879a6a9 146 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
mbed_official 229:9bd26d142f33 147 ((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);// ((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);//
mbed_official 85:e1a8e879a6a9 148
mbed_official 85:e1a8e879a6a9 149 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
mbed_official 85:e1a8e879a6a9 150 __NOP();
mbed_official 85:e1a8e879a6a9 151 __NOP();
mbed_official 229:9bd26d142f33 152 __NOP();
mbed_official 85:e1a8e879a6a9 153 }
mbed_official 85:e1a8e879a6a9 154 /** @brief Function for initializing the Programmable Peripheral Interconnect peripheral.
mbed_official 85:e1a8e879a6a9 155 */
mbed_official 85:e1a8e879a6a9 156 static void ppi_init(uint8_t pwm)
mbed_official 85:e1a8e879a6a9 157 {
mbed_official 229:9bd26d142f33 158 //using ppi channels 0-7 (only 0-7 are available)
mbed_official 85:e1a8e879a6a9 159 uint8_t channel_number = 2*pwm;
mbed_official 229:9bd26d142f33 160 NRF_TIMER_Type *timer = Timers[0];
mbed_official 85:e1a8e879a6a9 161
mbed_official 85:e1a8e879a6a9 162 // Configure PPI channel 0 to toggle ADVERTISING_LED_PIN_NO on every TIMER1 COMPARE[0] match
mbed_official 85:e1a8e879a6a9 163 NRF_PPI->CH[channel_number].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
mbed_official 85:e1a8e879a6a9 164 NRF_PPI->CH[channel_number+1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
mbed_official 229:9bd26d142f33 165 NRF_PPI->CH[channel_number].EEP = (uint32_t)&timer->EVENTS_COMPARE[pwm];
mbed_official 229:9bd26d142f33 166 NRF_PPI->CH[channel_number+1].EEP = (uint32_t)&timer->EVENTS_COMPARE[3];
mbed_official 85:e1a8e879a6a9 167
mbed_official 85:e1a8e879a6a9 168 // Enable PPI channels.
mbed_official 85:e1a8e879a6a9 169 NRF_PPI->CHEN |= (1 << channel_number)
mbed_official 85:e1a8e879a6a9 170 | (1 << (channel_number+1));
mbed_official 85:e1a8e879a6a9 171 }
mbed_official 85:e1a8e879a6a9 172
mbed_official 85:e1a8e879a6a9 173 void setModulation(pwmout_t* obj,uint8_t toggle,uint8_t high)
mbed_official 85:e1a8e879a6a9 174 {
mbed_official 85:e1a8e879a6a9 175 if(high){
mbed_official 85:e1a8e879a6a9 176 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 85:e1a8e879a6a9 177 if(toggle){
mbed_official 85:e1a8e879a6a9 178 NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 179 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 180 }
mbed_official 85:e1a8e879a6a9 181 else{
mbed_official 85:e1a8e879a6a9 182 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 183 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 184 }
mbed_official 85:e1a8e879a6a9 185 }
mbed_official 85:e1a8e879a6a9 186 else{
mbed_official 85:e1a8e879a6a9 187 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 85:e1a8e879a6a9 188
mbed_official 85:e1a8e879a6a9 189 if(toggle){
mbed_official 85:e1a8e879a6a9 190 NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 191 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 192 }
mbed_official 85:e1a8e879a6a9 193 else{
mbed_official 85:e1a8e879a6a9 194 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 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 85:e1a8e879a6a9 199 void pwmout_init(pwmout_t* obj, PinName pin) {
mbed_official 85:e1a8e879a6a9 200 // determine the channel
mbed_official 85:e1a8e879a6a9 201 uint8_t pwmOutSuccess = 0;
mbed_official 85:e1a8e879a6a9 202 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
mbed_official 229:9bd26d142f33 203
mbed_official 227:7bd0639b8911 204 MBED_ASSERT(pwm != (PWMName)NC);
mbed_official 85:e1a8e879a6a9 205
mbed_official 85:e1a8e879a6a9 206 if(PWM_taken[(uint8_t)pwm]){
mbed_official 85:e1a8e879a6a9 207 for(uint8_t i = 1; !pwmOutSuccess && (i<NO_PWMS) ;i++){
mbed_official 85:e1a8e879a6a9 208 if(!PWM_taken[i]){
mbed_official 85:e1a8e879a6a9 209 pwm = (PWMName)i;
mbed_official 85:e1a8e879a6a9 210 PWM_taken[i] = 1;
mbed_official 85:e1a8e879a6a9 211 pwmOutSuccess = 1;
mbed_official 85:e1a8e879a6a9 212 }
mbed_official 85:e1a8e879a6a9 213 }
mbed_official 85:e1a8e879a6a9 214 }
mbed_official 85:e1a8e879a6a9 215 else{
mbed_official 85:e1a8e879a6a9 216 pwmOutSuccess = 1;
mbed_official 85:e1a8e879a6a9 217 PWM_taken[(uint8_t)pwm] = 1;
mbed_official 85:e1a8e879a6a9 218 }
mbed_official 85:e1a8e879a6a9 219
mbed_official 85:e1a8e879a6a9 220 if(!pwmOutSuccess){
mbed_official 85:e1a8e879a6a9 221 error("PwmOut pin mapping failed. All available PWM channels are in use.");
mbed_official 85:e1a8e879a6a9 222 }
mbed_official 85:e1a8e879a6a9 223
mbed_official 85:e1a8e879a6a9 224 obj->pwm = pwm;
mbed_official 85:e1a8e879a6a9 225 obj->pin = pin;
mbed_official 85:e1a8e879a6a9 226
mbed_official 85:e1a8e879a6a9 227 gpiote_init(pin,(uint8_t)pwm);
mbed_official 85:e1a8e879a6a9 228 ppi_init((uint8_t)pwm);
mbed_official 85:e1a8e879a6a9 229
mbed_official 85:e1a8e879a6a9 230 if(pwm == 0){
mbed_official 85:e1a8e879a6a9 231 NRF_POWER->TASKS_CONSTLAT = 1;
mbed_official 85:e1a8e879a6a9 232 }
mbed_official 85:e1a8e879a6a9 233
mbed_official 85:e1a8e879a6a9 234 timer_init((uint8_t)pwm);
mbed_official 85:e1a8e879a6a9 235
mbed_official 85:e1a8e879a6a9 236 //default to 20ms: standard for servos, and fine for e.g. brightness control
mbed_official 85:e1a8e879a6a9 237 pwmout_period_ms(obj, 20);
mbed_official 85:e1a8e879a6a9 238 pwmout_write (obj, 0);
mbed_official 85:e1a8e879a6a9 239
mbed_official 85:e1a8e879a6a9 240 }
mbed_official 85:e1a8e879a6a9 241
mbed_official 85:e1a8e879a6a9 242 void pwmout_free(pwmout_t* obj) {
mbed_official 85:e1a8e879a6a9 243 // [TODO]
mbed_official 85:e1a8e879a6a9 244 }
mbed_official 85:e1a8e879a6a9 245
mbed_official 85:e1a8e879a6a9 246 void pwmout_write(pwmout_t* obj, float value) {
mbed_official 85:e1a8e879a6a9 247 uint16_t oldPulseWidth;
mbed_official 85:e1a8e879a6a9 248
mbed_official 229:9bd26d142f33 249 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 229:9bd26d142f33 250 NRF_TIMER2->TASKS_STOP = 1;
mbed_official 229:9bd26d142f33 251
mbed_official 85:e1a8e879a6a9 252 if (value < 0.0f) {
mbed_official 85:e1a8e879a6a9 253 value = 0.0;
mbed_official 85:e1a8e879a6a9 254 } else if (value > 1.0f) {
mbed_official 85:e1a8e879a6a9 255 value = 1.0;
mbed_official 229:9bd26d142f33 256 }
mbed_official 85:e1a8e879a6a9 257
mbed_official 85:e1a8e879a6a9 258 oldPulseWidth = ACTUAL_PULSE[obj->pwm];
mbed_official 229:9bd26d142f33 259 ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = value* PERIOD;
mbed_official 85:e1a8e879a6a9 260
mbed_official 85:e1a8e879a6a9 261 if(PULSE_WIDTH[obj->pwm] == 0){
mbed_official 85:e1a8e879a6a9 262 PULSE_WIDTH[obj->pwm] = 1;
mbed_official 229:9bd26d142f33 263 setModulation(obj,0,0);
mbed_official 85:e1a8e879a6a9 264 }
mbed_official 229:9bd26d142f33 265 else if(PULSE_WIDTH[obj->pwm] == PERIOD){
mbed_official 229:9bd26d142f33 266 PULSE_WIDTH[obj->pwm] = PERIOD-1;
mbed_official 85:e1a8e879a6a9 267 setModulation(obj,0,1);
mbed_official 85:e1a8e879a6a9 268 }
mbed_official 229:9bd26d142f33 269 else if( (oldPulseWidth == 0) || (oldPulseWidth == PERIOD) ){
mbed_official 229:9bd26d142f33 270 setModulation(obj,1,oldPulseWidth == PERIOD);
mbed_official 229:9bd26d142f33 271 }
mbed_official 229:9bd26d142f33 272
mbed_official 229:9bd26d142f33 273 NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
mbed_official 229:9bd26d142f33 274 NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
mbed_official 229:9bd26d142f33 275 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 276 }
mbed_official 85:e1a8e879a6a9 277
mbed_official 85:e1a8e879a6a9 278 float pwmout_read(pwmout_t* obj) {
mbed_official 229:9bd26d142f33 279 return ((float)PULSE_WIDTH[obj->pwm]/(float)PERIOD);
mbed_official 85:e1a8e879a6a9 280 }
mbed_official 85:e1a8e879a6a9 281
mbed_official 85:e1a8e879a6a9 282 void pwmout_period(pwmout_t* obj, float seconds) {
mbed_official 85:e1a8e879a6a9 283 pwmout_period_us(obj, seconds * 1000000.0f);
mbed_official 85:e1a8e879a6a9 284 }
mbed_official 85:e1a8e879a6a9 285
mbed_official 85:e1a8e879a6a9 286 void pwmout_period_ms(pwmout_t* obj, int ms) {
mbed_official 85:e1a8e879a6a9 287 pwmout_period_us(obj, ms * 1000);
mbed_official 85:e1a8e879a6a9 288 }
mbed_official 85:e1a8e879a6a9 289
mbed_official 85:e1a8e879a6a9 290 // Set the PWM period, keeping the duty cycle the same.
mbed_official 85:e1a8e879a6a9 291 void pwmout_period_us(pwmout_t* obj, int us) {
mbed_official 229:9bd26d142f33 292 uint32_t periodInTicks = us/TIMER_PRECISION;
mbed_official 229:9bd26d142f33 293
mbed_official 229:9bd26d142f33 294 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 229:9bd26d142f33 295 NRF_TIMER2->TASKS_STOP = 1;
mbed_official 85:e1a8e879a6a9 296
mbed_official 85:e1a8e879a6a9 297 if(periodInTicks>((1<<16) -1))
mbed_official 85:e1a8e879a6a9 298 {
mbed_official 229:9bd26d142f33 299 PERIOD = (1<<16 )-1;//131ms
mbed_official 85:e1a8e879a6a9 300 }
mbed_official 85:e1a8e879a6a9 301 else if(periodInTicks<5){
mbed_official 229:9bd26d142f33 302 PERIOD = 5;
mbed_official 85:e1a8e879a6a9 303 }
mbed_official 85:e1a8e879a6a9 304 else{
mbed_official 229:9bd26d142f33 305 PERIOD =periodInTicks;
mbed_official 227:7bd0639b8911 306 }
mbed_official 229:9bd26d142f33 307 NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
mbed_official 229:9bd26d142f33 308 NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
mbed_official 229:9bd26d142f33 309 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 310 }
mbed_official 85:e1a8e879a6a9 311
mbed_official 85:e1a8e879a6a9 312 void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
mbed_official 85:e1a8e879a6a9 313 pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
mbed_official 85:e1a8e879a6a9 314 }
mbed_official 85:e1a8e879a6a9 315
mbed_official 85:e1a8e879a6a9 316 void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
mbed_official 85:e1a8e879a6a9 317 pwmout_pulsewidth_us(obj, ms * 1000);
mbed_official 85:e1a8e879a6a9 318 }
mbed_official 85:e1a8e879a6a9 319
mbed_official 85:e1a8e879a6a9 320 void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
mbed_official 229:9bd26d142f33 321 uint32_t pulseInTicks = us/TIMER_PRECISION;
mbed_official 85:e1a8e879a6a9 322 uint16_t oldPulseWidth = ACTUAL_PULSE[obj->pwm];
mbed_official 85:e1a8e879a6a9 323
mbed_official 229:9bd26d142f33 324 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 229:9bd26d142f33 325 NRF_TIMER2->TASKS_STOP = 1;
mbed_official 229:9bd26d142f33 326
mbed_official 85:e1a8e879a6a9 327 ACTUAL_PULSE[obj->pwm] = PULSE_WIDTH[obj->pwm] = pulseInTicks;
mbed_official 85:e1a8e879a6a9 328
mbed_official 85:e1a8e879a6a9 329 if(PULSE_WIDTH[obj->pwm] == 0){
mbed_official 85:e1a8e879a6a9 330 PULSE_WIDTH[obj->pwm] = 1;
mbed_official 229:9bd26d142f33 331 setModulation(obj,0,0);
mbed_official 85:e1a8e879a6a9 332 }
mbed_official 229:9bd26d142f33 333 else if(PULSE_WIDTH[obj->pwm] == PERIOD){
mbed_official 229:9bd26d142f33 334 PULSE_WIDTH[obj->pwm] = PERIOD-1;
mbed_official 85:e1a8e879a6a9 335 setModulation(obj,0,1);
mbed_official 85:e1a8e879a6a9 336 }
mbed_official 229:9bd26d142f33 337 else if( (oldPulseWidth == 0) || (oldPulseWidth == PERIOD) ){
mbed_official 229:9bd26d142f33 338 setModulation(obj,1,oldPulseWidth == PERIOD);
mbed_official 229:9bd26d142f33 339 }
mbed_official 229:9bd26d142f33 340 NRF_TIMER2->INTENSET = TIMER_INTENSET_COMPARE3_Msk;
mbed_official 229:9bd26d142f33 341 NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk | TIMER_SHORTS_COMPARE3_STOP_Msk;
mbed_official 229:9bd26d142f33 342 NRF_TIMER2->TASKS_START = 1;
mbed_official 85:e1a8e879a6a9 343 }