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 Feb 07 18:00:11 2014 +0000
Revision:
85:e1a8e879a6a9
Child:
104:a6a92e2e5a92
Synchronized with git revision 4b2b368a6a3b1f0fd33d99917981c67436c4aebe

Full URL: https://github.com/mbedmicro/mbed/commit/4b2b368a6a3b1f0fd33d99917981c67436c4aebe/

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 85:e1a8e879a6a9 1 /* mbed Microcontroller Library
mbed_official 85:e1a8e879a6a9 2 * Copyright (c) 2006-2013 ARM Limited
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 85:e1a8e879a6a9 16 #include "pwmout_api.h"
mbed_official 85:e1a8e879a6a9 17 #include "cmsis.h"
mbed_official 85:e1a8e879a6a9 18 #include "pinmap.h"
mbed_official 85:e1a8e879a6a9 19 #include "error.h"
mbed_official 85:e1a8e879a6a9 20
mbed_official 85:e1a8e879a6a9 21 #define NO_PWMS 2
mbed_official 85:e1a8e879a6a9 22
mbed_official 85:e1a8e879a6a9 23 static const PinMap PinMap_PWM[] = {
mbed_official 85:e1a8e879a6a9 24 {p0, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 25 {p1, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 26 {p2, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 27 {p3, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 28 {p4, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 29 {p5, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 30 {p6, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 31 {p7, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 32 {p8, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 33 {p9, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 34 {p10, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 35 {p11, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 36 {p12, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 37 {p13, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 38 {p14, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 39 {p15, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 40 {p16, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 41 {p17, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 42 {p18, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 43 {p19, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 44 {p20, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 45 {p21, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 46 {p22, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 47 {p23, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 48 {p24, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 49 {p25, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 50 {p28, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 51 {p29, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 52 {p30, PWM_1, 1},
mbed_official 85:e1a8e879a6a9 53 {NC, NC, 0}
mbed_official 85:e1a8e879a6a9 54 };
mbed_official 85:e1a8e879a6a9 55
mbed_official 85:e1a8e879a6a9 56 static NRF_TIMER_Type *Timers[1] = {
mbed_official 85:e1a8e879a6a9 57 NRF_TIMER2
mbed_official 85:e1a8e879a6a9 58 };
mbed_official 85:e1a8e879a6a9 59
mbed_official 85:e1a8e879a6a9 60 uint8_t PWM_taken[NO_PWMS] = {0,0};
mbed_official 85:e1a8e879a6a9 61 uint16_t PERIOD[NO_PWMS] = {2500,2500};//20ms
mbed_official 85:e1a8e879a6a9 62 uint16_t PULSE_WIDTH[NO_PWMS] = {1,1};//set to 1 instead of 0
mbed_official 85:e1a8e879a6a9 63 uint16_t ACTUAL_PULSE[NO_PWMS] = {0,0};
mbed_official 85:e1a8e879a6a9 64
mbed_official 85:e1a8e879a6a9 65
mbed_official 85:e1a8e879a6a9 66 /** @brief Function for handling timer 2 peripheral interrupts.
mbed_official 85:e1a8e879a6a9 67 */
mbed_official 85:e1a8e879a6a9 68 #ifdef __cplusplus
mbed_official 85:e1a8e879a6a9 69 extern "C" {
mbed_official 85:e1a8e879a6a9 70 #endif
mbed_official 85:e1a8e879a6a9 71 void TIMER2_IRQHandler(void)
mbed_official 85:e1a8e879a6a9 72 {
mbed_official 85:e1a8e879a6a9 73 static uint16_t CCVal1 = 2501;
mbed_official 85:e1a8e879a6a9 74 static uint16_t CCVal2 = 2501;
mbed_official 85:e1a8e879a6a9 75
mbed_official 85:e1a8e879a6a9 76 if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) &&
mbed_official 85:e1a8e879a6a9 77 ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0)){
mbed_official 85:e1a8e879a6a9 78
mbed_official 85:e1a8e879a6a9 79 NRF_TIMER2->CC[0] = CCVal1;
mbed_official 85:e1a8e879a6a9 80 NRF_TIMER2->EVENTS_COMPARE[1] = 0;
mbed_official 85:e1a8e879a6a9 81 NRF_TIMER2->CC[1] = (NRF_TIMER2->CC[1] + PERIOD[0]);
mbed_official 85:e1a8e879a6a9 82
mbed_official 85:e1a8e879a6a9 83 CCVal1 = NRF_TIMER2->CC[1] + PULSE_WIDTH[0];
mbed_official 85:e1a8e879a6a9 84 }
mbed_official 85:e1a8e879a6a9 85 if ((NRF_TIMER2->EVENTS_COMPARE[3] != 0) &&
mbed_official 85:e1a8e879a6a9 86 ((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE3_Msk) != 0)){
mbed_official 85:e1a8e879a6a9 87
mbed_official 85:e1a8e879a6a9 88 NRF_TIMER2->CC[2] = CCVal2;
mbed_official 85:e1a8e879a6a9 89 NRF_TIMER2->EVENTS_COMPARE[3] = 0;
mbed_official 85:e1a8e879a6a9 90 NRF_TIMER2->CC[3] = (NRF_TIMER2->CC[3] + PERIOD[1]);
mbed_official 85:e1a8e879a6a9 91
mbed_official 85:e1a8e879a6a9 92 CCVal2 = NRF_TIMER2->CC[3] + PULSE_WIDTH[1];
mbed_official 85:e1a8e879a6a9 93 }
mbed_official 85:e1a8e879a6a9 94 }
mbed_official 85:e1a8e879a6a9 95 #ifdef __cplusplus
mbed_official 85:e1a8e879a6a9 96 }
mbed_official 85:e1a8e879a6a9 97 #endif
mbed_official 85:e1a8e879a6a9 98 /** @brief Function for initializing the Timer peripherals.
mbed_official 85:e1a8e879a6a9 99 */
mbed_official 85:e1a8e879a6a9 100 void timer_init(uint8_t pwmChoice)
mbed_official 85:e1a8e879a6a9 101 {
mbed_official 85:e1a8e879a6a9 102 NRF_TIMER_Type *timer = Timers[pwmChoice/2];
mbed_official 85:e1a8e879a6a9 103 if(!(pwmChoice%2)){
mbed_official 85:e1a8e879a6a9 104 timer->POWER = 0;
mbed_official 85:e1a8e879a6a9 105 timer->POWER = 1;
mbed_official 85:e1a8e879a6a9 106 timer->MODE = TIMER_MODE_MODE_Timer;
mbed_official 85:e1a8e879a6a9 107 timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
mbed_official 85:e1a8e879a6a9 108 timer->PRESCALER = 7;//8us ticks
mbed_official 85:e1a8e879a6a9 109 }
mbed_official 85:e1a8e879a6a9 110
mbed_official 85:e1a8e879a6a9 111 if(pwmChoice%2){
mbed_official 85:e1a8e879a6a9 112 timer->CC[2] = PERIOD[pwmChoice] + PULSE_WIDTH[pwmChoice];
mbed_official 85:e1a8e879a6a9 113 timer->CC[3] = PERIOD[pwmChoice];
mbed_official 85:e1a8e879a6a9 114
mbed_official 85:e1a8e879a6a9 115 // Interrupt setup.
mbed_official 85:e1a8e879a6a9 116 timer->INTENSET = (TIMER_INTENSET_COMPARE3_Enabled << TIMER_INTENSET_COMPARE3_Pos);
mbed_official 85:e1a8e879a6a9 117 }
mbed_official 85:e1a8e879a6a9 118 else{
mbed_official 85:e1a8e879a6a9 119 timer->CC[0] = PERIOD[pwmChoice] + PULSE_WIDTH[pwmChoice];
mbed_official 85:e1a8e879a6a9 120 timer->CC[1] = PERIOD[pwmChoice];
mbed_official 85:e1a8e879a6a9 121
mbed_official 85:e1a8e879a6a9 122 // Interrupt setup.
mbed_official 85:e1a8e879a6a9 123 timer->INTENSET |= (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
mbed_official 85:e1a8e879a6a9 124 }
mbed_official 85:e1a8e879a6a9 125 //high priority application interrupt
mbed_official 85:e1a8e879a6a9 126 NVIC_SetPriority(TIMER2_IRQn, 1);
mbed_official 85:e1a8e879a6a9 127 NVIC_EnableIRQ(TIMER2_IRQn);
mbed_official 85:e1a8e879a6a9 128
mbed_official 85:e1a8e879a6a9 129 timer->TASKS_START = 0x01;
mbed_official 85:e1a8e879a6a9 130 }
mbed_official 85:e1a8e879a6a9 131 /** @brief Function for initializing the GPIO Tasks/Events peripheral.
mbed_official 85:e1a8e879a6a9 132 */
mbed_official 85:e1a8e879a6a9 133 void gpiote_init(PinName pin,uint8_t channel_number)
mbed_official 85:e1a8e879a6a9 134 {
mbed_official 85:e1a8e879a6a9 135 // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
mbed_official 85:e1a8e879a6a9 136 NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
mbed_official 85:e1a8e879a6a9 137 | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
mbed_official 85:e1a8e879a6a9 138 | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
mbed_official 85:e1a8e879a6a9 139 | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
mbed_official 85:e1a8e879a6a9 140 | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
mbed_official 85:e1a8e879a6a9 141 NRF_GPIO->OUTCLR = (1UL << pin);
mbed_official 85:e1a8e879a6a9 142 // Configure GPIOTE channel 0 to toggle the PWM pin state
mbed_official 85:e1a8e879a6a9 143 // @note Only one GPIOTE task can be connected to an output pin.
mbed_official 85:e1a8e879a6a9 144 /* 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 145 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 146 (31UL << GPIOTE_CONFIG_PSEL_Pos) |
mbed_official 85:e1a8e879a6a9 147 (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 148 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
mbed_official 85:e1a8e879a6a9 149 __NOP();
mbed_official 85:e1a8e879a6a9 150 __NOP();
mbed_official 85:e1a8e879a6a9 151 __NOP();
mbed_official 85:e1a8e879a6a9 152 /* Launch the task to take the GPIOTE channel output to the desired level */
mbed_official 85:e1a8e879a6a9 153 NRF_GPIOTE->TASKS_OUT[channel_number] = 1;
mbed_official 85:e1a8e879a6a9 154
mbed_official 85:e1a8e879a6a9 155 /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
mbed_official 85:e1a8e879a6a9 156 If it does not, the channel output inheritance sets the proper level. */
mbed_official 85:e1a8e879a6a9 157 NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 158 ((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
mbed_official 85:e1a8e879a6a9 159 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
mbed_official 85:e1a8e879a6a9 160 ((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 85:e1a8e879a6a9 161
mbed_official 85:e1a8e879a6a9 162 /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
mbed_official 85:e1a8e879a6a9 163 __NOP();
mbed_official 85:e1a8e879a6a9 164 __NOP();
mbed_official 85:e1a8e879a6a9 165 __NOP();
mbed_official 85:e1a8e879a6a9 166 }
mbed_official 85:e1a8e879a6a9 167 /** @brief Function for initializing the Programmable Peripheral Interconnect peripheral.
mbed_official 85:e1a8e879a6a9 168 */
mbed_official 85:e1a8e879a6a9 169 static void ppi_init(uint8_t pwm)
mbed_official 85:e1a8e879a6a9 170 {
mbed_official 85:e1a8e879a6a9 171 //using ppi channels 0-3 (0-7 are available)
mbed_official 85:e1a8e879a6a9 172 uint8_t channel_number = 2*pwm;
mbed_official 85:e1a8e879a6a9 173 NRF_TIMER_Type *timer = Timers[pwm/2];
mbed_official 85:e1a8e879a6a9 174
mbed_official 85:e1a8e879a6a9 175 // Configure PPI channel 0 to toggle ADVERTISING_LED_PIN_NO on every TIMER1 COMPARE[0] match
mbed_official 85:e1a8e879a6a9 176 NRF_PPI->CH[channel_number].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
mbed_official 85:e1a8e879a6a9 177 NRF_PPI->CH[channel_number+1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pwm];
mbed_official 85:e1a8e879a6a9 178 NRF_PPI->CH[channel_number].EEP = (uint32_t)&timer->EVENTS_COMPARE[channel_number-(4*(channel_number/4))];
mbed_official 85:e1a8e879a6a9 179 NRF_PPI->CH[channel_number+1].EEP = (uint32_t)&timer->EVENTS_COMPARE[channel_number+1-(4*(channel_number/4))];
mbed_official 85:e1a8e879a6a9 180
mbed_official 85:e1a8e879a6a9 181 // Enable PPI channels.
mbed_official 85:e1a8e879a6a9 182 NRF_PPI->CHEN |= (1 << channel_number)
mbed_official 85:e1a8e879a6a9 183 | (1 << (channel_number+1));
mbed_official 85:e1a8e879a6a9 184 }
mbed_official 85:e1a8e879a6a9 185
mbed_official 85:e1a8e879a6a9 186 void setModulation(pwmout_t* obj,uint8_t toggle,uint8_t high)
mbed_official 85:e1a8e879a6a9 187 {
mbed_official 85:e1a8e879a6a9 188 if(high){
mbed_official 85:e1a8e879a6a9 189 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 85:e1a8e879a6a9 190 if(toggle){
mbed_official 85:e1a8e879a6a9 191 NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 192 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 193 }
mbed_official 85:e1a8e879a6a9 194 else{
mbed_official 85:e1a8e879a6a9 195 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 196 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 197 }
mbed_official 85:e1a8e879a6a9 198 }
mbed_official 85:e1a8e879a6a9 199 else{
mbed_official 85:e1a8e879a6a9 200 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_OUTINIT_High << GPIOTE_CONFIG_OUTINIT_Pos);
mbed_official 85:e1a8e879a6a9 201
mbed_official 85:e1a8e879a6a9 202 if(toggle){
mbed_official 85:e1a8e879a6a9 203 NRF_GPIOTE->CONFIG[obj->pwm] |= (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
mbed_official 85:e1a8e879a6a9 204 ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 205 }
mbed_official 85:e1a8e879a6a9 206 else{
mbed_official 85:e1a8e879a6a9 207 NRF_GPIOTE->CONFIG[obj->pwm] &= ~((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 208 NRF_GPIOTE->CONFIG[obj->pwm] |= ((uint32_t)GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
mbed_official 85:e1a8e879a6a9 209 }
mbed_official 85:e1a8e879a6a9 210 }
mbed_official 85:e1a8e879a6a9 211 }
mbed_official 85:e1a8e879a6a9 212 void pwmout_init(pwmout_t* obj, PinName pin) {
mbed_official 85:e1a8e879a6a9 213 // determine the channel
mbed_official 85:e1a8e879a6a9 214 uint8_t pwmOutSuccess = 0;
mbed_official 85:e1a8e879a6a9 215 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
mbed_official 85:e1a8e879a6a9 216
mbed_official 85:e1a8e879a6a9 217 if (pwm == (PWMName)NC){
mbed_official 85:e1a8e879a6a9 218 error("PwmOut pin mapping failed");
mbed_official 85:e1a8e879a6a9 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 85:e1a8e879a6a9 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 85:e1a8e879a6a9 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 85:e1a8e879a6a9 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 85:e1a8e879a6a9 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 85:e1a8e879a6a9 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 85:e1a8e879a6a9 338 }
mbed_official 85:e1a8e879a6a9 339 }