mbed SDK library sources

Fork of mbed-src by mbed official

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:
Mon Oct 07 09:15:08 2013 +0100
Revision:
33:e214068ab66c
Parent:
31:42176bc3c368
Synchronized with git revision 53edc82f7373bbfa01a161700524765f52fdb444

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 31:42176bc3c368 1 /* mbed Microcontroller Library
mbed_official 31:42176bc3c368 2 * Copyright (c) 2006-2013 ARM Limited
mbed_official 31:42176bc3c368 3 *
mbed_official 31:42176bc3c368 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 31:42176bc3c368 5 * you may not use this file except in compliance with the License.
mbed_official 31:42176bc3c368 6 * You may obtain a copy of the License at
mbed_official 31:42176bc3c368 7 *
mbed_official 31:42176bc3c368 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 31:42176bc3c368 9 *
mbed_official 31:42176bc3c368 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 31:42176bc3c368 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 31:42176bc3c368 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 31:42176bc3c368 13 * See the License for the specific language governing permissions and
mbed_official 31:42176bc3c368 14 * limitations under the License.
mbed_official 31:42176bc3c368 15 */
mbed_official 31:42176bc3c368 16 #include "pwmout_api.h"
mbed_official 31:42176bc3c368 17
mbed_official 31:42176bc3c368 18 #include "cmsis.h"
mbed_official 31:42176bc3c368 19 #include "pinmap.h"
mbed_official 31:42176bc3c368 20 #include "error.h"
mbed_official 31:42176bc3c368 21
mbed_official 31:42176bc3c368 22 static const PinMap PinMap_PWM[] = {
mbed_official 33:e214068ab66c 23 // LEDs - only RED pin is PWM capable
mbed_official 33:e214068ab66c 24 {LED_RED, PWM_3, 3}, // PTE29, TPM0 CH2
mbed_official 31:42176bc3c368 25
mbed_official 31:42176bc3c368 26 // Arduino digital pinout
mbed_official 31:42176bc3c368 27 {D0, PWM_9 , 3}, // PTA1 , TPM2 CH0
mbed_official 31:42176bc3c368 28 {D1, PWM_10, 3}, // PTA2 , TPM2 CH1
mbed_official 33:e214068ab66c 29 {D2, PWM_4 , 4}, // PTD3 , TPM0 CH3
mbed_official 31:42176bc3c368 30 {D3, PWM_7 , 3}, // PTA12, TPM1 CH0
mbed_official 31:42176bc3c368 31 {D4, PWM_2 , 3}, // PTA4 , TPM0 CH1
mbed_official 31:42176bc3c368 32 {D5, PWM_3 , 3}, // PTA5 , TPM0 CH2
mbed_official 31:42176bc3c368 33 {D6, PWM_5 , 3}, // PTC8 , TPM0 CH4
mbed_official 31:42176bc3c368 34 {D7, PWM_6 , 3}, // PTC9 , TPM0 CH5
mbed_official 31:42176bc3c368 35 {D8, PWM_8 , 3}, // PTA13, TPM1 CH1
mbed_official 33:e214068ab66c 36 {D9, PWM_3 , 4}, // PTD2 , TPM0 CH2
mbed_official 33:e214068ab66c 37 {D10, PWM_5 , 4}, // PTD4 , TPM0 CH4
mbed_official 33:e214068ab66c 38 //PWM on D11 not available
mbed_official 33:e214068ab66c 39 //PWM on D12 not available
mbed_official 33:e214068ab66c 40 {D13, PWM_2 , 4}, // PTD5 , TPM0 CH1,
mbed_official 31:42176bc3c368 41
mbed_official 31:42176bc3c368 42 {PTA0, PWM_6, 3},
mbed_official 31:42176bc3c368 43 {PTA3, PWM_1, 3},
mbed_official 33:e214068ab66c 44 {PTA6, PWM_4, 3},
mbed_official 33:e214068ab66c 45 {PTA7, PWM_5, 3},
mbed_official 31:42176bc3c368 46 {PTB0, PWM_7, 3},
mbed_official 31:42176bc3c368 47 {PTB1, PWM_8, 3},
mbed_official 31:42176bc3c368 48 {PTB2, PWM_9, 3},
mbed_official 31:42176bc3c368 49 {PTB3, PWM_10, 3},
mbed_official 31:42176bc3c368 50 {PTC1, PWM_1, 4},
mbed_official 31:42176bc3c368 51 {PTC2, PWM_2, 4},
mbed_official 31:42176bc3c368 52 {PTC3, PWM_3, 4},
mbed_official 31:42176bc3c368 53 {PTC4, PWM_4, 4},
mbed_official 31:42176bc3c368 54 {PTE20, PWM_7, 3},
mbed_official 31:42176bc3c368 55 {PTE21, PWM_8, 3},
mbed_official 31:42176bc3c368 56 {PTE22, PWM_9, 3},
mbed_official 31:42176bc3c368 57 {PTE23, PWM_10, 3},
mbed_official 31:42176bc3c368 58 {PTE24, PWM_1, 3},
mbed_official 31:42176bc3c368 59 {PTE25, PWM_2, 3},
mbed_official 33:e214068ab66c 60 {PTE26, PWM_6, 3},
mbed_official 31:42176bc3c368 61 {PTE29, PWM_3, 3},
mbed_official 31:42176bc3c368 62 {PTE30, PWM_4, 3},
mbed_official 31:42176bc3c368 63 {PTE31, PWM_5, 3},
mbed_official 31:42176bc3c368 64
mbed_official 31:42176bc3c368 65 {NC , NC , 0}
mbed_official 31:42176bc3c368 66 };
mbed_official 31:42176bc3c368 67
mbed_official 31:42176bc3c368 68 #define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz
mbed_official 31:42176bc3c368 69
mbed_official 31:42176bc3c368 70 void pwmout_init(pwmout_t* obj, PinName pin) {
mbed_official 31:42176bc3c368 71 // determine the channel
mbed_official 31:42176bc3c368 72 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
mbed_official 31:42176bc3c368 73 if (pwm == (PWMName)NC)
mbed_official 31:42176bc3c368 74 error("PwmOut pin mapping failed");
mbed_official 31:42176bc3c368 75
mbed_official 31:42176bc3c368 76 unsigned int port = (unsigned int)pin >> PORT_SHIFT;
mbed_official 31:42176bc3c368 77 unsigned int tpm_n = (pwm >> TPM_SHIFT);
mbed_official 31:42176bc3c368 78 unsigned int ch_n = (pwm & 0xFF);
mbed_official 31:42176bc3c368 79
mbed_official 31:42176bc3c368 80 SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
mbed_official 31:42176bc3c368 81 SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n);
mbed_official 31:42176bc3c368 82 SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
mbed_official 31:42176bc3c368 83
mbed_official 31:42176bc3c368 84 TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n);
mbed_official 31:42176bc3c368 85 tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz
mbed_official 31:42176bc3c368 86 tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */
mbed_official 31:42176bc3c368 87
mbed_official 31:42176bc3c368 88 obj->CnV = &tpm->CONTROLS[ch_n].CnV;
mbed_official 31:42176bc3c368 89 obj->MOD = &tpm->MOD;
mbed_official 31:42176bc3c368 90 obj->CNT = &tpm->CNT;
mbed_official 31:42176bc3c368 91
mbed_official 31:42176bc3c368 92 // default to 20ms: standard for servos, and fine for e.g. brightness control
mbed_official 31:42176bc3c368 93 pwmout_period_ms(obj, 20);
mbed_official 31:42176bc3c368 94 pwmout_write (obj, 0);
mbed_official 31:42176bc3c368 95
mbed_official 31:42176bc3c368 96 // Wire pinout
mbed_official 31:42176bc3c368 97 pinmap_pinout(pin, PinMap_PWM);
mbed_official 31:42176bc3c368 98 }
mbed_official 31:42176bc3c368 99
mbed_official 31:42176bc3c368 100 void pwmout_free(pwmout_t* obj) {}
mbed_official 31:42176bc3c368 101
mbed_official 31:42176bc3c368 102 void pwmout_write(pwmout_t* obj, float value) {
mbed_official 31:42176bc3c368 103 if (value < 0.0) {
mbed_official 31:42176bc3c368 104 value = 0.0;
mbed_official 31:42176bc3c368 105 } else if (value > 1.0) {
mbed_official 31:42176bc3c368 106 value = 1.0;
mbed_official 31:42176bc3c368 107 }
mbed_official 31:42176bc3c368 108
mbed_official 31:42176bc3c368 109 *obj->CnV = (uint32_t)((float)(*obj->MOD) * value);
mbed_official 31:42176bc3c368 110 *obj->CNT = 0;
mbed_official 31:42176bc3c368 111 }
mbed_official 31:42176bc3c368 112
mbed_official 31:42176bc3c368 113 float pwmout_read(pwmout_t* obj) {
mbed_official 31:42176bc3c368 114 float v = (float)(*obj->CnV) / (float)(*obj->MOD);
mbed_official 31:42176bc3c368 115 return (v > 1.0) ? (1.0) : (v);
mbed_official 31:42176bc3c368 116 }
mbed_official 31:42176bc3c368 117
mbed_official 31:42176bc3c368 118 void pwmout_period(pwmout_t* obj, float seconds) {
mbed_official 31:42176bc3c368 119 pwmout_period_us(obj, seconds * 1000000.0f);
mbed_official 31:42176bc3c368 120 }
mbed_official 31:42176bc3c368 121
mbed_official 31:42176bc3c368 122 void pwmout_period_ms(pwmout_t* obj, int ms) {
mbed_official 31:42176bc3c368 123 pwmout_period_us(obj, ms * 1000);
mbed_official 31:42176bc3c368 124 }
mbed_official 31:42176bc3c368 125
mbed_official 31:42176bc3c368 126 // Set the PWM period, keeping the duty cycle the same.
mbed_official 31:42176bc3c368 127 void pwmout_period_us(pwmout_t* obj, int us) {
mbed_official 31:42176bc3c368 128 float dc = pwmout_read(obj);
mbed_official 31:42176bc3c368 129 *obj->MOD = PWM_CLOCK_MHZ * us;
mbed_official 31:42176bc3c368 130 pwmout_write(obj, dc);
mbed_official 31:42176bc3c368 131 }
mbed_official 31:42176bc3c368 132
mbed_official 31:42176bc3c368 133 void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
mbed_official 31:42176bc3c368 134 pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
mbed_official 31:42176bc3c368 135 }
mbed_official 31:42176bc3c368 136
mbed_official 31:42176bc3c368 137 void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
mbed_official 31:42176bc3c368 138 pwmout_pulsewidth_us(obj, ms * 1000);
mbed_official 31:42176bc3c368 139 }
mbed_official 31:42176bc3c368 140
mbed_official 31:42176bc3c368 141 void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
mbed_official 31:42176bc3c368 142 *obj->CnV = PWM_CLOCK_MHZ * us;
mbed_official 31:42176bc3c368 143 }