LPC55 Problem to sync ADC with SCT

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC55 Problem to sync ADC with SCT

992 Views
Secad
Contributor II

Hi,

I have a custom board with a LPC5516JBD100. I am using MCUXpresso v11.5.1 with SDK v2.11.0.

My board control a DC motor and need to measure the current on the motor, so I want to synchronize ADC with SCT. The motor is turning one side with SCT0_4 (PIO0_23) and on the other side with SCT0_5 (PIO0_26).

The synchronisation is working with SCT0_4 but not for SCT0_5. Here is my code:

int Init_FTM0(void)
{
sctimer_config_t sctimerInfo;
sctimer_pwm_signal_param_t pwmParam;
uint32_t sctimerClock = SCTIMER_CLK_FREQ;

SCTIMER_GetDefaultConfig(&sctimerInfo);
sctimerInfo.enableCounterUnify = true;
sctimerInfo.clockMode = kSCTIMER_Input_ClockMode;
sctimerInfo.clockSelect = kSCTIMER_Clock_On_Rise_Input_7;

// Initialize SCTimer module
SCTIMER_Init(SCT0, &sctimerInfo);

// Configure PWM params with frequency 20kHZ from output
pwmParam.output = SCTIMER_MOT1; // SCT0_4
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 0;
if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_EdgeAlignedPwm, PWM_FREQ, sctimerClock, &eventOutputMot1) == kStatus_Fail)
{
return -1;
}
if ( pwmParam.dutyCyclePercent == 0 )
SCT0->OUT[SCTIMER_MOT1].SET = 0;

pwmParam.output = SCTIMER_MOT2; // SCT0_5
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 20;
if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_EdgeAlignedPwm, PWM_FREQ, sctimerClock, &eventOutputMot2) == kStatus_Fail)
{
return -1;
}
if ( pwmParam.dutyCyclePercent == 0 )
SCT0->OUT[SCTIMER_MOT2].SET = 0;

pwmParam.output = SCTIMER_LED; // SCT0_1
pwmParam.level = kSCTIMER_HighTrue;
pwmParam.dutyCyclePercent = 0;
if (SCTIMER_SetupPwm(SCT0, &pwmParam, kSCTIMER_EdgeAlignedPwm, PWM_FREQ, sctimerClock, &eventOutputLED) == kStatus_Fail)
{
return -1;
}
if ( pwmParam.dutyCyclePercent == 0 )
SCT0->OUT[SCTIMER_LED].SET = 0;

SCT0->EVEN = 0xFFFF; // Enable all event

// Start the 32-bit unify timer
SCTIMER_StartTimer(SCT0, kSCTIMER_Counter_U);

return 0;
}

void adc_init(void)
{
lpadc_config_t mLpadcConfigStruct;
lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
lpadc_conv_command_config_t mLpadcCommandConfigStruct;

// Disable LDOGPADC power down
POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC);

ANACTRL_Init(ANACTRL);
ANACTRL_EnableVref1V(ANACTRL, true);

LPADC_GetDefaultConfig(&mLpadcConfigStruct);
mLpadcConfigStruct.enableAnalogPreliminary = true;
mLpadcConfigStruct.referenceVoltageSource = kLPADC_ReferenceVoltageAlt3; // VREFP
mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage32;

LPADC_Init(LPADC_BASE, &mLpadcConfigStruct);

// Request offset calibration
LPADC_DoOffsetCalibration(LPADC_BASE);
// Request gain calibration
LPADC_DoAutoCalibration(LPADC_BASE);

// Set conversion CMD configuration for Imot Sens1 and Sens2
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.channelNumber = LPADC_IMOT_CHANNEL; // 0U = 8U - 8 (channel B)
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
#if defined(LPADC_USE_HIGH_RESOLUTION) && LPADC_USE_HIGH_RESOLUTION
mLpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
#endif /* DEMO_LPADC_USE_HIGH_RESOLUTION */
//mLpadcCommandConfigStruct.hardwareAverageMode = kLPADC_HardwareAverageCount32;
#if defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG
mLpadcCommandConfigStruct.enableWaitTrigger = true;
#endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
LPADC_SetConvCommandConfig(LPADC_BASE, TRIGGER_I_MOT_S1, &mLpadcCommandConfigStruct);
LPADC_SetConvCommandConfig(LPADC_BASE, TRIGGER_I_MOT_S2, &mLpadcCommandConfigStruct);
// Set trigger configuration for Imot Sens1
LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
mLpadcTriggerConfigStruct.targetCommandId = TRIGGER_I_MOT_S1;
mLpadcTriggerConfigStruct.delayPower = 2U;
mLpadcTriggerConfigStruct.enableHardwareTrigger = true;
mLpadcTriggerConfigStruct.priority = 1; // lower priority
LPADC_SetConvTriggerConfig(LPADC_BASE, 2U, &mLpadcTriggerConfigStruct); // SCT0-4 = 2U
// Set trigger configuration for Imot Sens2
mLpadcTriggerConfigStruct.targetCommandId = TRIGGER_I_MOT_S2;
LPADC_SetConvTriggerConfig(LPADC_BASE, 3U, &mLpadcTriggerConfigStruct); // SCT0-5 = 3U

