Last active
September 17, 2020 08:25
-
-
Save osvein/e5e0cb4693dea5dbf11492028026f239 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
| // Various useful I/O addresses and definitions for EFM32GG | |
| // GPIO | |
| GPIO_PA_BASE = 0x40006000 | |
| GPIO_PB_BASE = 0x40006024 | |
| GPIO_PC_BASE = 0x40006048 | |
| GPIO_PD_BASE = 0x4000606c | |
| GPIO_PE_BASE = 0x40006090 | |
| GPIO_PF_BASE = 0x400060b4 | |
| // register offsets from base address | |
| GPIO_CTRL = 0x00 | |
| GPIO_MODEL = 0x04 | |
| GPIO_MODEH = 0x08 | |
| GPIO_DOUT = 0x0c | |
| GPIO_DOUTSET = 0x10 | |
| GPIO_DOUTCLR = 0x14 | |
| GPIO_DOUTTGL = 0x18 | |
| GPIO_DIN = 0x1c | |
| GPIO_PINLOCKN = 0x20 | |
| GPIO_BASE = 0x40006100 | |
| // register offsets from base address | |
| GPIO_EXTIPSELL = 0x00 | |
| GPIO_EXTIPSELH = 0x04 | |
| GPIO_EXTIRISE = 0x08 | |
| GPIO_EXTIFALL = 0x0c | |
| GPIO_IEN = 0x10 | |
| GPIO_IF = 0x14 | |
| GPIO_IFC = 0x1c | |
| // CMU | |
| CMU_BASE = 0x400c8000 | |
| CMU_HFPERCLKDIV = 0x008 | |
| CMU_OSCENCMD = 0x020 | |
| CMU_OSCENCMD_LFRCOEN = 6 | |
| CMU_LFCLKSEL = 0x028 | |
| CMU_LFCLKSEL_LFAE = 16 | |
| CMU_HFCORECLKEN0 = 0x040 | |
| CMU_HFCORECLKEN0_LE = 4 | |
| CMU_HFPERCLKEN0 = 0x044 | |
| CMU_HFPERCLKEN0_GPIO = 13 | |
| CMU_LFACLKEN = 0x058 | |
| CMU_LFACLKEN_RTC = 1 | |
| // NVIC | |
| ISER0 = 0xe000e100 | |
| ISER1 = 0xe000e104 | |
| ICER0 = 0xe000e180 | |
| ICER1 = 0xe000e184 | |
| ISPR0 = 0xe000e200 | |
| ISPR1 = 0xe000e204 | |
| ICPR0 = 0xe000e280 | |
| ICPR1 = 0xe000e284 | |
| IABR0 = 0xe000e300 | |
| IABR1 = 0xe000e304 | |
| IPR_BASE = 0xe000e400 | |
| IPR0 = 0x00 | |
| IPR1 = 0x04 | |
| IPR2 = 0x08 | |
| IPR3 = 0x0c | |
| // EMU | |
| EMU_BASE = 0x400c6000 | |
| EMU_CTRL = 0x000 | |
| // System Control Block | |
| SCR = 0xe000ed10 | |
| AIRCR = 0xe000ed0c | |
| // RTC | |
| RTC_BASE = 0x40080000 | |
| RTC_CTRL = 0x000 | |
| RTC_CNT = 0x004 | |
| RTC_COMP0 = 0x008 | |
| RTC_IFC = 0x018 | |
| RTC_IEN = 0x01C |
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
| // DELAY is multiplied by 1-1/2^DELAY_MUL each bounce | |
| DELAY = 10000 | |
| DELAY_MUL = 3 | |
| LEDMASK = 0xFF00 | |
| // player button masks | |
| P1BTN = 0x0F | |
| P2BTN = 0xF0 | |
| // player LED masks | |
| P1LED = 1<<8 | |
| P2LED = 1<<15 | |
| .syntax unified | |
| .include "efm32gg.s" | |
| // Exception vector table | |
| .section .vectors | |
| .long stack_top // Top of Stack | |
| .long _reset // Reset Handler | |
| .long dummy_handler // NMI Handler | |
| .long dummy_handler // Hard Fault Handler | |
| .long dummy_handler // MPU Fault Handler | |
| .long dummy_handler // Bus Fault Handler | |
| .long dummy_handler // Usage Fault Handler | |
| .long dummy_handler // Reserved | |
| .long dummy_handler // Reserved | |
| .long dummy_handler // Reserved | |
| .long dummy_handler // Reserved | |
| .long dummy_handler // SVCall Handler | |
| .long dummy_handler // Debug Monitor Handler | |
| .long dummy_handler // Reserved | |
| .long dummy_handler // PendSV Handler | |
| .long dummy_handler // SysTick Handler | |
| // External Interrupts | |
| .long dummy_handler | |
| .long gpio_handler // GPIO even handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long gpio_handler // GPIO odd handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long rtc_handler // RTC handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .section .text | |
| .globl _reset | |
| .type _reset, %function | |
| .thumb_func | |
| _reset: | |
| // enable GPIO and RTC clocks in CMU | |
| // configure RTC to use ULFRCO for deeper sleep | |
| ldr r0, =CMU_BASE | |
| ldr r1, [r0, #CMU_HFCORECLKEN0] | |
| orr r1, #1<<CMU_HFCORECLKEN0_LE | |
| str r1, [r0, #CMU_HFCORECLKEN0] | |
| ldr r1, [r0, #CMU_HFPERCLKEN0] | |
| orr r1, #1<<CMU_HFPERCLKEN0_GPIO | |
| str r1, [r0, #CMU_HFPERCLKEN0] | |
| ldr r1, [r0, #CMU_LFCLKSEL] | |
| orr r1, #1<<CMU_LFCLKSEL_LFAE | |
| str r1, [r0, #CMU_LFCLKSEL] | |
| ldr r1, [r0, #CMU_LFACLKEN] | |
| orr r1, #1<<CMU_LFACLKEN_RTC | |
| str r1, [r0, #CMU_LFACLKEN] | |
| mov r1, #1<<CMU_OSCENCMD_LFRCOEN | |
| str r1, [r0, #CMU_OSCENCMD] | |
| // configure button GPIO input | |
| ldr r0, =GPIO_PC_BASE | |
| ldr r1, =0x33333333 | |
| str r1, [r0, #GPIO_MODEL] | |
| ldr r1, =0xFF | |
| str r1, [r0, #GPIO_DOUT] | |
| // short delay to avoid pull-down triggering interrupt | |
| ldr r0, =0x00100000 | |
| 0: subs r0, #1 | |
| bne 0b | |
| // configure button GPIO interrupt | |
| ldr r0, =GPIO_BASE | |
| ldr r1, =0x22222222 | |
| str r1, [r0, #GPIO_EXTIPSELL] | |
| ldr r1, =0xFF | |
| str r1, [r0, #GPIO_EXTIFALL] | |
| str r1, [r0, #GPIO_IEN] | |
| /* configure LED GPIO output | |
| * only a single LED will be lit at a time | |
| * the light will be rotated around | |
| */ | |
| ldr r0, =GPIO_PA_BASE | |
| ldr r1, =0x2 | |
| str r1, [r0, #GPIO_CTRL] | |
| ldr r1, =0x55555555 | |
| str r1, [r0, #GPIO_MODEH] | |
| ldr r1, =LEDMASK & ~(1<<8) // leftmost LED on, rest off | |
| str r1, [r0, #GPIO_DOUT] | |
| // configure RTC (interrupt on COMP0) | |
| ldr r0, =RTC_BASE | |
| ldr r1, =DELAY | |
| str r1, [r0, #RTC_COMP0] | |
| ldr r1, =2 | |
| str r1, [r0, #RTC_IEN] | |
| /* global direction state register | |
| * 1 = left-to-right, 31 = right-to-left | |
| * used to right-rotate LED register | |
| * (right-rotating by 31 is equivalent to left-rotating by 1) | |
| */ | |
| ldr r4, =1 | |
| // enable interrupts | |
| ldr r0, =ISER0 | |
| ldr r1, =(1<<30) | (1<<11) | (1<<1) | |
| str r1, [r0] | |
| // sleep | |
| ldr r0, =SCR | |
| ldr r1, =6 | |
| str r1, [r0] | |
| wfi | |
| b . | |
| .thumb_func | |
| gpio_handler: | |
| // enable RTC to start the game, in case it's not already started | |
| ldr r0, =RTC_BASE | |
| ldr r1, =(1<<2) | (1<<0) | |
| str r1, [r0, #RTC_CTRL] | |
| // set PnLED in r2 if player n lost (n = 1,2) | |
| ldr r0, =GPIO_BASE | |
| ldr r1, [r0, #GPIO_IF] | |
| ldr r0, =GPIO_PA_BASE | |
| ldr r2, [r0, #GPIO_DOUT] | |
| eor r2, #LEDMASK | |
| ands r3, r1, #P1BTN | |
| it ne | |
| eorne r2, #P1LED | |
| ands r3, r1, #P2BTN | |
| it ne | |
| eorne r2, #P2LED | |
| cbnz r2, lose | |
| // debounce buttons by disabling GPIO interrupt until next RTC tick | |
| ldr r0, =GPIO_BASE | |
| ldr r3, =0 | |
| str r3, [r0, #GPIO_IEN] | |
| // increase speed | |
| eor r4, #30 | |
| ldr r0, =RTC_BASE | |
| ldr r1, =0 | |
| str r1, [r0, #RTC_CNT] | |
| ldr r1, [r0, #RTC_COMP0] | |
| sub r1, r1, r1, LSR #DELAY_MUL // r1 -= r1 * 1/2^DELAY_MUL | |
| str r1, [r0, #RTC_COMP0] | |
| bx lr | |
| .thumb_func | |
| rtc_handler: | |
| ldr r0, =RTC_BASE | |
| ldr r1, =7 | |
| str r1, [r0, #RTC_IFC] | |
| // re-enable GPIO interrupt | |
| ldr r0, =GPIO_BASE | |
| ldr r1, =0xFF | |
| str r1, [r0, #GPIO_IFC] | |
| str r1, [r0, #GPIO_IEN] | |
| // rotate LED register | |
| ldr r0, =GPIO_PA_BASE | |
| ldr r1, [r0, #GPIO_DOUT] | |
| orn r1, #LEDMASK | |
| ror r1, r1, r4 | |
| and r1, #LEDMASK | |
| str r1, [r0, #GPIO_DOUT] | |
| // somebody loses if the light was rotated out one of the sides | |
| eors r1, #LEDMASK | |
| beq lose | |
| bx lr | |
| lose: | |
| // software reset | |
| ldr r0, =AIRCR | |
| ldr r1, =(0x5FA<<16) | (1<<2) | |
| str r1, [r0] | |
| b . | |
| .thumb_func | |
| dummy_handler: | |
| b . |
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
| .syntax unified | |
| .include "efm32gg.s" | |
| // Exception vector table | |
| .section .vectors | |
| .long stack_top /* Top of Stack */ | |
| .long _reset/* Reset Handler */ | |
| .long dummy_handler /* NMI Handler*/ | |
| .long dummy_handler /* Hard Fault Handler */ | |
| .long dummy_handler /* MPU Fault Handler*/ | |
| .long dummy_handler /* Bus Fault Handler*/ | |
| .long dummy_handler /* Usage Fault Handler */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* SVCall Handler */ | |
| .long dummy_handler /* Debug Monitor Handler */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* PendSV Handler */ | |
| .long dummy_handler /* SysTick Handler */ | |
| /* External Interrupts */ | |
| .long dummy_handler | |
| .long gpio_handler/* GPIO even handler */ | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long gpio_handler/* GPIO odd handler */ | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .section .text | |
| cmu_base: .long CMU_BASE | |
| gpio_pa_base: .long GPIO_PA_BASE | |
| gpio_pc_base: .long GPIO_PC_BASE | |
| gpio_base: .long GPIO_BASE | |
| iser0: .long ISER0 | |
| scr: .long SCR | |
| .globl _reset | |
| .type _reset, %function | |
| .thumb_func | |
| _reset: | |
| // enable GPIO clock in CMU | |
| ldr r1, cmu_base | |
| ldr r2, [r1, #CMU_HFPERCLKEN0] | |
| orr r2, #1<<CMU_HFPERCLKEN0_GPIO | |
| str r2, [r1, #CMU_HFPERCLKEN0] | |
| // configure LED GPIO output | |
| ldr r1, gpio_pa_base | |
| mov r2, #0x2 | |
| str r2, [r1, #GPIO_CTRL] | |
| mov r2, #0x55555555 | |
| str r2, [r1, #GPIO_MODEH] | |
| // configure button GPIO input | |
| ldr r1, gpio_pc_base | |
| mov r2, #0x33333333 | |
| str r2, [r1, #GPIO_MODEL] | |
| mov r2, #0xFF | |
| str r2, [r1, #GPIO_DOUT] | |
| // configure button GPIO interrupt | |
| ldr r1, gpio_base | |
| mov r2, #0x22222222 | |
| str r2, [r1, #GPIO_EXTIPSELL] | |
| mov r2, #0xFF | |
| str r2, [r1, #GPIO_EXTIFALL] | |
| str r2, [r1, #GPIO_EXTIRISE] | |
| str r2, [r1, #GPIO_IEN] | |
| ldr r1, iser0 | |
| mov r2, #(1<<1)|(1<<11) | |
| str r2, [r1] | |
| ldr r1, scr | |
| mov r2, #6 | |
| str r2, [r1] | |
| wfi | |
| b . | |
| // The CPU will jump here when there is a GPIO interrupt | |
| .thumb_func | |
| gpio_handler: | |
| // read button GPIO input | |
| ldr r1, gpio_pc_base | |
| ldr r2, [r1, #GPIO_DIN] | |
| lsl r2, #8 | |
| // write LED GPIO output | |
| ldr r1, gpio_pa_base | |
| str r2, [r1, #GPIO_DOUT] | |
| // clear interrupt flags | |
| ldr r1, gpio_base | |
| mov r2, #0xFF | |
| str r2, [r1, #GPIO_IFC] | |
| bx lr | |
| .thumb_func | |
| dummy_handler: | |
| b . |
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
| .syntax unified | |
| .include "efm32gg.s" | |
| // Exception vector table | |
| .section .vectors | |
| .long stack_top /* Top of Stack */ | |
| .long _reset/* Reset Handler */ | |
| .long dummy_handler /* NMI Handler*/ | |
| .long dummy_handler /* Hard Fault Handler */ | |
| .long dummy_handler /* MPU Fault Handler*/ | |
| .long dummy_handler /* Bus Fault Handler*/ | |
| .long dummy_handler /* Usage Fault Handler */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* SVCall Handler */ | |
| .long dummy_handler /* Debug Monitor Handler */ | |
| .long dummy_handler /* Reserved */ | |
| .long dummy_handler /* PendSV Handler */ | |
| .long dummy_handler /* SysTick Handler */ | |
| /* External Interrupts */ | |
| .long dummy_handler | |
| .long gpio_handler/* GPIO even handler */ | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long gpio_handler/* GPIO odd handler */ | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .long dummy_handler | |
| .section .text | |
| .globl _reset | |
| .type _reset, %function | |
| .thumb_func | |
| _reset: | |
| // enable GPIO clock in CMU | |
| ldr r1, 0f | |
| 0: .long CMU_BASE | |
| ldr r2, [r1, #CMU_HFPERCLKEN0] | |
| orr r2, #1<<CMU_HFPERCLKEN0_GPIO | |
| str r2, [r1, #CMU_HFPERCLKEN0] | |
| // configure LED GPIO output | |
| ldr r1, 0f | |
| 0: .long GPIO_PA_BASE | |
| mov r2, 0x2 | |
| str r2, [r1, #GPIO_CTRL] | |
| mov r2, 0x55555555 | |
| str r2, [r1, #GPIO_MODEH] | |
| // configure button GPIO output | |
| ldr r2, 0f | |
| 0: .long GPIO_PC_BASE | |
| mov r3, 0x33333333 | |
| str r3, [r2, #GPIO_MODEL] | |
| mov r3, 0xFF | |
| str r3, [r2, #GPIO_DOUT] | |
| // main loop | |
| loop: | |
| ldr r3, [r2, #GPIO_DIN] | |
| lsl r3, #8 | |
| str r3, [r1, #GPIO_DOUT] | |
| b loop | |
| // The CPU will jump here when there is a GPIO interrupt | |
| .thumb_func | |
| gpio_handler: | |
| b . | |
| .thumb_func | |
| dummy_handler: | |
| b . |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment