| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2019 Google LLC. |
| * All rights reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "LED_Dimmer.h" |
| #include "fsl_common.h" |
| #include "fsl_port.h" |
| #include "fsl_tpm.h" |
| |
| #include <lib/support/logging/CHIPLogging.h> |
| |
| #define BOARD_TPM_BASEADDR TPM0 |
| #define TPM_SOURCE_CLOCK CLOCK_GetIpFreq(kCLOCK_Tpm0) |
| #define BOARD_FIRST_TPM_CHANNEL kTPM_Chnl_0 |
| #define BOARD_SECOND_TPM_CHANNEL kTPM_Chnl_1 |
| #define BOARD_THIRD_TPM_CHANNEL kTPM_Chnl_2 |
| #ifndef TPM_LED_ON_LEVEL |
| #define TPM_LED_ON_LEVEL kTPM_HighTrue |
| #endif |
| #ifndef DEMO_PWM_FREQUENCY |
| #define DEMO_PWM_FREQUENCY (24000U) |
| #endif |
| |
| volatile uint8_t updatedDutycycle = 0U; |
| |
| void init_dimmable() |
| { |
| const port_pin_config_t porta20_pin17_config = { /* Internal pull-up/down resistor is disabled */ |
| (uint16_t) kPORT_PullDisable, |
| /* Low internal pull resistor value is selected. */ |
| (uint16_t) kPORT_LowPullResistor, |
| /* Fast slew rate is configured */ |
| (uint16_t) kPORT_FastSlewRate, |
| /* Passive input filter is disabled */ |
| (uint16_t) kPORT_PassiveFilterDisable, |
| /* Open drain output is disabled */ |
| (uint16_t) kPORT_OpenDrainDisable, |
| /* Low drive strength is configured */ |
| (uint16_t) kPORT_LowDriveStrength, |
| /* Normal drive strength is configured */ |
| (uint16_t) kPORT_NormalDriveStrength, |
| /* Pin is configured as TPM0_CH0 */ |
| (uint16_t) kPORT_MuxAlt5, |
| /* Pin Control Register fields [15:0] are not locked */ |
| (uint16_t) kPORT_UnlockRegister |
| }; |
| /* PORTA20 (pin 17) is configured as TPM0_CH0 */ |
| PORT_SetPinConfig(PORTA, 20U, &porta20_pin17_config); |
| |
| const port_pin_config_t porta21_pin18_config = { /* Internal pull-up/down resistor is disabled */ |
| (uint16_t) kPORT_PullDisable, |
| /* Low internal pull resistor value is selected. */ |
| (uint16_t) kPORT_LowPullResistor, |
| /* Fast slew rate is configured */ |
| (uint16_t) kPORT_FastSlewRate, |
| /* Passive input filter is disabled */ |
| (uint16_t) kPORT_PassiveFilterDisable, |
| /* Open drain output is disabled */ |
| (uint16_t) kPORT_OpenDrainDisable, |
| /* Low drive strength is configured */ |
| (uint16_t) kPORT_LowDriveStrength, |
| /* Normal drive strength is configured */ |
| (uint16_t) kPORT_NormalDriveStrength, |
| /* Pin is configured as TPM0_CH0 */ |
| (uint16_t) kPORT_MuxAlt5, |
| /* Pin Control Register fields [15:0] are not locked */ |
| (uint16_t) kPORT_UnlockRegister |
| }; |
| /* PORTA21 (pin 18) is configured as TPM0_CH0 */ |
| PORT_SetPinConfig(PORTA, 21U, &porta21_pin18_config); |
| |
| const port_pin_config_t porta19_pin14_config = { /* Internal pull-up/down resistor is disabled */ |
| (uint16_t) kPORT_PullDisable, |
| /* Low internal pull resistor value is selected. */ |
| (uint16_t) kPORT_LowPullResistor, |
| /* Fast slew rate is configured */ |
| (uint16_t) kPORT_FastSlewRate, |
| /* Passive input filter is disabled */ |
| (uint16_t) kPORT_PassiveFilterDisable, |
| /* Open drain output is disabled */ |
| (uint16_t) kPORT_OpenDrainDisable, |
| /* Low drive strength is configured */ |
| (uint16_t) kPORT_LowDriveStrength, |
| /* Normal drive strength is configured */ |
| (uint16_t) kPORT_NormalDriveStrength, |
| /* Pin is configured as TPM0_CH0 */ |
| (uint16_t) kPORT_MuxAlt5, |
| /* Pin Control Register fields [15:0] are not locked */ |
| (uint16_t) kPORT_UnlockRegister |
| }; |
| /* PORTA19 (pin 14) is configured as TPM0_CH0 */ |
| PORT_SetPinConfig(PORTA, 19U, &porta19_pin14_config); |
| |
| init_tpm(); |
| } |
| |
| void init_tpm() |
| { |
| tpm_config_t tpmInfo; |
| tpm_chnl_pwm_signal_param_t tpmParam[3]; |
| |
| /* TPM 0 Clock Gate Control: Clock enabled */ |
| CLOCK_EnableClock(kCLOCK_Tpm0); |
| /* Set the source for the LPIT module */ |
| CLOCK_SetIpSrc(kCLOCK_Tpm0, kCLOCK_IpSrcFro6M); |
| |
| /* Fill in the TPM config struct with the default settings */ |
| TPM_GetDefaultConfig(&tpmInfo); |
| /* Calculate the clock division based on the PWM frequency to be obtained */ |
| tpmInfo.prescale = TPM_CalculateCounterClkDiv(BOARD_TPM_BASEADDR, DEMO_PWM_FREQUENCY, TPM_SOURCE_CLOCK); |
| /* Initialize TPM module */ |
| TPM_Init(BOARD_TPM_BASEADDR, &tpmInfo); |
| |
| /* Configure tpm params with frequency 24kHZ */ |
| tpmParam[0].chnlNumber = (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL; |
| #if (defined(FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) && FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) |
| tpmParam[0].pauseLevel = kTPM_ClearOnPause; |
| #endif |
| tpmParam[0].level = TPM_LED_ON_LEVEL; |
| tpmParam[0].dutyCyclePercent = updatedDutycycle; |
| |
| tpmParam[1].chnlNumber = (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL; |
| #if (defined(FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) && FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) |
| tpmParam[1].pauseLevel = kTPM_ClearOnPause; |
| #endif |
| tpmParam[1].level = TPM_LED_ON_LEVEL; |
| tpmParam[1].dutyCyclePercent = updatedDutycycle; |
| |
| tpmParam[2].chnlNumber = (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL; |
| #if (defined(FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) && FSL_FEATURE_TPM_HAS_PAUSE_LEVEL_SELECT) |
| tpmParam[2].pauseLevel = kTPM_ClearOnPause; |
| #endif |
| tpmParam[2].level = TPM_LED_ON_LEVEL; |
| tpmParam[2].dutyCyclePercent = updatedDutycycle; |
| |
| if (kStatus_Success != |
| TPM_SetupPwm(BOARD_TPM_BASEADDR, tpmParam, 2U, kTPM_EdgeAlignedPwm, DEMO_PWM_FREQUENCY, TPM_SOURCE_CLOCK)) |
| { |
| return; |
| } |
| |
| TPM_StartTimer(BOARD_TPM_BASEADDR, kTPM_SystemClock); |
| } |
| |
| void move_to_level(uint8_t level) |
| { |
| uint8_t control; |
| |
| updatedDutycycle = static_cast<int>(level * 90) / 255; |
| |
| control = TPM_GetChannelContorlBits(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL); |
| |
| /* Disable output on each channel of the pair before updating the dutycycle */ |
| TPM_DisableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL); |
| TPM_DisableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL); |
| TPM_DisableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL); |
| |
| /* Update PWM duty cycle */ |
| if ((kStatus_Success == |
| TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL, kTPM_EdgeAlignedPwm, updatedDutycycle)) && |
| (kStatus_Success == |
| TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL, kTPM_EdgeAlignedPwm, |
| updatedDutycycle)) && |
| (kStatus_Success == |
| TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL, kTPM_EdgeAlignedPwm, updatedDutycycle))) |
| { |
| ChipLogError(NotSpecified, "TPM: Duty cycle updated successfully"); |
| } |
| else |
| { |
| ChipLogError(NotSpecified, "ERR: Duty cycle failed to updated"); |
| } |
| |
| /* Start output on each channel of the pair with updated dutycycle */ |
| TPM_EnableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_FIRST_TPM_CHANNEL, control); |
| TPM_EnableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_SECOND_TPM_CHANNEL, control); |
| TPM_EnableChannel(BOARD_TPM_BASEADDR, (tpm_chnl_t) BOARD_THIRD_TPM_CHANNEL, control); |
| } |