Hi
This solution is integrated in the uTasker Kinetis project as described at https://community.nxp.com/thread/446206
For example, the following sets TPM1 channels 0 and 1 to perform 20kHz sampling with one fixed input (ADC0-SE8) saving to a RAM buffer (sADC_buffer) by DMA. A PIT interrupt is then used to sample the B input
PWM_INTERRUPT_SETUP pwm_setup;
PIT_SETUP pit_setup;
ADC_SETUP adc_setup;
adc_setup.int_type = ADC_INTERRUPT;
adc_setup.dma_int_priority = 3;
adc_setup.dma_int_handler = 0;
adc_setup.ucDmaTriggerSource = DMAMUX0_CHCFG_SOURCE_TPM1_OVERFLOW;
adc_setup.ucDmaChannel = 2;
adc_setup.int_adc_mode = (ulCalibrate | ADC_FULL_BUFFER_DMA | ADC_HALF_BUFFER_DMA | ADC_SELECT_INPUTS_A | ADC_CLOCK_BUS_DIV_2 | ADC_CLOCK_DIVIDE_8 | ADC_SAMPLE_ACTIVATE_LONG | ADC_CONFIGURE_ADC | ADC_REFERENCE_VREF | ADC_CONFIGURE_CHANNEL | ADC_SINGLE_ENDED_INPUT | ADC_SINGLE_SHOT_MODE | ADC_12_BIT_MODE | ADC_HW_TRIGGERED);
adc_setup.int_adc_mode |= ADC_FULL_BUFFER_DMA_AUTO_REPEAT;
adc_setup.pga_gain = PGA_GAIN_OFF;
adc_setup.int_adc_controller = 0;
adc_setup.int_adc_int_type = (ADC_SINGLE_SHOT_TRIGGER_INT);
adc_setup.int_adc_offset = 0;
adc_setup.int_adc_bit = ADC_SE8_SINGLE;
adc_setup.ptrADC_Buffer = sADC_buffer;
adc_setup.ulADC_buffer_length = sizeof(sADC_buffer);
adc_setup.dma_int_handler = 0;
adc_setup.int_adc_sample = (ADC_SAMPLE_LONG_PLUS_12 | ADC_SAMPLE_AVERAGING_8);
adc_setup.int_adc_bit_b = ADC_TEMP_SENSOR;
adc_setup.int_adc_result = 0;
fnConfigureInterrupt((void *)&adc_setup);
pwm_setup.int_type = PWM_INTERRUPT;
pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_16 | PWM_CENTER_ALIGNED | PWM_DMA_PERIOD_ENABLE | PWM_NO_OUTPUT);
pwm_setup.int_handler = 0;
pwm_setup.pwm_frequency = PWM_FREQUENCY(20000, 16);
pwm_setup.pwm_value = _PWM_PERCENT(1, pwm_setup.pwm_frequency);
pwm_setup.pwm_reference = (_TIMER_1 | 0);
fnConfigureInterrupt((void *)&pwm_setup);
pwm_setup.pwm_value = _PWM_PERCENT(99, pwm_setup.pwm_frequency);
pwm_setup.pwm_reference = (_TIMER_1 | 1);
fnConfigureInterrupt((void *)&pwm_setup);
pit_setup.int_type = PIT_INTERRUPT;
pit_setup.mode = PIT_PERIODIC;
pit_setup.ucPIT = 0;
pit_setup.int_handler = slow_sample;
pit_setup.int_priority = PIT0_INTERRUPT_PRIORITY;
pit_setup.count_delay = PIT_MS_DELAY(5);
fnConfigureInterrupt((void *)&pit_setup);
The PIT interrupt can cycle through 4 x B inputs using (eg. of ADC0-SE4, ADC0-SE12 ADC0-Differential, temperature sensor sequence)
#define MUX_INPUT_COUNT 4
static const unsigned long ulNextMuxInput[MUX_INPUT_COUNT] = {
ADC_SE4_SINGLE, ADC_SE12_SINGLE, (ADC_D3_DIFF | ADC_SC1A_DIFF), ADC_TEMP_SENSOR
};
static unsigned short usLastSample[MUX_INPUT_COUNT];
static void slow_sample(void)
{
static int InputMuxSelect = 0;
usLastSample[InputMuxSelect] = ADC0_RB;
if (++InputMuxSelect >= MUX_INPUT_COUNT) {
InputMuxSelect = 0;
}
ADC0_SC1B = ulNextMuxInput[InputMuxSelect];
}
Regards
Mark
Professional support for Kinetis: http://www.utasker.com/index.html
Remote desktop one-on-one coaching: http://www.utasker.com/services.html
Getting started to expert videos: https://www.youtube.com/results?search_query=utasker+shorts