// Set conversion CMD configuration for FORCE
mLpadcCommandConfigStruct.channelNumber = LPADC_FORCE_CHANNEL;
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
#if defined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) && FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG
mLpadcCommandConfigStruct.enableWaitTrigger = false;
#endif /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */
LPADC_SetConvCommandConfig(LPADC_BASE, TRIGGER_FORCE, &mLpadcCommandConfigStruct);
// Set trigger configuration for Force
mLpadcTriggerConfigStruct.targetCommandId = TRIGGER_FORCE;
mLpadcTriggerConfigStruct.delayPower = 0U;
mLpadcTriggerConfigStruct.enableHardwareTrigger = false;
mLpadcTriggerConfigStruct.priority = 0;
LPADC_SetConvTriggerConfig(LPADC_BASE, TRIGGER_FORCE, &mLpadcTriggerConfigStruct);

// Set conversion CMD configuration for 24V
mLpadcCommandConfigStruct.channelNumber = LPADC_24V_CHANNEL;
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
LPADC_SetConvCommandConfig(LPADC_BASE, TRIGGER_24V, &mLpadcCommandConfigStruct);
// Set trigger configuration for 24V
mLpadcTriggerConfigStruct.targetCommandId = TRIGGER_24V;
LPADC_SetConvTriggerConfig(LPADC_BASE, TRIGGER_24V, &mLpadcTriggerConfigStruct);

// Set conversion CMD configuration for ANA IN
mLpadcCommandConfigStruct.channelNumber = LPADC_ANAIN_CHANNEL;
mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
LPADC_SetConvCommandConfig(LPADC_BASE, TRIGGER_E_ANA_IN, &mLpadcCommandConfigStruct);
// Set trigger configuration for 24V
mLpadcTriggerConfigStruct.targetCommandId = TRIGGER_E_ANA_IN;
LPADC_SetConvTriggerConfig(LPADC_BASE, TRIGGER_E_ANA_IN, &mLpadcTriggerConfigStruct);

// Enable the watermark interrupt
LPADC_EnableInterrupts(LPADC_BASE, kLPADC_FIFO0WatermarkInterruptEnable);
EnableIRQ(LPADC_IRQn);
}

And I am reading the value:

if ( PWM_TRACTION != 0 )
{
//LPADC_DoSoftwareTrigger(LPADC_BASE, 1U << TRIGGER_I_MOT_S1);
while (!g_LpadcConversionCompletedFlag)
{
}
IMot_A = (float)((g_LpadcResultConfigStruct.convValue) >> g_LpadcResultShift) * GAIN_I_MOT_A_PTS;
g_LpadcConversionCompletedFlag = false;
}
else if ( PWM_RETURN != 0 )
{
//LPADC_DoSoftwareTrigger(LPADC_BASE, 1U << TRIGGER_I_MOT_S2);
while (!g_LpadcConversionCompletedFlag )
{
}
IMot_A = (float)((g_LpadcResultConfigStruct.convValue) >> g_LpadcResultShift) * GAIN_I_MOT_A_PTS;
g_LpadcConversionCompletedFlag = false;
}
else
IMot_A = 0;

Can you help please, I have done several test but I don't succeed to synchronise with SCT0_5.

Cheers.

Cédric

0 Kudos
Reply
3 Replies

713 Views
lukas01
Contributor I

Hey there, I'm currently facing a similar issue and was wondering if you were able to find a solution for it. It's quite challenging, and the absence of examples is not making it any easier. Your insights would be greatly appreciated! Thanks in advance!

0 Kudos
Reply

706 Views
Secad
Contributor II

Hi Lukas01,

I don't succeed to solve this problem. I succeed to synchronise one ADC input with one SCT (example code in the question for NXP) but I don't succeed to synchronise one ADC input with 2 SCT.

Finally, I haven't used the SCT synchronisation but the accuracy on the current measurement is less good. As I haven't any other pin available on the microcontroler, so I have modified my current filtering function to have a mean value and I compute the peak current value with the ADC value and the PWM value.

If you have ADC input available pin, you can try to connect your current measurement to 2 different ADC input and synchronise one ADC input to the first PWM and the other ADC to the second PWM.

Cheers.

Cédric

0 Kudos
Reply

958 Views
_Leo_
NXP TechSupport
NXP TechSupport

Hi @Secad,

Thank you so much for your interest in our products and for using our community.

I am sorry to inform you that so far we do not have that specific example code with SCTimer and ADC are synchronization.

However you can use the SDK example lpcxpresso55s69_mc_pmsm_core0 version v2.12.0 for reference. In that example, the SCTimer and ADC are synchronized via a trigger from SCTimer sct0_output[9]. For more details you can consult the user guide MCUXpresso SDK 3-Phase PMSM Control (LPC) (rev0).

Hope it helps you.

Have a nice day!

Best Regards,
Leonardo

0 Kudos
Reply