#include "stm32f030.h" /****** project hardware ******/ // on this demo board, there is a push button on PB13 and // an LED on PA4 and PF5 #define LED 0x10 // port A bit 4 these LED are LOW=lit-up #define LED2 0x50020 // port F bit 5 GPIO_TypeDef * GROUP[] = {GPIOA, GPIOB, GPIOC, GPIOD, 0, GPIOF}; // 0,0x10000,0x20000, etc void gpio_set(uint32 bitPosition, bool value) { vu32* group = &((GROUP[bitPosition >> 16])->ODR); bitPosition &= 0xFFFF; if (value) *group |= bitPosition; else *group &= ~bitPosition; } /***** declarations ****/ #define NUM_EVENTS 10 volatile uint8 events[NUM_EVENTS]; void newEvent(uint8 e); void ledTask(uint8 evt); void respondToButtonTask(uint8 evt); enum { EVT_NONE, EVT_TICK, EVT_BUTTON}; /********** interrupts **************/ volatile uint32 tick; // increasing at 100 ticks/sec // takes a year to roll-over void timer_isr(void) { tick++; newEvent(EVT_TICK); // this interrupt is auto-ack'd } void button_isr(void) { newEvent(EVT_BUTTON); EXTI->PR |= 0x3001; // ack it } /** newEvent * add the event to the event queue * wrapped in critical section * * @param the event */ void newEvent(uint8 e) { static uint nextEvent; dint(); // critical section events[nextEvent++] = e; if (nextEvent==NUM_EVENTS) nextEvent = 0; eint(); } /***** init ******/ /* called by newlib startup */ void _init(void) { // startup code // use default clocks // turn on all the GPIO's RCC->AHBENR = 0x005e0014; // enable SysCfg RCC->APB2ENR = 0x00004801; // enable the two LEDs as outputs GPIOA->MODER = (GPIOA->MODER & 0xFFFFFCFF) | 0x00000100; // port A bit 4 GPIOF->MODER = (GPIOF->MODER & 0xFFFFF3FF) | 0x00000400; // port F bit 5 // and the push button as input + pulldown GPIOB->PUPDR = (GPIOB->PUPDR & 0xF3FFFFFF) | 0x08000000; // pulldown on 13 // keep the clocking system simple: just use the 8MHz HSI everywhere SysTick->LOAD = 10000; // 10 msec SysTick->VAL = 0; SysTick->CTRL = 3; // count at 1usec, use interrupts /* to configure an interrupt on the stm32f0xx, - enable the EXTI->IMR for the pin - set EXTI->RTSR for select rising edge - set the SYSCFG->EXTICRx pin to route it - enable the gating bit in the NVIC register - don't forget to ack each interrupt at EXTI->PR */ EXTI->IMR = 0x2000; // enable interrupt from line 13 EXTI->RTSR = 0x2000; // interrupt on rising edge SYSCFG->EXTICR[3] = 0x0010; // select prot B for exti-13 NVIC->ISER[0] = 0x00E1; // enable in NVIC: gpio & watchdog gpio_set(LED,1); // TODO: gpio_set(LED2,1); } void main(void) { eint(); while(1) { uint j; for (j=0; j LED_OFF_TIME) { gpio_set(LED2, LED_ON); ledTimerCount = LED_ON_TIME; ledState = LED_ON; } } break; case LED_ON: if (evt == EVT_TICK) { if (--ledTimerCount == 0) { gpio_set(LED2, LED_OFF); ledTimerCount = 0; ledState = LED_OFF; } } break; } } /* vector table */ #define STACK_TOP 0x20002000 void default_isr(void) {} extern void _start(void); void (*myvectors[])(void) __attribute__ ((section(".vectors")))= { (void(*)(void)) STACK_TOP, // stack pointer _start, // code entry point default_isr, // handle non-maskable interrupts default_isr, // handle hard faults 0,0,0,0, /* 10...1f */ 0,0,0,0, /* 20...2f */ 0,0,0,timer_isr, /* 30...3f */ 0,0,0,0, 0,button_isr,button_isr,button_isr, /* 50...5f */ 0,0,0,0, /* 60...6f */ 0,0,0,0, /* 70...7f */ 0,0,0,0, /* 80...8f */ 0,0,0,0, /* 90...9f */ 0,0,0,0, /* a0...af */ 0,0,0,0, /* b0...bf */ 0,0,0,0, /* c0...cf */ 0,0,0,0, /* d0...df */ 0,0,0,0, /* e0...ef */ 0,0,0,0, /* f0...ff */ 0,0,0,0, /* 100.10f */ 0,0,0,0 /* 110.11f */ };