mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #13492 from talorion/fix-PwmOut-resets-after-suspend
Fix pwm out resets after suspendpull/13587/head
commit
468372e759
|
|
@ -51,6 +51,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
{
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
}
|
||||
|
|
@ -63,4 +68,9 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
{
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // DEVICE_PWMOUT
|
||||
|
|
|
|||
|
|
@ -110,6 +110,12 @@ public:
|
|||
*/
|
||||
void period_us(int us);
|
||||
|
||||
/** Read the PWM period
|
||||
* @returns
|
||||
* The PWM period, specified in microseconds (int)
|
||||
*/
|
||||
int read_period_us();
|
||||
|
||||
/** 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)
|
||||
*/
|
||||
|
|
@ -125,6 +131,12 @@ public:
|
|||
*/
|
||||
void pulsewidth_us(int us);
|
||||
|
||||
/** Read the PWM pulsewidth
|
||||
* @returns
|
||||
* The PWM pulsewith, specified in microseconds (int)
|
||||
*/
|
||||
int read_pulsewitdth_us();
|
||||
|
||||
/** Suspend PWM operation
|
||||
*
|
||||
* Control the PWM state. This is primarily intended
|
||||
|
|
@ -191,6 +203,7 @@ protected:
|
|||
bool _deep_sleep_locked;
|
||||
bool _initialized;
|
||||
float _duty_cycle;
|
||||
int _period_us;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ PwmOut::PwmOut(PinName pin) :
|
|||
_pin(pin),
|
||||
_deep_sleep_locked(false),
|
||||
_initialized(false),
|
||||
_duty_cycle(0)
|
||||
_duty_cycle(0),
|
||||
_period_us(0)
|
||||
{
|
||||
PwmOut::init();
|
||||
}
|
||||
|
|
@ -83,6 +84,14 @@ void PwmOut::period_us(int us)
|
|||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
int PwmOut::read_period_us()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
auto val = pwmout_read_period_us(&_pwm);
|
||||
core_util_critical_section_exit();
|
||||
return val;
|
||||
}
|
||||
|
||||
void PwmOut::pulsewidth(float seconds)
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
|
|
@ -104,11 +113,20 @@ void PwmOut::pulsewidth_us(int us)
|
|||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
int PwmOut::read_pulsewitdth_us()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
auto val = pwmout_read_pulsewidth_us(&_pwm);
|
||||
core_util_critical_section_exit();
|
||||
return val;
|
||||
}
|
||||
|
||||
void PwmOut::suspend()
|
||||
{
|
||||
core_util_critical_section_enter();
|
||||
if (_initialized) {
|
||||
_duty_cycle = PwmOut::read();
|
||||
_period_us = PwmOut::read_period_us();
|
||||
PwmOut::deinit();
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
|
|
@ -120,6 +138,7 @@ void PwmOut::resume()
|
|||
if (!_initialized) {
|
||||
PwmOut::init();
|
||||
PwmOut::write(_duty_cycle);
|
||||
PwmOut::period_us(_period_us);
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,11 @@ typedef struct pwmout_s pwmout_t;
|
|||
* * ::pwmout_period sets the PWM period specified in seconds, keeping the duty cycle the same
|
||||
* * ::pwmout_period_ms sets the PWM period specified in miliseconds, keeping the duty cycle the same
|
||||
* * ::pwmout_period_us sets the PWM period specified in microseconds, keeping the duty cycle the same
|
||||
* * ::pwmout_read_period_us reads the PWM period specified in microseconds
|
||||
* * ::pwmout_pulsewidth sets the PWM pulsewidth specified in seconds, keeping the period the same
|
||||
* * ::pwmout_pulsewidth_ms sets the PWM pulsewidth specified in miliseconds, keeping the period the same
|
||||
* * ::pwmout_pulsewidth_us sets the PWM pulsewidth specified in microseconds, keeping the period the same
|
||||
* * ::pwmout_read_pulsewidth_us read the PWM pulsewidth specified in microseconds
|
||||
* * The accuracy of the PWM is +/- 10%
|
||||
* * The PWM operations ::pwmout_write, ::pwmout_read, ::pwmout_read, ::pwmout_period_ms, ::pwmout_period_us
|
||||
* ::pwmout_pulsewidth, ::pwmout_pulsewidth_ms, ::pwmout_pulsewidth_us take less than 20us to complete
|
||||
|
|
@ -125,6 +127,13 @@ void pwmout_period_ms(pwmout_t *obj, int ms);
|
|||
*/
|
||||
void pwmout_period_us(pwmout_t *obj, int us);
|
||||
|
||||
/** Read the PWM period specified in microseconds
|
||||
*
|
||||
* @param obj The pwmout object
|
||||
* @return A int output period
|
||||
*/
|
||||
int pwmout_read_period_us(pwmout_t *obj);
|
||||
|
||||
/** Set the PWM pulsewidth specified in seconds, keeping the period the same.
|
||||
*
|
||||
* @param obj The pwmout object
|
||||
|
|
@ -146,6 +155,13 @@ void pwmout_pulsewidth_ms(pwmout_t *obj, int ms);
|
|||
*/
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us);
|
||||
|
||||
/** Read the PWM pulsewidth specified in microseconds
|
||||
*
|
||||
* @param obj The pwmout object
|
||||
* @return A int output pulsewitdth
|
||||
*/
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj);
|
||||
|
||||
/** Get the pins that support PWM
|
||||
*
|
||||
* Return a PinMap array of pins that support PWM.
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
}
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * CY_US_PER_SECOND));
|
||||
|
|
@ -92,6 +97,11 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
}
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->width_us;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap(void)
|
||||
{
|
||||
return PinMap_PWM_OUT;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@
|
|||
|
||||
static float pwm_clock = 0;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -36,8 +37,9 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
while (clkval > 1) {
|
||||
clkdiv++;
|
||||
clkval /= 2.0;
|
||||
if (clkdiv == 7)
|
||||
if (clkdiv == 7) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pwm_clock = clkval;
|
||||
|
|
@ -53,7 +55,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
ftm->MODE = FTM_MODE_FTMEN_MASK;
|
||||
ftm->SYNC = FTM_SYNC_CNTMIN_MASK;
|
||||
ftm->SYNCONF = FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWWRBUF_MASK;
|
||||
|
||||
|
||||
//Without SYNCEN set CnV does not seem to update
|
||||
ftm->COMBINE = FTM_COMBINE_SYNCEN0_MASK | FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_SYNCEN2_MASK | FTM_COMBINE_SYNCEN3_MASK;
|
||||
|
||||
|
|
@ -64,60 +66,86 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write(obj, 0.0);
|
||||
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {}
|
||||
void pwmout_free(pwmout_t *obj) {}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0) {
|
||||
value = 1.0;
|
||||
}
|
||||
|
||||
while(*obj->SYNC & FTM_SYNC_SWSYNC_MASK);
|
||||
|
||||
while (*obj->SYNC & FTM_SYNC_SWSYNC_MASK);
|
||||
*obj->CnV = (uint32_t)((float)(*obj->MOD + 1) * value);
|
||||
*obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
|
||||
*obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
while(*obj->SYNC & FTM_SYNC_SWSYNC_MASK);
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
while (*obj->SYNC & FTM_SYNC_SWSYNC_MASK);
|
||||
float v = (float)(*obj->CnV) / (float)(*obj->MOD + 1);
|
||||
return (v > 1.0) ? (1.0) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
float dc = pwmout_read(obj);
|
||||
*obj->MOD = (uint32_t)(pwm_clock * (float)us) - 1;
|
||||
*obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
|
||||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock > 0) {
|
||||
pwm_period = ((*obj->MOD) + 1) / pwm_clock;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
*obj->CnV = (uint32_t)(pwm_clock * (float)us);
|
||||
*obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock > 0) {
|
||||
pwm_pulsewidth = (*obj->CnV) / pwm_clock;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@
|
|||
|
||||
static float pwm_clock;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -51,10 +52,11 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
while (clkval > 1) {
|
||||
clkdiv++;
|
||||
clkval /= 2.0;
|
||||
if (clkdiv == 7)
|
||||
if (clkdiv == 7) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pwm_clock = clkval;
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
unsigned int tpm_n = (pwm >> TPM_SHIFT);
|
||||
|
|
@ -73,15 +75,16 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {}
|
||||
void pwmout_free(pwmout_t *obj) {}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0) {
|
||||
|
|
@ -92,38 +95,63 @@ void pwmout_write(pwmout_t* obj, float value) {
|
|||
*obj->CNT = 0;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
float v = (float)(*obj->CnV) / (float)(*obj->MOD + 1);
|
||||
return (v > 1.0) ? (1.0) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
float dc = pwmout_read(obj);
|
||||
*obj->MOD = (uint32_t)(pwm_clock * (float)us) - 1;
|
||||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock > 0) {
|
||||
pwm_period = ((*obj->MOD) + 1) / pwm_clock;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
*obj->CnV = (uint32_t)(pwm_clock * (float)us);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock > 0) {
|
||||
pwm_pulsewidth = (*obj->CnV) / pwm_clock;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static float pwm_clock_mhz;
|
|||
/* Array of FTM peripheral base address. */
|
||||
static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -73,12 +73,12 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]);
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -96,30 +96,31 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK;
|
||||
uint16_t mod = base->MOD & FTM_MOD_MOD_MASK;
|
||||
|
||||
if (mod == 0)
|
||||
if (mod == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
float v = (float)(count) / (float)(mod);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
float dc = pwmout_read(obj);
|
||||
|
|
@ -129,17 +130,27 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
|
@ -150,6 +161,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static float pwm_clock_mhz;
|
|||
/* Array of FTM peripheral base address. */
|
||||
static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -73,12 +73,12 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]);
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -96,30 +96,31 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK;
|
||||
uint16_t mod = base->MOD & FTM_MOD_MOD_MASK;
|
||||
|
||||
if (mod == 0)
|
||||
if (mod == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
float v = (float)(count) / (float)(mod);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
float dc = pwmout_read(obj);
|
||||
|
|
@ -129,17 +130,27 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
|
@ -150,6 +161,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static float pwm_clock_mhz;
|
|||
/* Array of TPM peripheral base address. */
|
||||
static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -72,12 +72,12 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]);
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -93,30 +93,31 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
base->CNT = 0;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK;
|
||||
uint16_t mod = base->MOD & TPM_MOD_MOD_MASK;
|
||||
|
||||
if (mod == 0)
|
||||
if (mod == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
float v = (float)(count) / (float)(mod);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
float dc = pwmout_read(obj);
|
||||
|
|
@ -126,17 +127,27 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
|
@ -145,6 +156,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
base->CONTROLS[obj->pwm_name & 0xF].CnV = value;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static float pwm_clock_mhz;
|
|||
/* Array of TPM peripheral base address. */
|
||||
static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -72,12 +72,12 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]);
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -93,30 +93,31 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
base->CNT = 0;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK;
|
||||
uint16_t mod = base->MOD & TPM_MOD_MOD_MASK;
|
||||
|
||||
if (mod == 0)
|
||||
if (mod == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
float v = (float)(count) / (float)(mod);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
float dc = pwmout_read(obj);
|
||||
|
|
@ -126,17 +127,27 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
|
@ -145,6 +156,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
base->CONTROLS[obj->pwm_name & 0xF].CnV = value;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static float pwm_clock_mhz;
|
|||
/* Array of TPM peripheral base address. */
|
||||
static TPM_Type *const tpm_addrs[] = TPM_BASE_PTRS;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -72,12 +72,12 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
TPM_Deinit(tpm_addrs[obj->pwm_name >> TPM_SHIFT]);
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -93,30 +93,31 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
base->CNT = 0;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & TPM_CnV_VAL_MASK;
|
||||
uint16_t mod = base->MOD & TPM_MOD_MOD_MASK;
|
||||
|
||||
if (mod == 0)
|
||||
if (mod == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
float v = (float)(count) / (float)(mod);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
float dc = pwmout_read(obj);
|
||||
|
|
@ -126,17 +127,27 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
|
@ -145,6 +156,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
base->CONTROLS[obj->pwm_name & 0xF].CnV = value;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
TPM_Type *base = tpm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ static float pwm_clock_mhz;
|
|||
/* Array of FTM peripheral base address. */
|
||||
static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -73,12 +73,12 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
FTM_Deinit(ftm_addrs[obj->pwm_name >> TPM_SHIFT]);
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -96,30 +96,31 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t count = (base->CONTROLS[obj->pwm_name & 0xF].CnV) & FTM_CnV_VAL_MASK;
|
||||
uint16_t mod = base->MOD & FTM_MOD_MOD_MASK;
|
||||
|
||||
if (mod == 0)
|
||||
if (mod == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
float v = (float)(count) / (float)(mod);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
float dc = pwmout_read(obj);
|
||||
|
|
@ -129,17 +130,27 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];;
|
||||
pwm_period = ((base->MOD) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
|
@ -150,6 +161,16 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -158,6 +158,17 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_period = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
uint16_t mod = base->MOD & FTM_MOD_MOD_MASK;
|
||||
pwm_period = ((mod) + 1) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
|
|
@ -179,6 +190,16 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
FTM_SetSoftwareTrigger(base, true);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t pwm_pulsewidth = 0;
|
||||
if (pwm_clock_mhz > 0) {
|
||||
FTM_Type *base = ftm_addrs[obj->pwm_name >> TPM_SHIFT];
|
||||
pwm_pulsewidth = (base->CONTROLS[obj->pwm_name & 0xF].CnV) / pwm_clock_mhz;
|
||||
}
|
||||
return pwm_pulsewidth;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -249,6 +249,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
timer_enable(obj->pwm);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return TIMER_CAR(obj->pwm);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
|
|
@ -298,6 +303,34 @@ static uint32_t timer_get_clock(uint32_t timer_periph)
|
|||
return timerclk;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint16_t pulse = 0;
|
||||
|
||||
switch (obj->ch) {
|
||||
case TIMER_CH_0:
|
||||
pulse = TIMER_CH0CV(obj->pwm);
|
||||
break;
|
||||
|
||||
case TIMER_CH_1:
|
||||
pulse = TIMER_CH1CV(obj->pwm);
|
||||
break;
|
||||
|
||||
case TIMER_CH_2:
|
||||
pulse = TIMER_CH2CV(obj->pwm);
|
||||
break;
|
||||
|
||||
case TIMER_CH_3:
|
||||
pulse = TIMER_CH3CV(obj->pwm);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Error: pwm channel error! \r\n");
|
||||
}
|
||||
|
||||
return pulse;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -194,6 +194,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
timer_enable(obj->pwm);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return TIMER_CAR(obj->pwm);
|
||||
}
|
||||
|
||||
/** Set the PWM pulsewidth specified in seconds, keeping the period the same.
|
||||
*
|
||||
* @param obj The pwmout object
|
||||
|
|
@ -234,6 +239,34 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
timer_channel_output_pulse_value_config(obj->pwm, obj->ch, pulse);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint16_t pulse = 0;
|
||||
|
||||
switch (obj->ch) {
|
||||
case TIMER_CH_0:
|
||||
pulse = TIMER_CH0CV(obj->pwm);
|
||||
break;
|
||||
|
||||
case TIMER_CH_1:
|
||||
pulse = TIMER_CH1CV(obj->pwm);
|
||||
break;
|
||||
|
||||
case TIMER_CH_2:
|
||||
pulse = TIMER_CH2CV(obj->pwm);
|
||||
break;
|
||||
|
||||
case TIMER_CH_3:
|
||||
pulse = TIMER_CH3CV(obj->pwm);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Error: pwm channel error! \r\n");
|
||||
}
|
||||
|
||||
return pulse;
|
||||
}
|
||||
|
||||
static uint32_t timer_get_clock(uint32_t timer_periph)
|
||||
{
|
||||
uint32_t timerclk;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "PeripheralPins.h"
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// Make sure the pin is free for GPIO use
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
|
@ -51,20 +51,20 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
PinMap pwm = PinMap_PWM[0];
|
||||
|
||||
// Check if there is a pulse train already active on this port
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4);
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin * 4))) >> (port_pin * 4);
|
||||
MBED_ASSERT((pin_func < 1) || (pin_func > 3));
|
||||
|
||||
// Search through PinMap_PWM to find the pin
|
||||
while(pwm.pin != pin) {
|
||||
while (pwm.pin != pin) {
|
||||
pwm = PinMap_PWM[++i];
|
||||
}
|
||||
|
||||
// Find a free PT instance on this pin
|
||||
while(pwm.pin == pin) {
|
||||
while (pwm.pin == pin) {
|
||||
|
||||
// Check to see if this PT instance is free
|
||||
if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
if ((((mxc_pt_regs_t *)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -78,10 +78,10 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
obj->pwm = (mxc_pt_regs_t *)pwm.peripheral;
|
||||
|
||||
// Initialize object period and pulse width
|
||||
obj->period = -1;
|
||||
obj->period = -1;
|
||||
obj->pulse_width = -1;
|
||||
|
||||
// Disable the output
|
||||
|
|
@ -94,17 +94,17 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin * 4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin * 4)));
|
||||
|
||||
// Enable the global pwm
|
||||
MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// Set the registers to the reset value
|
||||
obj->pwm->train = 0;
|
||||
|
|
@ -112,39 +112,39 @@ void pwmout_free(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
static void pwmout_update(pwmout_t* obj)
|
||||
static void pwmout_update(pwmout_t *obj)
|
||||
{
|
||||
// Calculate and set the divider ratio
|
||||
int div = (obj->period * (SystemCoreClock/1000000))/32;
|
||||
if (div < 2){
|
||||
int div = (obj->period * (SystemCoreClock / 1000000)) / 32;
|
||||
if (div < 2) {
|
||||
div = 2;
|
||||
}
|
||||
MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div);
|
||||
|
||||
// Change the duty cycle to adjust the pulse width
|
||||
obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period)));
|
||||
obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period)));
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_write(pwmout_t* obj, float percent)
|
||||
void pwmout_write(pwmout_t *obj, float percent)
|
||||
{
|
||||
// Saturate percent if outside of range
|
||||
if(percent < 0.0) {
|
||||
if (percent < 0.0) {
|
||||
percent = 0.0;
|
||||
} else if(percent > 1.0) {
|
||||
} else if (percent > 1.0) {
|
||||
percent = 1.0;
|
||||
}
|
||||
|
||||
// Resize the pulse width to set the duty cycle
|
||||
pwmout_pulsewidth_us(obj, (int)(percent*obj->period));
|
||||
pwmout_pulsewidth_us(obj, (int)(percent * obj->period));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
// Check for when pulsewidth or period equals 0
|
||||
if((obj->pulse_width == 0) || (obj->period == 0)){
|
||||
if ((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -153,26 +153,26 @@ float pwmout_read(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, (int)(seconds * 1000000.0));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms*1000);
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the period
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32)));
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
||||
// Set pulse width to half the period if uninitialized
|
||||
if(obj->pulse_width == -1){
|
||||
obj->pulse_width = us/2;
|
||||
if (obj->pulse_width == -1) {
|
||||
obj->pulse_width = us / 2;
|
||||
}
|
||||
|
||||
// Save the period
|
||||
|
|
@ -183,26 +183,32 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms*1000);
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the pulsewidth
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32)));
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
||||
// Initialize period to double the pulsewidth if uninitialized
|
||||
if(obj->period == -1){
|
||||
obj->period = 2*us;
|
||||
if (obj->period == -1) {
|
||||
obj->period = 2 * us;
|
||||
}
|
||||
|
||||
// Save the pulsewidth
|
||||
|
|
@ -212,6 +218,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_update(obj);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulse_width;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "PeripheralPins.h"
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// Make sure the pin is free for GPIO use
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
|
@ -51,20 +51,20 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
PinMap pwm = PinMap_PWM[0];
|
||||
|
||||
// Check if there is a pulse train already active on this port
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4);
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin * 4))) >> (port_pin * 4);
|
||||
MBED_ASSERT((pin_func < 1) || (pin_func > 3));
|
||||
|
||||
// Search through PinMap_PWM to find the pin
|
||||
while(pwm.pin != pin) {
|
||||
while (pwm.pin != pin) {
|
||||
pwm = PinMap_PWM[++i];
|
||||
}
|
||||
|
||||
// Find a free PT instance on this pin
|
||||
while(pwm.pin == pin) {
|
||||
while (pwm.pin == pin) {
|
||||
|
||||
// Check to see if this PT instance is free
|
||||
if((((mxc_pt_regs_t*)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
if ((((mxc_pt_regs_t *)pwm.peripheral)->rate_length &
|
||||
MXC_F_PT_RATE_LENGTH_MODE)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -78,10 +78,10 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MXC_CLKMAN->clk_ctrl_2_pt = MXC_E_CLKMAN_CLK_SCALE_ENABLED;
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
obj->pwm = (mxc_pt_regs_t *)pwm.peripheral;
|
||||
|
||||
// Initialize object period and pulse width
|
||||
obj->period = -1;
|
||||
obj->period = -1;
|
||||
obj->pulse_width = -1;
|
||||
|
||||
// Disable the output
|
||||
|
|
@ -94,17 +94,17 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin*4)));
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin * 4)), (MXC_V_GPIO_OUT_MODE_NORMAL_DRIVE << (port_pin * 4)));
|
||||
|
||||
// Enable the global pwm
|
||||
MXC_PTG->ctrl = MXC_F_PT_CTRL_ENABLE_ALL;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// Set the registers to the reset value
|
||||
obj->pwm->train = 0;
|
||||
|
|
@ -112,39 +112,39 @@ void pwmout_free(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
static void pwmout_update(pwmout_t* obj)
|
||||
static void pwmout_update(pwmout_t *obj)
|
||||
{
|
||||
// Calculate and set the divider ratio
|
||||
int div = (obj->period * (SystemCoreClock/1000000))/32;
|
||||
if (div < 2){
|
||||
int div = (obj->period * (SystemCoreClock / 1000000)) / 32;
|
||||
if (div < 2) {
|
||||
div = 2;
|
||||
}
|
||||
MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div);
|
||||
|
||||
// Change the duty cycle to adjust the pulse width
|
||||
obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period)));
|
||||
obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period)));
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_write(pwmout_t* obj, float percent)
|
||||
void pwmout_write(pwmout_t *obj, float percent)
|
||||
{
|
||||
// Saturate percent if outside of range
|
||||
if(percent < 0.0) {
|
||||
if (percent < 0.0) {
|
||||
percent = 0.0;
|
||||
} else if(percent > 1.0) {
|
||||
} else if (percent > 1.0) {
|
||||
percent = 1.0;
|
||||
}
|
||||
|
||||
// Resize the pulse width to set the duty cycle
|
||||
pwmout_pulsewidth_us(obj, (int)(percent*obj->period));
|
||||
pwmout_pulsewidth_us(obj, (int)(percent * obj->period));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
// Check for when pulsewidth or period equals 0
|
||||
if((obj->pulse_width == 0) || (obj->period == 0)){
|
||||
if ((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -153,26 +153,26 @@ float pwmout_read(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, (int)(seconds * 1000000.0));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms*1000);
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the period
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32)));
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
||||
// Set pulse width to half the period if uninitialized
|
||||
if(obj->pulse_width == -1){
|
||||
obj->pulse_width = us/2;
|
||||
if (obj->pulse_width == -1) {
|
||||
obj->pulse_width = us / 2;
|
||||
}
|
||||
|
||||
// Save the period
|
||||
|
|
@ -183,26 +183,32 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms*1000);
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the pulsewidth
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32)));
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
||||
// Initialize period to double the pulsewidth if uninitialized
|
||||
if(obj->period == -1){
|
||||
obj->period = 2*us;
|
||||
if (obj->period == -1) {
|
||||
obj->period = 2 * us;
|
||||
}
|
||||
|
||||
// Save the pulsewidth
|
||||
|
|
@ -212,6 +218,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_update(obj);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulse_width;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
#include "PeripheralPins.h"
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// Make sure the pin is free for GPIO use
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
|
@ -50,7 +50,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
PinMap pwm = PinMap_PWM[0];
|
||||
|
||||
// Check if there is a pulse train already active on this port
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin*4))) >> (port_pin*4);
|
||||
int pin_func = (MXC_GPIO->func_sel[port] & (0xF << (port_pin * 4))) >> (port_pin * 4);
|
||||
MBED_ASSERT((pin_func < 1) || (pin_func > 3));
|
||||
|
||||
// Search through PinMap_PWM to find the pin
|
||||
|
|
@ -62,7 +62,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
while (pwm.pin == pin) {
|
||||
|
||||
// Check to see if this PT instance is free
|
||||
if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1;
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
obj->pwm = (mxc_pt_regs_t *)pwm.peripheral;
|
||||
|
||||
// Initialize object period and pulse width
|
||||
obj->period = -1;
|
||||
|
|
@ -92,17 +92,17 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin*4)), (MXC_V_GPIO_OUT_MODE_NORMAL << (port_pin*4)));
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port], (0x7 << (port_pin * 4)), (MXC_V_GPIO_OUT_MODE_NORMAL << (port_pin * 4)));
|
||||
|
||||
// Enable this PWM channel
|
||||
MXC_PTG->enable |= (1 << MXC_PT_GET_IDX(obj->pwm));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// Set the registers to the reset value
|
||||
obj->pwm->train = 0;
|
||||
|
|
@ -110,36 +110,36 @@ void pwmout_free(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
static void pwmout_update(pwmout_t* obj)
|
||||
static void pwmout_update(pwmout_t *obj)
|
||||
{
|
||||
// Calculate and set the divider ratio
|
||||
int div = (obj->period * (SystemCoreClock/1000000))/32;
|
||||
int div = (obj->period * (SystemCoreClock / 1000000)) / 32;
|
||||
if (div < 2) {
|
||||
div = 2;
|
||||
}
|
||||
MXC_SET_FIELD(&obj->pwm->rate_length, MXC_F_PT_RATE_LENGTH_RATE_CONTROL, div);
|
||||
|
||||
// Change the duty cycle to adjust the pulse width
|
||||
obj->pwm->train = (0xFFFFFFFF << (32-((32*obj->pulse_width)/obj->period)));
|
||||
obj->pwm->train = (0xFFFFFFFF << (32 - ((32 * obj->pulse_width) / obj->period)));
|
||||
}
|
||||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_write(pwmout_t* obj, float percent)
|
||||
void pwmout_write(pwmout_t *obj, float percent)
|
||||
{
|
||||
// Saturate percent if outside of range
|
||||
if (percent < 0.0f) {
|
||||
percent = 0.0f;
|
||||
} else if(percent > 1.0f) {
|
||||
} else if (percent > 1.0f) {
|
||||
percent = 1.0f;
|
||||
}
|
||||
|
||||
// Resize the pulse width to set the duty cycle
|
||||
pwmout_pulsewidth_us(obj, (int)(percent*obj->period));
|
||||
pwmout_pulsewidth_us(obj, (int)(percent * obj->period));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
// Check for when pulsewidth or period equals 0
|
||||
if ((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
|
|
@ -151,26 +151,26 @@ float pwmout_read(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms*1000);
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the period
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32)));
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
||||
// Set pulse width to half the period if uninitialized
|
||||
if (obj->pulse_width == -1) {
|
||||
obj->pulse_width = us/2;
|
||||
obj->pulse_width = us / 2;
|
||||
}
|
||||
|
||||
// Save the period
|
||||
|
|
@ -181,26 +181,32 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms*1000);
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the pulsewidth
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock/32)));
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
||||
// Initialize period to double the pulsewidth if uninitialized
|
||||
if (obj->period == -1) {
|
||||
obj->period = 2*us;
|
||||
obj->period = 2 * us;
|
||||
}
|
||||
|
||||
// Save the pulsewidth
|
||||
|
|
@ -210,6 +216,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_update(obj);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulse_width;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// Make sure the pin is free for GPIO use
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
|
@ -69,7 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
while (pwm.pin == pin) {
|
||||
|
||||
// Check to see if this PT instance is free
|
||||
if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1;
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
obj->pwm = (mxc_pt_regs_t *)pwm.peripheral;
|
||||
|
||||
// Initialize object period and pulse width
|
||||
obj->period = -1;
|
||||
|
|
@ -99,7 +99,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port],
|
||||
|
|
@ -111,7 +111,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// Set the registers to the reset value
|
||||
obj->pwm->train = 0;
|
||||
|
|
@ -119,10 +119,10 @@ void pwmout_free(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
static void pwmout_update(pwmout_t* obj)
|
||||
static void pwmout_update(pwmout_t *obj)
|
||||
{
|
||||
// Calculate and set the divider ratio
|
||||
int div = (obj->period * (SystemCoreClock / 1000000))/32;
|
||||
int div = (obj->period * (SystemCoreClock / 1000000)) / 32;
|
||||
if (div < 2) {
|
||||
div = 2;
|
||||
}
|
||||
|
|
@ -134,24 +134,24 @@ static void pwmout_update(pwmout_t* obj)
|
|||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_write(pwmout_t* obj, float percent)
|
||||
void pwmout_write(pwmout_t *obj, float percent)
|
||||
{
|
||||
// Saturate percent if outside of range
|
||||
if(percent < 0.0f) {
|
||||
if (percent < 0.0f) {
|
||||
percent = 0.0f;
|
||||
} else if(percent > 1.0f) {
|
||||
} else if (percent > 1.0f) {
|
||||
percent = 1.0f;
|
||||
}
|
||||
|
||||
// Resize the pulse width to set the duty cycle
|
||||
pwmout_pulsewidth_us(obj, (int)(percent*obj->period));
|
||||
pwmout_pulsewidth_us(obj, (int)(percent * obj->period));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
// Check for when pulsewidth or period equals 0
|
||||
if((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
if ((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -160,19 +160,19 @@ float pwmout_read(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the period
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
|
@ -190,19 +190,25 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the pulsewidth
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
|
@ -219,6 +225,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_update(obj);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulse_width;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// Make sure the pin is free for GPIO use
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
|
@ -69,7 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
while (pwm.pin == pin) {
|
||||
|
||||
// Check to see if this PT instance is free
|
||||
if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1;
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
obj->pwm = (mxc_pt_regs_t *)pwm.peripheral;
|
||||
|
||||
// Initialize object period and pulse width
|
||||
obj->period = -1;
|
||||
|
|
@ -99,7 +99,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port],
|
||||
|
|
@ -111,7 +111,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// Set the registers to the reset value
|
||||
obj->pwm->train = 0;
|
||||
|
|
@ -119,10 +119,10 @@ void pwmout_free(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
static void pwmout_update(pwmout_t* obj)
|
||||
static void pwmout_update(pwmout_t *obj)
|
||||
{
|
||||
// Calculate and set the divider ratio
|
||||
int div = (obj->period * (SystemCoreClock / 1000000))/32;
|
||||
int div = (obj->period * (SystemCoreClock / 1000000)) / 32;
|
||||
if (div < 2) {
|
||||
div = 2;
|
||||
}
|
||||
|
|
@ -134,24 +134,24 @@ static void pwmout_update(pwmout_t* obj)
|
|||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_write(pwmout_t* obj, float percent)
|
||||
void pwmout_write(pwmout_t *obj, float percent)
|
||||
{
|
||||
// Saturate percent if outside of range
|
||||
if(percent < 0.0f) {
|
||||
if (percent < 0.0f) {
|
||||
percent = 0.0f;
|
||||
} else if(percent > 1.0f) {
|
||||
} else if (percent > 1.0f) {
|
||||
percent = 1.0f;
|
||||
}
|
||||
|
||||
// Resize the pulse width to set the duty cycle
|
||||
pwmout_pulsewidth_us(obj, (int)(percent*obj->period));
|
||||
pwmout_pulsewidth_us(obj, (int)(percent * obj->period));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
// Check for when pulsewidth or period equals 0
|
||||
if((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
if ((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -160,19 +160,19 @@ float pwmout_read(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the period
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
|
@ -190,19 +190,25 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the pulsewidth
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
|
@ -219,6 +225,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_update(obj);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulse_width;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// Make sure the pin is free for GPIO use
|
||||
unsigned int port = (unsigned int)pin >> PORT_SHIFT;
|
||||
|
|
@ -69,7 +69,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
while (pwm.pin == pin) {
|
||||
|
||||
// Check to see if this PT instance is free
|
||||
if (((mxc_pt_regs_t*)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
if (((mxc_pt_regs_t *)pwm.peripheral)->rate_length & MXC_F_PT_RATE_LENGTH_MODE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
MXC_CLKMAN->sys_clk_ctrl_7_pt = MXC_S_CLKMAN_CLK_SCALE_DIV_1;
|
||||
|
||||
// Set the obj pointer to the propper PWM instance
|
||||
obj->pwm = (mxc_pt_regs_t*)pwm.peripheral;
|
||||
obj->pwm = (mxc_pt_regs_t *)pwm.peripheral;
|
||||
|
||||
// Initialize object period and pulse width
|
||||
obj->period = -1;
|
||||
|
|
@ -99,7 +99,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_us(obj, 20000);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Set the drive mode to normal
|
||||
MXC_SET_FIELD(&MXC_GPIO->out_mode[port],
|
||||
|
|
@ -111,7 +111,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// Set the registers to the reset value
|
||||
obj->pwm->train = 0;
|
||||
|
|
@ -119,10 +119,10 @@ void pwmout_free(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
static void pwmout_update(pwmout_t* obj)
|
||||
static void pwmout_update(pwmout_t *obj)
|
||||
{
|
||||
// Calculate and set the divider ratio
|
||||
int div = (obj->period * (SystemCoreClock / 1000000))/32;
|
||||
int div = (obj->period * (SystemCoreClock / 1000000)) / 32;
|
||||
if (div < 2) {
|
||||
div = 2;
|
||||
}
|
||||
|
|
@ -134,24 +134,24 @@ static void pwmout_update(pwmout_t* obj)
|
|||
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_write(pwmout_t* obj, float percent)
|
||||
void pwmout_write(pwmout_t *obj, float percent)
|
||||
{
|
||||
// Saturate percent if outside of range
|
||||
if(percent < 0.0f) {
|
||||
if (percent < 0.0f) {
|
||||
percent = 0.0f;
|
||||
} else if(percent > 1.0f) {
|
||||
} else if (percent > 1.0f) {
|
||||
percent = 1.0f;
|
||||
}
|
||||
|
||||
// Resize the pulse width to set the duty cycle
|
||||
pwmout_pulsewidth_us(obj, (int)(percent*obj->period));
|
||||
pwmout_pulsewidth_us(obj, (int)(percent * obj->period));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
// Check for when pulsewidth or period equals 0
|
||||
if((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
if ((obj->pulse_width == 0) || (obj->period == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -160,19 +160,19 @@ float pwmout_read(pwmout_t* obj)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the period
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
|
@ -190,19 +190,25 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (int)(seconds * 1000000.0f));
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// Check the range of the pulsewidth
|
||||
MBED_ASSERT((us >= 0) && (us <= (int)(SystemCoreClock / 32)));
|
||||
|
|
@ -219,6 +225,12 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
pwmout_update(obj);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulse_width;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ void pwmout_init(pwmout_t *obj, PinName pin)
|
|||
/* Get hardware instance from pinmap. */
|
||||
int instance = pin_instance_pwm(pin);
|
||||
|
||||
MBED_ASSERT(instance < (int) (sizeof(nordic_nrf5_pwm_instance) / sizeof(nrfx_pwm_t)));
|
||||
MBED_ASSERT(instance < (int)(sizeof(nordic_nrf5_pwm_instance) / sizeof(nrfx_pwm_t)));
|
||||
|
||||
/* Populate PWM object with default values. */
|
||||
obj->instance = instance;
|
||||
|
|
@ -287,6 +287,11 @@ void pwmout_period_us(pwmout_t *obj, int period)
|
|||
nordic_pwm_restart(obj);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
/** Set the PWM pulsewidth specified in seconds, keeping the period the same.
|
||||
*
|
||||
* Parameter obj The pwmout object
|
||||
|
|
@ -348,6 +353,10 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int pulse)
|
|||
nordic_pwm_restart(obj);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj) {
|
||||
return (obj->period) * (obj->percent);
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM_testing;
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start);
|
||||
static void pwmout_config(pwmout_t *obj, int start);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -91,7 +91,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
if (!((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
/* Reset module
|
||||
*
|
||||
* NOTE: We must call secure version (from non-secure domain) because SYS/CLK regions are secure.
|
||||
|
|
@ -113,7 +113,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm_modinit_mask |= 1 << i;
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
@ -142,29 +142,29 @@ void pwmout_free(pwmout_t* obj)
|
|||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -173,23 +173,33 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj, int start)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start);
|
||||
static void pwmout_config(pwmout_t *obj, int start);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -86,7 +86,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
if (!((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm_modinit_mask |= 1 << i;
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
@ -128,29 +128,29 @@ void pwmout_free(pwmout_t* obj)
|
|||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -159,23 +159,32 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj) {
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj, int start)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright (c) 2019-2020 Nuvoton Technology Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
|
|
@ -58,9 +58,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start);
|
||||
static void pwmout_config(pwmout_t *obj, int start);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -85,7 +85,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
if (!((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm_modinit_mask |= 1 << i;
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
@ -127,29 +127,29 @@ void pwmout_free(pwmout_t* obj)
|
|||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -158,23 +158,33 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj, int start)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pwmout_api.h"
|
||||
|
||||
#if DEVICE_PWMOUT
|
||||
|
|
@ -46,20 +46,20 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{PWM_0_3, PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, 0, PWM0_RST, PWM0P1_IRQn, &pwm0_var},
|
||||
{PWM_0_4, PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, 0, PWM0_RST, PWM0P2_IRQn, &pwm0_var},
|
||||
{PWM_0_5, PWM0_MODULE, CLK_CLKSEL2_PWM0SEL_PCLK0, 0, PWM0_RST, PWM0P2_IRQn, &pwm0_var},
|
||||
|
||||
|
||||
{PWM_1_0, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P0_IRQn, &pwm1_var},
|
||||
{PWM_1_1, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P0_IRQn, &pwm1_var},
|
||||
{PWM_1_2, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P1_IRQn, &pwm1_var},
|
||||
{PWM_1_3, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P1_IRQn, &pwm1_var},
|
||||
{PWM_1_4, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P2_IRQn, &pwm1_var},
|
||||
{PWM_1_5, PWM1_MODULE, CLK_CLKSEL2_PWM1SEL_PCLK1, 0, PWM1_RST, PWM1P2_IRQn, &pwm1_var},
|
||||
|
||||
|
||||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj);
|
||||
static void pwmout_config(pwmout_t *obj);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
if (!((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
}
|
||||
|
|
@ -107,22 +107,22 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm_modinit_mask |= 1 << i;
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
PWM_ForceStop(pwm_base, 1 << chn);
|
||||
|
||||
|
||||
const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab);
|
||||
MBED_ASSERT(modinit != NULL);
|
||||
MBED_ASSERT(modinit->modname == obj->pwm);
|
||||
((struct nu_pwm_var *) modinit->var)->en_msk &= ~(1 << chn);
|
||||
|
||||
|
||||
|
||||
|
||||
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0x3F) == 0) {
|
||||
CLK_DisableModuleClock(modinit->clkidx);
|
||||
}
|
||||
|
||||
|
||||
// Mark this module to be deinited.
|
||||
int i = modinit - pwm_modinit_tab;
|
||||
pwm_modinit_mask &= ~(1 << i);
|
||||
|
|
@ -132,29 +132,29 @@ void pwmout_free(pwmout_t* obj)
|
|||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -163,23 +163,33 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -60,9 +60,9 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start);
|
||||
static void pwmout_config(pwmout_t *obj, int start);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -86,7 +86,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
if (!((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm_modinit_mask |= 1 << i;
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
@ -130,29 +130,29 @@ void pwmout_free(pwmout_t* obj)
|
|||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -161,23 +161,33 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj, 1);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj, int start)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj, int start)
|
||||
{
|
||||
EPWM_T *pwm_base = (EPWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pwmout_api.h"
|
||||
|
||||
#if DEVICE_PWMOUT
|
||||
|
|
@ -52,18 +52,18 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{PWM_0_1, PWM0_CH01_MODULE, CLK_CLKSEL1_PWM0_CH01_S_HCLK, 0, PWM0_RST, PWM0_IRQn, &pwm0_01_var},
|
||||
{PWM_0_2, PWM0_CH23_MODULE, CLK_CLKSEL1_PWM0_CH23_S_HCLK, 0, PWM0_RST, PWM0_IRQn, &pwm0_23_var},
|
||||
{PWM_0_3, PWM0_CH23_MODULE, CLK_CLKSEL1_PWM0_CH23_S_HCLK, 0, PWM0_RST, PWM0_IRQn, &pwm0_23_var},
|
||||
|
||||
|
||||
{PWM_1_0, PWM1_CH01_MODULE, CLK_CLKSEL2_PWM1_CH01_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_01_var},
|
||||
{PWM_1_1, PWM1_CH01_MODULE, CLK_CLKSEL2_PWM1_CH01_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_01_var},
|
||||
{PWM_1_2, PWM1_CH23_MODULE, CLK_CLKSEL2_PWM1_CH23_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_23_var},
|
||||
{PWM_1_3, PWM1_CH23_MODULE, CLK_CLKSEL2_PWM1_CH23_S_HCLK, 0, PWM1_RST, PWM1_IRQn, &pwm1_23_var},
|
||||
|
||||
|
||||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj);
|
||||
static void pwmout_config(pwmout_t *obj);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -108,22 +108,22 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
PWM_ForceStop(pwm_base, 1 << chn);
|
||||
|
||||
|
||||
const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab);
|
||||
MBED_ASSERT(modinit != NULL);
|
||||
MBED_ASSERT((PWMName) modinit->modname == obj->pwm);
|
||||
((struct nu_pwm_var *) modinit->var)->en_msk &= ~(1 << chn);
|
||||
|
||||
|
||||
|
||||
|
||||
if ((((struct nu_pwm_var *) modinit->var)->en_msk & 0xF) == 0) {
|
||||
CLK_DisableModuleClock(modinit->clkidx);
|
||||
}
|
||||
|
||||
|
||||
if (((struct nu_pwm_var *) modinit->var)->en_msk == 0) {
|
||||
// Mark this module to be deinited.
|
||||
int i = modinit - pwm_modinit_tab;
|
||||
|
|
@ -135,29 +135,29 @@ void pwmout_free(pwmout_t* obj)
|
|||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -166,23 +166,33 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#include "pwmout_api.h"
|
||||
|
||||
#if DEVICE_PWMOUT
|
||||
|
|
@ -47,20 +47,20 @@ static const struct nu_modinit_s pwm_modinit_tab[] = {
|
|||
{PWM_0_3, PWM0CH23_MODULE, CLK_CLKSEL2_PWM0CH23SEL_HIRC, 0, PWM0_RST, PWM0CH3_IRQn, &pwm0_var},
|
||||
{PWM_0_4, PWM0CH45_MODULE, CLK_CLKSEL2_PWM0CH45SEL_HIRC, 0, PWM0_RST, PWM0CH4_IRQn, &pwm0_var},
|
||||
{PWM_0_5, PWM0CH45_MODULE, CLK_CLKSEL2_PWM0CH45SEL_HIRC, 0, PWM0_RST, PWM0CH5_IRQn, &pwm0_var},
|
||||
|
||||
|
||||
{PWM_1_0, PWM1CH01_MODULE, CLK_CLKSEL2_PWM1CH01SEL_HIRC, 0, PWM1_RST, PWM1CH0_IRQn, &pwm1_var},
|
||||
{PWM_1_1, PWM1CH01_MODULE, CLK_CLKSEL2_PWM1CH01SEL_HIRC, 0, PWM1_RST, PWM1CH1_IRQn, &pwm1_var},
|
||||
{PWM_1_2, PWM1CH23_MODULE, CLK_CLKSEL2_PWM1CH23SEL_HIRC, 0, PWM1_RST, PWM1CH2_IRQn, &pwm1_var},
|
||||
{PWM_1_3, PWM1CH23_MODULE, CLK_CLKSEL2_PWM1CH23SEL_HIRC, 0, PWM1_RST, PWM1CH3_IRQn, &pwm1_var},
|
||||
{PWM_1_4, PWM1CH45_MODULE, CLK_CLKSEL2_PWM1CH45SEL_HIRC, 0, PWM1_RST, PWM1CH4_IRQn, &pwm1_var},
|
||||
{PWM_1_5, PWM1CH45_MODULE, CLK_CLKSEL2_PWM1CH45SEL_HIRC, 0, PWM1_RST, PWM1CH5_IRQn, &pwm1_var},
|
||||
|
||||
|
||||
{NC, 0, 0, 0, 0, (IRQn_Type) 0, NULL}
|
||||
};
|
||||
|
||||
static void pwmout_config(pwmout_t* obj);
|
||||
static void pwmout_config(pwmout_t *obj);
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
obj->pwm = (PWMName) pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT((int) obj->pwm != NC);
|
||||
|
|
@ -83,7 +83,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
// Enable clock of paired channels
|
||||
CLK_EnableModuleClock(modinit->clkidx);
|
||||
|
||||
|
||||
// FIXME: PWM_1_2/3 design bug. PWM_1_2/3 also require PWM_1_0/1 clock enabled.
|
||||
if (obj->pwm == PWM_1_2 || obj->pwm == PWM_1_3) {
|
||||
CLK_EnableModuleClock(PWM1CH01_MODULE);
|
||||
|
|
@ -91,7 +91,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
}
|
||||
|
||||
// NOTE: All channels (identified by PWMName) share a PWM module. This reset will also affect other channels of the same PWM module.
|
||||
if (! ((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
if (!((struct nu_pwm_var *) modinit->var)->en_msk) {
|
||||
// Reset this module if no channel enabled
|
||||
SYS_ResetModule(modinit->rsetidx);
|
||||
}
|
||||
|
|
@ -102,30 +102,30 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
obj->period_us = 1000 * 10;
|
||||
obj->pulsewidth_us = 0;
|
||||
pwmout_config(obj);
|
||||
|
||||
|
||||
// Enable output of the specified PWM channel
|
||||
PWM_EnableOutput(pwm_base, 1 << chn);
|
||||
PWM_Start(pwm_base, 1 << chn);
|
||||
|
||||
|
||||
((struct nu_pwm_var *) modinit->var)->en_msk |= 1 << chn;
|
||||
|
||||
|
||||
// Mark this module to be inited.
|
||||
int i = modinit - pwm_modinit_tab;
|
||||
pwm_modinit_mask |= 1 << i;
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
PWM_ForceStop(pwm_base, 1 << chn);
|
||||
|
||||
|
||||
const struct nu_modinit_s *modinit = get_modinit(obj->pwm, pwm_modinit_tab);
|
||||
MBED_ASSERT(modinit != NULL);
|
||||
MBED_ASSERT(modinit->modname == obj->pwm);
|
||||
((struct nu_pwm_var *) modinit->var)->en_msk &= ~(1 << chn);
|
||||
|
||||
|
||||
|
||||
|
||||
if ((((struct nu_pwm_var *) modinit->var)->en_msk & (0x3 << (chn / 2 * 2))) == 0) {
|
||||
// FIXME: PWM_1_2/3 design bug. PWM_1_2/3 also require PWM_1_0/1 clock enabled.
|
||||
switch (obj->pwm) {
|
||||
|
|
@ -134,51 +134,51 @@ void pwmout_free(pwmout_t* obj)
|
|||
if (pwm1_var.en_msk & 0xC) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PWM_1_2:
|
||||
case PWM_1_3:
|
||||
if (! (pwm1_var.en_msk & 0x3)) {
|
||||
if (!(pwm1_var.en_msk & 0x3)) {
|
||||
CLK_DisableModuleClock(PWM1CH01_MODULE);
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
// Disable clock of paired channels
|
||||
CLK_DisableModuleClock(modinit->clkidx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mark this module to be deinited.
|
||||
int i = modinit - pwm_modinit_tab;
|
||||
pwm_modinit_mask &= ~(1 << i);
|
||||
|
||||
|
||||
// Free up pins
|
||||
gpio_set(obj->pin);
|
||||
obj->pin = NC;
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t) (value * obj->period_us), 0, obj->period_us);
|
||||
obj->pulsewidth_us = NU_CLAMP((uint32_t)(value * obj->period_us), 0, obj->period_us);
|
||||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
return NU_CLAMP((((float) obj->pulsewidth_us) / obj->period_us), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t period_us_old = obj->period_us;
|
||||
uint32_t pulsewidth_us_old = obj->pulsewidth_us;
|
||||
|
|
@ -187,23 +187,33 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period_us;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
obj->pulsewidth_us = NU_CLAMP(us, 0, obj->period_us);
|
||||
pwmout_config(obj);
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t* obj)
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pulsewidth_us;
|
||||
}
|
||||
|
||||
static void pwmout_config(pwmout_t *obj)
|
||||
{
|
||||
PWM_T *pwm_base = (PWM_T *) NU_MODBASE(obj->pwm);
|
||||
uint32_t chn = NU_MODSUBINDEX(obj->pwm);
|
||||
|
|
|
|||
|
|
@ -25,36 +25,39 @@
|
|||
|
||||
static const PinMap PinMap_PWM[] = {
|
||||
{P1_19, SCT0_0, 2},
|
||||
{P2_2 , SCT0_1, 3},
|
||||
{P2_7 , SCT0_2, 2},
|
||||
{P2_2, SCT0_1, 3},
|
||||
{P2_7, SCT0_2, 2},
|
||||
{P1_13, SCT0_3, 2},
|
||||
{P2_16, SCT1_0, 1},
|
||||
{P2_17, SCT1_1, 1},
|
||||
{P2_18, SCT1_2, 1},
|
||||
{P2_19, SCT1_3, 1},
|
||||
{NC , NC ,0}
|
||||
{NC, NC, 0}
|
||||
};
|
||||
|
||||
|
||||
static LPC_SCT0_Type *SCTs[SCT_CHANNELS] = {
|
||||
(LPC_SCT0_Type*)LPC_SCT0,
|
||||
(LPC_SCT0_Type*)LPC_SCT1,
|
||||
(LPC_SCT0_Type *)LPC_SCT0,
|
||||
(LPC_SCT0_Type *)LPC_SCT1,
|
||||
|
||||
};
|
||||
|
||||
// bit flags for used SCTs
|
||||
static unsigned char sct_used = 0;
|
||||
|
||||
static int get_available_sct(void) {
|
||||
static int get_available_sct(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<SCT_CHANNELS; i++) {
|
||||
if ((sct_used & (1 << i)) == 0)
|
||||
for (i = 0; i < SCT_CHANNELS; i++) {
|
||||
if ((sct_used & (1 << i)) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// determine the SPI to use
|
||||
PWMName pwm_mapped = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
if (pwm_mapped == (PWMName)NC) {
|
||||
|
|
@ -73,17 +76,17 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 31);
|
||||
|
||||
// Clear peripheral reset the SCT:
|
||||
LPC_SYSCON->PRESETCTRL |= (1 << (obj->pwm_ch + 9));
|
||||
LPC_SYSCON->PRESETCTRL |= (1 << (obj->pwm_ch + 9));
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
LPC_SCT0_Type* pwm = obj->pwm;
|
||||
|
||||
LPC_SCT0_Type *pwm = obj->pwm;
|
||||
|
||||
// Unified 32-bit counter, autolimit
|
||||
pwm->CONFIG |= ((0x3 << 17) | 0x01);
|
||||
|
||||
|
||||
// halt and clear the counter
|
||||
pwm->CTRL |= (1 << 2) | (1 << 3);
|
||||
|
||||
switch(pwm_mapped) {
|
||||
|
||||
switch (pwm_mapped) {
|
||||
case SCT0_0:
|
||||
case SCT1_0:
|
||||
pwm->OUT0_SET = (1 << 0); // event 0
|
||||
|
|
@ -116,10 +119,11 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
pwmout_write(obj, 0);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
sct_used &= ~(1 << obj->pwm_ch);
|
||||
if (sct_used == 0) {
|
||||
// Disable the SCT clock
|
||||
|
|
@ -127,8 +131,9 @@ void pwmout_free(pwmout_t* obj) {
|
|||
}
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
LPC_SCT0_Type* pwm = obj->pwm;
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
LPC_SCT0_Type *pwm = obj->pwm;
|
||||
if (value < 0.0f) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0f) {
|
||||
|
|
@ -137,7 +142,7 @@ void pwmout_write(pwmout_t* obj, float value) {
|
|||
uint32_t t_on = (uint32_t)((float)(pwm->MATCHREL0 + 1) * value);
|
||||
if (t_on > 0) {
|
||||
pwm->MATCHREL1 = t_on - 1;
|
||||
|
||||
|
||||
// Un-halt the timer and ensure the new pulse-width takes immediate effect if necessary
|
||||
if (pwm->CTRL & (1 << 2)) {
|
||||
pwm->MATCH1 = pwm->MATCHREL1;
|
||||
|
|
@ -150,34 +155,38 @@ void pwmout_write(pwmout_t* obj, float value) {
|
|||
}
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
LPC_SCT0_Type* pwm = obj->pwm;
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
LPC_SCT0_Type *pwm = obj->pwm;
|
||||
uint32_t t_off = pwm->MATCHREL0 + 1;
|
||||
uint32_t t_on = (!(pwm->CTRL & (1 << 2))) ? pwm->MATCHREL1 + 1 : 0;
|
||||
float v = (float)t_on/(float)t_off;
|
||||
float v = (float)t_on / (float)t_off;
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
LPC_SCT0_Type* pwm = obj->pwm;
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
LPC_SCT0_Type *pwm = obj->pwm;
|
||||
uint32_t t_off = pwm->MATCHREL0 + 1;
|
||||
uint32_t t_on = (!(pwm->CTRL & (1 << 2))) ? pwm->MATCHREL1 + 1 : 0;
|
||||
float v = (float)t_on/(float)t_off;
|
||||
float v = (float)t_on / (float)t_off;
|
||||
uint32_t period_ticks = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000);
|
||||
uint32_t pulsewidth_ticks = period_ticks * v;
|
||||
pwm->MATCHREL0 = period_ticks - 1;
|
||||
if (pulsewidth_ticks > 0) {
|
||||
pwm->MATCHREL1 = pulsewidth_ticks - 1;
|
||||
|
||||
|
||||
// Un-halt the timer and ensure the new period & pulse-width take immediate effect if necessary
|
||||
if (pwm->CTRL & (1 << 2)) {
|
||||
pwm->MATCH0 = pwm->MATCHREL0;
|
||||
|
|
@ -188,25 +197,33 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
// Halt the timer and force the output low
|
||||
pwm->CTRL |= (1 << 2) | (1 << 3);
|
||||
pwm->OUTPUT = 0x00000000;
|
||||
|
||||
|
||||
// Ensure the new period will take immediate effect when the timer is un-halted
|
||||
pwm->MATCH0 = pwm->MATCHREL0;
|
||||
}
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return pwm->MATCHREL0 + 1;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
LPC_SCT0_Type* pwm = obj->pwm;
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
LPC_SCT0_Type *pwm = obj->pwm;
|
||||
if (us > 0) {
|
||||
pwm->MATCHREL1 = (uint32_t)(((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000) - 1;
|
||||
|
||||
|
||||
// Un-halt the timer and ensure the new pulse-width takes immediate effect if necessary
|
||||
if (pwm->CTRL & (1 << 2)) {
|
||||
pwm->MATCH1 = pwm->MATCHREL1;
|
||||
|
|
@ -219,6 +236,11 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
|||
}
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return (!(pwm->CTRL & (1 << 2))) ? pwm->MATCHREL1 + 1 : 0;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@
|
|||
*/
|
||||
static const PinMap PinMap_PWM[] = {
|
||||
/* CT16B0 */
|
||||
{P0_8 , PWM_1, 0x02}, /* MR0 */
|
||||
{P0_9 , PWM_2, 0x02}, /* MR1 */
|
||||
{P0_8, PWM_1, 0x02}, /* MR0 */
|
||||
{P0_9, PWM_2, 0x02}, /* MR1 */
|
||||
|
||||
/* CT16B1 */
|
||||
{P1_9 , PWM_3, 0x01}, /* MR0 */
|
||||
{P1_9, PWM_3, 0x01}, /* MR0 */
|
||||
{P1_10, PWM_4, 0x02}, /* MR1 */
|
||||
|
||||
/* CT32B0 */
|
||||
{P0_1 , PWM_5, 0x02}, /* MR2 */
|
||||
{P0_1, PWM_5, 0x02}, /* MR2 */
|
||||
|
||||
{NC , NC ,0x00}
|
||||
{NC, NC, 0x00}
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -61,49 +61,52 @@ static LPC_TMR_TypeDef *Timers[3] = {
|
|||
LPC_TMR32B0
|
||||
};
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
||||
obj->pwm = pwm;
|
||||
|
||||
|
||||
// Timer registers
|
||||
timer_mr tid = pwm_timer_map[pwm];
|
||||
LPC_TMR_TypeDef *timer = Timers[tid.timer];
|
||||
|
||||
|
||||
// Disable timer
|
||||
timer->TCR = 0;
|
||||
|
||||
|
||||
// Power the correspondent timer
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7);
|
||||
|
||||
|
||||
/* Enable PWM function */
|
||||
timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0);
|
||||
|
||||
timer->PWMC = (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
|
||||
|
||||
/* Reset Functionality on MR3 controlling the PWM period */
|
||||
timer->MCR = 1 << 10;
|
||||
|
||||
|
||||
if (timer == LPC_TMR16B0 || timer == LPC_TMR16B1) {
|
||||
/* Set 16-bit timer prescaler to avoid timer expire for default 20ms */
|
||||
/* This can be also modified by user application, but the prescaler value */
|
||||
/* might be trade-off to timer accuracy */
|
||||
/* Set 16-bit timer prescaler to avoid timer expire for default 20ms */
|
||||
/* This can be also modified by user application, but the prescaler value */
|
||||
/* might be trade-off to timer accuracy */
|
||||
timer->PR = 30;
|
||||
}
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// [TODO]
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0f) {
|
||||
|
|
@ -123,10 +126,11 @@ void pwmout_write(pwmout_t* obj, float value) {
|
|||
timer->TCR = TCR_CNT_EN;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
timer_mr tid = pwm_timer_map[obj->pwm];
|
||||
LPC_TMR_TypeDef *timer = Timers[tid.timer];
|
||||
|
||||
|
||||
float v = (float)(timer->MR3 - timer->MR[tid.mr]) / (float)(timer->MR3);
|
||||
if (timer->MR[tid.mr] > timer->MR3) {
|
||||
v = 0.0f;
|
||||
|
|
@ -134,19 +138,22 @@ float pwmout_read(pwmout_t* obj) {
|
|||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
int i = 0;
|
||||
uint32_t period_ticks;
|
||||
|
||||
|
||||
timer_mr tid = pwm_timer_map[obj->pwm];
|
||||
LPC_TMR_TypeDef *timer = Timers[tid.timer];
|
||||
uint32_t old_period_ticks = timer->MR3;
|
||||
|
|
@ -154,10 +161,10 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
|
||||
timer->TCR = TCR_RESET;
|
||||
timer->MR3 = period_ticks;
|
||||
|
||||
|
||||
// Scale the pulse width to preserve the duty ratio
|
||||
if (old_period_ticks > 0) {
|
||||
for (i=0; i<3; i++) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
uint32_t t_off = period_ticks - (uint32_t)(((uint64_t)timer->MR[i] * (uint64_t)period_ticks) / (uint64_t)old_period_ticks);
|
||||
timer->MR[i] = t_off;
|
||||
}
|
||||
|
|
@ -165,19 +172,29 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
timer->TCR = TCR_CNT_EN;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
timer_mr tid = pwm_timer_map[obj->pwm];
|
||||
LPC_TMR_TypeDef *timer = Timers[tid.timer];
|
||||
return (timer->MR3);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
timer_mr tid = pwm_timer_map[obj->pwm];
|
||||
LPC_TMR_TypeDef *timer = Timers[tid.timer];
|
||||
uint32_t t_on = (uint32_t)((((uint64_t)SystemCoreClock * (uint64_t)us) / (uint64_t)1000000) / (timer->PR + 1));
|
||||
|
||||
|
||||
timer->TCR = TCR_RESET;
|
||||
if (t_on > timer->MR3) {
|
||||
pwmout_period_us(obj, us);
|
||||
|
|
@ -187,6 +204,13 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
|||
timer->TCR = TCR_CNT_EN;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
timer_mr tid = pwm_timer_map[obj->pwm];
|
||||
LPC_TMR_TypeDef *timer = Timers[tid.timer];
|
||||
return (timer->MR3 - timer->MR[tid.mr]);
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ static const PinMap PinMap_PWM[] = {
|
|||
{P1_23, PWM_4, 2},
|
||||
{P1_24, PWM_5, 2},
|
||||
{P1_26, PWM_6, 2},
|
||||
{P2_0 , PWM_1, 1},
|
||||
{P2_1 , PWM_2, 1},
|
||||
{P2_2 , PWM_3, 1},
|
||||
{P2_3 , PWM_4, 1},
|
||||
{P2_4 , PWM_5, 1},
|
||||
{P2_5 , PWM_6, 1},
|
||||
{P2_0, PWM_1, 1},
|
||||
{P2_1, PWM_2, 1},
|
||||
{P2_2, PWM_3, 1},
|
||||
{P2_3, PWM_4, 1},
|
||||
{P2_4, PWM_5, 1},
|
||||
{P2_5, PWM_6, 1},
|
||||
{P3_25, PWM_2, 3},
|
||||
{P3_26, PWM_3, 3},
|
||||
{NC, NC, 0}
|
||||
|
|
@ -54,77 +54,84 @@ __IO uint32_t *PWM_MATCH[] = {
|
|||
|
||||
static unsigned int pwm_clock_mhz;
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
||||
obj->pwm = pwm;
|
||||
obj->MR = PWM_MATCH[pwm];
|
||||
|
||||
|
||||
// ensure the power is on
|
||||
LPC_SC->PCONP |= 1 << 6;
|
||||
|
||||
|
||||
// ensure clock to /4
|
||||
LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // pclk = /4
|
||||
LPC_PWM1->PR = 0; // no pre-scale
|
||||
|
||||
|
||||
// ensure single PWM mode
|
||||
LPC_PWM1->MCR = 1 << 1; // reset TC on match 0
|
||||
|
||||
|
||||
// enable the specific PWM output
|
||||
LPC_PWM1->PCR |= 1 << (8 + pwm);
|
||||
|
||||
|
||||
pwm_clock_mhz = SystemCoreClock / 4000000;
|
||||
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
|
||||
pwmout_write(obj, 0);
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
// [TODO]
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0f) {
|
||||
value = 1.0;
|
||||
}
|
||||
|
||||
|
||||
// set channel match to percentage
|
||||
uint32_t v = (uint32_t)((float)(LPC_PWM1->MR0) * value);
|
||||
|
||||
|
||||
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
|
||||
if (v == LPC_PWM1->MR0) {
|
||||
v++;
|
||||
}
|
||||
|
||||
|
||||
*obj->MR = v;
|
||||
|
||||
|
||||
// accept on next period start
|
||||
LPC_PWM1->LER |= 1 << obj->pwm;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
float v = (float)(*obj->MR) / (float)(LPC_PWM1->MR0);
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// calculate number of ticks
|
||||
uint32_t ticks = pwm_clock_mhz * us;
|
||||
|
||||
|
|
@ -146,30 +153,43 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return (LPC_PWM1->MR0);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
// calculate number of ticks
|
||||
uint32_t v = pwm_clock_mhz * us;
|
||||
|
||||
|
||||
// workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
|
||||
if (v == LPC_PWM1->MR0) {
|
||||
v++;
|
||||
}
|
||||
|
||||
|
||||
// set the match register value
|
||||
*obj->MR = v;
|
||||
|
||||
|
||||
// set the channel latch to update value at next period start
|
||||
LPC_PWM1->LER |= 1 << obj->pwm;
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return (*obj->MR);
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ static PWM_Type *const pwm_addrs[] = PWM_BASE_PTRS;
|
|||
extern void pwm_setup();
|
||||
extern uint32_t pwm_get_clock();
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -93,7 +93,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pinmap_pinout(pin, PinMap_PWM);
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
uint32_t instance = (obj->pwm_name >> PWM_SHIFT) & 0x7;
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
|
|
@ -101,7 +101,7 @@ void pwmout_free(pwmout_t* obj)
|
|||
PWM_StopTimer(pwm_addrs[instance], (1 << module));
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
if (value < 0.0f) {
|
||||
value = 0.0f;
|
||||
|
|
@ -130,7 +130,7 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
PWM_SetPwmLdok(base, (1 << module), true);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7];
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
|
|
@ -153,18 +153,18 @@ float pwmout_read(pwmout_t* obj)
|
|||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds)
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7];
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
|
|
@ -194,17 +194,24 @@ void pwmout_period_us(pwmout_t* obj, int us)
|
|||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7];
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
return (base->SM[module].VAL1) & PWM_VAL1_VAL1_MASK;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7];
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
|
|
@ -223,6 +230,20 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
PWM_SetPwmLdok(base, (1 << module), true);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj) {
|
||||
uint16_t count;
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7];
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
uint32_t pwmchannel = obj->pwm_name & 0x1;
|
||||
if (pwmchannel == 0)
|
||||
{
|
||||
count = (base->SM[module].VAL3) & PWM_VAL3_VAL3_MASK;
|
||||
} else
|
||||
{
|
||||
count = (base->SM[module].VAL5) & PWM_VAL5_VAL5_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -46,22 +46,22 @@ typedef enum {
|
|||
} PWMType;
|
||||
|
||||
static const PWMType PORT[] = {
|
||||
PWM1A, // PWM_PWM1A
|
||||
PWM1B, // PWM_PWM1B
|
||||
PWM1C, // PWM_PWM1C
|
||||
PWM1D, // PWM_PWM1D
|
||||
PWM1E, // PWM_PWM1E
|
||||
PWM1F, // PWM_PWM1F
|
||||
PWM1G, // PWM_PWM1G
|
||||
PWM1H, // PWM_PWM1H
|
||||
PWM2A, // PWM_PWM2A
|
||||
PWM2B, // PWM_PWM2B
|
||||
PWM2C, // PWM_PWM2C
|
||||
PWM2D, // PWM_PWM2D
|
||||
PWM2E, // PWM_PWM2E
|
||||
PWM2F, // PWM_PWM2F
|
||||
PWM2G, // PWM_PWM2G
|
||||
PWM2H, // PWM_PWM2H
|
||||
PWM1A, // PWM_PWM1A
|
||||
PWM1B, // PWM_PWM1B
|
||||
PWM1C, // PWM_PWM1C
|
||||
PWM1D, // PWM_PWM1D
|
||||
PWM1E, // PWM_PWM1E
|
||||
PWM1F, // PWM_PWM1F
|
||||
PWM1G, // PWM_PWM1G
|
||||
PWM1H, // PWM_PWM1H
|
||||
PWM2A, // PWM_PWM2A
|
||||
PWM2B, // PWM_PWM2B
|
||||
PWM2C, // PWM_PWM2C
|
||||
PWM2D, // PWM_PWM2D
|
||||
PWM2E, // PWM_PWM2E
|
||||
PWM2F, // PWM_PWM2F
|
||||
PWM2G, // PWM_PWM2G
|
||||
PWM2H, // PWM_PWM2H
|
||||
};
|
||||
|
||||
static __IO uint16_t *PWM_MATCH[] = {
|
||||
|
|
@ -111,23 +111,23 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
MTU2_PWMType port;
|
||||
__IO uint16_t * pulse1;
|
||||
__IO uint16_t * pulse2;
|
||||
__IO uint16_t * period1;
|
||||
__IO uint16_t * period2;
|
||||
__IO uint8_t * tior;
|
||||
__IO uint8_t * tcr;
|
||||
__IO uint8_t * tmdr;
|
||||
__IO uint16_t *pulse1;
|
||||
__IO uint16_t *pulse2;
|
||||
__IO uint16_t *period1;
|
||||
__IO uint16_t *period2;
|
||||
__IO uint8_t *tior;
|
||||
__IO uint8_t *tcr;
|
||||
__IO uint8_t *tmdr;
|
||||
int max_period;
|
||||
} st_mtu2_ctrl_t;
|
||||
|
||||
static st_mtu2_ctrl_t mtu2_ctl[] = {
|
||||
{ TIOC0A, &MTU2TGRA_0, &MTU2TGRC_0, &MTU2TGRB_0, &MTU2TGRD_0, &MTU2TIORH_0, &MTU2TCR_0, &MTU2TMDR_0, 125000 }, // PWM_TIOC0A
|
||||
{ TIOC0C, &MTU2TGRC_0, &MTU2TGRA_0, &MTU2TGRB_0, &MTU2TGRD_0, &MTU2TIORL_0, &MTU2TCR_0, &MTU2TMDR_0, 125000 }, // PWM_TIOC0C
|
||||
{ TIOC1A, &MTU2TGRA_1, NULL , &MTU2TGRB_1, NULL , &MTU2TIOR_1 , &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1A
|
||||
{ TIOC1B, &MTU2TGRB_1, NULL , &MTU2TGRA_1, NULL , &MTU2TIOR_1 , &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1B
|
||||
{ TIOC2A, &MTU2TGRA_2, NULL , &MTU2TGRB_2, NULL , &MTU2TIOR_2 , &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2A
|
||||
{ TIOC2B, &MTU2TGRB_2, NULL , &MTU2TGRA_2, NULL , &MTU2TIOR_2 , &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2B
|
||||
{ TIOC1A, &MTU2TGRA_1, NULL, &MTU2TGRB_1, NULL, &MTU2TIOR_1, &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1A
|
||||
{ TIOC1B, &MTU2TGRB_1, NULL, &MTU2TGRA_1, NULL, &MTU2TIOR_1, &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1B
|
||||
{ TIOC2A, &MTU2TGRA_2, NULL, &MTU2TGRB_2, NULL, &MTU2TIOR_2, &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2A
|
||||
{ TIOC2B, &MTU2TGRB_2, NULL, &MTU2TGRA_2, NULL, &MTU2TIOR_2, &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2B
|
||||
{ TIOC3A, &MTU2TGRA_3, &MTU2TGRC_3, &MTU2TGRB_3, &MTU2TGRD_3, &MTU2TIORH_3, &MTU2TCR_3, &MTU2TMDR_3, 2000000 }, // PWM_TIOC3A
|
||||
{ TIOC3C, &MTU2TGRC_3, &MTU2TGRA_3, &MTU2TGRB_3, &MTU2TGRD_3, &MTU2TIORL_3, &MTU2TCR_3, &MTU2TMDR_3, 2000000 }, // PWM_TIOC3C
|
||||
{ TIOC4A, &MTU2TGRA_4, &MTU2TGRC_4, &MTU2TGRB_4, &MTU2TGRD_4, &MTU2TIORH_4, &MTU2TCR_4, &MTU2TMDR_4, 2000000 }, // PWM_TIOC4A
|
||||
|
|
@ -138,7 +138,8 @@ static uint16_t init_mtu2_period_ch[5] = {0};
|
|||
static int32_t mtu2_period_ch[5] = {1, 1, 1, 1, 1};
|
||||
#endif
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||
void pwmout_init(pwmout_t *obj, PinName pin)
|
||||
{
|
||||
// determine the channel
|
||||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
|
@ -150,7 +151,7 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
mtu2_init();
|
||||
|
||||
obj->pwm = pwm;
|
||||
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
|
||||
obj->ch = (uint8_t)(((uint32_t)p_mtu2_ctl->port & 0x000000F0) >> 4);
|
||||
if (obj->ch == 4) {
|
||||
|
|
@ -208,18 +209,20 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
|
|||
}
|
||||
}
|
||||
|
||||
void pwmout_free(pwmout_t* obj) {
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
pwmout_write(obj, 0);
|
||||
mtu2_free();
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value) {
|
||||
void pwmout_write(pwmout_t *obj, float value)
|
||||
{
|
||||
uint32_t wk_cycle;
|
||||
|
||||
if (obj->pwm >= MTU2_PWM_OFFSET) {
|
||||
#ifdef FUMC_MTU2_PWM
|
||||
/* PWM by MTU2 */
|
||||
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
uint8_t tmp_tstr_st;
|
||||
|
||||
if (value < 0.0f) {
|
||||
|
|
@ -229,7 +232,7 @@ void pwmout_write(pwmout_t* obj, float value) {
|
|||
} else {
|
||||
// Do Nothing
|
||||
}
|
||||
wk_cycle = (uint32_t)*p_mtu2_ctl->period1;
|
||||
wk_cycle = (uint32_t) * p_mtu2_ctl->period1;
|
||||
if ((obj->ch == 4) || (obj->ch == 3)) {
|
||||
tmp_tstr_st = (1 << (obj->ch + 3));
|
||||
} else {
|
||||
|
|
@ -291,7 +294,8 @@ void pwmout_write(pwmout_t* obj, float value) {
|
|||
}
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj) {
|
||||
float pwmout_read(pwmout_t *obj)
|
||||
{
|
||||
uint32_t wk_cycle;
|
||||
float value;
|
||||
|
||||
|
|
@ -299,10 +303,10 @@ float pwmout_read(pwmout_t* obj) {
|
|||
#ifdef FUMC_MTU2_PWM
|
||||
/* PWM by MTU2 */
|
||||
uint32_t wk_pulse;
|
||||
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
|
||||
wk_cycle = (uint32_t)*p_mtu2_ctl->period1;
|
||||
wk_pulse = (uint32_t)*p_mtu2_ctl->pulse1;
|
||||
wk_cycle = (uint32_t) * p_mtu2_ctl->period1;
|
||||
wk_pulse = (uint32_t) * p_mtu2_ctl->pulse1;
|
||||
value = ((float)wk_pulse / (float)wk_cycle);
|
||||
#endif
|
||||
} else {
|
||||
|
|
@ -320,16 +324,19 @@ float pwmout_read(pwmout_t* obj) {
|
|||
return (value > 1.0f) ? (1.0f) : (value);
|
||||
}
|
||||
|
||||
void pwmout_period(pwmout_t* obj, float seconds) {
|
||||
void pwmout_period(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_period_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_period_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
#ifdef FUNC_MOTOR_CTL_PWM
|
||||
static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){
|
||||
static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle)
|
||||
{
|
||||
uint16_t wk_pwmpbfr;
|
||||
float value;
|
||||
uint16_t v;
|
||||
|
|
@ -342,7 +349,8 @@ static void set_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16
|
|||
#endif
|
||||
|
||||
#ifdef FUMC_MTU2_PWM
|
||||
static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){
|
||||
static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle)
|
||||
{
|
||||
uint16_t wk_pwmpbfr;
|
||||
float value;
|
||||
|
||||
|
|
@ -353,7 +361,8 @@ static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, u
|
|||
#endif
|
||||
|
||||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||
void pwmout_period_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint32_t pclk_base;
|
||||
uint32_t wk_cycle;
|
||||
uint32_t wk_cks = 0;
|
||||
|
|
@ -365,7 +374,7 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
int max_us = 0;
|
||||
|
||||
/* PWM by MTU2 */
|
||||
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
uint8_t tmp_tcr_up;
|
||||
uint8_t tmp_tstr_st;
|
||||
|
||||
|
|
@ -387,10 +396,10 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
wk_cycle_mtu2 = (uint64_t)pclk_base * us;
|
||||
while (wk_cycle_mtu2 >= 65535000000) {
|
||||
if ((obj->ch == 1) && (wk_cks == 3)) {
|
||||
wk_cks+=2;
|
||||
wk_cks += 2;
|
||||
} else if ((obj->ch == 2) && (wk_cks == 3)) {
|
||||
wk_cycle_mtu2 >>= 2;
|
||||
wk_cks+=3;
|
||||
wk_cks += 3;
|
||||
}
|
||||
wk_cycle_mtu2 >>= 2;
|
||||
wk_cks++;
|
||||
|
|
@ -494,15 +503,44 @@ void pwmout_period_us(pwmout_t* obj, int us) {
|
|||
}
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t wk_cycle;
|
||||
float value;
|
||||
|
||||
if (obj->pwm >= MTU2_PWM_OFFSET) {
|
||||
#ifdef FUMC_MTU2_PWM
|
||||
/* PWM by MTU2 */
|
||||
st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
|
||||
wk_cycle = (uint32_t) * p_mtu2_ctl->period1;
|
||||
#endif
|
||||
} else {
|
||||
#ifdef FUNC_MOTOR_CTL_PWM
|
||||
/* PWM */
|
||||
if (obj->ch == 2) {
|
||||
wk_cycle = PWMPWCYR_2 & 0x03ff;
|
||||
} else {
|
||||
wk_cycle = PWMPWCYR_1 & 0x03ff;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return wk_cycle;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
float value = 0;
|
||||
|
||||
if (obj->pwm >= MTU2_PWM_OFFSET) {
|
||||
|
|
@ -529,6 +567,23 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
|||
pwmout_write(obj, value);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
uint32_t wk_pulse = 0;
|
||||
|
||||
if (obj->pwm >= MTU2_PWM_OFFSET) {
|
||||
#ifdef FUMC_MTU2_PWM
|
||||
/* PWM by MTU2 */
|
||||
|
||||
st_mtu2_ctrl_t *p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
|
||||
|
||||
wk_pulse = (uint32_t) * p_mtu2_ctl->pulse1;
|
||||
#endif
|
||||
}
|
||||
|
||||
return wk_pulse;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -166,6 +166,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
pwmout_write(obj, obj->duty);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->pwm->GTPR.LONG;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
|
|
@ -188,6 +193,14 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
pwmout_write(obj, value);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
if (obj->type == 0) {
|
||||
return (float)obj->pwm->GTCCRC.LONG;
|
||||
}
|
||||
return (float)obj->pwm->GTCCRE.LONG ;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -386,6 +386,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
__HAL_TIM_ENABLE(&TimHandle);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->period;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||
|
|
@ -402,6 +407,12 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
pwmout_write(obj, value);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
float pwm_duty_cycle = pwmout_read(obj);
|
||||
return (int)(pwm_duty_cycle * (float)obj->period);
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -78,15 +78,16 @@ uint32_t pwmout_get_channel_route(uint32_t channel)
|
|||
/*
|
||||
* Disables the route location given. Returns true if it was enabled, false if it wasn't.
|
||||
*/
|
||||
bool pwmout_disable_channel_route(uint32_t routeloc) {
|
||||
bool pwmout_disable_channel_route(uint32_t routeloc)
|
||||
{
|
||||
#ifdef TIMER_ROUTEPEN_CC0PEN
|
||||
if(PWM_TIMER->ROUTEPEN & routeloc) {
|
||||
if (PWM_TIMER->ROUTEPEN & routeloc) {
|
||||
//This channel was in use, so disable
|
||||
PWM_TIMER->ROUTEPEN &= ~routeloc;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if(PWM_TIMER->ROUTE & routeloc) {
|
||||
if (PWM_TIMER->ROUTE & routeloc) {
|
||||
//This channel was in use, so disable
|
||||
PWM_TIMER->ROUTE &= ~routeloc;
|
||||
return true;
|
||||
|
|
@ -98,13 +99,14 @@ bool pwmout_disable_channel_route(uint32_t routeloc) {
|
|||
/*
|
||||
* Check if a channel is active
|
||||
*/
|
||||
bool pwmout_channel_route_active(uint32_t routeloc) {
|
||||
bool pwmout_channel_route_active(uint32_t routeloc)
|
||||
{
|
||||
#ifdef TIMER_ROUTEPEN_CC0PEN
|
||||
if(PWM_TIMER->ROUTEPEN & routeloc) {
|
||||
if (PWM_TIMER->ROUTEPEN & routeloc) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if(PWM_TIMER->ROUTE & routeloc) {
|
||||
if (PWM_TIMER->ROUTE & routeloc) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -114,7 +116,8 @@ bool pwmout_channel_route_active(uint32_t routeloc) {
|
|||
/*
|
||||
* Set the given route PEN flag
|
||||
*/
|
||||
void pwmout_set_channel_route(uint32_t routeloc) {
|
||||
void pwmout_set_channel_route(uint32_t routeloc)
|
||||
{
|
||||
#ifdef TIMER_ROUTEPEN_CC0PEN
|
||||
PWM_TIMER->ROUTEPEN |= routeloc;
|
||||
#else
|
||||
|
|
@ -125,9 +128,10 @@ void pwmout_set_channel_route(uint32_t routeloc) {
|
|||
/*
|
||||
* Check if all routes are disabled
|
||||
*/
|
||||
bool pwmout_all_inactive(void) {
|
||||
bool pwmout_all_inactive(void)
|
||||
{
|
||||
#ifdef TIMER_ROUTEPEN_CC0PEN
|
||||
if(PWM_TIMER->ROUTEPEN == _TIMER_ROUTEPEN_RESETVALUE) {
|
||||
if (PWM_TIMER->ROUTEPEN == _TIMER_ROUTEPEN_RESETVALUE) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
|
@ -148,7 +152,8 @@ void pwmout_enable_pins(pwmout_t *obj, uint8_t enable)
|
|||
}
|
||||
}
|
||||
|
||||
void pwmout_enable(pwmout_t *obj, uint8_t enable){
|
||||
void pwmout_enable(pwmout_t *obj, uint8_t enable)
|
||||
{
|
||||
if (enable) {
|
||||
// Set mode to PWM
|
||||
PWM_TIMER->CC[obj->channel].CTRL = TIMER_CC_CTRL_MODE_PWM;
|
||||
|
|
@ -168,13 +173,13 @@ void pwmout_init(pwmout_t *obj, PinName pin)
|
|||
CMU_ClockEnable(PWM_TIMER_CLOCK, true);
|
||||
|
||||
/* Turn on timer */
|
||||
if(!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) {
|
||||
if (!(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING)) {
|
||||
TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT;
|
||||
TIMER_Init(PWM_TIMER, &timerInit);
|
||||
}
|
||||
|
||||
// Set route enable
|
||||
if(pwmout_channel_route_active(pwmout_get_channel_route(obj->channel))) {
|
||||
if (pwmout_channel_route_active(pwmout_get_channel_route(obj->channel))) {
|
||||
//This channel was already in use
|
||||
//TODO: gracefully handle this case. mbed_error?
|
||||
return;
|
||||
|
|
@ -190,19 +195,19 @@ void pwmout_init(pwmout_t *obj, PinName pin)
|
|||
switch (obj->channel) {
|
||||
case PWM_CH0:
|
||||
PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC0LOC_MASK;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC0LOC_SHIFT;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC0LOC_SHIFT;
|
||||
break;
|
||||
case PWM_CH1:
|
||||
PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC1LOC_MASK;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM)<< _TIMER_ROUTELOC0_CC1LOC_SHIFT;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC1LOC_SHIFT;
|
||||
break;
|
||||
case PWM_CH2:
|
||||
PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC2LOC_MASK;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC2LOC_SHIFT;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC2LOC_SHIFT;
|
||||
break;
|
||||
case PWM_CH3:
|
||||
PWM_TIMER->ROUTELOC0 &= ~_TIMER_ROUTELOC0_CC3LOC_MASK;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTELOC0_CC3LOC_SHIFT;
|
||||
PWM_TIMER->ROUTELOC0 |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTELOC0_CC3LOC_SHIFT;
|
||||
break;
|
||||
default:
|
||||
MBED_ASSERT(false);
|
||||
|
|
@ -211,10 +216,10 @@ void pwmout_init(pwmout_t *obj, PinName pin)
|
|||
// On P1, the route location is statically defined for the entire timer.
|
||||
PWM_TIMER->ROUTE &= ~_TIMER_ROUTE_LOCATION_MASK;
|
||||
// Make sure the route location is not overwritten
|
||||
if(pwmout_all_inactive()) {
|
||||
PWM_TIMER->ROUTE |= pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT;
|
||||
if (pwmout_all_inactive()) {
|
||||
PWM_TIMER->ROUTE |= pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT;
|
||||
} else {
|
||||
MBED_ASSERT((PWM_TIMER->ROUTE & _TIMER_ROUTE_LOCATION_MASK) == pinmap_find_function(pin,PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT);
|
||||
MBED_ASSERT((PWM_TIMER->ROUTE & _TIMER_ROUTE_LOCATION_MASK) == pinmap_find_function(pin, PinMap_PWM) << _TIMER_ROUTE_LOCATION_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -224,7 +229,7 @@ void pwmout_init(pwmout_t *obj, PinName pin)
|
|||
|
||||
void pwmout_free(pwmout_t *obj)
|
||||
{
|
||||
if(pwmout_disable_channel_route(pwmout_get_channel_route(obj->channel))) {
|
||||
if (pwmout_disable_channel_route(pwmout_get_channel_route(obj->channel))) {
|
||||
//Channel was previously enabled, so do housekeeping
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
} else {
|
||||
|
|
@ -233,10 +238,10 @@ void pwmout_free(pwmout_t *obj)
|
|||
|
||||
pwmout_enable_pins(obj, false);
|
||||
|
||||
if(pwmout_all_inactive()) {
|
||||
if (pwmout_all_inactive()) {
|
||||
//Stop timer
|
||||
PWM_TIMER->CMD = TIMER_CMD_STOP;
|
||||
while(PWM_TIMER->STATUS & TIMER_STATUS_RUNNING);
|
||||
while (PWM_TIMER->STATUS & TIMER_STATUS_RUNNING);
|
||||
|
||||
//Disable clock
|
||||
CMU_ClockEnable(PWM_TIMER_CLOCK, false);
|
||||
|
|
@ -248,14 +253,15 @@ void pwmout_write(pwmout_t *obj, float value)
|
|||
pwmout_write_channel(obj->channel, value);
|
||||
}
|
||||
|
||||
void pwmout_write_channel(uint32_t channel, float value) {
|
||||
void pwmout_write_channel(uint32_t channel, float value)
|
||||
{
|
||||
uint32_t width_cycles = 0;
|
||||
if (value < 0.0f) {
|
||||
width_cycles = 0;
|
||||
} else if (value >= 1.0f) {
|
||||
width_cycles = PWM_TIMER->TOPB + 1;
|
||||
} else {
|
||||
width_cycles = (uint16_t)((float)PWM_TIMER->TOPB * value);
|
||||
width_cycles = (uint16_t)((float)PWM_TIMER->TOPB * value);
|
||||
}
|
||||
|
||||
TIMER_CompareBufSet(PWM_TIMER, channel, width_cycles);
|
||||
|
|
@ -266,14 +272,13 @@ float pwmout_read(pwmout_t *obj)
|
|||
return pwmout_calculate_duty(TIMER_CaptureGet(PWM_TIMER, obj->channel), TIMER_TopGet(PWM_TIMER));
|
||||
}
|
||||
|
||||
float pwmout_calculate_duty(uint32_t width_cycles, uint32_t period_cycles) {
|
||||
if(width_cycles > period_cycles) {
|
||||
float pwmout_calculate_duty(uint32_t width_cycles, uint32_t period_cycles)
|
||||
{
|
||||
if (width_cycles > period_cycles) {
|
||||
return 1.0f;
|
||||
}
|
||||
else if (width_cycles == 0) {
|
||||
} else if (width_cycles == 0) {
|
||||
return 0.0f;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return (float) width_cycles / (float) period_cycles;
|
||||
}
|
||||
}
|
||||
|
|
@ -302,7 +307,9 @@ void pwmout_period(pwmout_t *obj, float seconds)
|
|||
}
|
||||
|
||||
//Check if anything changed
|
||||
if(((PWM_TIMER->CTRL & _TIMER_CTRL_PRESC_MASK) == (pwm_prescaler_div << _TIMER_CTRL_PRESC_SHIFT)) && (TIMER_TopGet(PWM_TIMER) == cycles)) return;
|
||||
if (((PWM_TIMER->CTRL & _TIMER_CTRL_PRESC_MASK) == (pwm_prescaler_div << _TIMER_CTRL_PRESC_SHIFT)) && (TIMER_TopGet(PWM_TIMER) == cycles)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Save previous period for recalculation of duty cycles
|
||||
uint32_t previous_period_cycles = PWM_TIMER->TOPB;
|
||||
|
|
@ -315,8 +322,8 @@ void pwmout_period(pwmout_t *obj, float seconds)
|
|||
|
||||
//For each active channel, re-calculate the compare value
|
||||
uint32_t channel = 0;
|
||||
while(pwmout_get_channel_route(channel) != 0) {
|
||||
if(pwmout_channel_route_active(channel)) {
|
||||
while (pwmout_get_channel_route(channel) != 0) {
|
||||
if (pwmout_channel_route_active(channel)) {
|
||||
//recalc and reset compare value
|
||||
pwmout_write_channel(channel, pwmout_calculate_duty(PWM_TIMER->CC[channel].CCVB, previous_period_cycles));
|
||||
}
|
||||
|
|
@ -334,24 +341,34 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
pwmout_period(obj, us / 1000000.0f);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return (TIMER_TopGet(PWM_TIMER) * 1000000) / REFERENCE_FREQUENCY;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
uint16_t width_cycles = (uint16_t) (((float) (REFERENCE_FREQUENCY >> pwm_prescaler_div)) * seconds);
|
||||
uint16_t width_cycles = (uint16_t)(((float)(REFERENCE_FREQUENCY >> pwm_prescaler_div)) * seconds);
|
||||
TIMER_CompareBufSet(PWM_TIMER, obj->channel, width_cycles);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_ms(pwmout_t *obj, int ms)
|
||||
{
|
||||
uint16_t width_cycles = (uint16_t) (((REFERENCE_FREQUENCY >> pwm_prescaler_div) * ms) / 1000);
|
||||
uint16_t width_cycles = (uint16_t)(((REFERENCE_FREQUENCY >> pwm_prescaler_div) * ms) / 1000);
|
||||
TIMER_CompareBufSet(PWM_TIMER, obj->channel, width_cycles);
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
||||
{
|
||||
uint16_t width_cycles = (uint16_t) (((uint64_t)(REFERENCE_FREQUENCY >> pwm_prescaler_div) * (uint64_t)us) / 1000000UL);
|
||||
uint16_t width_cycles = (uint16_t)(((uint64_t)(REFERENCE_FREQUENCY >> pwm_prescaler_div) * (uint64_t)us) / 1000000UL);
|
||||
TIMER_CompareBufSet(PWM_TIMER, obj->channel, width_cycles);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return (TIMER_CaptureGet(PWM_TIMER, obj->channel) * 1000000) / REFERENCE_FREQUENCY ;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ void pwmout_free(pwmout_t *obj)
|
|||
{
|
||||
// Stops and clear count operation
|
||||
TMRB_SetRunState(obj->channel, TMRB_STOP);
|
||||
pwmout_write(obj,0);
|
||||
pwmout_write(obj, 0);
|
||||
obj->channel = NULL;
|
||||
obj->trailing_timing = 0;
|
||||
obj->leading_timing = 0;
|
||||
|
|
@ -169,7 +169,7 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
// Restore the duty-cycle
|
||||
duty_cycle = (float)((obj->trailing_timing - obj->leading_timing) / obj->trailing_timing);
|
||||
obj->trailing_timing = cycles;
|
||||
obj->leading_timing = ((cycles)- (uint16_t)(cycles * duty_cycle));
|
||||
obj->leading_timing = ((cycles) - (uint16_t)(cycles * duty_cycle));
|
||||
|
||||
// Change the source clock division and period
|
||||
m_tmrb.Mode = TMRB_INTERVAL_TIMER;
|
||||
|
|
@ -192,6 +192,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
TMRB_SetRunState(obj->channel, TMRB_RUN);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->trailing_timing;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (seconds * 1000000.0f));
|
||||
|
|
@ -212,6 +217,11 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
pwmout_write(obj, value);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->trailing_timing - obj->leading_timing;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
prscl = T32A_PRSCLx_32;
|
||||
|
||||
obj->trailing_timing = (us * CALCULATE_RGC1_VAL);
|
||||
obj->leading_timing = ((obj->trailing_timing)- (obj->trailing_timing * duty_cycle));
|
||||
obj->leading_timing = ((obj->trailing_timing) - (obj->trailing_timing * duty_cycle));
|
||||
|
||||
obj->p_t32a.p_instance->MOD = T32A_MODE_32;
|
||||
obj->p_t32a.p_instance->RUNC = (T32A_RUN_DISABLE | T32A_COUNT_STOP);
|
||||
|
|
@ -207,6 +207,11 @@ void pwmout_period_us(pwmout_t *obj, int us)
|
|||
obj->p_t32a.p_instance->RUNC = (T32A_RUN_ENABLE | T32A_COUNT_START);
|
||||
}
|
||||
|
||||
int pwmout_read_period_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->trailing_timing;
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t *obj, float seconds)
|
||||
{
|
||||
pwmout_pulsewidth_us(obj, (seconds * 1000000.0f));
|
||||
|
|
@ -227,6 +232,11 @@ void pwmout_pulsewidth_us(pwmout_t *obj, int us)
|
|||
pwmout_write(obj, value);
|
||||
}
|
||||
|
||||
int pwmout_read_pulsewidth_us(pwmout_t *obj)
|
||||
{
|
||||
return obj->trailing_timing - obj->leading_timing;
|
||||
}
|
||||
|
||||
const PinMap *pwmout_pinmap()
|
||||
{
|
||||
return PinMap_PWM;
|
||||
|
|
|
|||
Loading…
Reference in New Issue