uart.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * This Source Code Form is subject to the terms of the MIT License.
  3. * If a copy of the MIT License was not distributed with this file,
  4. * you can obtain one at https://opensource.org/licenses/MIT
  5. */
  6. #include <string.h>
  7. #include "main.h"
  8. #include "uart.h"
  9. #include "system.h"
  10. #define UART_BUFFER_LEN (12u)
  11. #define UART1 (0x40004000)
  12. #define UART2 (0x40004400)
  13. #define UART3 (0x40004800)
  14. #define UART2_SR (*(volatile uint32_t *)(UART2))
  15. #define UART2_DR (*(volatile uint32_t *)(UART2 + 0x04))
  16. #define UART2_BRR (*(volatile uint32_t *)(UART2 + 0x08))
  17. #define UART2_CR1 (*(volatile uint32_t *)(UART2 + 0x0c))
  18. #define UART2_CR2 (*(volatile uint32_t *)(UART2 + 0x10))
  19. #define UART_CR1_UART_ENABLE (1 << 13)
  20. #define UART_CR1_SYMBOL_LEN (1 << 12)
  21. #define UART_CR1_PARITY_ENABLED (1 << 10)
  22. #define UART_CR1_PARITY_ODD (1 << 9)
  23. #define UART_CR1_TX_ENABLE (1 << 3)
  24. #define UART_CR1_RX_ENABLE (1 << 2)
  25. #define UART_CR2_STOPBITS (3 << 12)
  26. #define UART_SR_TX_EMPTY (1 << 7)
  27. #define UART_SR_RX_NOTEMPTY (1 << 5)
  28. //#define UART_WAIT_TRANSMIT do { } while(0)
  29. #define UART_WAIT_TRANSMIT do { ; } while (!(UART2_SR & UART_SR_TX_EMPTY))
  30. #define CLOCK_SPEED (168000000)
  31. #define NVIC_UART1_IRQN (37)
  32. #define NVIC_UART2_IRQN (38)
  33. #define NVIC_UART3_IRQN (39)
  34. #define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
  35. #define UART1_APB1_CLOCK_ER_VAL (1 << 14)
  36. #define UART2_APB1_CLOCK_ER_VAL (1 << 17)
  37. #define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
  38. #define GPIOD_AHB1_CLOCK_ER (1 << 3)
  39. #define GPIOD_BASE 0x40020c00
  40. #define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
  41. #define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
  42. #define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
  43. #define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
  44. #define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
  45. #define GPIO_MODE_AF (2)
  46. #define UART2_PIN_AF 7
  47. #ifndef CUSTOM_HW
  48. #define UART_PIO_MODE GPIOA_MODE
  49. #define UART_PIO_AFL GPIOA_AFL
  50. #define UART_PIO_AFH GPIOA_AFH
  51. #define UART2_RX_PIN 3
  52. #define UART2_TX_PIN 2
  53. #else
  54. #define UART_PIO_MODE GPIOA_MODE
  55. #define UART_PIO_AFL GPIOA_AFL
  56. #define UART_PIO_AFH GPIOA_AFH
  57. #define UART2_RX_PIN 3
  58. #define UART2_TX_PIN 2
  59. #endif
  60. static const char chrTbl[] = "0123456789ABCDEF";
  61. uint8_t uartStr[UART_BUFFER_LEN] = {0u};
  62. uint8_t uartStrInd = 0u;
  63. static void uartExecCmd( uint8_t const * const cmd, uartControl_t * const ctrl );
  64. /* UART: PA2 (TX), PA3 (RX) */
  65. static void uart2_pins_setup(void)
  66. {
  67. uint32_t reg;
  68. /* Set mode = AF */
  69. reg = UART_PIO_MODE & ~ (0x03 << (UART2_RX_PIN * 2));
  70. UART_PIO_MODE = reg | (2 << (UART2_RX_PIN * 2));
  71. reg = UART_PIO_MODE & ~ (0x03 << (UART2_TX_PIN * 2));
  72. UART_PIO_MODE = reg | (2 << (UART2_TX_PIN * 2));
  73. /* Alternate function: use low pins (5 and 6) */
  74. #if (UART2_RX_PIN > 7)
  75. reg = UART_PIO_AFH & ~(0xf << ((UART2_RX_PIN - 8) * 4));
  76. UART_PIO_AFH = reg | (UART2_PIN_AF << ((UART2_RX_PIN - 8) * 4));
  77. #else
  78. reg = UART_PIO_AFL & ~(0xf << ((UART2_RX_PIN) * 4));
  79. UART_PIO_AFL = reg | (UART2_PIN_AF << ((UART2_RX_PIN) * 4));
  80. #endif
  81. #if (UART2_TX_PIN > 7)
  82. reg = UART_PIO_AFH & ~(0xf << ((UART2_TX_PIN - 8) * 4));
  83. UART_PIO_AFH = reg | (UART2_PIN_AF << ((UART2_TX_PIN - 8) * 4));
  84. #else
  85. reg = UART_PIO_AFL & ~(0xf << ((UART2_TX_PIN) * 4));
  86. UART_PIO_AFL = reg | (UART2_PIN_AF << ((UART2_TX_PIN) * 4));
  87. #endif
  88. }
  89. void uartInit( void )
  90. {
  91. uint32_t reg;
  92. const int data = 8;
  93. const char parity = 'N';
  94. const char stop = 1;
  95. const unsigned bitrate = 115200;
  96. uint8_t uartData;
  97. /* Enable pins and configure for AF7 */
  98. uart2_pins_setup();
  99. /* Turn on the device */
  100. APB1_CLOCK_ER |= UART2_APB1_CLOCK_ER_VAL;
  101. /* Configure for TX + RX */
  102. UART2_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
  103. /* Configure clock */
  104. UART2_BRR = CLOCK_SPEED / bitrate;
  105. /* Configure data bits */
  106. if (data == 8)
  107. UART2_CR1 &= ~UART_CR1_SYMBOL_LEN;
  108. else
  109. UART2_CR1 |= UART_CR1_SYMBOL_LEN;
  110. /* Configure parity */
  111. switch (parity) {
  112. case 'O':
  113. UART2_CR1 |= UART_CR1_PARITY_ODD;
  114. /* fall through to enable parity */
  115. /* fall through */
  116. case 'E':
  117. UART2_CR1 |= UART_CR1_PARITY_ENABLED;
  118. break;
  119. default:
  120. UART2_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
  121. }
  122. /* Set stop bits */
  123. reg = UART2_CR2 & ~UART_CR2_STOPBITS;
  124. if (stop > 1)
  125. UART2_CR2 = reg & (2 << 12);
  126. else
  127. UART2_CR2 = reg;
  128. /* Turn on uart */
  129. UART2_CR1 |= UART_CR1_UART_ENABLE;
  130. /* Flush UART buffers */
  131. uartData = UART2_DR;
  132. uartData = UART2_DR;
  133. uartData = UART2_DR;
  134. (void)uartData;
  135. return ;
  136. }
  137. static void uartExecCmd( uint8_t const * const cmd, uartControl_t * const ctrl )
  138. {
  139. uint8_t i = 1u;
  140. uint8_t c = 0u;
  141. uint32_t hConv = 0u;
  142. switch (cmd[0])
  143. {
  144. case 'a':
  145. case 'A':
  146. case 'l':
  147. case 'L':
  148. hConv = 0u;
  149. for (i = 1; i < (UART_BUFFER_LEN - 1u); ++i)
  150. {
  151. c = cmd[i];
  152. if ((c <= '9') && (c >= '0'))
  153. {
  154. c -= '0';
  155. }
  156. else if ((c >= 'a') && (c <= 'f'))
  157. {
  158. c -= 'a';
  159. c += 0x0A;
  160. }
  161. else if ((c >= 'A') && (c <= 'F'))
  162. {
  163. c -= 'A';
  164. c += 0x0A;
  165. }
  166. else
  167. {
  168. break;
  169. }
  170. hConv <<= 4u;
  171. hConv |= c;
  172. }
  173. if ((cmd[0] == 'a') || (cmd[0] == 'A'))
  174. {
  175. /* Enforce 32-bit alignment */
  176. while ((hConv & 0x00000003u) != 0x00u)
  177. {
  178. --hConv;
  179. }
  180. ctrl->readoutAddress = hConv;
  181. uartSendStr("Start address set to 0x");
  182. uartSendWordHexBE(hConv);
  183. uartSendStr("\r\n");
  184. }
  185. else /* l or L */
  186. {
  187. /* Enforce 32-bit alignment */
  188. while ((hConv & 0x00000003u) != 0x00u)
  189. {
  190. ++hConv;
  191. }
  192. ctrl->readoutLen = hConv;
  193. uartSendStr("Readout length set to 0x");
  194. uartSendWordHexBE(hConv);
  195. uartSendStr("\r\n");
  196. }
  197. break;
  198. case 'b':
  199. case 'B':
  200. ctrl->transmitHex = 0u;
  201. uartSendStr("Binary output mode selected\r\n");
  202. break;
  203. case 'e':
  204. ctrl->transmitLittleEndian = 1u;
  205. uartSendStr("Little Endian mode enabled\r\n");
  206. break;
  207. case 'E':
  208. ctrl->transmitLittleEndian = 0u;
  209. uartSendStr("Big Endian mode enabled\r\n");
  210. break;
  211. case 'h':
  212. case 'H':
  213. ctrl->transmitHex = 1u;
  214. uartSendStr("Hex output mode selected\r\n");
  215. break;
  216. case 'p':
  217. case 'P':
  218. printExtractionStatistics();
  219. break;
  220. case 's':
  221. case 'S':
  222. ctrl->active = 1u;
  223. uartSendStr("Flash readout started!\r\n");
  224. break;
  225. case '\n':
  226. case '\r':
  227. case '\0':
  228. /* ignore */
  229. break;
  230. default:
  231. uartSendStr("ERROR: unknown command\r\n");
  232. break;
  233. }
  234. }
  235. void uartReceiveCommands( uartControl_t * const ctrl )
  236. {
  237. uint8_t uartData = 0u;
  238. if (UART2_SR & UART_SR_RX_NOTEMPTY)
  239. {
  240. uartData = UART2_DR;
  241. switch (uartData)
  242. {
  243. /* ignore \t */
  244. case '\t':
  245. break;
  246. /* Accept \r and \n as command delimiter */
  247. case '\r':
  248. case '\n':
  249. /* Execute Command */
  250. uartExecCmd(uartStr, ctrl);
  251. uartStrInd = 0u;
  252. memset(uartStr, 0x00u, sizeof(uartStr));
  253. break;
  254. default:
  255. if (uartStrInd < (UART_BUFFER_LEN - 1u))
  256. {
  257. uartStr[uartStrInd] = uartData;
  258. ++uartStrInd;
  259. }
  260. break;
  261. }
  262. }
  263. return ;
  264. }
  265. void uartSendWordBin( uint32_t const val, uartControl_t const * const ctrl )
  266. {
  267. if (ctrl->transmitLittleEndian)
  268. {
  269. uartSendWordBinLE( val );
  270. }
  271. else
  272. {
  273. uartSendWordBinBE( val );
  274. }
  275. }
  276. void uartSendWordHex( uint32_t const val, uartControl_t const * const ctrl )
  277. {
  278. if (ctrl->transmitLittleEndian)
  279. {
  280. uartSendWordHexLE( val );
  281. }
  282. else
  283. {
  284. uartSendWordHexBE( val );
  285. }
  286. }
  287. void uartSendWordBinLE( uint32_t const val )
  288. {
  289. uint8_t i = 0u;
  290. uint32_t tval = val;
  291. for (i = 0u; i < 4u; ++i)
  292. {
  293. UART2_DR = tval & 0xFFu;
  294. tval >>= 8u;
  295. UART_WAIT_TRANSMIT;
  296. }
  297. return ;
  298. }
  299. void uartSendWordBinBE( uint32_t const val )
  300. {
  301. uint8_t i = 0u;
  302. uint32_t tval = val;
  303. for (i = 0u; i < 4u; ++i)
  304. {
  305. UART2_DR = ((tval >> ((3u - i) << 3u)) & 0xFFu);
  306. UART_WAIT_TRANSMIT;
  307. }
  308. return ;
  309. }
  310. void uartSendWordHexLE( uint32_t const val )
  311. {
  312. uint8_t i = 0u;
  313. uint32_t tval = val;
  314. for (i = 0u; i < 4u; ++i)
  315. {
  316. uartSendByteHex( tval & 0xFFu );
  317. tval >>= 8u;
  318. }
  319. return;
  320. }
  321. void uartSendWordHexBE( uint32_t const val )
  322. {
  323. uint8_t i = 0u;
  324. uint32_t tval = val;
  325. for (i = 0u; i < 4u; ++i)
  326. {
  327. uartSendByteHex((tval >> ((3u - i) << 3u)) & 0xFFu);
  328. UART_WAIT_TRANSMIT;
  329. }
  330. return ;
  331. }
  332. void uartSendByteHex( uint8_t const val )
  333. {
  334. char sendstr[3] = {0};
  335. sendstr[0] = chrTbl[(val >> 4u) & 0x0Fu];
  336. sendstr[1] = chrTbl[val & 0x0Fu];
  337. sendstr[2] = '\0';
  338. uartSendStr( sendstr );
  339. return ;
  340. }
  341. void uartSendStr( const char * const str )
  342. {
  343. const char * strptr = str;
  344. while (*strptr)
  345. {
  346. UART2_DR = *strptr;
  347. ++strptr;
  348. UART_WAIT_TRANSMIT;
  349. }
  350. return ;
  351. }