Created
June 13, 2016 07:50
-
-
Save monpetit/395cc642073784025e15d53e7e352f85 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 "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