Skip to content

Instantly share code, notes, and snippets.

@monpetit
Created June 13, 2016 07:50
Show Gist options
  • Select an option

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

Select an option

Save monpetit/395cc642073784025e15d53e7e352f85 to your computer and use it in GitHub Desktop.
#include "em_system.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "em_device.h"
#include "em_chip.h"
#include "em_gpio.h"
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t u08;
typedef struct {
GPIO_Port_TypeDef port;
unsigned int pin;
} gpio_pin_t;
void init_clocks(void);
void init_gpio(void);
void __delay_ms(uint32_t milliseconds);
void setup_systick_timer(void);
uint32_t get_systick(void);
volatile uint32_t systick_count = 0;
uint32_t clock_freq;
#define delay(MS) __delay_ms(MS)
#define millis() get_systick()
// $[User-defined pin name abstraction]
#define GPIO_PA2_PIN (2)
#define GPIO_PA2_PORT (gpioPortA)
#define GPIO_PB11_PIN (11)
#define GPIO_PB11_PORT (gpioPortB)
#define GPIO_PC13_PIN (13)
#define GPIO_PC13_PORT (gpioPortC)
#define GPIO_PC14_PIN (14)
#define GPIO_PC14_PORT (gpioPortC)
#define GPIO_PC15_PIN (15)
#define GPIO_PC15_PORT (gpioPortC)
#define GPIO_PD5_PIN (5)
#define GPIO_PD5_PORT (gpioPortD)
#define GPIO_PD6_PIN (6)
#define GPIO_PD6_PORT (gpioPortD)
#define GPIO_PD7_PIN (7)
#define GPIO_PD7_PORT (gpioPortD)
#define GPIO_PE10_PIN (10)
#define GPIO_PE10_PORT (gpioPortE)
#define GPIO_PE11_PIN (11)
#define GPIO_PE11_PORT (gpioPortE)
#define GPIO_PE12_PIN (12)
#define GPIO_PE12_PORT (gpioPortE)
#define GPIO_PE13_PIN (13)
#define GPIO_PE13_PORT (gpioPortE)
#define HFXO_N_PIN (14)
#define HFXO_N_PORT (gpioPortB)
#define HFXO_P_PIN (13)
#define HFXO_P_PORT (gpioPortB)
#define LFXO_N_PIN (8)
#define LFXO_N_PORT (gpioPortB)
#define LFXO_P_PIN (7)
#define LFXO_P_PORT (gpioPortB)
// [User-defined pin name abstraction]$
//
// PINS ORDER: A, B, C, D, E, F, G, DP
//
const gpio_pin_t segment_pins[] = {
{GPIO_PE12_PORT, GPIO_PE12_PIN}, // A = PE12
{GPIO_PD6_PORT, GPIO_PD6_PIN}, // B = PD6
{GPIO_PC13_PORT, GPIO_PC13_PIN}, // C = PC13
{GPIO_PA2_PORT, GPIO_PA2_PIN}, // D = PA2
{GPIO_PD5_PORT, GPIO_PD5_PIN}, // E = PD5
{GPIO_PE11_PORT, GPIO_PE11_PIN}, // F = PE11
{GPIO_PC14_PORT, GPIO_PC14_PIN}, // G = PC14
{GPIO_PB11_PORT, GPIO_PB11_PIN}, // DP = PB11
};
const gpio_pin_t digit_pins[] = {
{GPIO_PC15_PORT, GPIO_PC15_PIN}, // DIG4 = PC15
{GPIO_PD7_PORT, GPIO_PD7_PIN}, // DIG3 = PD7
{GPIO_PE10_PORT, GPIO_PE10_PIN}, // DIG2 = PE10
{GPIO_PE13_PORT, GPIO_PE13_PIN}, // DIG1 = PE13
};
//
// BIT ORDER(MSB): A, B, C, D, E, F, G, DP
//
const u08 number_code[10] = {
0b11111100, //0
0b01100000, //1
0b11011010, //2
0b11110010, //3
0b01100110, //4
0b10110110, //5
0b10111110, //6
0b11100000, //7
0b11111110, //8
0b11110110, //9
};
__STATIC_INLINE void pin_hi(gpio_pin_t p)
{
GPIO_PinOutSet(p.port, p.pin);
}
__STATIC_INLINE void pin_lo(gpio_pin_t p)
{
GPIO_PinOutClear(p.port, p.pin);
}
__STATIC_INLINE void pin_write(gpio_pin_t p, u08 value)
{
if (value)
pin_hi(p);
else
pin_lo(p);
}
__STATIC_INLINE void display_digit1(u08 number)
{
u08 ncode = number_code[number];
for (int i = 0; i < 8; i++) {
pin_write(segment_pins[i], (ncode & 0x80));
ncode <<= 1;
}
}
__STATIC_INLINE void display_digit4(int number)
{
for (int i = 0; i < 4; i++) {
pin_lo(digit_pins[i]);
pin_hi(digit_pins[(i + 3) % 4]);
display_digit1(number % 10);
number /= 10;
__delay_ms(2); // delay millisecons
}
}
__STATIC_INLINE void display_7segment_led(int number, uint32_t ms)
{
uint32_t tick = get_systick();
while ((get_systick() - tick) < ms)
display_digit4(number);
}
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
/* Chip errata */
CHIP_Init();
init_clocks();
init_gpio();
for (int i = 0; i < 4; i++)
pin_hi(digit_pins[i]);
setup_systick_timer();
__delay_ms(2000);
/* Infinite loop */
while (1) {
for (int n = 0; n < 10000; n++) {
display_7segment_led(n, 100);
}
}
}
void init_clocks(void)
{
/* ----------------------------------- */
/* INIT 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);
/* ----------------------------------- */
/* INIT LFXO */
/* ----------------------------------- */
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;
/* ----------------------------------- */
/* INIT CLOCKS */
/* ----------------------------------- */
// $[LFXO enable]
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
// $[HFXO enable]
CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
// $[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 clock for GPIO by default */
CMU_ClockEnable(cmuClock_GPIO, true);
}
void init_gpio(void)
{
// $[Port A Configuration]
/* 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]$
// $[Port B Configuration]
/* Pin PB11 is configured to Push-pull */
GPIO->P[1].MODEH = (GPIO->P[1].MODEH & ~_GPIO_P_MODEH_MODE11_MASK)
| GPIO_P_MODEH_MODE11_PUSHPULL;
// [Port B Configuration]$
// $[Port C Configuration]
/* Pin PC13 is configured to Push-pull */
GPIO->P[2].MODEH = (GPIO->P[2].MODEH & ~_GPIO_P_MODEH_MODE13_MASK)
| GPIO_P_MODEH_MODE13_PUSHPULL;
/* Pin PC14 is configured to Push-pull */
GPIO->P[2].MODEH = (GPIO->P[2].MODEH & ~_GPIO_P_MODEH_MODE14_MASK)
| GPIO_P_MODEH_MODE14_PUSHPULL;
/* Pin PC15 is configured to Push-pull */
GPIO->P[2].MODEH = (GPIO->P[2].MODEH & ~_GPIO_P_MODEH_MODE15_MASK)
| GPIO_P_MODEH_MODE15_PUSHPULL;
// [Port C Configuration]$
// $[Port D Configuration]
/* Pin PD5 is configured to Push-pull */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE5_MASK)
| GPIO_P_MODEL_MODE5_PUSHPULL;
/* Pin PD6 is configured to Push-pull */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE6_MASK)
| GPIO_P_MODEL_MODE6_PUSHPULL;
/* Pin PD7 is configured to Push-pull */
GPIO->P[3].MODEL = (GPIO->P[3].MODEL & ~_GPIO_P_MODEL_MODE7_MASK)
| GPIO_P_MODEL_MODE7_PUSHPULL;
// [Port D Configuration]$
// $[Port E Configuration]
/* Pin PE10 is configured to Push-pull */
GPIO->P[4].MODEH = (GPIO->P[4].MODEH & ~_GPIO_P_MODEH_MODE10_MASK)
| GPIO_P_MODEH_MODE10_PUSHPULL;
/* Pin PE11 is configured to Push-pull */
GPIO->P[4].MODEH = (GPIO->P[4].MODEH & ~_GPIO_P_MODEH_MODE11_MASK)
| GPIO_P_MODEH_MODE11_PUSHPULL;
/* Pin PE12 is configured to Push-pull */
GPIO->P[4].MODEH = (GPIO->P[4].MODEH & ~_GPIO_P_MODEH_MODE12_MASK)
| GPIO_P_MODEH_MODE12_PUSHPULL;
/* Pin PE13 is configured to Push-pull */
GPIO->P[4].MODEH = (GPIO->P[4].MODEH & ~_GPIO_P_MODEH_MODE13_MASK)
| GPIO_P_MODEH_MODE13_PUSHPULL;
// [Port E Configuration]$
}
/******************************************************************************
* @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);
}
uint32_t get_systick(void)
{
return systick_count;
}
/******************************************************************************
* SYSTICK ISR
*****************************************************************************/
void SysTick_Handler(void)
{
systick_count++;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment