demo.stm32f0xx.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include "stm32f030.h"
  2. /****** project hardware ******/
  3. // on this demo board, there is a push button on PB13 and
  4. // an LED on PA4 and PF5
  5. #define LED 0x10 // port A bit 4 these LED are LOW=lit-up
  6. #define LED2 0x50020 // port F bit 5
  7. GPIO_TypeDef * GROUP[] = {GPIOA, GPIOB, GPIOC, GPIOD, 0, GPIOF}; // 0,0x10000,0x20000, etc
  8. void gpio_set(uint32 bitPosition, bool value) {
  9. vu32* group = &((GROUP[bitPosition >> 16])->ODR);
  10. bitPosition &= 0xFFFF;
  11. if (value)
  12. *group |= bitPosition;
  13. else
  14. *group &= ~bitPosition;
  15. }
  16. /***** declarations ****/
  17. #define NUM_EVENTS 10
  18. volatile uint8 events[NUM_EVENTS];
  19. void newEvent(uint8 e);
  20. void ledTask(uint8 evt);
  21. void respondToButtonTask(uint8 evt);
  22. enum { EVT_NONE,
  23. EVT_TICK,
  24. EVT_BUTTON};
  25. /********** interrupts **************/
  26. volatile uint32 tick; // increasing at 100 ticks/sec
  27. // takes a year to roll-over
  28. void timer_isr(void) {
  29. tick++;
  30. newEvent(EVT_TICK);
  31. // this interrupt is auto-ack'd
  32. }
  33. void button_isr(void) {
  34. newEvent(EVT_BUTTON);
  35. EXTI->PR |= 0x3001; // ack it
  36. }
  37. /** newEvent
  38. * add the event to the event queue
  39. * wrapped in critical section
  40. *
  41. * @param the event
  42. */
  43. void newEvent(uint8 e) {
  44. static uint nextEvent;
  45. dint(); // critical section
  46. events[nextEvent++] = e;
  47. if (nextEvent==NUM_EVENTS)
  48. nextEvent = 0;
  49. eint();
  50. }
  51. /***** init ******/
  52. /* called by newlib startup */
  53. void _init(void) {
  54. // startup code
  55. // use default clocks
  56. // turn on all the GPIO's
  57. RCC->AHBENR = 0x005e0014;
  58. // enable SysCfg
  59. RCC->APB2ENR = 0x00004801;
  60. // enable the two LEDs as outputs
  61. GPIOA->MODER = (GPIOA->MODER & 0xFFFFFCFF) | 0x00000100; // port A bit 4
  62. GPIOF->MODER = (GPIOF->MODER & 0xFFFFF3FF) | 0x00000400; // port F bit 5
  63. // and the push button as input + pulldown
  64. GPIOB->PUPDR = (GPIOB->PUPDR & 0xF3FFFFFF) | 0x08000000; // pulldown on 13
  65. // keep the clocking system simple: just use the 8MHz HSI everywhere
  66. SysTick->LOAD = 10000; // 10 msec
  67. SysTick->VAL = 0;
  68. SysTick->CTRL = 3; // count at 1usec, use interrupts
  69. /* to configure an interrupt on the stm32f0xx,
  70. - enable the EXTI->IMR for the pin
  71. - set EXTI->RTSR for select rising edge
  72. - set the SYSCFG->EXTICRx pin to route it
  73. - enable the gating bit in the NVIC register
  74. - don't forget to ack each interrupt at EXTI->PR
  75. */
  76. EXTI->IMR = 0x2000; // enable interrupt from line 13
  77. EXTI->RTSR = 0x2000; // interrupt on rising edge
  78. SYSCFG->EXTICR[3] = 0x0010; // select prot B for exti-13
  79. NVIC->ISER[0] = 0x00E1; // enable in NVIC: gpio & watchdog
  80. gpio_set(LED,1); // TODO:
  81. gpio_set(LED2,1);
  82. }
  83. void main(void) {
  84. eint();
  85. while(1) {
  86. uint j;
  87. for (j=0; j<NUM_EVENTS; j++) {
  88. while (events[j]==EVT_NONE)
  89. {}
  90. ledTask(events[j]);
  91. respondToButtonTask(events[j]);
  92. events[j] = EVT_NONE;
  93. }
  94. }
  95. }
  96. /*********** task code, with states ************/
  97. enum {LED_ON, LED_OFF};
  98. enum {RTB_IDLE, RTB_ON}; // states
  99. static uint8 rtbState = RTB_IDLE;
  100. static uint16 rtbTimerCount = 0;
  101. const uint16 BUTTON_LED_ON_TIME = 150;
  102. void respondToButtonTask(uint8 evt) {
  103. switch(rtbState) {
  104. case RTB_IDLE:
  105. if (evt == EVT_BUTTON) {
  106. rtbState = RTB_ON;
  107. rtbTimerCount = BUTTON_LED_ON_TIME;
  108. gpio_set(LED, LED_ON);
  109. }
  110. break;
  111. case RTB_ON:
  112. if (evt == EVT_TICK) {
  113. if (--rtbTimerCount == 0) {
  114. gpio_set(LED, LED_OFF);
  115. rtbState = RTB_IDLE;
  116. }
  117. }
  118. break;
  119. }
  120. }
  121. const int LED_ON_TIME = 150;
  122. const int LED_OFF_TIME = 50;
  123. static uint8 ledState = LED_OFF;
  124. static uint16 ledTimerCount = 0;
  125. void ledTask(uint8 evt) {
  126. switch(ledState) {
  127. case LED_OFF:
  128. if (evt == EVT_TICK) {
  129. if (++ledTimerCount > LED_OFF_TIME) {
  130. gpio_set(LED2, LED_ON);
  131. ledTimerCount = LED_ON_TIME;
  132. ledState = LED_ON;
  133. }
  134. }
  135. break;
  136. case LED_ON:
  137. if (evt == EVT_TICK) {
  138. if (--ledTimerCount == 0) {
  139. gpio_set(LED2, LED_OFF);
  140. ledTimerCount = 0;
  141. ledState = LED_OFF;
  142. }
  143. }
  144. break;
  145. }
  146. }
  147. /* vector table */
  148. #define STACK_TOP 0x20002000
  149. void default_isr(void) {}
  150. extern void _start(void);
  151. void (*myvectors[])(void) __attribute__ ((section(".vectors")))= {
  152. (void(*)(void)) STACK_TOP, // stack pointer
  153. _start, // code entry point
  154. default_isr, // handle non-maskable interrupts
  155. default_isr, // handle hard faults
  156. 0,0,0,0, /* 10...1f */
  157. 0,0,0,0, /* 20...2f */
  158. 0,0,0,timer_isr, /* 30...3f */
  159. 0,0,0,0,
  160. 0,button_isr,button_isr,button_isr, /* 50...5f */
  161. 0,0,0,0, /* 60...6f */
  162. 0,0,0,0, /* 70...7f */
  163. 0,0,0,0, /* 80...8f */
  164. 0,0,0,0, /* 90...9f */
  165. 0,0,0,0, /* a0...af */
  166. 0,0,0,0, /* b0...bf */
  167. 0,0,0,0, /* c0...cf */
  168. 0,0,0,0, /* d0...df */
  169. 0,0,0,0, /* e0...ef */
  170. 0,0,0,0, /* f0...ff */
  171. 0,0,0,0, /* 100.10f */
  172. 0,0,0,0 /* 110.11f */
  173. };