Timer based PWM output for MAX32630FTHR platform
This library provides PWM output using the MAX32630 32-bit timers.
The mbed PwmOut API implementation uses the MAX32630 Pulse Train peripherals.
The table below contains the available GPIO pins that can be connected to the six 32-bit timers (TMR0-5). Timer 0 is used for the microsecond ticker API and is not available for PWM output. Timer 5 is used by the BLE API and will not be available for PWM output if the BLE API is used.
Timer | GPIO Port and Pin |
TMR1 | P3_1, P5_3 |
TMR2 | P2_4, P3_2, P4_0, P5_4 |
TMR3 | P2_5, P3_3, P5_5 |
TMR4 | P2_6, P3_4, P5_0, P5_6 |
TMR5 | P3_5, P5_1 |
Note GPIO P2_4, P2_5 and P2_6 are connected to onboard LEDs 1, 2 and 3.
Diff: MAX32630FTHR_PwmOut.h
- Revision:
- 0:9df5e4328319
- Child:
- 1:27721b0d390b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX32630FTHR_PwmOut.h Fri Apr 20 16:39:48 2018 +0000 @@ -0,0 +1,266 @@ +/* Original files PwmOut.h and pwmout_api.h contined the following copyright */ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* Original files PwmOut.h and pwmout_api.h combined and modified: + 19 April 2018 Maxim Integrated Products, Inc. + */ + +#ifndef _MAX32630FTHR_PWMOUT_H_ +#define _MAX32630FTHR_PWMOUT_H_ + +#include "mbed.h" +#include "PinNames.h" +#include "platform/mbed_critical.h" +#include "platform/mbed_power_mgmt.h" +#include "tmr_regs.h" + +class MAX32630FTHR_PwmOut +{ +public: + + /** Create a PwmOut connected to the specified pin + * + * @param pin PwmOut pin to connect to + */ + MAX32630FTHR_PwmOut(PinName pin) : _deep_sleep_locked(false) { + core_util_critical_section_enter(); + pwmout_init(pin); + core_util_critical_section_exit(); + } + + ~MAX32630FTHR_PwmOut() { + core_util_critical_section_enter(); + unlock_deep_sleep(); + core_util_critical_section_exit(); + } + + /** Set the ouput duty-cycle, specified as a percentage (float) + * + * @param value A floating-point value representing the output duty-cycle, + * specified as a percentage. The value should lie between + * 0.0f (representing on 0%) and 1.0f (representing on 100%). + * Values outside this range will be saturated to 0.0f or 1.0f. + */ + void write(float value) { + core_util_critical_section_enter(); + lock_deep_sleep(); + pwmout_write(value); + core_util_critical_section_exit(); + } + + /** Return the current output duty-cycle setting, measured as a percentage (float) + * + * @returns + * A floating-point value representing the current duty-cycle being output on the pin, + * measured as a percentage. The returned value will lie between + * 0.0f (representing on 0%) and 1.0f (representing on 100%). + * + * @note + * This value may not match exactly the value set by a previous write(). + */ + float read() { + core_util_critical_section_enter(); + float val = pwmout_read(); + core_util_critical_section_exit(); + return val; + } + + /** Set the PWM period, specified in seconds (float), keeping the duty cycle the same. + * + * @param seconds Change the period of a PWM signal in seconds (float) without modifying the duty cycle + * @note + * The resolution is currently in microseconds; periods smaller than this + * will be set to zero. + */ + void period(float seconds) { + core_util_critical_section_enter(); + pwmout_period(seconds); + core_util_critical_section_exit(); + } + + /** Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same. + * @param ms Change the period of a PWM signal in milli-seconds without modifying the duty cycle + */ + void period_ms(int ms) { + core_util_critical_section_enter(); + pwmout_period_ms(ms); + core_util_critical_section_exit(); + } + + /** Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same. + * @param us Change the period of a PWM signal in micro-seconds without modifying the duty cycle + */ + void period_us(int us) { + core_util_critical_section_enter(); + pwmout_period_us(us); + core_util_critical_section_exit(); + } + + /** Set the PWM pulsewidth, specified in seconds (float), keeping the period the same. + * @param seconds Change the pulse width of a PWM signal specified in seconds (float) + */ + void pulsewidth(float seconds) { + core_util_critical_section_enter(); + pwmout_pulsewidth(seconds); + core_util_critical_section_exit(); + } + + /** Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same. + * @param ms Change the pulse width of a PWM signal specified in milli-seconds + */ + void pulsewidth_ms(int ms) { + core_util_critical_section_enter(); + pwmout_pulsewidth_ms(ms); + core_util_critical_section_exit(); + } + + /** Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same. + * @param us Change the pulse width of a PWM signal specified in micro-seconds + */ + void pulsewidth_us(int us) { + core_util_critical_section_enter(); + pwmout_pulsewidth_us(us); + core_util_critical_section_exit(); + } + + /** A operator shorthand for write() + * \sa PwmOut::write() + */ + MAX32630FTHR_PwmOut& operator= (float value) { + // Underlying call is thread safe + write(value); + return *this; + } + + /** A operator shorthand for write() + * \sa PwmOut::write() + */ + MAX32630FTHR_PwmOut& operator= (PwmOut& rhs) { + // Underlying call is thread safe + write(rhs.read()); + return *this; + } + + /** An operator shorthand for read() + * \sa PwmOut::read() + */ + operator float() { + // Underlying call is thread safe + return read(); + } + +protected: + /** Lock deep sleep only if it is not yet locked */ + void lock_deep_sleep() { + if (_deep_sleep_locked == false) { + sleep_manager_lock_deep_sleep(); + _deep_sleep_locked = true; + } + } + + /** Unlock deep sleep in case it is locked */ + void unlock_deep_sleep() { + if (_deep_sleep_locked == true) { + sleep_manager_unlock_deep_sleep(); + _deep_sleep_locked = false; + } + } + + bool _deep_sleep_locked; + +private: + /** Initialize the pwm out peripheral and configure the pin + * + * @param obj The pwmout object to initialize + * @param pin The pwmout pin to initialize + */ + void pwmout_init(PinName pin); + + /** Deinitialize the pwmout object + * + * @param obj The pwmout object + */ + void pwmout_free(); + + /** Set the output duty-cycle in range <0.0f, 1.0f> + * + * Value 0.0f represents 0 percentage, 1.0f represents 100 percent. + * @param obj The pwmout object + * @param percent The floating-point percentage number + */ + void pwmout_write(float percent); + + /** Read the current float-point output duty-cycle + * + * @param obj The pwmout object + * @return A floating-point output duty-cycle + */ + float pwmout_read(); + + /** Set the PWM period specified in seconds, keeping the duty cycle the same + * + * Periods smaller than microseconds (the lowest resolution) are set to zero. + * @param obj The pwmout object + * @param seconds The floating-point seconds period + */ + void pwmout_period(float seconds); + + /** Set the PWM period specified in miliseconds, keeping the duty cycle the same + * + * @param obj The pwmout object + * @param ms The milisecond period + */ + void pwmout_period_ms(int ms); + + /** Set the PWM period specified in microseconds, keeping the duty cycle the same + * + * @param obj The pwmout object + * @param us The microsecond period + */ + void pwmout_period_us(int us); + + /** Set the PWM pulsewidth specified in seconds, keeping the period the same. + * + * @param obj The pwmout object + * @param seconds The floating-point pulsewidth in seconds + */ + void pwmout_pulsewidth(float seconds); + + /** Set the PWM pulsewidth specified in miliseconds, keeping the period the same. + * + * @param obj The pwmout object + * @param ms The floating-point pulsewidth in miliseconds + */ + void pwmout_pulsewidth_ms(int ms); + + /** Set the PWM pulsewidth specified in microseconds, keeping the period the same. + * + * @param obj The pwmout object + * @param us The floating-point pulsewidth in microseconds + */ + void pwmout_pulsewidth_us(int us); + + + PinName pin; + mxc_tmr_regs_t *tmr; + int tmr_idx; + int pwm_period; + int pulse_width; + int last_pulse_width; + void pwmout_update(void); +}; + +#endif