Skip to content

Instantly share code, notes, and snippets.

@monpetit
Last active June 16, 2016 04:15
Show Gist options
  • Select an option

  • Save monpetit/a9b32d1c867122806c0f8469d8993891 to your computer and use it in GitHub Desktop.

Select an option

Save monpetit/a9b32d1c867122806c0f8469d8993891 to your computer and use it in GitHub Desktop.
#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