blob: 02a62724716e53796a4db29b15f0c0975dfe43fe [file] [log] [blame]
/*
*
* 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);
}