Pin initialization of differential ADC of MK60DX256VLL10

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

Pin initialization of differential ADC of MK60DX256VLL10

Jump to solution
694 Views
hfabbasi
Contributor III

Using the SDK for MK60DX256VLL10, how to initialize pins of differential ADC of MK60DX256VLL10 in pin_mux.c file?

0 Kudos
1 Solution
672 Views
myke_predko
Senior Contributor III

@hfabbasi 

I'm using the SDK and the initialization code in a FreeRTOS application and it is quite simple (I hardcoded in channel "0" to use ADC0_DP0/ADC0_DM0 - you should probably have a #define for the channel that you use):

EnableIRQ(ADC0POLL_ADC16_IRQn);

// ADC Initialization Code
ADC16_GetDefaultConfig(&adc0pollConfigStruct);
#ifdef BOARD_ADC_USE_ALT_VREF
adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt;
#endif
ADC16_Init(ADC0_ADC16_BASE
, &adc0pollConfigStruct);
ADC16_EnableHardwareTrigger(ADC0_ADC16_BASE
, FALSE);
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
if (kStatus_Success != ADC16_DoAutoCalibration(ADC0_ADC16_BASE)) {
#if (2 != SDK_DEBUGCONSOLE)
PRINTF("ADCPOLL ADC16_DoAutoCalibration() Failed.\r\n");
#endif
vTaskSuspend(NULL);
}
#endif
adc0pollChannelConfigStruct.enableInterruptOnConversionCompleted = TRUE;
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
adc0pollChannelConfigStruct.enableDifferentialConversion = TRUE;
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */

to initiate an ADC operation:

adc0pollConversionDoneFlag = FALSE;
adc0pollChannelConfigStruct.channelNumber = 0; // For ADC0_DP0/ADC0_DM0
adc0pollChannelConfigStruct.enableDifferentialConversion = TRUE;
ADC16_SetChannelConfig(ADC0_ADC16_BASE
, ADC0POLL_TASK_CHANNEL_GROUP
, &adc0pollChannelConfigStruct);

The IRQ Handler:

void ADC0POLL_ADC16_IRQ_HANDLER_FUNC(void) {
/* Read conversion result to clear the conversion completed flag. */
adc0pollSensorValue = ADC16_GetChannelConversionValue(ADC0_ADC16_BASE
, ADC0POLL_TASK_CHANNEL_GROUP);
adc0pollConversionDoneFlag = TRUE;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

This code is really basically the same as the SDK example applications.  I'm noting that in case you are wondering where the "adc16ConfigStruct" & "adc0pollChannelConfigStruct" variable structures come from and how they are defined.  

Good luck!

View solution in original post

3 Replies
692 Views
myke_predko
Senior Contributor III

@hfabbasi 

You don't - the functionality has to be set within your code.  

If you use the Pin Wizard to specify the pins as ADC inputs, you'll discover that the IO in the pin_mux.h file will look something like below for the DP pin:

/*! @name ADC1_DP3 (coord L1), SPECTRO_SENSE_MIDDLE
@{ */
/* @} */

with no #defines associated with it.  I recommend that you do select the pin in the Wizard so that if there is a conflict, it will be picked up.  

To enable differential mode, when you are initializing the ADC, you will need to set "TRUE" the "enableDifferentialConverstion" boolean in your configStruct if you are using the SDK.  

If you are not using the SDK, you will have to set the SC1n(DIFF) bit to true and then when you select the channel, the ADC operation will be a differential operation using the DP# and DM# ADC input that you've selected.  

Good luck!

0 Kudos
675 Views
hfabbasi
Contributor III

Do you have any sample code to help me through it?

0 Kudos
673 Views
myke_predko
Senior Contributor III

@hfabbasi 

I'm using the SDK and the initialization code in a FreeRTOS application and it is quite simple (I hardcoded in channel "0" to use ADC0_DP0/ADC0_DM0 - you should probably have a #define for the channel that you use):

EnableIRQ(ADC0POLL_ADC16_IRQn);

// ADC Initialization Code
ADC16_GetDefaultConfig(&adc0pollConfigStruct);
#ifdef BOARD_ADC_USE_ALT_VREF
adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceValt;
#endif
ADC16_Init(ADC0_ADC16_BASE
, &adc0pollConfigStruct);
ADC16_EnableHardwareTrigger(ADC0_ADC16_BASE
, FALSE);
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
if (kStatus_Success != ADC16_DoAutoCalibration(ADC0_ADC16_BASE)) {
#if (2 != SDK_DEBUGCONSOLE)
PRINTF("ADCPOLL ADC16_DoAutoCalibration() Failed.\r\n");
#endif
vTaskSuspend(NULL);
}
#endif
adc0pollChannelConfigStruct.enableInterruptOnConversionCompleted = TRUE;
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
adc0pollChannelConfigStruct.enableDifferentialConversion = TRUE;
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */

to initiate an ADC operation:

adc0pollConversionDoneFlag = FALSE;
adc0pollChannelConfigStruct.channelNumber = 0; // For ADC0_DP0/ADC0_DM0
adc0pollChannelConfigStruct.enableDifferentialConversion = TRUE;
ADC16_SetChannelConfig(ADC0_ADC16_BASE
, ADC0POLL_TASK_CHANNEL_GROUP
, &adc0pollChannelConfigStruct);

The IRQ Handler:

void ADC0POLL_ADC16_IRQ_HANDLER_FUNC(void) {
/* Read conversion result to clear the conversion completed flag. */
adc0pollSensorValue = ADC16_GetChannelConversionValue(ADC0_ADC16_BASE
, ADC0POLL_TASK_CHANNEL_GROUP);
adc0pollConversionDoneFlag = TRUE;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

This code is really basically the same as the SDK example applications.  I'm noting that in case you are wondering where the "adc16ConfigStruct" & "adc0pollChannelConfigStruct" variable structures come from and how they are defined.  

Good luck!