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.

HardwareSerial.cpp 11KB

3 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. // ArduinoCompat/HardwareSerial.cpp
  2. //
  3. // Author: mikem@airspayce.com
  4. #include <RadioHead.h>
  5. #if (RH_PLATFORM == RH_PLATFORM_STM32STD)
  6. #include <HardwareSerial.h>
  7. #include <stm32f4xx_usart.h>
  8. // Preinstantiated Serial objects
  9. HardwareSerial Serial1(USART1);
  10. HardwareSerial Serial2(USART2);
  11. HardwareSerial Serial3(USART3);
  12. HardwareSerial Serial4(UART4);
  13. HardwareSerial Serial5(UART5);
  14. HardwareSerial Serial6(USART6);
  15. ///////////////////////////////////////////////////////////////
  16. // RingBuffer
  17. ///////////////////////////////////////////////////////////////
  18. RingBuffer::RingBuffer()
  19. : _head(0),
  20. _tail(0),
  21. _overruns(0),
  22. _underruns(0)
  23. {
  24. }
  25. bool RingBuffer::isEmpty()
  26. {
  27. return _head == _tail;
  28. }
  29. bool RingBuffer::isFull()
  30. {
  31. return ((_head + 1) % ARDUINO_RINGBUFFER_SIZE) == _tail;
  32. }
  33. bool RingBuffer::write(uint8_t ch)
  34. {
  35. if (isFull())
  36. {
  37. _overruns++;
  38. return false;
  39. }
  40. _buffer[_head] = ch;
  41. if (++_head >= ARDUINO_RINGBUFFER_SIZE)
  42. _head = 0;
  43. return true;
  44. }
  45. uint8_t RingBuffer::read()
  46. {
  47. if (isEmpty())
  48. {
  49. _underruns++;
  50. return 0; // What else can we do?
  51. }
  52. uint8_t ret = _buffer[_tail];
  53. if (++_tail >= ARDUINO_RINGBUFFER_SIZE)
  54. _tail = 0;
  55. return ret;
  56. }
  57. ///////////////////////////////////////////////////////////////
  58. // HardwareSerial
  59. ///////////////////////////////////////////////////////////////
  60. // On STM32F4 Discovery, USART 1 is not very useful conflicts with the Green lED
  61. HardwareSerial::HardwareSerial(USART_TypeDef* usart)
  62. : _usart(usart)
  63. {
  64. }
  65. void HardwareSerial::begin(unsigned long baud)
  66. {
  67. USART_InitTypeDef USART_InitStructure;
  68. GPIO_InitTypeDef GPIO_InitStructure_TX;
  69. GPIO_InitTypeDef GPIO_InitStructure_RX;
  70. // Common GPIO structure init:
  71. GPIO_InitStructure_TX.GPIO_Speed = GPIO_Speed_50MHz;
  72. GPIO_InitStructure_TX.GPIO_Mode = GPIO_Mode_AF;
  73. GPIO_InitStructure_TX.GPIO_OType = GPIO_OType_PP;
  74. GPIO_InitStructure_TX.GPIO_PuPd = GPIO_PuPd_UP;
  75. GPIO_InitStructure_RX.GPIO_Speed = GPIO_Speed_50MHz;
  76. GPIO_InitStructure_RX.GPIO_Mode = GPIO_Mode_AF;
  77. GPIO_InitStructure_RX.GPIO_OType = GPIO_OType_PP;
  78. GPIO_InitStructure_RX.GPIO_PuPd = GPIO_PuPd_UP;
  79. // CTS or SCLK outputs are not supported.
  80. USART_InitStructure.USART_BaudRate = baud * 25/8; // Why?
  81. // Only 8N1 is currently supported
  82. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  83. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  84. USART_InitStructure.USART_Parity = USART_Parity_No;
  85. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  86. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  87. // Different for each USART:
  88. if (_usart == USART1)
  89. {
  90. // Initialise the clocks for this USART and its RX, TX pins port
  91. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  92. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  93. GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
  94. GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
  95. GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_9;
  96. GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_10;
  97. GPIO_Init(GPIOA, &GPIO_InitStructure_TX);
  98. GPIO_Init(GPIOA, &GPIO_InitStructure_RX);
  99. // Initialise the USART
  100. USART_Init(USART1, &USART_InitStructure);
  101. // Enable the RXNE interrupt
  102. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  103. // Enable global interrupt
  104. NVIC_EnableIRQ(USART1_IRQn);
  105. }
  106. else if (_usart == USART2)
  107. {
  108. // Initialise the clocks for this USART and its RX, TX pins port
  109. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  110. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  111. GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
  112. GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
  113. GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_2;
  114. GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_3;
  115. GPIO_Init(GPIOA, &GPIO_InitStructure_TX);
  116. GPIO_Init(GPIOA, &GPIO_InitStructure_RX);
  117. // Initialise the USART
  118. USART_Init(USART2, &USART_InitStructure);
  119. // Enable the RXNE interrupt
  120. USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
  121. // Enable global interrupt
  122. NVIC_EnableIRQ(USART2_IRQn);
  123. }
  124. else if (_usart == USART3)
  125. {
  126. // Initialise the clocks for this USART and its RX, TX pins port
  127. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
  128. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  129. GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
  130. GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
  131. GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_8;
  132. GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_9;
  133. GPIO_Init(GPIOD, &GPIO_InitStructure_TX);
  134. GPIO_Init(GPIOD, &GPIO_InitStructure_RX);
  135. // Initialise the USART
  136. USART_Init(USART3, &USART_InitStructure);
  137. // Enable the RXNE interrupt
  138. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
  139. // Enable global interrupt
  140. NVIC_EnableIRQ(USART3_IRQn);
  141. }
  142. else if (_usart == UART4)
  143. {
  144. // Initialise the clocks for this USART and its RX, TX pins port
  145. RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
  146. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  147. GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_UART4);
  148. GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_UART4);
  149. GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_0;
  150. GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_1;
  151. GPIO_Init(GPIOA, &GPIO_InitStructure_TX);
  152. GPIO_Init(GPIOA, &GPIO_InitStructure_RX);
  153. // Initialise the USART
  154. USART_Init(UART4, &USART_InitStructure);
  155. // Enable the RXNE interrupt
  156. USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);
  157. // Enable global interrupt
  158. NVIC_EnableIRQ(UART4_IRQn);
  159. }
  160. else if (_usart == UART5)
  161. {
  162. // Initialise the clocks for this USART and its RX, TX pins port
  163. RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
  164. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);
  165. GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
  166. GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
  167. GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_12;
  168. GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_2;
  169. GPIO_Init(GPIOC, &GPIO_InitStructure_TX);
  170. GPIO_Init(GPIOD, &GPIO_InitStructure_RX);
  171. // Initialise the USART
  172. USART_Init(UART5, &USART_InitStructure);
  173. // Enable the RXNE interrupt
  174. USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);
  175. // Enable global interrupt
  176. NVIC_EnableIRQ(UART5_IRQn);
  177. }
  178. else if (_usart == USART6)
  179. {
  180. // Initialise the clocks for this USART and its RX, TX pins port
  181. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
  182. RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  183. GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6);
  184. GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
  185. GPIO_InitStructure_TX.GPIO_Pin = GPIO_Pin_6;
  186. GPIO_InitStructure_RX.GPIO_Pin = GPIO_Pin_7;
  187. GPIO_Init(GPIOC, &GPIO_InitStructure_TX);
  188. GPIO_Init(GPIOC, &GPIO_InitStructure_RX);
  189. // Initialise the USART
  190. USART_Init(USART6, &USART_InitStructure);
  191. // Enable the RXNE interrupt
  192. USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);
  193. // Enable global interrupt
  194. NVIC_EnableIRQ(USART6_IRQn);
  195. }
  196. USART_Cmd(_usart, ENABLE);
  197. }
  198. void HardwareSerial::end()
  199. {
  200. USART_Cmd(_usart, DISABLE);
  201. USART_DeInit(_usart);
  202. }
  203. int HardwareSerial::available(void)
  204. {
  205. return !_rxRingBuffer.isEmpty();
  206. }
  207. int HardwareSerial::read(void)
  208. {
  209. return _rxRingBuffer.read();
  210. }
  211. size_t HardwareSerial::write(uint8_t ch)
  212. {
  213. _txRingBuffer.write(ch); // Queue it
  214. USART_ITConfig(_usart, USART_IT_TXE, ENABLE); // Enable the TX interrupt
  215. return 1;
  216. }
  217. extern "C"
  218. {
  219. void USART1_IRQHandler(void)
  220. {
  221. if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  222. {
  223. Serial1._rxRingBuffer.write(USART_ReceiveData(USART1));
  224. }
  225. if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
  226. {
  227. // Transmitter is empty, maybe send another char?
  228. if (Serial1._txRingBuffer.isEmpty())
  229. USART_ITConfig(USART1, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
  230. else
  231. USART_SendData(USART1, Serial1._txRingBuffer.read());
  232. }
  233. }
  234. void USART2_IRQHandler(void)
  235. {
  236. if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
  237. {
  238. // Newly received char, try to put it in our rx buffer
  239. Serial2._rxRingBuffer.write(USART_ReceiveData(USART2));
  240. }
  241. if (USART_GetITStatus(USART2, USART_IT_TXE) != RESET)
  242. {
  243. // Transmitter is empty, maybe send another char?
  244. if (Serial2._txRingBuffer.isEmpty())
  245. USART_ITConfig(USART2, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
  246. else
  247. USART_SendData(USART2, Serial2._txRingBuffer.read());
  248. }
  249. }
  250. void USART3_IRQHandler(void)
  251. {
  252. if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
  253. {
  254. // Newly received char, try to put it in our rx buffer
  255. Serial3._rxRingBuffer.write(USART_ReceiveData(USART3));
  256. }
  257. if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET)
  258. {
  259. // Transmitter is empty, maybe send another char?
  260. if (Serial3._txRingBuffer.isEmpty())
  261. USART_ITConfig(USART3, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
  262. else
  263. USART_SendData(USART3, Serial3._txRingBuffer.read());
  264. }
  265. }
  266. void UART4_IRQHandler(void)
  267. {
  268. if (USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)
  269. {
  270. // Newly received char, try to put it in our rx buffer
  271. Serial4._rxRingBuffer.write(USART_ReceiveData(UART4));
  272. }
  273. if (USART_GetITStatus(UART4, USART_IT_TXE) != RESET)
  274. {
  275. // Transmitter is empty, maybe send another char?
  276. if (Serial4._txRingBuffer.isEmpty())
  277. USART_ITConfig(UART4, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
  278. else
  279. USART_SendData(UART4, Serial4._txRingBuffer.read());
  280. }
  281. }
  282. void UART5_IRQHandler(void)
  283. {
  284. if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)
  285. {
  286. // Newly received char, try to put it in our rx buffer
  287. Serial5._rxRingBuffer.write(USART_ReceiveData(UART5));
  288. }
  289. if (USART_GetITStatus(UART5, USART_IT_TXE) != RESET)
  290. {
  291. // Transmitter is empty, maybe send another char?
  292. if (Serial5._txRingBuffer.isEmpty())
  293. USART_ITConfig(UART5, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
  294. else
  295. USART_SendData(UART5, Serial5._txRingBuffer.read());
  296. }
  297. }
  298. void USART6_IRQHandler(void)
  299. {
  300. if (USART_GetITStatus(USART6, USART_IT_RXNE) != RESET)
  301. {
  302. // Newly received char, try to put it in our rx buffer
  303. Serial6._rxRingBuffer.write(USART_ReceiveData(USART6));
  304. }
  305. if (USART_GetITStatus(USART6, USART_IT_TXE) != RESET)
  306. {
  307. // Transmitter is empty, maybe send another char?
  308. if (Serial6._txRingBuffer.isEmpty())
  309. USART_ITConfig(USART6, USART_IT_TXE, DISABLE); // No more to send, disable the TX interrupt
  310. else
  311. USART_SendData(USART6, Serial6._txRingBuffer.read());
  312. }
  313. }
  314. }
  315. #endif