]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/pwmout_api.c
1 /* mbed Microcontroller Library
2 * Copyright (c) 2006-2013 ARM Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "mbed_assert.h"
17 #include "pwmout_api.h"
21 #include "clk_freqs.h"
22 #include "PeripheralPins.h"
24 static float pwm_clock
;
26 void pwmout_init(pwmout_t
* obj
, PinName pin
) {
27 // determine the channel
28 PWMName pwm
= (PWMName
)pinmap_peripheral(pin
, PinMap_PWM
);
29 MBED_ASSERT(pwm
!= (PWMName
)NC
);
34 #if defined(TARGET_KL43Z)
35 if (mcgirc_frequency()) {
36 SIM
->SOPT2
|= SIM_SOPT2_TPMSRC(3); // Clock source: MCGIRCLK
37 clkval
= mcgirc_frequency() / 1000000.0f
;
39 SIM
->SOPT2
|= SIM_SOPT2_TPMSRC(1); // Clock source: IRC48M
40 clkval
= CPU_INT_IRC_CLK_HZ
/ 1000000.0f
;
43 if (mcgpllfll_frequency()) {
44 SIM
->SOPT2
|= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK
45 clkval
= mcgpllfll_frequency() / 1000000.0f
;
47 SIM
->SOPT2
|= SIM_SOPT2_TPMSRC(2); // Clock source: ExtOsc
48 clkval
= extosc_frequency() / 1000000.0f
;
59 unsigned int port
= (unsigned int)pin
>> PORT_SHIFT
;
60 unsigned int tpm_n
= (pwm
>> TPM_SHIFT
);
61 unsigned int ch_n
= (pwm
& 0xFF);
63 SIM
->SCGC5
|= 1 << (SIM_SCGC5_PORTA_SHIFT
+ port
);
64 SIM
->SCGC6
|= 1 << (SIM_SCGC6_TPM0_SHIFT
+ tpm_n
);
66 TPM_Type
*tpm
= (TPM_Type
*)(TPM0_BASE
+ 0x1000 * tpm_n
);
67 tpm
->SC
= TPM_SC_CMOD(1) | TPM_SC_PS(clkdiv
); // (clock)MHz / clkdiv ~= (0.75)MHz
68 tpm
->CONTROLS
[ch_n
].CnSC
= (TPM_CnSC_MSB_MASK
| TPM_CnSC_ELSB_MASK
); /* No Interrupts; High True pulses on Edge Aligned PWM */
70 obj
->CnV
= &tpm
->CONTROLS
[ch_n
].CnV
;
74 // default to 20ms: standard for servos, and fine for e.g. brightness control
75 pwmout_period_ms(obj
, 20);
76 pwmout_write (obj
, 0);
79 pinmap_pinout(pin
, PinMap_PWM
);
82 void pwmout_free(pwmout_t
* obj
) {}
84 void pwmout_write(pwmout_t
* obj
, float value
) {
87 } else if (value
> 1.0) {
91 *obj
->CnV
= (uint32_t)((float)(*obj
->MOD
+ 1) * value
);
95 float pwmout_read(pwmout_t
* obj
) {
96 float v
= (float)(*obj
->CnV
) / (float)(*obj
->MOD
+ 1);
97 return (v
> 1.0) ? (1.0) : (v
);
100 void pwmout_period(pwmout_t
* obj
, float seconds
) {
101 pwmout_period_us(obj
, seconds
* 1000000.0f
);
104 void pwmout_period_ms(pwmout_t
* obj
, int ms
) {
105 pwmout_period_us(obj
, ms
* 1000);
108 // Set the PWM period, keeping the duty cycle the same.
109 void pwmout_period_us(pwmout_t
* obj
, int us
) {
110 float dc
= pwmout_read(obj
);
111 *obj
->MOD
= (uint32_t)(pwm_clock
* (float)us
) - 1;
112 pwmout_write(obj
, dc
);
115 void pwmout_pulsewidth(pwmout_t
* obj
, float seconds
) {
116 pwmout_pulsewidth_us(obj
, seconds
* 1000000.0f
);
119 void pwmout_pulsewidth_ms(pwmout_t
* obj
, int ms
) {
120 pwmout_pulsewidth_us(obj
, ms
* 1000);
123 void pwmout_pulsewidth_us(pwmout_t
* obj
, int us
) {
124 *obj
->CnV
= (uint32_t)(pwm_clock
* (float)us
);