From e059f65fd09694418f9fa4f38da90954ab9decfe Mon Sep 17 00:00:00 2001 From: 0xc0170 Date: Wed, 5 Feb 2014 21:35:49 +0100 Subject: [PATCH] pwm mbed HAL - using jusst ftm hal from KPSDK, not yet functional --- .../TARGET_K64F/PeripheralNames.h | 14 ++++ .../TARGET_KPSDK_MCUS/TARGET_K64F/objects.h | 5 +- .../TARGET_K64F/pwmout_api.c | 66 ++++++++++++++++--- .../sim/fsl_sim_clock_module_names_K64F12.c | 2 +- 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/PeripheralNames.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/PeripheralNames.h index c5f589948bf..694ee042f9b 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/PeripheralNames.h +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/PeripheralNames.h @@ -48,6 +48,20 @@ typedef enum { PWM_8 = (0 << TPM_SHIFT) | (7), // FTM0 CH7 PWM_9 = (1 << TPM_SHIFT) | (0), // FTM1 CH0 PWM_10 = (1 << TPM_SHIFT) | (1), // FTM1 CH1 + PWM_11 = (1 << TPM_SHIFT) | (2), // FTM1 CH2 + PWM_12 = (1 << TPM_SHIFT) | (3), // FTM1 CH3 + PWM_13 = (1 << TPM_SHIFT) | (4), // FTM1 CH4 + PWM_14 = (1 << TPM_SHIFT) | (5), // FTM1 CH5 + PWM_15 = (1 << TPM_SHIFT) | (6), // FTM1 CH6 + PWM_16 = (1 << TPM_SHIFT) | (7), // FTM1 CH7 + PWM_17 = (2 << TPM_SHIFT) | (0), // FTM2 CH0 + PWM_18 = (2 << TPM_SHIFT) | (1), // FTM2 CH1 + PWM_19 = (2 << TPM_SHIFT) | (2), // FTM2 CH2 + PWM_20 = (2 << TPM_SHIFT) | (3), // FTM2 CH3 + PWM_21 = (2 << TPM_SHIFT) | (4), // FTM2 CH4 + PWM_22 = (2 << TPM_SHIFT) | (5), // FTM2 CH5 + PWM_23 = (2 << TPM_SHIFT) | (6), // FTM2 CH6 + PWM_24 = (2 << TPM_SHIFT) | (7), // FTM2 CH7 } PWMName; #define ADC_SHIFT 8 diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/objects.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/objects.h index 77ec6fcefd3..c8f4e086879 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/objects.h +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/objects.h @@ -38,10 +38,7 @@ struct port_s { }; struct pwmout_s { - __IO uint32_t *MOD; - __IO uint32_t *CNT; - __IO uint32_t *CnV; - __IO uint32_t *SYNC; + PWMName pwm_name; }; struct serial_s { diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/pwmout_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/pwmout_api.c index e6857961030..2b7ce5c68d2 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/pwmout_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_K64F/pwmout_api.c @@ -18,45 +18,93 @@ #include "cmsis.h" #include "pinmap.h" #include "error.h" +#include "fsl_ftm_hal.h" +#include "fsl_mcg_hal.h" +#include "fsl_clock_manager.h" static const PinMap PinMap_PWM[] = { - {NC , NC , 0} + {PTB18, PWM_17, 3}, + {NC , NC , 0} }; -#define PWM_CLOCK_MHZ (0.75) // (48)MHz / 64 = (0.75)MHz +static float pwm_clock; void pwmout_init(pwmout_t* obj, PinName pin) { - + PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); + if (pwm == (PWMName)NC) { + error("PwmOut pin mapping failed"); + } + obj->pwm_name = pwm; + + float clkval = clock_hal_get_fllclk() / 1000000.0f; + uint32_t clkdiv = 0; + while (clkval > 1) { + clkdiv++; + clkval /= 2.0f; + if (clkdiv == 7) + break; + } + uint32_t channel = pwm & 0xF; + uint32_t instance = pwm >> TPM_SHIFT; + clock_manager_set_gate(kClockModuleFTM, instance, true); + ftm_hal_set_clock_ps(instance, (ftm_clock_ps_t)clkdiv); + ftm_hal_set_clock_source(instance, kClock_source_FTM_SystemClk); + ftm_hal_set_channel_edge_level(instance, channel, 2); + // default to 20ms: standard for servos, and fine for e.g. brightness control + pwmout_period_ms(obj, 20); + 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) { - + if (value < 0.0f) { + value = 0.0f; + } else if (value > 1.0f) { + value = 1.0f; + } + uint16_t mod = ftm_hal_get_mod(obj->pwm_name >> TPM_SHIFT); + uint32_t new_count = (uint32_t)((float)(mod) * value); + ftm_hal_set_channel_count_value(obj->pwm_name >> TPM_SHIFT, obj->pwm_name & 0xF, new_count); + // *obj->CNT = 0; } float pwmout_read(pwmout_t* obj) { - return 1; + uint16_t count = ftm_hal_get_channel_count_value(obj->pwm_name >> TPM_SHIFT, obj->pwm_name & 0xF, 0); + uint16_t mod = ftm_hal_get_mod(obj->pwm_name >> TPM_SHIFT); + float v = (float)(count) / (float)(mod); + return (v > 1.0f) ? (1.0f) : (v); } void pwmout_period(pwmout_t* obj, float seconds) { - + pwmout_period_us(obj, seconds * 1000000.0f); } 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) { + float dc = pwmout_read(obj); + ftm_hal_set_mod(obj->pwm_name >> TPM_SHIFT, (uint32_t)(pwm_clock * (float)us)); + pwmout_write(obj, dc); + } void pwmout_pulsewidth(pwmout_t* obj, float seconds) { - + pwmout_pulsewidth_us(obj, seconds * 1000000.0f); } void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) { + pwmout_pulsewidth_us(obj, ms * 1000); } void pwmout_pulsewidth_us(pwmout_t* obj, int us) { - + uint32_t value = (uint32_t)(pwm_clock * (float)us); + ftm_hal_set_channel_count_value(obj->pwm_name >> TPM_SHIFT, obj->pwm_name & 0xF, value); } diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sim/fsl_sim_clock_module_names_K64F12.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sim/fsl_sim_clock_module_names_K64F12.c index 98d8aa3a6a1..e320dab9409 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sim/fsl_sim_clock_module_names_K64F12.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sim/fsl_sim_clock_module_names_K64F12.c @@ -82,7 +82,7 @@ const sim_clock_gate_module_config_t kSimClockGateModuleConfigTable [] = { {kSimClockModulePDB, 0, HW_SIM_SCGC6_ADDR, SIM_SCGC6_PDB_MASK}, {kSimClockModuleFTM, 0, HW_SIM_SCGC6_ADDR, SIM_SCGC6_FTM0_MASK}, {kSimClockModuleFTM, 1, HW_SIM_SCGC6_ADDR, SIM_SCGC6_FTM1_MASK}, - {kSimClockModuleFTM, 2, HW_SIM_SCGC3_ADDR, SIM_SCGC3_FTM2_MASK}, + {kSimClockModuleFTM, 2, HW_SIM_SCGC6_ADDR, SIM_SCGC6_FTM2_MASK}, {kSimClockModuleFTM, 3, HW_SIM_SCGC3_ADDR, SIM_SCGC3_FTM3_MASK}, {kSimClockModulePIT, 0, HW_SIM_SCGC6_ADDR, SIM_SCGC6_PIT_MASK}, {kSimClockModuleLPTIMER, 0, HW_SIM_SCGC5_ADDR, SIM_SCGC5_LPTMR_MASK},