demo.stm32f1xx.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "stm32f10x.h"
  2. /****** project hardware ******/
  3. #define PCOUT GPIOC->ODR // for output LEDs PC8 PC9
  4. #define PAIN GPIOA->IDR // for input push button PA0
  5. #define PADDR_HIGH GPIOA->CRH
  6. #define PADDR_LOW GPIOA->CRL
  7. #define PBDDR_HIGH GPIOB->CRH
  8. #define PBDDR_LOW GPIOB->CRL
  9. #define PCDDR_HIGH GPIOC->CRH
  10. #define PCDDR_LOW GPIOC->CRL
  11. #define LED 8 // port C, bit 8
  12. #define LED2 9
  13. inline void gpio_set(int bitPosition, int value) {
  14. if (value)
  15. PCOUT |= (1<<bitPosition);
  16. else
  17. PCOUT &= ~(1<<bitPosition);
  18. }
  19. /************ events ************/
  20. void newEvent(char e);
  21. #define NUM_EVENTS 10
  22. volatile char events[NUM_EVENTS]; // starts full of zeros EVT_NONE
  23. #define EVT_NONE 0
  24. #define EVT_TICK 1
  25. #define EVT_BUTTON 2
  26. /********** tasks ***********/
  27. void ledTask(char evt);
  28. void respondToButtonTask(char evt);
  29. /********** interrupts **************/
  30. volatile int tick; // increasing at 100 ticks/sec
  31. // takes a year to roll-over
  32. #define eint() asm volatile("cpsie i")
  33. #define dint() asm volatile("cpsid i")
  34. void timer_isr(void) {
  35. tick++;
  36. newEvent(EVT_TICK);
  37. // this interrupt is auto-ack'd
  38. }
  39. void button_isr(void) {
  40. newEvent(EVT_BUTTON);
  41. EXTI->PR |= 1; // ack both
  42. }
  43. /** newEvent
  44. * add the event to the event queue
  45. * wrapped in critical section
  46. *
  47. * @param the event
  48. */
  49. void newEvent(char e) {
  50. static unsigned char nextEvent;
  51. if (events[nextEvent])
  52. return;
  53. dint(); // critical section
  54. events[nextEvent++] = e;
  55. if (nextEvent==NUM_EVENTS)
  56. nextEvent = 0;
  57. eint();
  58. }
  59. /***** init ******/
  60. /* called by newlib startup */
  61. void _init(void) {
  62. // startup code
  63. // turn on all the GPIO's
  64. RCC->APB2ENR = 0x74A3D; // enable the GPIO devices and timers
  65. RCC -> APB1ENR = 0x1ff; // enable timers 2-14
  66. AFIO -> MAPR |= 0x02008C00; // remap osc to PD0/1 and tim3 to PB4/5/0/1
  67. PADDR_HIGH = 0x44444444; // PortA all inputs
  68. PCDDR_HIGH = 0x11111111; // PortC all outputs
  69. // keep the clocking system simple: just use the 8MHz HSI everywhere
  70. SysTick->LOAD = 10000; // 10 msec
  71. SysTick->Val = 0;
  72. SysTick->CTRL = 3; // count at 1usec, use interrupts
  73. /* configure the blue button on the discovery module, PA0 */
  74. EXTI->IMR |= 1; // enable interrupt from line 0
  75. EXTI->RTSR |= 1; // interrupt on rising edge
  76. AFIO->EXTICR[0] |= 0x0; // select port A
  77. /* enable all interrupt sources */
  78. NVIC->ISER[0] = 0xFFFFFFFF; // enable in NVIC
  79. NVIC->ISER[1] = 0x00FFFFFF; // enable in NVIC
  80. gpio_set(9,0);
  81. gpio_set(8,0);
  82. }
  83. void main(void) {
  84. eint();
  85. while(1) {
  86. int 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. /*********** state code ************/
  97. #define RTB_IDLE 0
  98. #define RTB_ON 1
  99. #define TIMER_LIMIT 150
  100. static int rtbState = RTB_IDLE;
  101. static int rtbTimerCount = 0;
  102. void respondToButtonTask(char evt) {
  103. switch(rtbState) {
  104. case RTB_IDLE:
  105. if (evt == EVT_BUTTON) {
  106. rtbState = RTB_ON;
  107. gpio_set(LED, 1);
  108. }
  109. break;
  110. case RTB_ON:
  111. if (evt == EVT_TICK) {
  112. if (++rtbTimerCount > TIMER_LIMIT) {
  113. gpio_set(LED, 0);
  114. rtbState = RTB_IDLE;
  115. rtbTimerCount = 0;
  116. }
  117. }
  118. break;
  119. }
  120. }
  121. #define LED_OFF 0
  122. #define LED_ON 1
  123. #define LED_ON_TIME 150
  124. #define LED_OFF_TIME 50
  125. static int ledState = LED_OFF;
  126. static int ledTimerCount = 0;
  127. void ledTask(char evt) {
  128. switch(ledState) {
  129. case LED_OFF:
  130. if (evt == EVT_TICK) {
  131. if (++ledTimerCount > LED_OFF_TIME) {
  132. gpio_set(LED2, LED_ON);
  133. ledTimerCount = 0;
  134. ledState = LED_ON;
  135. }
  136. }
  137. break;
  138. case LED_ON:
  139. if (evt == EVT_TICK) {
  140. if (++ledTimerCount > LED_ON_TIME) {
  141. gpio_set(LED2, LED_OFF);
  142. ledTimerCount = 0;
  143. ledState = LED_OFF;
  144. }
  145. }
  146. break;
  147. }
  148. }
  149. /* vector table */
  150. #define STACK_TOP 0x20002000
  151. void default_isr(void) {}
  152. extern void _start(void);
  153. void (*myvectors[])(void) __attribute__ ((section(".vectors")))= {
  154. (void(*)(void)) STACK_TOP, // stack pointer
  155. _start, // code entry point
  156. default_isr, // handle non-maskable interrupts
  157. default_isr, // handle hard faults
  158. 0,0,0,0, /* 10...1f */
  159. 0,0,0,0, /* 20...2f */
  160. 0,0,0,timer_isr, /* 30...3f */
  161. 0,0,0,0, /* 40...4f */
  162. 0,0,button_isr,0, /* 50...5f */
  163. 0,0,0,0, /* 60...6f */
  164. 0,0,0,0, /* 70...7f */
  165. 0,0,0,0, /* 80...8f */
  166. 0,0,0,0, /* 90...9f */
  167. 0,0,0,0, /* a0...af */
  168. 0,0,0,0, /* b0...bf */
  169. 0,0,0,0, /* c0...cf */
  170. 0,0,0,0, /* d0...df */
  171. 0,0,0,0, /* e0...ef */
  172. 0,0,0,0, /* f0...ff */
  173. 0,0,0,0, /* 100.10f */
  174. 0,0,0,0 /* 110.11f */
  175. };