sci.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. /** @file sci.c
  2. * @brief SCI Driver Implementation File
  3. * @date 29.May.2013
  4. * @version 03.05.02
  5. *
  6. */
  7. /* (c) Texas Instruments 2009-2013, All rights reserved. */
  8. /* USER CODE BEGIN (0) */
  9. /* USER CODE END */
  10. #include "sci.h"
  11. /* USER CODE BEGIN (1) */
  12. /* USER CODE END */
  13. /** @struct g_sciTransfer
  14. * @brief Interrupt mode globals
  15. *
  16. */
  17. static struct g_sciTransfer
  18. {
  19. uint32 mode;
  20. uint32 length;
  21. uint8 * data;
  22. } g_sciTransfer_t[2U];
  23. /** @fn void sciInit(void)
  24. * @brief Initializes the SCI Driver
  25. *
  26. * This function initializes the SCI module.
  27. */
  28. void sciInit(void)
  29. {
  30. /* USER CODE BEGIN (2) */
  31. /* USER CODE END */
  32. /** @b initialize @b SCILIN */
  33. /** - bring SCI out of reset */
  34. scilinREG->GCR0 = 1U;
  35. /** - Disable all interrupts */
  36. scilinREG->CLRINT = 0xFFFFFFFFU;
  37. scilinREG->CLRINTLVL = 0xFFFFFFFFU;
  38. /** - global control 1 */
  39. scilinREG->GCR1 = (1U << 25U) /* enable transmit */
  40. | (1U << 24U) /* enable receive */
  41. | (1U << 5U) /* internal clock (device has no clock pin) */
  42. | ((1U-1U) << 4U) /* number of stop bits */
  43. | (0U << 3U) /* even parity, otherwise odd */
  44. | (0U << 2U) /* enable parity */
  45. | (1U << 1U); /* asynchronous timing mode */
  46. /** - set baudrate */
  47. scilinREG->BRS = 53U; /* baudrate */
  48. /** - transmission length */
  49. scilinREG->FORMAT = 8U - 1U; /* length */
  50. /** - set SCI pins functional mode */
  51. scilinREG->FUN = (1U << 2U) /* tx pin */
  52. | (1U << 1U) /* rx pin */
  53. | (0U); /* clk pin */
  54. /** - set SCI pins default output value */
  55. scilinREG->DOUT = (0U << 2U) /* tx pin */
  56. | (0U << 1U) /* rx pin */
  57. | (0U); /* clk pin */
  58. /** - set SCI pins output direction */
  59. scilinREG->DIR = (0U << 2U) /* tx pin */
  60. | (0U << 1U) /* rx pin */
  61. | (0U); /* clk pin */
  62. /** - set SCI pins open drain enable */
  63. scilinREG->ODR = (0U << 2U) /* tx pin */
  64. | (0U << 1U) /* rx pin */
  65. | (0U); /* clk pin */
  66. /** - set SCI pins pullup/pulldown enable */
  67. scilinREG->PD = (0U << 2U) /* tx pin */
  68. | (0U << 1U) /* rx pin */
  69. | (0U); /* clk pin */
  70. /** - set SCI pins pullup/pulldown select */
  71. scilinREG->PSL = (1U << 2U) /* tx pin */
  72. | (1U << 1U) /* rx pin */
  73. | (1U); /* clk pin */
  74. /** - set interrupt level */
  75. scilinREG->SETINTLVL = (0U << 26U) /* Framing error */
  76. | (0U << 25U) /* Overrun error */
  77. | (0U << 24U) /* Parity error */
  78. | (0U << 9U) /* Receive */
  79. | (0U << 8U) /* Transmit */
  80. | (0U << 1U) /* Wakeup */
  81. | (0U); /* Break detect */
  82. /** - set interrupt enable */
  83. scilinREG->SETINT = (0U << 26U) /* Framing error */
  84. | (0U << 25U) /* Overrun error */
  85. | (0U << 24U) /* Parity error */
  86. | (1U << 9U) /* Receive */
  87. | (0U << 1U) /* Wakeup */
  88. | (0U); /* Break detect */
  89. /** - initialize global transfer variables */
  90. g_sciTransfer_t[1U].mode = 0U << 8U;
  91. g_sciTransfer_t[1U].length = 0U;
  92. /** - Finaly start SCILIN */
  93. scilinREG->GCR1 |= (1U << 7U);
  94. /* USER CODE BEGIN (3) */
  95. /* USER CODE END */
  96. }
  97. /** @fn void sciSetFunctional(sciBASE_t *sci, uint32 port)
  98. * @brief Change functional behavior of pins at runtime.
  99. * @param[in] sci - sci module base address
  100. * @param[in] port - Value to write to FUN register
  101. *
  102. * Change the value of the PCFUN register at runtime, this allows to
  103. * dynamically change the functionality of the SCI pins between functional
  104. * and GIO mode.
  105. */
  106. void sciSetFunctional(sciBASE_t *sci, uint32 port)
  107. {
  108. /* USER CODE BEGIN (4) */
  109. /* USER CODE END */
  110. sci->FUN = port;
  111. /* USER CODE BEGIN (5) */
  112. /* USER CODE END */
  113. }
  114. /** @fn void sciSetBaudrate(sciBASE_t *sci, uint32 baud)
  115. * @brief Change baudrate at runtime.
  116. * @param[in] sci - sci module base address
  117. * @param[in] baud - baudrate in Hz
  118. *
  119. * Change the SCI baudrate at runtime.
  120. */
  121. void sciSetBaudrate(sciBASE_t *sci, uint32 baud)
  122. {
  123. float64 vclk = 100.000 * 1000000.0;
  124. uint32 f = ((sci->GCR1 & 2U) == 2U) ? 16U : 1U;
  125. /* USER CODE BEGIN (6) */
  126. /* USER CODE END */
  127. /*SAFETYMCUSW 96 S MR:6.1 <REVIEWED> "Calculations including int and float cannot be avoided" */
  128. sci->BRS = ((uint32)((vclk /(f*baud) + 0.5)) - 1U) & 0x00FFFFFFU;
  129. /* USER CODE BEGIN (7) */
  130. /* USER CODE END */
  131. }
  132. /** @fn uint32 sciIsTxReady(sciBASE_t *sci)
  133. * @brief Check if Tx buffer empty
  134. * @param[in] sci - sci module base address
  135. *
  136. * @return The TX ready flag
  137. *
  138. * Checks to see if the Tx buffer ready flag is set, returns
  139. * 0 is flags not set otherwise will return the Tx flag itself.
  140. */
  141. uint32 sciIsTxReady(sciBASE_t *sci)
  142. {
  143. /* USER CODE BEGIN (8) */
  144. /* USER CODE END */
  145. return sci->FLR & SCI_TX_INT;
  146. }
  147. /** @fn void sciSendByte(sciBASE_t *sci, uint8 byte)
  148. * @brief Send Byte
  149. * @param[in] sci - sci module base address
  150. * @param[in] byte - byte to transfer
  151. *
  152. * Sends a single byte in polling mode, will wait in the
  153. * routine until the transmit buffer is empty before sending
  154. * the byte. Use sciIsTxReady to check for Tx buffer empty
  155. * before calling sciSendByte to avoid waiting.
  156. */
  157. void sciSendByte(sciBASE_t *sci, uint8 byte)
  158. {
  159. /* USER CODE BEGIN (9) */
  160. /* USER CODE END */
  161. while ((sci->FLR & SCI_TX_INT) == 0U)
  162. {
  163. } /* Wait */
  164. sci->TD = byte;
  165. /* USER CODE BEGIN (10) */
  166. /* USER CODE END */
  167. }
  168. /** @fn void sciSend(sciBASE_t *sci, uint32 length, uint8 * data)
  169. * @brief Send Data
  170. * @param[in] sci - sci module base address
  171. * @param[in] length - number of data words to transfer
  172. * @param[in] data - pointer to data to send
  173. *
  174. * Send a block of data pointed to by 'data' and 'length' bytes
  175. * long. If interrupts have been enabled the data is sent using
  176. * interrupt mode, otherwise polling mode is used. In interrupt
  177. * mode transmission of the first byte is started and the routine
  178. * returns immediately, sciSend must not be called again until the
  179. * transfer is complete, when the sciNotification callback will
  180. * be called. In polling mode, sciSend will not return until
  181. * the transfer is complete.
  182. *
  183. * @note if data word is less than 8 bits, then the data must be left
  184. * aligned in the data byte.
  185. */
  186. void sciSend(sciBASE_t *sci, uint32 length, uint8 * data)
  187. {
  188. uint32 index = sci == sciREG ? 0U : 1U;
  189. /* USER CODE BEGIN (11) */
  190. /* USER CODE END */
  191. if ((g_sciTransfer_t[index].mode & SCI_TX_INT) != 0U)
  192. {
  193. /* we are in interrupt mode */
  194. g_sciTransfer_t[index].length = length;
  195. g_sciTransfer_t[index].data = data;
  196. /* start transmit by sending first byte */
  197. sci->TD = *g_sciTransfer_t[index].data++ ;
  198. sci->SETINT = SCI_TX_INT;
  199. }
  200. else
  201. {
  202. /* send the data */
  203. while (length-- > 0U)
  204. {
  205. while ((sci->FLR & SCI_TX_INT) == 0U)
  206. {
  207. } /* Wait */
  208. sci->TD = *data++;
  209. }
  210. }
  211. /* USER CODE BEGIN (12) */
  212. /* USER CODE END */
  213. }
  214. /** @fn uint32 sciIsRxReady(sciBASE_t *sci)
  215. * @brief Check if Rx buffer full
  216. * @param[in] sci - sci module base address
  217. *
  218. * @return The Rx ready flag
  219. *
  220. * Checks to see if the Rx buffer full flag is set, returns
  221. * 0 is flags not set otherwise will return the Rx flag itself.
  222. */
  223. uint32 sciIsRxReady(sciBASE_t *sci)
  224. {
  225. /* USER CODE BEGIN (13) */
  226. /* USER CODE END */
  227. return sci->FLR & SCI_RX_INT;
  228. }
  229. /** @fn uint32 sciIsIdleDetected(sciBASE_t *sci)
  230. * @brief Check if Idle Period is Detected
  231. * @param[in] sci - sci module base address
  232. *
  233. * @return The Idle flag
  234. *
  235. * Checks to see if the SCI Idle flag is set, returns 0 is flags
  236. * not set otherwise will return the Ilde flag itself.
  237. */
  238. uint32 sciIsIdleDetected(sciBASE_t *sci)
  239. {
  240. /* USER CODE BEGIN (14) */
  241. /* USER CODE END */
  242. return sci->FLR & SCI_IDLE;
  243. }
  244. /** @fn uint32 sciRxError(sciBASE_t *sci)
  245. * @brief Return Rx Error flags
  246. * @param[in] sci - sci module base address
  247. *
  248. * @return The Rx error flags
  249. *
  250. * Returns the Rx framing, overrun and parity errors flags,
  251. * also clears the error flags before returning.
  252. */
  253. uint32 sciRxError(sciBASE_t *sci)
  254. {
  255. uint32 status = sci->FLR & (SCI_FE_INT | SCI_OE_INT |SCI_PE_INT);
  256. /* USER CODE BEGIN (15) */
  257. /* USER CODE END */
  258. sci->FLR = SCI_FE_INT | SCI_OE_INT | SCI_PE_INT;
  259. return status;
  260. }
  261. /** @fn uint32 sciReceiveByte(sciBASE_t *sci)
  262. * @brief Receive Byte
  263. * @param[in] sci - sci module base address
  264. *
  265. * @return Received byte
  266. *
  267. * Receives a single byte in polling mode. If there is
  268. * not a byte in the receive buffer the routine will wait
  269. * until one is received. Use sciIsRxReady to check to
  270. * see if the buffer is full to avoid waiting.
  271. */
  272. uint32 sciReceiveByte(sciBASE_t *sci)
  273. {
  274. /* USER CODE BEGIN (16) */
  275. /* USER CODE END */
  276. while ((sci->FLR & SCI_RX_INT) == 0U)
  277. {
  278. } /* Wait */
  279. return (sci->RD & 0x000000FFU);
  280. }
  281. /** @fn void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data)
  282. * @brief Receive Data
  283. * @param[in] sci - sci module base address
  284. * @param[in] length - number of data words to transfer
  285. * @param[in] data - pointer to data buffer
  286. *
  287. * Receive a block of 'length' bytes long and place it into the
  288. * data buffer pointed to by 'data'. If interrupts have been
  289. * enabled the data is received using interrupt mode, otherwise
  290. * polling mode is used. In interrupt mode receive is setup and
  291. * the routine returns immediately, sciReceive must not be called
  292. * again until the transfer is complete, when the sciNotification
  293. * callback will be called. In polling mode, sciReceive will not
  294. * return until the transfer is complete.
  295. */
  296. void sciReceive(sciBASE_t *sci, uint32 length, uint8 * data)
  297. {
  298. /* USER CODE BEGIN (17) */
  299. /* USER CODE END */
  300. if ((sci->SETINT & SCI_RX_INT) == SCI_RX_INT)
  301. {
  302. /* we are in interrupt mode */
  303. uint32 index = sci == sciREG ? 0U : 1U;
  304. /* clear error flags */
  305. sci->FLR = SCI_FE_INT | SCI_OE_INT | SCI_PE_INT;
  306. g_sciTransfer_t[index].length = length;
  307. g_sciTransfer_t[index].data = data;
  308. }
  309. else
  310. {
  311. while (length-- > 0U)
  312. {
  313. while ((sci->FLR & SCI_RX_INT) == 0U)
  314. {
  315. } /* Wait */
  316. *data++ = (uint8)(sci->RD & 0x000000FFU);
  317. }
  318. }
  319. /* USER CODE BEGIN (18) */
  320. /* USER CODE END */
  321. }
  322. /** @fn void sciEnableLoopback(sciBASE_t *sci, loopBackType_t Loopbacktype)
  323. * @brief Enable Loopback mode for self test
  324. * @param[in] sci - sci module base address
  325. * @param[in] Loopbacktype - Digital or Analog
  326. *
  327. * This function enables the Loopback mode for self test.
  328. */
  329. void sciEnableLoopback(sciBASE_t *sci, loopBackType_t Loopbacktype)
  330. {
  331. /* USER CODE BEGIN (19) */
  332. /* USER CODE END */
  333. /* Clear Loopback incase enabled already */
  334. sci->IODFTCTRL = 0U;
  335. /* Enable Loopback either in Analog or Digital Mode */
  336. sci->IODFTCTRL = 0x00000A00U
  337. | (Loopbacktype << 1U);
  338. /* USER CODE BEGIN (20) */
  339. /* USER CODE END */
  340. }
  341. /** @fn void sciDisableLoopback(sciBASE_t *sci)
  342. * @brief Enable Loopback mode for self test
  343. * @param[in] sci - sci module base address
  344. *
  345. * This function disable the Loopback mode.
  346. */
  347. void sciDisableLoopback(sciBASE_t *sci)
  348. {
  349. /* USER CODE BEGIN (21) */
  350. /* USER CODE END */
  351. /* Disable Loopback Mode */
  352. sci->IODFTCTRL = 0x00000500U;
  353. /* USER CODE BEGIN (22) */
  354. /* USER CODE END */
  355. }
  356. /** @fn sciEnableNotification(sciBASE_t *sci, uint32 flags)
  357. * @brief Enable interrupts
  358. * @param[in] sci - sci module base address
  359. * @param[in] flags - Interrupts to be enabled, can be ored value of:
  360. * SCI_FE_INT - framing error,
  361. * SCI_OE_INT - overrun error,
  362. * SCI_PE_INT - parity error,
  363. * SCI_RX_INT - receive buffer ready,
  364. * SCI_TX_INT - transmit buffer ready,
  365. * SCI_WAKE_INT - wakeup,
  366. * SCI_BREAK_INT - break detect
  367. */
  368. void sciEnableNotification(sciBASE_t *sci, uint32 flags)
  369. {
  370. uint32 index = sci == sciREG ? 0U : 1U;
  371. /* USER CODE BEGIN (23) */
  372. /* USER CODE END */
  373. g_sciTransfer_t[index].mode |= (flags & SCI_TX_INT);
  374. sci->SETINT = (flags & (~(SCI_TX_INT)));
  375. /* USER CODE BEGIN (24) */
  376. /* USER CODE END */
  377. }
  378. /** @fn sciDisableNotification(sciBASE_t *sci, uint32 flags)
  379. * @brief Disable interrupts
  380. * @param[in] sci - sci module base address
  381. * @param[in] flags - Interrupts to be disabled, can be ored value of:
  382. * SCI_FE_INT - framing error,
  383. * SCI_OE_INT - overrun error,
  384. * SCI_PE_INT - parity error,
  385. * SCI_RX_INT - receive buffer ready,
  386. * SCI_TX_INT - transmit buffer ready,
  387. * SCI_WAKE_INT - wakeup,
  388. * SCI_BREAK_INT - break detect
  389. */
  390. void sciDisableNotification(sciBASE_t *sci, uint32 flags)
  391. {
  392. uint32 index = sci == sciREG ? 0U : 1U;
  393. /* USER CODE BEGIN (25) */
  394. /* USER CODE END */
  395. g_sciTransfer_t[index].mode &= ~(flags & SCI_TX_INT);
  396. sci->CLRINT = (flags & (~SCI_TX_INT));
  397. /* USER CODE BEGIN (26) */
  398. /* USER CODE END */
  399. }
  400. /** @fn void linHighLevelInterrupt(void)
  401. * @brief Level 0 Interrupt for SCILIN
  402. */
  403. void linHighLevelInterrupt(void)
  404. {
  405. uint32 vec = scilinREG->INTVECT0;
  406. /* USER CODE BEGIN (35) */
  407. /* USER CODE END */
  408. switch (vec)
  409. {
  410. case 1U:
  411. sciNotification(scilinREG, SCI_WAKE_INT);
  412. break;
  413. case 3U:
  414. sciNotification(scilinREG, SCI_PE_INT);
  415. break;
  416. case 6U:
  417. sciNotification(scilinREG, SCI_FE_INT);
  418. break;
  419. case 7U:
  420. sciNotification(scilinREG, SCI_BREAK_INT);
  421. break;
  422. case 9U:
  423. sciNotification(scilinREG, SCI_OE_INT);
  424. break;
  425. case 11U:
  426. /* receive */
  427. { uint32 byte = (scilinREG->RD & 0x000000FFU);
  428. if (g_sciTransfer_t[1U].length > 0U)
  429. {
  430. *g_sciTransfer_t[1U].data++ = byte;
  431. g_sciTransfer_t[1U].length--;
  432. if (g_sciTransfer_t[1U].length == 0U)
  433. {
  434. sciNotification(scilinREG, SCI_RX_INT);
  435. }
  436. }
  437. }
  438. break;
  439. case 12U:
  440. /* transmit */
  441. if (--g_sciTransfer_t[1U].length > 0U)
  442. {
  443. scilinREG->TD = *g_sciTransfer_t[1U].data++;
  444. }
  445. else
  446. {
  447. scilinREG->CLRINT = SCI_TX_INT;
  448. sciNotification(scilinREG, SCI_TX_INT);
  449. }
  450. break;
  451. default:
  452. /* phantom interrupt, clear flags and return */
  453. scilinREG->FLR = ~scilinREG->SETINTLVL & 0x07000303U;
  454. break;
  455. }
  456. /* USER CODE BEGIN (36) */
  457. /* USER CODE END */
  458. }
  459. /* USER CODE BEGIN (37) */
  460. /* USER CODE END */