PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wirish.cpp 15KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // ArduinoCompat/wirish.cpp
  2. //
  3. // Arduino-like API for STM32F4 Discovery and similar
  4. // using STM32F4xx_DSP_StdPeriph_Lib_V1.3.0
  5. #include <RadioHead.h>
  6. #if (RH_PLATFORM == RH_PLATFORM_STM32STD)
  7. #include <wirish.h>
  8. SerialUSBClass SerialUSB;
  9. // Describes all the STM32 things we need to know about a digital IO pin to
  10. // make it input or output or to configure as an interrupt
  11. typedef struct
  12. {
  13. uint32_t ahbperiph;
  14. GPIO_TypeDef* port;
  15. uint16_t pin;
  16. uint8_t extiportsource;
  17. uint8_t extipinsource;
  18. } GPIOPin;
  19. // These describe the registers and bits for each digital IO pin to allow us to
  20. // provide Arduino-like pin addressing, digitalRead etc.
  21. // Indexed by pin number
  22. GPIOPin pins[] =
  23. {
  24. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_0, EXTI_PortSourceGPIOA, EXTI_PinSource0 }, // 0 = PA0
  25. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_1, EXTI_PortSourceGPIOA, EXTI_PinSource1 },
  26. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_2, EXTI_PortSourceGPIOA, EXTI_PinSource2 },
  27. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_3, EXTI_PortSourceGPIOA, EXTI_PinSource3 },
  28. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_4, EXTI_PortSourceGPIOA, EXTI_PinSource4 },
  29. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_5, EXTI_PortSourceGPIOA, EXTI_PinSource5 },
  30. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_6, EXTI_PortSourceGPIOA, EXTI_PinSource6 },
  31. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_7, EXTI_PortSourceGPIOA, EXTI_PinSource7 },
  32. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_8, EXTI_PortSourceGPIOA, EXTI_PinSource8 },
  33. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_9, EXTI_PortSourceGPIOA, EXTI_PinSource9 },
  34. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_10, EXTI_PortSourceGPIOA, EXTI_PinSource10 },
  35. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_11, EXTI_PortSourceGPIOA, EXTI_PinSource11 },
  36. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_12, EXTI_PortSourceGPIOA, EXTI_PinSource12 },
  37. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_13, EXTI_PortSourceGPIOA, EXTI_PinSource13 },
  38. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_14, EXTI_PortSourceGPIOA, EXTI_PinSource14 },
  39. { RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_15, EXTI_PortSourceGPIOA, EXTI_PinSource15 }, // 15 = PA15
  40. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_0, EXTI_PortSourceGPIOB, EXTI_PinSource0 }, // 16 = PB0
  41. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_1, EXTI_PortSourceGPIOB, EXTI_PinSource1 },
  42. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_2, EXTI_PortSourceGPIOB, EXTI_PinSource2 },
  43. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_3, EXTI_PortSourceGPIOB, EXTI_PinSource3 },
  44. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_4, EXTI_PortSourceGPIOB, EXTI_PinSource4 },
  45. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_5, EXTI_PortSourceGPIOB, EXTI_PinSource5 },
  46. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_6, EXTI_PortSourceGPIOB, EXTI_PinSource6 },
  47. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_7, EXTI_PortSourceGPIOB, EXTI_PinSource7 },
  48. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_8, EXTI_PortSourceGPIOB, EXTI_PinSource8 },
  49. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_9, EXTI_PortSourceGPIOB, EXTI_PinSource9 },
  50. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_10, EXTI_PortSourceGPIOB, EXTI_PinSource10 },
  51. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_11, EXTI_PortSourceGPIOB, EXTI_PinSource11 },
  52. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_12, EXTI_PortSourceGPIOB, EXTI_PinSource12 },
  53. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_13, EXTI_PortSourceGPIOB, EXTI_PinSource13 },
  54. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_14, EXTI_PortSourceGPIOB, EXTI_PinSource14 },
  55. { RCC_AHB1Periph_GPIOB, GPIOB, GPIO_Pin_15, EXTI_PortSourceGPIOB, EXTI_PinSource15 }, // 31 = PB15
  56. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_0, EXTI_PortSourceGPIOC, EXTI_PinSource0 }, // 32 = PC0
  57. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_1, EXTI_PortSourceGPIOC, EXTI_PinSource1 },
  58. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_2, EXTI_PortSourceGPIOC, EXTI_PinSource2 },
  59. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_3, EXTI_PortSourceGPIOC, EXTI_PinSource3 },
  60. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_4, EXTI_PortSourceGPIOC, EXTI_PinSource4 },
  61. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_5, EXTI_PortSourceGPIOC, EXTI_PinSource5 },
  62. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_6, EXTI_PortSourceGPIOC, EXTI_PinSource6 },
  63. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_7, EXTI_PortSourceGPIOC, EXTI_PinSource7 },
  64. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_8, EXTI_PortSourceGPIOC, EXTI_PinSource8 },
  65. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_9, EXTI_PortSourceGPIOC, EXTI_PinSource9 },
  66. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_10, EXTI_PortSourceGPIOC, EXTI_PinSource10 },
  67. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_11, EXTI_PortSourceGPIOC, EXTI_PinSource11 },
  68. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_12, EXTI_PortSourceGPIOC, EXTI_PinSource12 },
  69. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_13, EXTI_PortSourceGPIOC, EXTI_PinSource13 },
  70. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_14, EXTI_PortSourceGPIOC, EXTI_PinSource14 },
  71. { RCC_AHB1Periph_GPIOC, GPIOC, GPIO_Pin_15, EXTI_PortSourceGPIOC, EXTI_PinSource15 }, // 47 = PC15
  72. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_0, EXTI_PortSourceGPIOD, EXTI_PinSource0 }, // 48 = PD0
  73. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_1, EXTI_PortSourceGPIOD, EXTI_PinSource1 },
  74. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_2, EXTI_PortSourceGPIOD, EXTI_PinSource2 },
  75. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_3, EXTI_PortSourceGPIOD, EXTI_PinSource3 },
  76. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_4, EXTI_PortSourceGPIOD, EXTI_PinSource4 },
  77. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_5, EXTI_PortSourceGPIOD, EXTI_PinSource5 },
  78. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_6, EXTI_PortSourceGPIOD, EXTI_PinSource6 },
  79. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_7, EXTI_PortSourceGPIOD, EXTI_PinSource7 },
  80. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_8, EXTI_PortSourceGPIOD, EXTI_PinSource8 },
  81. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_9, EXTI_PortSourceGPIOD, EXTI_PinSource9 },
  82. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_10, EXTI_PortSourceGPIOD, EXTI_PinSource10 },
  83. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_11, EXTI_PortSourceGPIOD, EXTI_PinSource11 },
  84. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_12, EXTI_PortSourceGPIOD, EXTI_PinSource12 },
  85. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_13, EXTI_PortSourceGPIOD, EXTI_PinSource13 },
  86. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_14, EXTI_PortSourceGPIOD, EXTI_PinSource14 },
  87. { RCC_AHB1Periph_GPIOD, GPIOD, GPIO_Pin_15, EXTI_PortSourceGPIOD, EXTI_PinSource15 }, // 63 = PD15
  88. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_0, EXTI_PortSourceGPIOE, EXTI_PinSource0 }, // 64 = PE0
  89. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_1, EXTI_PortSourceGPIOE, EXTI_PinSource1 },
  90. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_2, EXTI_PortSourceGPIOE, EXTI_PinSource2 },
  91. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_3, EXTI_PortSourceGPIOE, EXTI_PinSource3 },
  92. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_4, EXTI_PortSourceGPIOE, EXTI_PinSource4 },
  93. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_5, EXTI_PortSourceGPIOE, EXTI_PinSource5 },
  94. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_6, EXTI_PortSourceGPIOE, EXTI_PinSource6 },
  95. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_7, EXTI_PortSourceGPIOE, EXTI_PinSource7 },
  96. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_8, EXTI_PortSourceGPIOE, EXTI_PinSource8 },
  97. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_9, EXTI_PortSourceGPIOE, EXTI_PinSource9 },
  98. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_10, EXTI_PortSourceGPIOE, EXTI_PinSource10 },
  99. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_11, EXTI_PortSourceGPIOE, EXTI_PinSource11 },
  100. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_12, EXTI_PortSourceGPIOE, EXTI_PinSource12 },
  101. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_13, EXTI_PortSourceGPIOE, EXTI_PinSource13 },
  102. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_14, EXTI_PortSourceGPIOE, EXTI_PinSource14 },
  103. { RCC_AHB1Periph_GPIOE, GPIOE, GPIO_Pin_15, EXTI_PortSourceGPIOE, EXTI_PinSource15 }, // 79 = PE15
  104. };
  105. #define NUM_PINS (sizeof(pins) / sizeof(GPIOPin))
  106. typedef struct
  107. {
  108. uint32_t extiline;
  109. uint8_t extiirqn;
  110. void (*handler)(void);
  111. } IRQLine;
  112. // IRQ line data indexed by pin source number with its port
  113. // and the programmable handler that will handle interrupts on that line
  114. IRQLine irqlines[] =
  115. {
  116. { EXTI_Line0, EXTI0_IRQn, 0 },
  117. { EXTI_Line1, EXTI1_IRQn, 0 },
  118. { EXTI_Line2, EXTI2_IRQn, 0 },
  119. { EXTI_Line3, EXTI3_IRQn, 0 },
  120. { EXTI_Line4, EXTI4_IRQn, 0 },
  121. { EXTI_Line5, EXTI9_5_IRQn, 0 },
  122. { EXTI_Line6, EXTI9_5_IRQn, 0 },
  123. { EXTI_Line7, EXTI9_5_IRQn, 0 },
  124. { EXTI_Line8, EXTI9_5_IRQn, 0 },
  125. { EXTI_Line9, EXTI9_5_IRQn, 0 },
  126. { EXTI_Line10, EXTI15_10_IRQn, 0 },
  127. { EXTI_Line11, EXTI15_10_IRQn, 0 },
  128. { EXTI_Line12, EXTI15_10_IRQn, 0 },
  129. { EXTI_Line13, EXTI15_10_IRQn, 0 },
  130. { EXTI_Line14, EXTI15_10_IRQn, 0 },
  131. { EXTI_Line15, EXTI15_10_IRQn, 0 },
  132. };
  133. #define NUM_IRQ_LINES (sizeof(irqlines) / sizeof(IRQLine))
  134. // Functions we expect to find in the sketch
  135. extern void setup();
  136. extern void loop();
  137. volatile unsigned long systick_count = 0;
  138. void SysTickConfig()
  139. {
  140. /* Setup SysTick Timer for 1ms interrupts */
  141. if (SysTick_Config(SystemCoreClock / 1000))
  142. {
  143. /* Capture error */
  144. while (1);
  145. }
  146. /* Configure the SysTick handler priority */
  147. NVIC_SetPriority(SysTick_IRQn, 0x0);
  148. // SysTick_Handler will now be called every 1 ms
  149. }
  150. // These interrupt handlers have to be extern C else they dont get linked in to the interrupt vectors
  151. extern "C"
  152. {
  153. // Called every 1 ms
  154. void SysTick_Handler(void)
  155. {
  156. systick_count++;
  157. }
  158. // Interrupt handlers for optional external GPIO interrupts
  159. void EXTI0_IRQHandler(void)
  160. {
  161. if (EXTI_GetITStatus(EXTI_Line0) != RESET)
  162. {
  163. if (irqlines[0].handler)
  164. irqlines[0].handler();
  165. EXTI_ClearITPendingBit(EXTI_Line0);
  166. }
  167. }
  168. void EXTI1_IRQHandler(void)
  169. {
  170. if (EXTI_GetITStatus(EXTI_Line1) != RESET)
  171. {
  172. if (irqlines[1].handler)
  173. irqlines[1].handler();
  174. EXTI_ClearITPendingBit(EXTI_Line1);
  175. }
  176. }
  177. void EXTI2_IRQHandler(void)
  178. {
  179. if (EXTI_GetITStatus(EXTI_Line2) != RESET)
  180. {
  181. if (irqlines[2].handler)
  182. irqlines[2].handler();
  183. EXTI_ClearITPendingBit(EXTI_Line2);
  184. }
  185. }
  186. void EXTI3_IRQHandler(void)
  187. {
  188. if (EXTI_GetITStatus(EXTI_Line3) != RESET)
  189. {
  190. if (irqlines[3].handler)
  191. irqlines[3].handler();
  192. EXTI_ClearITPendingBit(EXTI_Line3);
  193. }
  194. }
  195. void EXTI4_IRQHandler(void)
  196. {
  197. if (EXTI_GetITStatus(EXTI_Line4) != RESET)
  198. {
  199. if (irqlines[4].handler)
  200. irqlines[4].handler();
  201. EXTI_ClearITPendingBit(EXTI_Line4);
  202. }
  203. }
  204. void EXTI9_5_IRQHandler(void)
  205. {
  206. if (EXTI_GetITStatus(EXTI_Line5) != RESET)
  207. {
  208. if (irqlines[5].handler)
  209. irqlines[5].handler();
  210. EXTI_ClearITPendingBit(EXTI_Line5);
  211. }
  212. if (EXTI_GetITStatus(EXTI_Line6) != RESET)
  213. {
  214. if (irqlines[6].handler)
  215. irqlines[6].handler();
  216. EXTI_ClearITPendingBit(EXTI_Line6);
  217. }
  218. if (EXTI_GetITStatus(EXTI_Line7) != RESET)
  219. {
  220. if (irqlines[7].handler)
  221. irqlines[7].handler();
  222. EXTI_ClearITPendingBit(EXTI_Line7);
  223. }
  224. if (EXTI_GetITStatus(EXTI_Line8) != RESET)
  225. {
  226. if (irqlines[8].handler)
  227. irqlines[8].handler();
  228. EXTI_ClearITPendingBit(EXTI_Line8);
  229. }
  230. if (EXTI_GetITStatus(EXTI_Line9) != RESET)
  231. {
  232. if (irqlines[9].handler)
  233. irqlines[9].handler();
  234. EXTI_ClearITPendingBit(EXTI_Line9);
  235. }
  236. }
  237. void EXTI15_10_IRQHandler(void)
  238. {
  239. if (EXTI_GetITStatus(EXTI_Line10) != RESET)
  240. {
  241. if (irqlines[10].handler)
  242. irqlines[10].handler();
  243. EXTI_ClearITPendingBit(EXTI_Line10);
  244. }
  245. if (EXTI_GetITStatus(EXTI_Line11) != RESET)
  246. {
  247. if (irqlines[11].handler)
  248. irqlines[11].handler();
  249. EXTI_ClearITPendingBit(EXTI_Line11);
  250. }
  251. if (EXTI_GetITStatus(EXTI_Line12) != RESET)
  252. {
  253. if (irqlines[12].handler)
  254. irqlines[12].handler();
  255. EXTI_ClearITPendingBit(EXTI_Line12);
  256. }
  257. if (EXTI_GetITStatus(EXTI_Line13) != RESET)
  258. {
  259. if (irqlines[13].handler)
  260. irqlines[13].handler();
  261. EXTI_ClearITPendingBit(EXTI_Line13);
  262. }
  263. if (EXTI_GetITStatus(EXTI_Line14) != RESET)
  264. {
  265. if (irqlines[14].handler)
  266. irqlines[14].handler();
  267. EXTI_ClearITPendingBit(EXTI_Line14);
  268. }
  269. if (EXTI_GetITStatus(EXTI_Line15) != RESET)
  270. {
  271. if (irqlines[15].handler)
  272. irqlines[15].handler();
  273. EXTI_ClearITPendingBit(EXTI_Line15);
  274. }
  275. }
  276. }
  277. // The sketch we want to run
  278. //#include "examples/rf22/rf22_client/rf22_client.pde"
  279. // Run the Arduino standard functions in the main loop
  280. int main(int argc, char** argv)
  281. {
  282. SysTickConfig();
  283. // Seed the random number generator
  284. // srand(getpid() ^ (unsigned) time(NULL)/2);
  285. setup();
  286. while (1)
  287. loop();
  288. }
  289. void pinMode(uint8_t pin, WiringPinMode mode)
  290. {
  291. if (pin > NUM_PINS)
  292. return;
  293. // Enable the GPIO clock
  294. RCC_AHB1PeriphClockCmd(pins[pin].ahbperiph, ENABLE);
  295. GPIO_InitTypeDef GPIO_InitStructure;
  296. GPIO_InitStructure.GPIO_Pin = pins[pin].pin;
  297. if (mode == INPUT)
  298. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // REVISIT
  299. else if (mode == OUTPUT)
  300. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // REVISIT
  301. else
  302. return; // Unknown so far
  303. GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  304. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  305. GPIO_Init(pins[pin].port, &GPIO_InitStructure);
  306. }
  307. // This takes about 150ns on STM32F4 Discovery
  308. void digitalWrite(uint8_t pin, uint8_t val)
  309. {
  310. if (pin > NUM_PINS)
  311. return;
  312. if (val)
  313. GPIO_SetBits(pins[pin].port, pins[pin].pin);
  314. else
  315. GPIO_ResetBits(pins[pin].port, pins[pin].pin);
  316. }
  317. uint8_t digitalRead(uint8_t pin)
  318. {
  319. if (pin > NUM_PINS)
  320. return 0;
  321. return GPIO_ReadInputDataBit(pins[pin].port, pins[pin].pin);
  322. }
  323. void attachInterrupt(uint8_t pin, void (*handler)(void), int mode)
  324. {
  325. EXTI_InitTypeDef EXTI_InitStructure;
  326. NVIC_InitTypeDef NVIC_InitStructure;
  327. // Record the handler to call when the interrupt occurs
  328. irqlines[pins[pin].extipinsource].handler = handler;
  329. /* Connect EXTI Line to GPIO Pin */
  330. SYSCFG_EXTILineConfig(pins[pin].extiportsource, pins[pin].extipinsource);
  331. /* Configure EXTI line */
  332. EXTI_InitStructure.EXTI_Line = irqlines[pins[pin].extipinsource].extiline;
  333. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  334. if (mode == RISING)
  335. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  336. else if (mode == FALLING)
  337. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  338. else if (mode == CHANGE)
  339. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  340. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  341. EXTI_Init(&EXTI_InitStructure);
  342. /* Enable and set EXTI Interrupt to the lowest priority */
  343. NVIC_InitStructure.NVIC_IRQChannel = irqlines[pins[pin].extipinsource].extiirqn;
  344. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  345. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  346. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  347. NVIC_Init(&NVIC_InitStructure);
  348. // The relevant EXTI?_IRQHandler
  349. // will now be called when the pin makes the selected transition
  350. }
  351. void delay(unsigned long ms)
  352. {
  353. unsigned long start = millis();
  354. while (millis() - start < ms)
  355. ;
  356. }
  357. unsigned long millis()
  358. {
  359. return systick_count;
  360. }
  361. long random(long from, long to)
  362. {
  363. return from + (RNG_GetRandomNumber() % (to - from));
  364. }
  365. long random(long to)
  366. {
  367. return random(0, to);
  368. }
  369. extern "C"
  370. {
  371. // These need to be in C land for correct linking
  372. void _init() {}
  373. void _fini() {}
  374. }
  375. #endif