Skip to content

Instantly share code, notes, and snippets.

@monpetit
Last active July 12, 2016 21:26
Show Gist options
  • Save monpetit/bfb53385cd64bff31cc717d4dfc06201 to your computer and use it in GitHub Desktop.
Save monpetit/bfb53385cd64bff31cc717d4dfc06201 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_int.h"
#include "em_timer.h"
#define LED_PIN (0)
#define LED_PORT (gpioPortA)
volatile uint32_t systick_count = 0;
uint32_t clock_freq;
__STATIC_INLINE void __delay_tick(volatile uint32_t n);
__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);
void init_clocks(void);
void init_timer0(void);
void init_portio(void);
/* Define PWM frequency value */
#define PWM_FREQ 20000
uint32_t timer0_top;
void pulse_out(unsigned int ch, uint32_t duty_cycle)
{
if (duty_cycle <= 100)
TIMER_CompareBufSet(TIMER0, ch, (duty_cycle * timer0_top) / 100);
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
/* Enter default mode */
init_clocks();
init_portio();
init_timer0();
/* Ensure core frequency has been updated */
SystemCoreClockUpdate();
/* Start Systick Timer */
setup_systick_timer();
/* Set Top Value */
uint32_t freq = CMU_ClockFreqGet(cmuClock_HFPER);
timer0_top = freq / PWM_FREQ;
TIMER_TopSet(TIMER0, timer0_top);
reset_blink(30);
/* Infinite loop */
while (1) {
for (uint32_t i = 0; i <= 100; i++) {
pulse_out(0, i);
pulse_out(2, 100 - i);
__delay_ms(15);
}
}
}
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)
{
volatile uint8_t cnt = countdown / 2;
while (cnt--) {
pulse_out(0, 100);
__delay_ms(20);
pulse_out(0, 0);
__delay_ms(20);
}
__delay_ms(1000);
}
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 Boost Percent]$
// $[LFXO enable]
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
// [LFXO enable]$
// $[HFXO enable]
CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
// [HFXO enable]$
// $[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);
// [High Frequency Clock select]$
// $[Peripheral Clock enables]
/* Enable clock for TIMER0 */
CMU_ClockEnable(cmuClock_TIMER0, true);
/* Enable clock for GPIO by default */
CMU_ClockEnable(cmuClock_GPIO, true);
// [Peripheral Clock enables]$
}
void init_portio(void)
{
// $[Port A Configuration]
/* 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 PA2 is configured to Push-pull */
GPIO->P[0].MODEL = (GPIO->P[0].MODEL & ~_GPIO_P_MODEL_MODE2_MASK)
| GPIO_P_MODEL_MODE2_PUSHPULL;
// [Port A Configuration]$
// $[Route Configuration]
/* Enable signals CC0, CC2 */
TIMER0->ROUTE |= TIMER_ROUTE_CC0PEN | TIMER_ROUTE_CC2PEN;
// [Route Configuration]$
}
void init_timer0(void)
{
// $[TIMER0 initialization]
TIMER_Init_TypeDef init = TIMER_INIT_DEFAULT;
init.enable = 1;
init.debugRun = 1;
init.dmaClrAct = 0;
init.sync = 0;
init.clkSel = timerClkSelHFPerClk;
init.prescale = timerPrescale64;
init.fallAction = timerInputActionNone;
init.riseAction = timerInputActionNone;
init.mode = timerModeUp;
init.quadModeX4 = 0;
init.oneShot = 0;
TIMER_Init(TIMER0, &init);
// [TIMER0 initialization]$
// $[TIMER0 CC0 init]
TIMER_InitCC_TypeDef initCC0 = TIMER_INITCC_DEFAULT;
initCC0.prsInput = false;
initCC0.prsSel = timerPRSSELCh0;
initCC0.edge = timerEdgeBoth;
initCC0.mode = timerCCModePWM;
initCC0.eventCtrl = timerEventEveryEdge;
initCC0.filter = 0;
initCC0.cofoa = timerOutputActionNone;
initCC0.cufoa = timerOutputActionNone;
initCC0.cmoa = timerOutputActionToggle;
initCC0.coist = 0;
initCC0.outInvert = 0;
TIMER_InitCC(TIMER0, 0, &initCC0);
// [TIMER0 CC0 init]$
// $[TIMER0 CC2 init]
TIMER_InitCC_TypeDef initCC2 = TIMER_INITCC_DEFAULT;
initCC2.prsInput = false;
initCC2.prsSel = timerPRSSELCh0;
initCC2.edge = timerEdgeBoth;
initCC2.mode = timerCCModePWM;
initCC2.eventCtrl = timerEventEveryEdge;
initCC2.filter = 0;
initCC2.cofoa = timerOutputActionNone;
initCC2.cufoa = timerOutputActionNone;
initCC2.cmoa = timerOutputActionToggle;
initCC2.coist = 0;
initCC2.outInvert = 0;
TIMER_InitCC(TIMER0, 2, &initCC2);
// [TIMER0 CC2 init]$
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment