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:
Wed Jun 11 16:00:09 2014 +0100
Revision:
227:7bd0639b8911
Parent:
104:a6a92e2e5a92
Child:
229:9bd26d142f33
Synchronized with git revision d58d532ebc0e0a96f4fffb8edefc082b71b964af

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

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