Files
TX/source/pwm.c
Brent Perteet 2ff7291c63 More refactoring
Lots of things removed but compiles again
2025-06-25 11:18:44 -05:00

243 lines
7.5 KiB
C

/*
* pwm.c
*
* Created on: Jul 25, 2023
* Author: Keith.Lloyd
*/
#include "pin_mux.h"
#include "board.h"
#include "fsl_sctimer.h"
#include <stdbool.h>
#include <stdint.h>
#include "pwm.h"
#include "ports.h"
#include "arm_math.h"
#include "timer.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define SCTIMER_CLK_FREQ CLOCK_GetFreq(kCLOCK_BusClk)
#define DEMO_SCTIMER_OUT kSCTIMER_Out_1
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool sctimerIsrFlag = false;
volatile bool brightnessUp = true; /* Indicate LED is brighter or dimmer */
volatile uint8_t BC_Duty_Cycle = 10;
uint32_t eventNumberOutput;
uint32_t eventNumberOutput2;
volatile bool PWM_Update_Flag = false;
extern uint8_t Port_State[];
/*******************************************************************************
* Code
******************************************************************************/
//OBSOLETE - DO NOT USE
void init_PWM(void)
{
sctimer_config_t sctimerInfo;
sctimer_pwm_signal_param_t pwmParam;
sctimer_pwm_signal_param_t pwmParam2; //Added this for 2nd output
uint32_t sctimerClock;
SCTIMER_GetDefaultConfig(&sctimerInfo);
#if 0 //Testing_external_clock
sctimerClock = 16384000; //SCTIMER_CLK_FREQ;
//change SCTimer schtuff here
sctimerInfo.clockMode = kSCTIMER_Input_ClockMode;
sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_0; //Note: 100MHz max external clock
#else
sctimerClock = SCTIMER_CLK_FREQ;
//todo: set sctimerInfo.clockMode and sctimerInfo.clockSelect for internal 144MHz clock - for changing back from external
#endif
/* Initialize SCTimer module */
SCTIMER_Init(SCT0, &sctimerInfo);
status_t status;
BC_Duty_Cycle = 10;
uint32_t BC_Frequency = 32768;
/* Configure PWM params with frequency 24kHZ from output */
pwmParam.output = kSCTIMER_Out_1; //output 1 = pin 43
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = BC_Duty_Cycle;
status = SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, BC_Frequency, sctimerClock, &eventNumberOutput);
// Configure 2nd PWM output pin
pwmParam2.output = kSCTIMER_Out_2; //Output 2 = pin 44
pwmParam2.level = kSCTIMER_LowTrue; //invert polarity
pwmParam2.dutyCyclePercent = 100 - BC_Duty_Cycle;
status = SCTIMER_SetupPwm(SCT0, &pwmParam2, kSCTIMER_CenterAlignedPwm, BC_Frequency, sctimerClock, &eventNumberOutput2);
/* Start the 32-bit unify timer */
SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U);
}
/*
* Set PWM frequency and duty cycle
* Set duty to 0 to disable
* Use Flexcomm 0 outputs 1 and 2
*/
void PWM_Setup(uint32_t newFreq, uint32_t dutyCycle)
{
//Error check
if(dutyCycle > 49 )
{
dutyCycle = 49;
}
sctimer_config_t sctimerInfo;
sctimer_pwm_signal_param_t pwmParam;
sctimer_pwm_signal_param_t pwmParam2; //Added this for 2nd output
uint32_t sctimerClock;
SCTIMER_GetDefaultConfig(&sctimerInfo);
#if 0 //New code Selects appropriate external oscillator.
SCTIMER_Deinit(SCT0);
SCTIMER_GetDefaultConfig(&sctimerInfo);
//Set up for correct clock
CLOCK_SELECT_t clock = PWM_GetBroadcastFrequencyOK(newFreq);
switch(clock)
{
case CS_EXT1:
sctimerClock = PWM_EXT1_FREQ_HZ;
sctimerInfo.clockMode = kSCTIMER_Input_ClockMode;
sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_0; //Note: 100MHz max external clock
break;
case CS_EXT2:
sctimerClock = PWM_EXT2_FREQ_HZ;
sctimerInfo.clockMode = kSCTIMER_Input_ClockMode;
sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_0;
break;
case CS_INTERNAL:
case CS_NUM:
default:
//Use internal clock. This is default setup for sctimerinfo.
sctimerClock = SCTIMER_CLK_FREQ;
break;
}
PWM_SetExternalClockSource(clock); //Set the external clock
#else //Functional code using internal clock
sctimerClock = SCTIMER_CLK_FREQ;
//todo: set sctimerInfo.clockMode and sctimerInfo.clockSelect for internal 144MHz clock - for changing back from external
#endif
/* Initialize SCTimer module */
SCTIMER_Init(SCT0, &sctimerInfo);
status_t status;
/* Configure PWM params with frequency 24kHZ from output */
pwmParam.output = kSCTIMER_Out_1; //output 1 = pin 43
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = dutyCycle;
status = SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_CenterAlignedPwm, newFreq, sctimerClock, &eventNumberOutput);
// Configure 2nd PWM output pin
pwmParam2.output = kSCTIMER_Out_2; //Output 2 = pin 44
pwmParam2.level = kSCTIMER_LowTrue; //invert polarity
pwmParam2.dutyCyclePercent = 100 - dutyCycle;
status = SCTIMER_SetupPwm(SCT0, &pwmParam2, kSCTIMER_CenterAlignedPwm, newFreq, sctimerClock, &eventNumberOutput2);
/* Start the 32-bit unify timer */
SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U);
}
/*
* Determine whether a frequency will work for broadcast and which clock to use
* returns CS_INTERNAL, CS_EXT1, or CS_EXT2 if one of them works
* returns the FIRST one that works
* returns CS_NUM if none of them work
*/
CLOCK_SELECT_t PWM_GetBroadcastFrequencyOK(uint32_t newFreq)
{
uint32_t clockFreq = 0;
uint32_t divider = 0;
float32_t testFreq = 0;
CLOCK_SELECT_t retval = (CS_NUM);
//Check internal clock
clockFreq = SCTIMER_CLK_FREQ;
divider = (uint32_t)(clockFreq / (newFreq * 2.0));
testFreq = clockFreq / (divider * 2.0);
if(fabs(testFreq - (float32_t)(newFreq)) <= PWM_MAX_BROADCAST_ERR_HZ)
{
return CS_INTERNAL;
}
//Check External 2
clockFreq = PWM_EXT2_FREQ_HZ;
divider = (uint32_t)(clockFreq / (newFreq * 2.0));
testFreq = clockFreq / (divider * 2.0);
if(fabs(testFreq - (float32_t)(newFreq)) <= PWM_MAX_BROADCAST_ERR_HZ)
{
return CS_EXT2;
}
//Check External 1
clockFreq = PWM_EXT1_FREQ_HZ;
divider = (uint32_t)(clockFreq / (newFreq * 2.0));
testFreq = clockFreq / (divider * 2.0);
if(fabs(testFreq - (float32_t)(newFreq)) <= PWM_MAX_BROADCAST_ERR_HZ)
{
return CS_EXT1;
}
return CS_NUM; //return this if none of the options work
}
void PWM_SetExternalClockSource(CLOCK_SELECT_t clock)
{
Port_State[TOP_SR] &= CLK_MASK_BITS; //clear external clock select bits
switch(clock)
{
case CS_EXT1:
Port_State[TOP_SR] |= MASK_15; //15.61MHz external
break;
case CS_EXT2:
Port_State[TOP_SR] |= MASK_58; //58.98MHz external
break;
case CS_INTERNAL:
Port_State[TOP_SR] |= MASK_144; //external OFF, use 144MHz internal clock
break;
}
SPI0_SendBytes(Port_State, 3, EXPANDER);
Delay_Ticks(1);
}