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:
Fri Aug 15 16:30:08 2014 +0100
Revision:
285:31249416b6f9
Parent:
270:e2babe29baf8
Child:
300:55638feb26a4
Synchronized with git revision 601712595f49bbd2a2771c52cf3e84c9c7a591af

Full URL: https://github.com/mbedmicro/mbed/commit/601712595f49bbd2a2771c52cf3e84c9c7a591af/

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 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 }