mirror of https://github.com/ARMmbed/mbed-os.git
MIMXRT1050_EVK: Fix the PWM Hal driver
1. Add Pin defines for missing PWM pins 2. Update the hal to account for the number of PWM instances 3. Fix the register reload policy 4. Configure the XBAR to put the PWM fault inputs in inactive state Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>pull/8099/head
parent
920db63453
commit
3661dc7e71
|
@ -23,12 +23,13 @@
|
|||
#include "fsl_pwm.h"
|
||||
#include "PeripheralPins.h"
|
||||
|
||||
static float pwm_clock_mhz;
|
||||
static float pwm_clock_mhz = 0;
|
||||
|
||||
|
||||
/* Array of PWM peripheral base address. */
|
||||
static PWM_Type *const pwm_addrs[] = PWM_BASE_PTRS;
|
||||
|
||||
extern void pwm_setup_clock();
|
||||
extern void pwm_setup();
|
||||
extern uint32_t pwm_get_clock();
|
||||
|
||||
void pwmout_init(pwmout_t* obj, PinName pin)
|
||||
|
@ -36,48 +37,57 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
|
||||
MBED_ASSERT(pwm != (PWMName)NC);
|
||||
|
||||
pwm_setup_clock();
|
||||
uint32_t pwm_base_clock;
|
||||
uint32_t instance = (pwm >> PWM_SHIFT) & 0x7;
|
||||
uint32_t module = (pwm >> PWM_MODULE_SHIFT) & 0x3;
|
||||
uint32_t pwmchannel = pwm & 0x1;
|
||||
pwm_config_t pwmInfo;
|
||||
static uint32_t clkdiv;
|
||||
|
||||
obj->pwm_name = pwm;
|
||||
|
||||
uint32_t pwm_base_clock;
|
||||
pwm_base_clock = pwm_get_clock();
|
||||
float clkval = (float)pwm_base_clock / 1000000.0f;
|
||||
uint32_t clkdiv = 0;
|
||||
while (clkval > 1) {
|
||||
clkdiv++;
|
||||
clkval /= 2.0f;
|
||||
if (clkdiv == 7) {
|
||||
break;
|
||||
|
||||
if (pwm_clock_mhz == 0) {
|
||||
float clkval = (float)pwm_base_clock / 1000000.0f;
|
||||
|
||||
while (clkval > 1) {
|
||||
clkdiv++;
|
||||
clkval /= 2.0f;
|
||||
if (clkdiv == 7) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
pwm_clock_mhz = clkval;
|
||||
}
|
||||
|
||||
pwm_clock_mhz = clkval;
|
||||
uint32_t instance = (pwm >> PWM_SHIFT) & 0x3;
|
||||
uint32_t module = pwm >> PWM_MODULE_SHIFT;
|
||||
uint8_t pwmchannel = pwm & 0x1;
|
||||
pwm_config_t pwmInfo;
|
||||
pwm_setup(instance);
|
||||
|
||||
/* Initialize PWM module */
|
||||
PWM_GetDefaultConfig(&pwmInfo);
|
||||
pwmInfo.prescale = (pwm_clock_prescale_t)clkdiv;
|
||||
/* Initialize PWM module */
|
||||
|
||||
PWM_Init(pwm_addrs[instance], (pwm_submodule_t)module, &pwmInfo);
|
||||
|
||||
pwm_signal_param_t config = {
|
||||
pwm_signal_param_t channel_config = {
|
||||
.level = kPWM_HighTrue,
|
||||
.dutyCyclePercent = 0,
|
||||
.deadtimeValue = 0
|
||||
};
|
||||
|
||||
if (pwmchannel == 0) {
|
||||
config.pwmChannel = kPWM_PwmA;
|
||||
channel_config.pwmChannel = kPWM_PwmA;
|
||||
} else {
|
||||
config.pwmChannel = kPWM_PwmB;
|
||||
channel_config.pwmChannel = kPWM_PwmB;
|
||||
}
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
PWM_SetupPwm(pwm_addrs[instance], (pwm_submodule_t)module, &config, 1, kPWM_EdgeAligned, 50, pwm_base_clock);
|
||||
// Setup the module signals to be low
|
||||
PWM_SetupPwm(pwm_addrs[instance], (pwm_submodule_t)module, &channel_config, 1, kPWM_EdgeAligned, 50, pwm_base_clock);
|
||||
|
||||
PWM_StartTimer(pwm_addrs[instance], module);
|
||||
/* Set the load okay bit for all submodules to load registers from their buffer */
|
||||
PWM_SetPwmLdok(pwm_addrs[instance], (1 << module), true);
|
||||
|
||||
/* Start the timer for the sub-module */
|
||||
PWM_StartTimer(pwm_addrs[instance], (1 << module));
|
||||
|
||||
// Wire pinout
|
||||
pinmap_pinout(pin, PinMap_PWM);
|
||||
|
@ -85,10 +95,10 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
|
||||
void pwmout_free(pwmout_t* obj)
|
||||
{
|
||||
uint32_t instance = (obj->pwm_name >> PWM_SHIFT) & 0x3;
|
||||
uint32_t module = obj->pwm_name >> PWM_MODULE_SHIFT;
|
||||
uint32_t instance = (obj->pwm_name >> PWM_SHIFT) & 0x7;
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
|
||||
PWM_Deinit(pwm_addrs[instance], (pwm_submodule_t)module);
|
||||
PWM_StopTimer(pwm_addrs[instance], (1 << module));
|
||||
}
|
||||
|
||||
void pwmout_write(pwmout_t* obj, float value)
|
||||
|
@ -99,9 +109,9 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
value = 1.0f;
|
||||
}
|
||||
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x3];
|
||||
uint32_t module = obj->pwm_name >> PWM_MODULE_SHIFT;
|
||||
uint32_t pwmchannel = obj->pwm_name & 0xF;
|
||||
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;
|
||||
uint16_t pulseCnt = 0;
|
||||
|
||||
pulseCnt = base->SM[module].VAL1;
|
||||
|
@ -117,15 +127,14 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
}
|
||||
|
||||
/* Set the load okay bit */
|
||||
PWM_SetPwmLdok(base, module, true);
|
||||
|
||||
PWM_SetPwmLdok(base, (1 << module), true);
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x3];
|
||||
uint32_t module = obj->pwm_name >> PWM_MODULE_SHIFT;
|
||||
uint32_t pwmchannel = obj->pwm_name & 0xF;
|
||||
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;
|
||||
uint16_t count;
|
||||
uint16_t mod = (base->SM[module].VAL1) & PWM_VAL1_VAL1_MASK;
|
||||
|
||||
|
@ -157,12 +166,30 @@ void pwmout_period_ms(pwmout_t* obj, int ms)
|
|||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x3];
|
||||
uint32_t module = obj->pwm_name >> PWM_MODULE_SHIFT;
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x7];
|
||||
uint32_t module = (obj->pwm_name >> PWM_MODULE_SHIFT) & 0x3;
|
||||
float dc = pwmout_read(obj);
|
||||
uint32_t pwm_base_clock;
|
||||
|
||||
pwm_base_clock = pwm_get_clock();
|
||||
uint32_t clkdiv = 0;
|
||||
|
||||
pwm_clock_mhz = (float) pwm_base_clock / 1000000.0f;
|
||||
uint32_t mod = (pwm_clock_mhz * (float) us) - 1;
|
||||
while (mod > 0xFFFF) {
|
||||
++clkdiv;
|
||||
pwm_clock_mhz /= 2.0f;
|
||||
mod = (pwm_clock_mhz * (float) us) - 1;
|
||||
if (clkdiv == 7) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
uint32_t PRSC = base->SM[module].CTRL & ~PWM_CTRL_PRSC_MASK;
|
||||
PRSC |= PWM_CTRL_PRSC(clkdiv);
|
||||
base->SM[module].CTRL = PRSC;
|
||||
|
||||
/* Indicates the end of the PWM period */
|
||||
base->SM[module].VAL1 = PWM_VAL1_VAL1((pwm_clock_mhz * (float)us) - 1);
|
||||
base->SM[module].VAL1 = PWM_VAL1_VAL1(mod);
|
||||
|
||||
pwmout_write(obj, dc);
|
||||
}
|
||||
|
@ -179,9 +206,9 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
|||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
{
|
||||
PWM_Type *base = pwm_addrs[(obj->pwm_name >> PWM_SHIFT) & 0x3];
|
||||
uint32_t module = obj->pwm_name >> PWM_MODULE_SHIFT;
|
||||
uint32_t pwmchannel = obj->pwm_name & 0xF;
|
||||
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;
|
||||
uint32_t value = (uint32_t)(pwm_clock_mhz * (float)us);
|
||||
|
||||
/* Setup the PWM dutycycle */
|
||||
|
@ -193,7 +220,7 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
|||
base->SM[module].VAL5 = value;
|
||||
}
|
||||
/* Set the load okay bit */
|
||||
PWM_SetPwmLdok(base, module, true);
|
||||
PWM_SetPwmLdok(base, (1 << module), true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,14 +52,38 @@ typedef enum {
|
|||
#define PWM_SHIFT 8
|
||||
|
||||
typedef enum {
|
||||
PWM_1 = (0 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 0 PWMA
|
||||
PWM_2 = (0 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 0 PWMB
|
||||
PWM_3 = (0 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 1 PWMA
|
||||
PWM_4 = (0 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 1 PWMB
|
||||
PWM_5 = (0 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 2 PWMA
|
||||
PWM_6 = (0 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 2 PWMB
|
||||
PWM_7 = (0 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 3 PWMA
|
||||
PWM_8 = (0 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 3 PWMB
|
||||
PWM_1 = (1 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 0 PWMA
|
||||
PWM_2 = (1 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 0 PWMB
|
||||
PWM_3 = (1 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 1 PWMA
|
||||
PWM_4 = (1 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 1 PWMB
|
||||
PWM_5 = (1 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 2 PWMA
|
||||
PWM_6 = (1 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 2 PWMB
|
||||
PWM_7 = (1 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (0), // PWM1 Submodule 3 PWMA
|
||||
PWM_8 = (1 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (1), // PWM1 Submodule 3 PWMB
|
||||
PWM_9 = (2 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (0), // PWM2 Submodule 0 PWMA
|
||||
PWM_10 = (2 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (1), // PWM2 Submodule 0 PWMB
|
||||
PWM_11 = (2 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (0), // PWM2 Submodule 1 PWMA
|
||||
PWM_12 = (2 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (1), // PWM2 Submodule 1 PWMB
|
||||
PWM_13 = (2 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (0), // PWM2 Submodule 2 PWMA
|
||||
PWM_14 = (2 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (1), // PWM2 Submodule 2 PWMB
|
||||
PWM_15 = (2 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (0), // PWM2 Submodule 3 PWMA
|
||||
PWM_16 = (2 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (1), // PWM2 Submodule 3 PWMB
|
||||
PWM_17 = (3 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (0), // PWM3 Submodule 0 PWMA
|
||||
PWM_18 = (3 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (1), // PWM3 Submodule 0 PWMB
|
||||
PWM_19 = (3 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (0), // PWM3 Submodule 1 PWMA
|
||||
PWM_20 = (3 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (1), // PWM3 Submodule 1 PWMB
|
||||
PWM_21 = (3 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (0), // PWM3 Submodule 2 PWMA
|
||||
PWM_22 = (3 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (1), // PWM3 Submodule 2 PWMB
|
||||
PWM_23 = (3 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (0), // PWM3 Submodule 3 PWMA
|
||||
PWM_24 = (3 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (1), // PWM3 Submodule 3 PWMB
|
||||
PWM_25 = (4 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (0), // PWM4 Submodule 0 PWMA
|
||||
PWM_26 = (4 << PWM_SHIFT) | (0 << PWM_MODULE_SHIFT) | (1), // PWM4 Submodule 0 PWMB
|
||||
PWM_27 = (4 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (0), // PWM4 Submodule 1 PWMA
|
||||
PWM_28 = (4 << PWM_SHIFT) | (1 << PWM_MODULE_SHIFT) | (1), // PWM4 Submodule 1 PWMB
|
||||
PWM_29 = (4 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (0), // PWM4 Submodule 2 PWMA
|
||||
PWM_30 = (4 << PWM_SHIFT) | (2 << PWM_MODULE_SHIFT) | (1), // PWM4 Submodule 2 PWMB
|
||||
PWM_31 = (4 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (0), // PWM4 Submodule 3 PWMA
|
||||
PWM_32 = (4 << PWM_SHIFT) | (3 << PWM_MODULE_SHIFT) | (1) // PWM4 Submodule 3 PWMB
|
||||
} PWMName;
|
||||
|
||||
#define ADC_INSTANCE_SHIFT 8
|
||||
|
|
|
@ -88,6 +88,9 @@ const PinMap PinMap_SPI_SSEL[] = {
|
|||
const PinMap PinMap_PWM[] = {
|
||||
{GPIO_AD_B0_10, PWM_7, ((3U << DAISY_REG_VALUE_SHIFT) | (0x454 << DAISY_REG_SHIFT) | 1)},
|
||||
{GPIO_AD_B0_11, PWM_8, ((3U << DAISY_REG_VALUE_SHIFT) | (0x464 << DAISY_REG_SHIFT) | 1)},
|
||||
{GPIO_AD_B1_08, PWM_25, ((1U << DAISY_REG_VALUE_SHIFT) | (0x494 << DAISY_REG_SHIFT) | 1)},
|
||||
{GPIO_SD_B0_00, PWM_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x458 << DAISY_REG_SHIFT) | 1)},
|
||||
{GPIO_SD_B0_01, PWM_2, ((1U << DAISY_REG_VALUE_SHIFT) | (0x468 << DAISY_REG_SHIFT) | 1)},
|
||||
{NC , NC , 0}
|
||||
};
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "pinmap.h"
|
||||
#include "fsl_clock_config.h"
|
||||
#include "fsl_clock.h"
|
||||
#include "fsl_xbara.h"
|
||||
#include "lpm.h"
|
||||
|
||||
#define LPSPI_CLOCK_SOURCE_DIVIDER (7U)
|
||||
|
@ -217,9 +218,35 @@ uint32_t i2c_get_clock()
|
|||
return ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U));
|
||||
}
|
||||
|
||||
void pwm_setup_clock()
|
||||
void pwm_setup(uint32_t instance)
|
||||
{
|
||||
/* Use default settings */
|
||||
/* Use default clock settings */
|
||||
/* Set the PWM Fault inputs to a low value */
|
||||
XBARA_Init(XBARA1);
|
||||
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault2);
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1234Fault3);
|
||||
|
||||
switch (instance) {
|
||||
case 1:
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault0);
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm1Fault1);
|
||||
break;
|
||||
case 2:
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm2Fault0);
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm2Fault1);
|
||||
break;
|
||||
case 3:
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm3Fault0);
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm3Fault1);
|
||||
break;
|
||||
case 4:
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm4Fault0);
|
||||
XBARA_SetSignalsConnection(XBARA1, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm4Fault1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t pwm_get_clock()
|
||||
|
|
Loading…
Reference in New Issue