[11U68]fix P0_11 to use GPIO

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri May 22 10:45:46 2015 +0100
Revision:
548:1abac31e188e
Parent:
544:1af5f1c39e80
Child:
554:edd95c0879f8
Synchronized with git revision 88d158e43b54f97c5e94da305ea9a096889cc81b

Full URL: https://github.com/mbedmicro/mbed/commit/88d158e43b54f97c5e94da305ea9a096889cc81b/

Silicon Labs - Cosmetic: apply mbed coding style to HAL

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 525:c320967f86b9 1 /* mbed Microcontroller Library
mbed_official 525:c320967f86b9 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 525:c320967f86b9 3 *
mbed_official 525:c320967f86b9 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 525:c320967f86b9 5 * you may not use this file except in compliance with the License.
mbed_official 525:c320967f86b9 6 * You may obtain a copy of the License at
mbed_official 525:c320967f86b9 7 *
mbed_official 525:c320967f86b9 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 525:c320967f86b9 9 *
mbed_official 525:c320967f86b9 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 525:c320967f86b9 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 525:c320967f86b9 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 525:c320967f86b9 13 * See the License for the specific language governing permissions and
mbed_official 525:c320967f86b9 14 * limitations under the License.
mbed_official 525:c320967f86b9 15 */
mbed_official 525:c320967f86b9 16
mbed_official 525:c320967f86b9 17 #include "device.h"
mbed_official 525:c320967f86b9 18 #include "clocking.h"
mbed_official 525:c320967f86b9 19 #if DEVICE_PWMOUT
mbed_official 525:c320967f86b9 20
mbed_official 525:c320967f86b9 21 #include "mbed_assert.h"
mbed_official 525:c320967f86b9 22 #include "pwmout_api.h"
mbed_official 525:c320967f86b9 23 #include "cmsis.h"
mbed_official 525:c320967f86b9 24 #include "pinmap.h"
mbed_official 525:c320967f86b9 25 #include "PeripheralPins.h"
mbed_official 525:c320967f86b9 26 #include "device_peripherals.h"
mbed_official 544:1af5f1c39e80 27 #include "sleepmodes.h"
mbed_official 525:c320967f86b9 28
mbed_official 525:c320967f86b9 29 #include "em_cmu.h"
mbed_official 525:c320967f86b9 30 #include "em_gpio.h"
mbed_official 525:c320967f86b9 31 #include "em_timer.h"
mbed_official 525:c320967f86b9 32
mbed_official 544:1af5f1c39e80 33 static int pwm_clockfreq;
mbed_official 544:1af5f1c39e80 34 static int pwm_prescaler_div;
mbed_official 525:c320967f86b9 35
mbed_official 548:1abac31e188e 36 uint32_t pwmout_get_channel_route(pwmout_t *obj)
mbed_official 548:1abac31e188e 37 {
mbed_official 548:1abac31e188e 38 MBED_ASSERT(obj->channel != (PWMName) NC);
mbed_official 525:c320967f86b9 39
mbed_official 548:1abac31e188e 40 switch (obj->channel) {
mbed_official 548:1abac31e188e 41 case PWM_CH0:
mbed_official 548:1abac31e188e 42 return TIMER_ROUTE_CC0PEN;
mbed_official 548:1abac31e188e 43 break;
mbed_official 548:1abac31e188e 44 case PWM_CH1:
mbed_official 548:1abac31e188e 45 return TIMER_ROUTE_CC1PEN;
mbed_official 548:1abac31e188e 46 break;
mbed_official 548:1abac31e188e 47 case PWM_CH2:
mbed_official 548:1abac31e188e 48 return TIMER_ROUTE_CC2PEN;
mbed_official 548:1abac31e188e 49 break;
mbed_official 548:1abac31e188e 50 default:
mbed_official 548:1abac31e188e 51 return 0;
mbed_official 548:1abac31e188e 52 }
mbed_official 525:c320967f86b9 53 }
mbed_official 525:c320967f86b9 54
mbed_official 525:c320967f86b9 55 void pwmout_enable_pins(pwmout_t *obj, uint8_t enable)
mbed_official 525:c320967f86b9 56 {
mbed_official 525:c320967f86b9 57 if (enable) {
mbed_official 525:c320967f86b9 58 pin_mode(obj->pin, PushPull);
mbed_official 525:c320967f86b9 59 } else {
mbed_official 525:c320967f86b9 60 // TODO_LP return PinMode to the previous state
mbed_official 525:c320967f86b9 61 pin_mode(obj->pin, Disabled);
mbed_official 525:c320967f86b9 62 }
mbed_official 525:c320967f86b9 63 }
mbed_official 525:c320967f86b9 64
mbed_official 525:c320967f86b9 65 void pwmout_enable(pwmout_t *obj, uint8_t enable)
mbed_official 525:c320967f86b9 66 {
mbed_official 548:1abac31e188e 67 /* Start with default CC (Compare/Capture) channel parameters */
mbed_official 548:1abac31e188e 68 TIMER_InitCC_TypeDef timerCCInit = TIMER_INITCC_DEFAULT;
mbed_official 525:c320967f86b9 69 if (enable) {
mbed_official 525:c320967f86b9 70 /* Set mode to PWM */
mbed_official 525:c320967f86b9 71 timerCCInit.mode = timerCCModePWM;
mbed_official 544:1af5f1c39e80 72 }
mbed_official 525:c320967f86b9 73
mbed_official 544:1af5f1c39e80 74 /* Configure CC channel */
mbed_official 544:1af5f1c39e80 75 TIMER_InitCC(PWM_TIMER, obj->channel, &timerCCInit);
mbed_official 525:c320967f86b9 76 }
mbed_official 525:c320967f86b9 77
mbed_official 544:1af5f1c39e80 78 void pwmout_init(pwmout_t *obj, PinName pin)
mbed_official 544:1af5f1c39e80 79 {
mbed_official 548:1abac31e188e 80 obj->channel = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
mbed_official 548:1abac31e188e 81 obj->pin = pin;
mbed_official 548:1abac31e188e 82 MBED_ASSERT(obj->channel != (PWMName) NC);
mbed_official 544:1af5f1c39e80 83
mbed_official 548:1abac31e188e 84 /* Turn on clock */
mbed_official 548:1abac31e188e 85 CMU_ClockEnable(PWM_TIMER_CLOCK, true);
mbed_official 544:1af5f1c39e80 86
mbed_official 548:1abac31e188e 87 /* Turn on timer */
mbed_official 548:1abac31e188e 88 if(!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) {
mbed_official 548:1abac31e188e 89 TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
mbed_official 548:1abac31e188e 90 TIMER_Init(PWM_TIMER, &timerInit);
mbed_official 548:1abac31e188e 91 }
mbed_official 544:1af5f1c39e80 92
mbed_official 544:1af5f1c39e80 93 /* Enable correct channel */
mbed_official 548:1abac31e188e 94 uint32_t routeloc = pwmout_get_channel_route(obj);
mbed_official 548:1abac31e188e 95 if(PWM_TIMER->ROUTE & routeloc) {
mbed_official 548:1abac31e188e 96 //This channel was already in use
mbed_official 548:1abac31e188e 97 //TODO: gracefully handle this case
mbed_official 548:1abac31e188e 98 } else {
mbed_official 548:1abac31e188e 99 //This channel was unused up to now
mbed_official 548:1abac31e188e 100 PWM_TIMER->ROUTE |= routeloc;
mbed_official 548:1abac31e188e 101 blockSleepMode(EM1);
mbed_official 544:1af5f1c39e80 102
mbed_official 548:1abac31e188e 103 //TODO: check if any channel was up already, then don't re-init timer
mbed_official 548:1abac31e188e 104 pwmout_enable(obj, true);
mbed_official 548:1abac31e188e 105 pwmout_enable_pins(obj, true);
mbed_official 548:1abac31e188e 106 }
mbed_official 544:1af5f1c39e80 107
mbed_official 544:1af5f1c39e80 108 /* Route correct channel to location 1 */
mbed_official 544:1af5f1c39e80 109 PWM_TIMER->ROUTE &= ~_TIMER_ROUTE_LOCATION_MASK;
mbed_official 544:1af5f1c39e80 110 PWM_TIMER->ROUTE |= PWM_ROUTE;
mbed_official 544:1af5f1c39e80 111
mbed_official 544:1af5f1c39e80 112 /*HFPER is the default clock we will use. It has a frequency of 14MHz*/
mbed_official 544:1af5f1c39e80 113 pwm_clockfreq = REFERENCE_FREQUENCY;
mbed_official 544:1af5f1c39e80 114
mbed_official 544:1af5f1c39e80 115 /* Set default 20ms frequency and 0ms pulse width */
mbed_official 544:1af5f1c39e80 116 pwmout_period(obj, 0.02);
mbed_official 544:1af5f1c39e80 117 }
mbed_official 544:1af5f1c39e80 118
mbed_official 548:1abac31e188e 119 void pwmout_free(pwmout_t *obj)
mbed_official 548:1abac31e188e 120 {
mbed_official 548:1abac31e188e 121 uint32_t routeloc = pwmout_get_channel_route(obj);
mbed_official 548:1abac31e188e 122 if(PWM_TIMER->ROUTE & routeloc) {
mbed_official 548:1abac31e188e 123 //This channel was in use, so disable
mbed_official 548:1abac31e188e 124 PWM_TIMER->ROUTE &= ~routeloc;
mbed_official 548:1abac31e188e 125 pwmout_enable_pins(obj, false);
mbed_official 548:1abac31e188e 126 unblockSleepMode(EM1);
mbed_official 544:1af5f1c39e80 127
mbed_official 548:1abac31e188e 128 //TODO: check if all channels are down, then switch off timer
mbed_official 548:1abac31e188e 129 } else {
mbed_official 548:1abac31e188e 130 //This channel was disabled already
mbed_official 548:1abac31e188e 131 }
mbed_official 544:1af5f1c39e80 132 }
mbed_official 525:c320967f86b9 133
mbed_official 525:c320967f86b9 134 void pwmout_write(pwmout_t *obj, float value)
mbed_official 525:c320967f86b9 135 {
mbed_official 525:c320967f86b9 136 if (value < 0.0f) {
mbed_official 525:c320967f86b9 137 value = 0;
mbed_official 525:c320967f86b9 138 } else if (value > 1.0f) {
mbed_official 525:c320967f86b9 139 value = 1;
mbed_official 525:c320967f86b9 140 }
mbed_official 525:c320967f86b9 141
mbed_official 544:1af5f1c39e80 142 float pulse_period_in_s = obj->period_cycles / (float) pwm_clockfreq;
mbed_official 525:c320967f86b9 143 pwmout_pulsewidth(obj, value * pulse_period_in_s);
mbed_official 525:c320967f86b9 144 }
mbed_official 525:c320967f86b9 145
mbed_official 525:c320967f86b9 146 float pwmout_read(pwmout_t *obj)
mbed_official 525:c320967f86b9 147 {
mbed_official 525:c320967f86b9 148 return obj->width_cycles / (float) obj->period_cycles;
mbed_official 525:c320967f86b9 149 }
mbed_official 525:c320967f86b9 150
mbed_official 525:c320967f86b9 151 // Set the PWM period, keeping the absolute pulse width the same.
mbed_official 525:c320967f86b9 152 void pwmout_period(pwmout_t *obj, float seconds)
mbed_official 525:c320967f86b9 153 {
mbed_official 525:c320967f86b9 154 // Find the lowest prescaler divider possible.
mbed_official 525:c320967f86b9 155 // This gives us max resolution for a given period
mbed_official 525:c320967f86b9 156
mbed_official 525:c320967f86b9 157 //The value of the top register if prescaler is set to 0
mbed_official 544:1af5f1c39e80 158 int cycles = pwm_clockfreq * seconds;
mbed_official 544:1af5f1c39e80 159 pwm_prescaler_div = 0;
mbed_official 525:c320967f86b9 160
mbed_official 525:c320967f86b9 161 //The top register is only 16 bits, so we keep dividing till we are below 0xFFFF
mbed_official 525:c320967f86b9 162 while (cycles > 0xFFFF) {
mbed_official 525:c320967f86b9 163 cycles /= 2;
mbed_official 544:1af5f1c39e80 164 pwm_prescaler_div++;
mbed_official 525:c320967f86b9 165
mbed_official 544:1af5f1c39e80 166 //Max pwm_prescaler_div supported is 10
mbed_official 544:1af5f1c39e80 167 if (pwm_prescaler_div > 10) {
mbed_official 544:1af5f1c39e80 168 pwm_prescaler_div = 10;
mbed_official 525:c320967f86b9 169 cycles = 0xFFFF; //Set it to max possible value;
mbed_official 525:c320967f86b9 170 break;
mbed_official 525:c320967f86b9 171 }
mbed_official 525:c320967f86b9 172 }
mbed_official 525:c320967f86b9 173
mbed_official 525:c320967f86b9 174 obj->period_cycles = cycles;
mbed_official 525:c320967f86b9 175
mbed_official 525:c320967f86b9 176 //Set prescaler
mbed_official 544:1af5f1c39e80 177 PWM_TIMER->CTRL = (PWM_TIMER->CTRL & ~_TIMER_CTRL_PRESC_MASK) | (pwm_prescaler_div << _TIMER_CTRL_PRESC_SHIFT);
mbed_official 525:c320967f86b9 178
mbed_official 525:c320967f86b9 179 /* Set Top Value, which controls the PWM period */
mbed_official 525:c320967f86b9 180 TIMER_TopSet(PWM_TIMER, obj->period_cycles);
mbed_official 525:c320967f86b9 181 }
mbed_official 525:c320967f86b9 182
mbed_official 525:c320967f86b9 183 void pwmout_period_ms(pwmout_t *obj, int ms)
mbed_official 525:c320967f86b9 184 {
mbed_official 525:c320967f86b9 185 pwmout_period(obj, ms / 1000.0f);
mbed_official 525:c320967f86b9 186 }
mbed_official 525:c320967f86b9 187
mbed_official 525:c320967f86b9 188 void pwmout_period_us(pwmout_t *obj, int us)
mbed_official 525:c320967f86b9 189 {
mbed_official 525:c320967f86b9 190 pwmout_period_ms(obj, us / 1000.0f);
mbed_official 525:c320967f86b9 191 }
mbed_official 525:c320967f86b9 192
mbed_official 525:c320967f86b9 193 void pwmout_pulsewidth(pwmout_t *obj, float seconds)
mbed_official 525:c320967f86b9 194 {
mbed_official 544:1af5f1c39e80 195 obj->width_cycles = pwm_clockfreq * seconds;
mbed_official 525:c320967f86b9 196 TIMER_CompareBufSet(PWM_TIMER, obj->channel, obj->width_cycles);
mbed_official 525:c320967f86b9 197 }
mbed_official 525:c320967f86b9 198
mbed_official 525:c320967f86b9 199 void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
mbed_official 525:c320967f86b9 200 {
mbed_official 525:c320967f86b9 201 pwmout_pulsewidth(obj, ms / 1000.0f);
mbed_official 525:c320967f86b9 202 }
mbed_official 525:c320967f86b9 203
mbed_official 525:c320967f86b9 204 void pwmout_pulsewidth_us(pwmout_t *obj, int us)
mbed_official 525:c320967f86b9 205 {
mbed_official 525:c320967f86b9 206 pwmout_pulsewidth_ms(obj, us / 1000.0f);
mbed_official 525:c320967f86b9 207 }
mbed_official 525:c320967f86b9 208
mbed_official 525:c320967f86b9 209 #endif