/* * Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_debug_console.h" #include "pin_mux.h" #include "clock_config.h" #include "board.h" #include "fsl_lpit.h" #include "fsl_lptmr.h" #include "fsl_trgmux.h" #include "fsl_common.h" #include "fsl_lpadc.h" #include "fsl_dac12.h" #include "fsl_gpio.h" /******************************************************************************* * Definitions ******************************************************************************/ /* Get source clock for LPTMR driver */ #define LPTMR_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_SlowClk) /* Define LPTMR microseconds counts value */ #define LPTMR_USEC_COUNT 65U /* Define GPIO for debugging*/ #define BOARD_LED_GPIO GPIOA #define BOARD_LED_GPIO_PIN 8U #define DEMO_LPADC_BASE ADC1 #define DEMO_LPADC_IRQn ADC1_IRQn #define DEMO_LPADC_USER_CHANNEL 6U #define DEMO_LPADC_USER_CMDID 15U #define DEMO_LPADC_IRQ_HANDLER_FUNC ADC1_IRQHandler /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ volatile bool lpitIsrFlag = false; volatile uint32_t lpitCounter = 0U; volatile bool g_LpadcConversionInProgressFlag = true; volatile uint16_t local_data[16]; lpadc_conv_result_t g_LpadcResultConfigStruct; /******************************************************************************* * Code ******************************************************************************/ void LPTMR0_IRQHandler(void) { LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag); /* * Workaround for TWR-KV58: because write buffer is enabled, adding * memory barrier instructions to make sure clearing interrupt flag completed * before go out ISR */ __DSB(); __ISB(); /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt */ __DSB(); } void ADC1_IRQHandler(void) { /* * Workaround for TWR-KV58: because write buffer is enabled, adding * memory barrier instructions to make sure clearing interrupt flag completed * before go out ISR */ __DSB(); __ISB(); /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping exception return operation might vector to incorrect interrupt */ __DSB(); // if (ADC_STAT_FOF(DEMO_LPADC_BASE->STAT)) // { // PRINTF("Error bit\r\n"); // DEMO_LPADC_BASE->STAT = DEMO_LPADC_BASE->STAT; // } g_LpadcConversionInProgressFlag = true; int i = 0; while (g_LpadcConversionInProgressFlag) { g_LpadcConversionInProgressFlag = LPADC_GetConvResult(DEMO_LPADC_BASE, &g_LpadcResultConfigStruct); local_data[i] = ((g_LpadcResultConfigStruct.convValue) >> 3U); i++; } /* Toggle GPIO to PIN J11-1*/ GPIO_PortToggle(BOARD_LED_GPIO, 1u << BOARD_LED_GPIO_PIN); SDK_ISR_EXIT_BARRIER; } void AdcInit(void) { PRINTF("Entering AdcInit\r\n"); /* ADC variables */ lpadc_config_t mLpadcConfigStruct; lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct; lpadc_conv_command_config_t mLpadcCommandConfigStruct; SCG0->FIRCDIV &= ~SCG_FIRCDIV_FIRCDIV2_MASK; SCG0->FIRCDIV |= SCG_FIRCDIV_FIRCDIV2(2); /* 24MHZ. */ CLOCK_SetIpSrc(kCLOCK_Adc1, kCLOCK_IpSrcFircAsync); PRINTF("LPADC Single Interrupt and DAC Example\r\n"); LPADC_GetDefaultConfig(&mLpadcConfigStruct); mLpadcConfigStruct.enableAnalogPreliminary = true; mLpadcConfigStruct.FIFOWatermark = 15U; /* Set watermark as 15U. */ LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct); /* Set conversion CMD configuration. */ LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct); mLpadcCommandConfigStruct.channelNumber = DEMO_LPADC_USER_CHANNEL; mLpadcCommandConfigStruct.sampleScaleMode = kLPADC_SamplePartScale; LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, DEMO_LPADC_USER_CMDID, &mLpadcCommandConfigStruct); /* Set trigger configuration. */ LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct); mLpadcTriggerConfigStruct.targetCommandId = DEMO_LPADC_USER_CMDID; mLpadcTriggerConfigStruct.enableHardwareTrigger = true; LPADC_SetConvTriggerConfig(DEMO_LPADC_BASE, 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */ /* Enable the watermark interrupt. */ LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFOWatermarkInterruptEnable); EnableIRQ(DEMO_LPADC_IRQn); } static void DEMO_InitLptmrTrigger(void) { lptmr_config_t lptmrConfig; /* Configure LPTMR */ /* * lptmrConfig.timerMode = kLPTMR_TimerModeTimeCounter; * lptmrConfig.pinSelect = kLPTMR_PinSelectInput_0; * lptmrConfig.pinPolarity = kLPTMR_PinPolarityActiveHigh; * lptmrConfig.enableFreeRunning = false; * lptmrConfig.bypassPrescaler = true; * lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_1; * lptmrConfig.value = kLPTMR_Prescale_Glitch_0; */ LPTMR_GetDefaultConfig(&lptmrConfig); lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_0; /* Initialize the LPTMR */ LPTMR_Init(LPTMR0, &lptmrConfig); /* * Set timer period. * Note : the parameter "ticks" of LPTMR_SetTimerPeriod should be equal or greater than 1. */ // LPTMR_SetTimerPeriod(LPTMR0, USEC_TO_COUNT(LPTMR_USEC_COUNT, LPTMR_SOURCE_CLOCK)); LPTMR_SetTimerPeriod(LPTMR0, 1600U); uint32_t clock_value = LPTMR_SOURCE_CLOCK; /* Enable timer interrupt */ LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable); /* Enable at the NVIC */ EnableIRQ(LPTMR0_IRQn); // /* Initialize ADC */ AdcInit(); PRINTF("Example Starts!\r\n"); /* Start counting */ LPTMR_StartTimer(LPTMR0); } void ConfigTriggerSource(void) { // TRGMUX_SetTriggerSource(TRGMUX0, kTRGMUX0_LPIT0, kTRGMUX_TriggerInput0, kTRGMUX0_SourceLPTMR0); //This setting routes lp timer to adc via trigger mux: TRGMUX_SetTriggerSource(TRGMUX0, kTRGMUX0_ADC1, kTRGMUX_TriggerInput0, kTRGMUX0_SourceLPTMR0); } /*! * @brief Main function */ int main(void) { /* Structure of initialize LPIT */ lpit_config_t lpitConfig; lpit_chnl_params_t lpitChannelConfig; /* Define the init structure for the output LED pin*/ gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, }; /* Board pin, clock, debug console init */ BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); /*GPIO*/ CLOCK_EnableClock(kCLOCK_Rgpio2p0); /* Set the source for the LPIT module */ CLOCK_SetIpSrc(kCLOCK_Lpit0, kCLOCK_IpSrcSystem); ConfigTriggerSource(); /* * lpitConfig.enableRunInDebug = false; * lpitConfig.enableRunInDoze = false; */ LPIT_GetDefaultConfig(&lpitConfig); /* Init lpit module */ LPIT_Init(LPIT0, &lpitConfig); lpitChannelConfig.chainChannel = false; lpitChannelConfig.enableReloadOnTrigger = false; lpitChannelConfig.enableStartOnTrigger = false; lpitChannelConfig.enableStopOnTimeout = false; lpitChannelConfig.timerMode = kLPIT_TriggerAccumulator; /* Set default values for the trigger source */ lpitChannelConfig.triggerSelect = kLPIT_Trigger_TimerChn0; lpitChannelConfig.triggerSource = kLPIT_TriggerSource_External; /* Init lpit channel 0 */ LPIT_SetupChannel(LPIT0, kLPIT_Chnl_0, &lpitChannelConfig); /* Set timer period for channel 0 */ LPIT_SetTimerPeriod(LPIT0, kLPIT_Chnl_0, 3); /* Enable timer interrupts for channel 0 */ LPIT_EnableInterrupts(LPIT0, kLPIT_Channel0TimerInterruptEnable); /* Enable at the NVIC */ EnableIRQ(LPIT0_IRQn); LPIT_StartTimer(LPIT0, kLPIT_Chnl_0); DEMO_InitLptmrTrigger(); /* Init output LED GPIO. */ GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &led_config); // int i; while (true) { if(!g_LpadcConversionInProgressFlag) { /*Print sample values in buffer for debugging*/ // for(i=0; i<16; i++) // { // PRINTF("%d, ", local_data[i]); // } // PRINTF("\r\n"); g_LpadcConversionInProgressFlag = true; } } }