mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

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 }