Last active
June 16, 2016 04:15
-
-
Save monpetit/a9b32d1c867122806c0f8469d8993891 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <inttypes.h> | |
| #include "em_device.h" | |
| #include "em_chip.h" | |
| #include "em_usart.h" | |
| #include "em_cmu.h" | |
| #include "em_emu.h" | |
| #include "em_adc.h" | |
| #include "em_gpio.h" | |
| volatile uint32_t systick_count = 0; | |
| uint32_t clock_freq; | |
| __STATIC_INLINE uint32_t get_systick(void); | |
| void __delay_ms(uint32_t milliseconds); | |
| void setup_systick_timer(void); | |
| void reset_blink(volatile uint8_t countdown); | |
| uint32_t get_adc_ch4(void); | |
| __STATIC_INLINE void __uart_clear_screen(void); | |
| void init_clocks(void); | |
| void init_gpio(void); | |
| void init_adc0(void); | |
| void init_usart1(void); | |
| /**************************************************************************//** | |
| * @brief Main function | |
| *****************************************************************************/ | |
| int main(void) | |
| { | |
| /* Chip errata */ | |
| CHIP_Init(); | |
| init_clocks(); | |
| init_gpio(); | |
| init_adc0(); | |
| init_usart1(); | |
| /* Ensure core frequency has been updated */ | |
| SystemCoreClockUpdate(); | |
| /* Start Systick Timer */ | |
| setup_systick_timer(); | |
| reset_blink(30); | |
| /* Infinite loop */ | |
| while (1) { | |
| uint32_t adc_result = 0; | |
| float voltage; | |
| adc_result = get_adc_ch4(); | |
| voltage = (2.5 * ((adc_result + 1) * 4)) / 4096; // 3:1 ---> x4 | |
| GPIO_PinOutClear(gpioPortA, 0); | |
| __delay_ms(10); | |
| GPIO_PinOutSet(gpioPortA, 0); | |
| __uart_clear_screen(); | |
| printf("[ADC0] %u\r\n", adc_result); | |
| printf("[VBAT] %4.2fV", voltage); | |
| __delay_ms(2000); | |
| } | |
| } | |
| ///////////////////////////////////////// | |
| void SysTick_Handler(void) | |
| { | |
| systick_count++; | |
| } | |
| __STATIC_INLINE uint32_t get_systick(void) | |
| { | |
| return systick_count; | |
| } | |
| /****************************************************************************** | |
| * @brief Delay function | |
| *****************************************************************************/ | |
| void __delay_ms(uint32_t milliseconds) | |
| { | |
| uint32_t start_tick = get_systick(); | |
| while ((get_systick() - start_tick) < milliseconds) { | |
| } | |
| } | |
| void setup_systick_timer(void) | |
| { | |
| clock_freq = CMU_ClockFreqGet(cmuClock_CORE); | |
| /* Enable SysTick interrupt, necessary for __delay_ms() */ | |
| if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ; | |
| NVIC_EnableIRQ(SysTick_IRQn); | |
| } | |
| void reset_blink(volatile uint8_t countdown) | |
| { | |
| while (countdown--) { | |
| GPIO_PinOutToggle(gpioPortA, 0); | |
| __delay_ms(20); | |
| } | |
| } | |
| uint32_t get_adc_ch4(void) | |
| { | |
| ADC_Start(ADC0, adcStartSingle); | |
| /* Wait while conversion is active */ | |
| while (ADC0->STATUS & ADC_STATUS_SINGLEACT) ; | |
| /* Get ADC result */ | |
| return ADC_DataSingleGet(ADC0); | |
| } | |
| __STATIC_INLINE void __uart_clear_screen(void) | |
| { | |
| USART_Tx(USART1, (uint8_t) 0x11); | |
| __delay_ms(2); | |
| USART_Tx(USART1, (uint8_t) 0x13); | |
| __delay_ms(2); | |
| USART_Tx(USART1, (uint8_t) 0x00); | |
| __delay_ms(2); | |
| } | |
| void init_clocks(void) | |
| { | |
| // $[HFXO] | |
| CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOMODE_MASK) | CMU_CTRL_HFXOMODE_XTAL; | |
| CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_HFXOBOOST_MASK) | |
| | CMU_CTRL_HFXOBOOST_50PCENT; | |
| SystemHFXOClockSet(32000000); | |
| // $[Use oscillator source] | |
| CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOMODE_MASK) | CMU_CTRL_LFXOMODE_XTAL; | |
| // [Use oscillator source]$ | |
| // $[LFXO Boost Percent] | |
| CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | |
| | CMU_CTRL_LFXOBOOST_100PCENT; | |
| // $[LFXO enable] | |
| CMU_OscillatorEnable(cmuOsc_LFXO, true, true); | |
| // $[HFXO enable] | |
| CMU_OscillatorEnable(cmuOsc_HFXO, true, true); | |
| // $[LFACLK Setup] | |
| /* Select LFXO as clock source for LFACLK */ | |
| CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); | |
| // $[High Frequency Clock select] | |
| /* Using HFXO as high frequency clock, HFCLK */ | |
| CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); | |
| /* Enable peripheral clock */ | |
| CMU_ClockEnable(cmuClock_HFPER, true); | |
| /* Enable LF clocks */ | |
| CMU_ClockEnable(cmuClock_CORELE, true); | |
| CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); | |
| // $[Peripheral Clock enables] | |
| /* Enable clock for ADC0 */ | |
| CMU_ClockEnable(cmuClock_ADC0, true); | |
| /* Enable clock for USART1 */ | |
| CMU_ClockEnable(cmuClock_USART1, true); | |
| /* Enable clock for GPIO by default */ | |
| CMU_ClockEnable(cmuClock_GPIO, true); | |
| } | |
| void init_gpio(void) | |
| { | |
| /* Pin PA0 is configured to Push-pull */ | |
| GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | |
| | GPIO_P_MODEL_MODE0_PUSHPULL; | |
| /* Pin PA1 is configured to Input enabled with pull-up */ | |
| GPIO->P[0].DOUT |= (1 << 1); | |
| GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE1_MASK) | |
| | GPIO_P_MODEL_MODE1_INPUTPULL; | |
| } | |
| void init_adc0(void) | |
| { | |
| // $[ADC_Init] | |
| ADC_Init_TypeDef init = ADC_INIT_DEFAULT; | |
| init.ovsRateSel = adcOvsRateSel2; | |
| init.lpfMode = adcLPFilterBypass; | |
| init.warmUpMode = adcWarmupNormal; | |
| init.timebase = ADC_TimebaseCalc(0); | |
| init.prescale = ADC_PrescaleCalc(7000000, 0); | |
| init.tailgate = 0; | |
| ADC_Init(ADC0, &init); | |
| // $[ADC_InitSingle] | |
| ADC_InitSingle_TypeDef initsingle = ADC_INITSINGLE_DEFAULT; | |
| initsingle.prsSel = adcPRSSELCh0; | |
| initsingle.acqTime = adcAcqTime32; | |
| initsingle.reference = adcRef2V5; | |
| initsingle.resolution = adcRes12Bit; | |
| initsingle.input = adcSingleInpCh4; | |
| initsingle.diff = 0; | |
| initsingle.prsEnable = 0; | |
| initsingle.leftAdjust = 0; | |
| initsingle.rep = 0; | |
| /* Initialize a single sample conversion. | |
| * To start a conversion, use ADC_Start(). | |
| * Conversion result can be read with ADC_DataSingleGet(). */ | |
| ADC_InitSingle(ADC0, &initsingle); | |
| } | |
| void init_usart1(void) | |
| { | |
| /* Pin PC0 is configured to Push-pull */ | |
| GPIO->P[2].DOUT |= (1 << 0); | |
| GPIO->P[2].MODEL = (GPIO->P[2].MODEL & ~_GPIO_P_MODEL_MODE0_MASK) | |
| | GPIO_P_MODEL_MODE0_PUSHPULL; | |
| /* Pin PC1 is configured to Input enabled */ | |
| GPIO->P[2].MODEL = (GPIO->P[2].MODEL & ~_GPIO_P_MODEL_MODE1_MASK) | |
| | GPIO_P_MODEL_MODE1_INPUT; | |
| /* Enable signals RX, TX */ | |
| USART1->ROUTE |= USART_ROUTE_RXPEN | USART_ROUTE_TXPEN; | |
| // [Route Configuration]$ | |
| // $[USART_InitAsync] | |
| USART_InitAsync_TypeDef initasync = USART_INITASYNC_DEFAULT; | |
| initasync.baudrate = 9600; | |
| initasync.databits = usartDatabits8; | |
| initasync.parity = usartNoParity; | |
| initasync.stopbits = usartStopbits1; | |
| initasync.oversampling = usartOVS16; | |
| #if defined( USART_INPUT_RXPRS ) && defined( USART_CTRL_MVDIS ) | |
| initasync.mvdis = 0; | |
| initasync.prsRxEnable = 0; | |
| initasync.prsRxCh = 0; | |
| #endif | |
| USART_InitAsync(USART1, &initasync); | |
| // $[USART_InitPrsTrigger] | |
| USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT; | |
| initprs.rxTriggerEnable = 0; | |
| initprs.txTriggerEnable = 0; | |
| initprs.prsTriggerChannel = usartPrsTriggerCh0; | |
| USART_InitPrsTrigger(USART1, &initprs); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment