uart.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. #include <stdio.h>
  2. #include <stddef.h>
  3. #include <string.h>
  4. #include "FreeRTOS.h"
  5. #include "chip.h"
  6. #include "board.h"
  7. #include "serial.h"
  8. #include "sysinfo.h"
  9. /* UART Register Offsets. */
  10. #define UART_DR 0x00 /* Data read or written from the interface. */
  11. #define UART_RSR 0x04 /* Receive status register (Read). */
  12. #define UART_FR 0x18 /* Flag register (Read only). */
  13. #define UART_ILPR 0x20 /* IrDA low power counter register. */
  14. #define UART_IBRD 0x24 /* Integer baud rate divisor register. */
  15. #define UART_FBRD 0x28 /* Fractional baud rate divisor register. */
  16. #define UART_LCRH 0x2c /* Line control register. */
  17. #define UART_CR 0x30 /* Control register. */
  18. #define UART_IFLS 0x34 /* Interrupt fifo level select. */
  19. #define UART_IMSC 0x38 /* Interrupt mask. */
  20. #define UART_RIS 0x3c /* Raw interrupt status. */
  21. #define UART_MIS 0x40 /* Masked interrupt status. */
  22. #define UART_ICR 0x44 /* Interrupt clear register. */
  23. #define UART_DMACR 0x48 /* DMA control register. */
  24. #define UART_DR_OE (1 << 11)
  25. #define UART_DR_BE (1 << 10)
  26. #define UART_DR_PE (1 << 9)
  27. #define UART_DR_FE (1 << 8)
  28. #define UART_RSR_OE 0x08
  29. #define UART_RSR_BE 0x04
  30. #define UART_RSR_PE 0x02
  31. #define UART_RSR_FE 0x01
  32. #define UART_FR_RI 0x100
  33. #define UART_FR_TXFE 0x080
  34. #define UART_FR_RXFF 0x040
  35. #define UART_FR_TXFF 0x020
  36. #define UART_FR_RXFE 0x010
  37. #define UART_FR_BUSY 0x008
  38. #define UART_FR_DCD 0x004
  39. #define UART_FR_DSR 0x002
  40. #define UART_FR_CTS 0x001
  41. #define UART_FR_TMSK (UART_FR_TXFF + UART_FR_BUSY)
  42. #define UART_CR_CTSEN 0x8000 /* CTS hardware flow control */
  43. #define UART_CR_RTSEN 0x4000 /* RTS hardware flow control */
  44. #define UART_CR_OUT2 0x2000 /* OUT2 */
  45. #define UART_CR_OUT1 0x1000 /* OUT1 */
  46. #define UART_CR_RTS 0x0800 /* RTS */
  47. #define UART_CR_DTR 0x0400 /* DTR */
  48. #define UART_CR_RXE 0x0200 /* receive enable */
  49. #define UART_CR_TXE 0x0100 /* transmit enable */
  50. #define UART_CR_LBE 0x0080 /* loopback enable */
  51. #define UART_CR_RTIE 0x0040
  52. #define UART_CR_TIE 0x0020
  53. #define UART_CR_RIE 0x0010
  54. #define UART_CR_MSIE 0x0008
  55. #define UART_CR_IIRLP 0x0004 /* SIR low power mode */
  56. #define UART_CR_SIREN 0x0002 /* SIR enable */
  57. #define UART_CR_UARTEN 0x0001 /* UART enable */
  58. #define UART_LCRH_SPS 0x80
  59. #define UART_LCRH_WLEN_8 0x60
  60. #define UART_LCRH_WLEN_7 0x40
  61. #define UART_LCRH_WLEN_6 0x20
  62. #define UART_LCRH_WLEN_5 0x00
  63. #define UART_LCRH_FEN 0x10
  64. #define UART_LCRH_STP2 0x08
  65. #define UART_LCRH_EPS 0x04
  66. #define UART_LCRH_PEN 0x02
  67. #define UART_LCRH_BRK 0x01
  68. #define UART_IFLS_RX1_8 (0 << 3)
  69. #define UART_IFLS_RX2_8 (1 << 3)
  70. #define UART_IFLS_RX4_8 (2 << 3)
  71. #define UART_IFLS_RX6_8 (3 << 3)
  72. #define UART_IFLS_RX7_8 (4 << 3)
  73. #define UART_IFLS_TX1_8 (0 << 0)
  74. #define UART_IFLS_TX2_8 (1 << 0)
  75. #define UART_IFLS_TX4_8 (2 << 0)
  76. #define UART_IFLS_TX6_8 (3 << 0)
  77. #define UART_IFLS_TX7_8 (4 << 0)
  78. #define UART_OEIM (1 << 10) /* overrun error interrupt mask */
  79. #define UART_BEIM (1 << 9) /* break error interrupt mask */
  80. #define UART_PEIM (1 << 8) /* parity error interrupt mask */
  81. #define UART_FEIM (1 << 7) /* framing error interrupt mask */
  82. #define UART_RTIM (1 << 6) /* receive timeout interrupt mask */
  83. #define UART_TXIM (1 << 5) /* transmit interrupt mask */
  84. #define UART_RXIM (1 << 4) /* receive interrupt mask */
  85. #define UART_DSRMIM (1 << 3) /* DSR interrupt mask */
  86. #define UART_DCDMIM (1 << 2) /* DCD interrupt mask */
  87. #define UART_CTSMIM (1 << 1) /* CTS interrupt mask */
  88. #define UART_RIMIM (1 << 0) /* RI interrupt mask */
  89. #define UART_OEIS (1 << 10) /* overrun error interrupt status */
  90. #define UART_BEIS (1 << 9) /* break error interrupt status */
  91. #define UART_PEIS (1 << 8) /* parity error interrupt status */
  92. #define UART_FEIS (1 << 7) /* framing error interrupt status */
  93. #define UART_RTIS (1 << 6) /* receive timeout interrupt status */
  94. #define UART_TXIS (1 << 5) /* transmit interrupt status */
  95. #define UART_RXIS (1 << 4) /* receive interrupt status */
  96. #define UART_DSRMIS (1 << 3) /* DSR interrupt status */
  97. #define UART_DCDMIS (1 << 2) /* DCD interrupt status */
  98. #define UART_CTSMIS (1 << 1) /* CTS interrupt status */
  99. #define UART_RIMIS (1 << 0) /* RI interrupt status */
  100. #define UART485_RBR_THR_DLL 0x000
  101. #define UART485_DLH_IER 0x004
  102. #define UART485_IIR_FCR 0x008
  103. #define UART485_RBR 0x000
  104. #define UART485_THR 0x000
  105. #define UART485_DLL 0x000
  106. #define UART485_DLH 0x004
  107. #define UART485_IER 0x004
  108. #define UART485_IIR 0x008
  109. #define UART485_FCR 0x008
  110. #define UART485_LCR 0x00C
  111. #define UART485_MCR 0x010
  112. #define UART485_LSR 0x014
  113. #define UART485_MSR 0x018
  114. #define UART485_SCR 0x01C
  115. #define UART485_LPDLL 0x020
  116. #define UART485_LPDLH 0x024
  117. #define UART485_RESERVED 0x028
  118. #define UART485_SRBR 0x030
  119. #define UART485_STHR 0x06C
  120. #define UART485_FAR 0x070
  121. #define UART485_TFR 0x074
  122. #define UART485_RFW 0x078
  123. #define UART485_USR 0x07C
  124. #define UART485_TFL 0x080
  125. #define UART485_RFL 0x084
  126. #define UART485_SRR 0x088
  127. #define UART485_SRTS 0x08C
  128. #define UART485_SBCR 0x090
  129. #define UART485_SDMAM 0x094
  130. #define UART485_SFE 0x098
  131. #define UART485_SRT 0x09C
  132. #define UART485_STET 0x0A0
  133. #define UART485_HTX 0x0A4
  134. #define UART485_DMASA 0x0A8
  135. #define UART485_TCR 0x0AC
  136. #define UART485_DE_EN 0x0B0
  137. #define UART485_RE_EN 0x0B4
  138. #define UART485_DET 0x0B8
  139. #define UART485_TAT 0x0BC
  140. #define UART485_DLF 0x0C0
  141. #define UART485_RAR 0x0C4
  142. #define UART485_TAR 0x0C8
  143. #define UART485_LCR_EXT 0x0CC
  144. #define UART485_CPR 0x0F4
  145. #define UART485_UCV 0x0F8
  146. #define UART485_CTR 0x0FC
  147. #define UART485_LSR_RFE (1 << 7)
  148. #define UART485_LSR_TEMT (1 << 6)
  149. #define UART485_LSR_THRE (1 << 5)
  150. #define UART485_LSR_BI (1 << 4)
  151. #define UART485_LSR_FE (1 << 3)
  152. #define UART485_LSR_PE (1 << 2)
  153. #define UART485_LSR_OE (1 << 1)
  154. #define UART485_LSR_DR (1 << 0)
  155. #define UART485_IIR_IID_MASK (0xf << 0)
  156. #define UART485_IIR_IID_MODEM_STATUS 0x0
  157. #define UART485_IIR_IID_NO_INT_PENDING 0x1
  158. #define UART485_IIR_IID_THR_EMPTY 0x2
  159. #define UART485_IIR_IID_REV_DATA_AVAIL 0x4
  160. #define UART485_IIR_IID_REV_LINE_STATUS 0x6
  161. #define UART485_IIR_IID_BUSY_DETECT 0x7
  162. #define UART485_IIR_IID_CHAR_TIMEOUT 0xc
  163. #define CSIZE 0x0003
  164. #define CS8 0x0000
  165. #define CS6 0x0001
  166. #define CS7 0x0002
  167. #define CS5 0x0003
  168. #define CSTOPB 0x0004
  169. #define PARENB 0x0010
  170. #define PARODD 0x0020
  171. #define CMSPAR 0x0100 /* mark or space (stick) parity */
  172. #define CRTSCTS 0x0200 /* flow control */
  173. #define UART_CLK 24000000
  174. #define UART_DEBUG_PORT UART_ID0
  175. #define UART_BUF_SIZE 4096
  176. #define UART_ISR_PASS_LIMIT 16
  177. #define UART_BLOCK_TIMEOUT pdMS_TO_TICKS(100)
  178. #define UART_NO_BLOCK ( ( TickType_t ) 0 )
  179. static uint32_t ulUartBase[UART_NUM] = {REGS_UART0_BASE, REGS_UART1_BASE, REGS_UART2_BASE, REGS_UART3_BASE};
  180. static UartPort_t *pxUartPort[UART_NUM] = {NULL};
  181. #define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
  182. #define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
  183. #define uart_circ_chars_pending(circ) \
  184. (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
  185. #define uart_circ_chars_free(circ) \
  186. (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
  187. /* static void vUartSlectPad(uint32_t id)
  188. {
  189. switch (id) {
  190. case UART_ID0:
  191. vSysctlConfigure(SYS_PAD_CTRL02, 12, 0xf, 5);
  192. break;
  193. case UART_ID1:
  194. vSysctlConfigure(SYS_PAD_CTRL02, 16, 0xf, 5);
  195. break;
  196. case UART_ID2:
  197. vSysctlConfigure(SYS_PAD_CTRL02, 20, 0xf, 5);
  198. break;
  199. case UART_ID3:
  200. vSysctlConfigure(SYS_PAD_CTRL02, 24, 0xf, 5);
  201. break;
  202. }
  203. } */
  204. static int iUartRxChars(UartPort_t *uap)
  205. {
  206. uint32_t status;
  207. unsigned int ch, max_count = 256;
  208. int fifotaken = 0;
  209. while (max_count--) {
  210. status = readl(uap->regbase + UART_FR);
  211. if (status & UART_FR_RXFE)
  212. break;
  213. /* Take chars from the FIFO and update status */
  214. ch = readl(uap->regbase + UART_DR);
  215. fifotaken++;
  216. /* discard when rx buf is full */
  217. if (CIRC_SPACE_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE) > 0) {
  218. *(uap->rxbuf.buf + uap->rxbuf.head) = ch;
  219. uap->rxbuf.head = (uap->rxbuf.head + 1) & (UART_BUF_SIZE - 1);
  220. } else {
  221. ;//printf("uart%d rx buf is full, discard a data.\n", uap->id);
  222. }
  223. }
  224. if (fifotaken > 0)
  225. xSemaphoreGiveFromISR(uap->xRev, NULL);
  226. return fifotaken;
  227. }
  228. static void vUartStopTx(UartPort_t *uap)
  229. {
  230. writel(readl(uap->regbase + UART_IMSC) & ~UART_TXIM, uap->regbase + UART_IMSC);
  231. }
  232. static void vUartStartTx(UartPort_t *uap)
  233. {
  234. writel(readl(uap->regbase + UART_IMSC) | UART_TXIM, uap->regbase + UART_IMSC);
  235. }
  236. static BaseType_t xUartTxChar(UartPort_t *uap, unsigned char c, int from_irq)
  237. {
  238. if (!from_irq && (readl(uap->regbase + UART_FR) & UART_FR_TXFF))
  239. return pdFALSE; /* unable to transmit character */
  240. writel(c, uap->regbase + UART_DR);
  241. return pdTRUE;
  242. }
  243. /* Returns true if tx interrupts have to be (kept) enabled */
  244. static BaseType_t xUartTxChars(UartPort_t *uap, int from_irq)
  245. {
  246. struct circ_buf *xmit = &uap->txbuf;
  247. int count = uap->fifosize >> 1;
  248. if (uart_circ_empty(xmit)) {
  249. vUartStopTx(uap);
  250. return pdFALSE;
  251. }
  252. do {
  253. if (from_irq && count-- == 0)
  254. break;
  255. if (!xUartTxChar(uap, xmit->buf[xmit->tail], from_irq))
  256. break;
  257. xmit->tail = (xmit->tail + 1) & (UART_BUF_SIZE - 1);
  258. } while (!uart_circ_empty(xmit));
  259. if (from_irq)
  260. xSemaphoreGiveFromISR(uap->xSend, NULL);
  261. if (uart_circ_empty(xmit)) {
  262. vUartStopTx(uap);
  263. return pdFALSE;
  264. }
  265. return pdTRUE;
  266. }
  267. static void vUartIntHandler(void *param)
  268. {
  269. UartPort_t *uap = param;
  270. uint32_t status;
  271. uint32_t imsc;
  272. uint32_t pass_counter = UART_ISR_PASS_LIMIT;
  273. imsc = readl(uap->regbase + UART_IMSC);
  274. status = readl(uap->regbase + UART_RIS) & imsc;
  275. if (status) {
  276. do {
  277. writel(status & ~(UART_TXIS | UART_RTIS | UART_RXIS),
  278. uap->regbase + UART_ICR);
  279. if (status & (UART_RTIS | UART_RXIS)) {
  280. iUartRxChars(uap);
  281. }
  282. if (status & UART_TXIS)
  283. xUartTxChars(uap, pdTRUE);
  284. if (pass_counter-- == 0)
  285. break;
  286. status = readl(uap->regbase + UART_RIS) & imsc;
  287. } while (status != 0);
  288. }
  289. }
  290. static void vUart485StopTx(UartPort_t *uap)
  291. {
  292. writel(readl(uap->regbase + UART485_IER) & ~(1 << 1), uap->regbase + UART485_IER);
  293. }
  294. static void vUart485StartTx(UartPort_t *uap)
  295. {
  296. writel(readl(uap->regbase + UART485_IER) | (1 << 1), uap->regbase + UART485_IER);
  297. }
  298. static int iUart485RxChars(UartPort_t *uap)
  299. {
  300. uint32_t lsr;
  301. unsigned int ch, max_count = 256;
  302. int fifotaken = 0;
  303. while (max_count--) {
  304. lsr = readl(uap->regbase + UART485_LSR);
  305. if (!(lsr & UART485_LSR_DR))
  306. break;
  307. /* Take chars from the FIFO and update status */
  308. ch = readl(uap->regbase + UART485_RBR);
  309. fifotaken++;
  310. /* discard when rx buf is full */
  311. if (CIRC_SPACE_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE) > 0) {
  312. *(uap->rxbuf.buf + uap->rxbuf.head) = ch;
  313. uap->rxbuf.head = (uap->rxbuf.head + 1) & (UART_BUF_SIZE - 1);
  314. } else {
  315. printf("uart%d rx buf is full, discard a data.\n", uap->id);
  316. }
  317. }
  318. if (fifotaken > 0)
  319. xSemaphoreGiveFromISR(uap->xRev, NULL);
  320. return fifotaken;
  321. }
  322. /* Returns true if tx interrupts have to be (kept) enabled */
  323. static BaseType_t xUart485TxChars(UartPort_t *uap, int from_irq)
  324. {
  325. struct circ_buf *xmit = &uap->txbuf;
  326. int count = uap->fifosize >> 1;
  327. if (uart_circ_empty(xmit)) {
  328. vUart485StopTx(uap);
  329. return pdFALSE;
  330. }
  331. do {
  332. if (from_irq && count-- == 0)
  333. break;
  334. writel(xmit->buf[xmit->tail], uap->regbase + UART485_THR);
  335. xmit->tail = (xmit->tail + 1) & (UART_BUF_SIZE - 1);
  336. } while (!uart_circ_empty(xmit));
  337. if (from_irq)
  338. xSemaphoreGiveFromISR(uap->xSend, NULL);
  339. return pdTRUE;
  340. }
  341. static void vUart485IntHandler(void *param)
  342. {
  343. UartPort_t *uap = param;
  344. uint32_t iir;
  345. uint32_t status;
  346. iir = readl(uap->regbase + UART485_IIR);
  347. switch (iir & UART485_IIR_IID_MASK) {
  348. case UART485_IIR_IID_THR_EMPTY:
  349. xUart485TxChars(uap, 1);
  350. break;
  351. case UART485_IIR_IID_REV_DATA_AVAIL:
  352. case UART485_IIR_IID_REV_LINE_STATUS:
  353. case UART485_IIR_IID_CHAR_TIMEOUT:
  354. iUart485RxChars(uap);
  355. break;
  356. case UART485_IIR_IID_BUSY_DETECT:
  357. status = readl(uap->regbase + UART485_USR);
  358. printf("busy status 0x%x.\n", status);
  359. break;
  360. }
  361. }
  362. UartPort_t *xUartOpen(uint32_t id)
  363. {
  364. int irq;
  365. if (id >= UART_NUM) {
  366. TRACE_INFO("Wrong input uart id.\n");
  367. return NULL;
  368. }
  369. if (pxUartPort[id] != NULL) {
  370. if (id != UART_DEBUG_PORT)
  371. TRACE_ERROR("Uart %d is already in use.\n", id);
  372. return NULL;
  373. }
  374. UartPort_t *uap = (UartPort_t *)pvPortMalloc(sizeof(UartPort_t));
  375. if (uap == NULL) {
  376. if (id != UART_DEBUG_PORT)
  377. TRACE_ERROR("Out of memory for uart%d.\n", id);
  378. return NULL;
  379. }
  380. memset(uap, 0, sizeof(*uap));
  381. uap->rxbuf.buf = (char*)pvPortMalloc(UART_BUF_SIZE);
  382. if (uap->rxbuf.buf == NULL) {
  383. if (id != UART_DEBUG_PORT)
  384. TRACE_ERROR("Out of memory for uart%d.\n", id);
  385. goto err;
  386. }
  387. uap->txbuf.buf = (char*)pvPortMalloc(UART_BUF_SIZE);
  388. if (uap->txbuf.buf == NULL) {
  389. if (id != UART_DEBUG_PORT)
  390. TRACE_ERROR("Out of memory for uart%d.\n", id);
  391. goto err;
  392. }
  393. uap->xMutex = xSemaphoreCreateRecursiveMutex();
  394. configASSERT(uap->xMutex);
  395. uap->xRev = xSemaphoreCreateBinary();
  396. configASSERT(uap->xRev);
  397. uap->xSend = xSemaphoreCreateBinary();
  398. configASSERT(uap->xSend);
  399. //vUartSlectPad(id);
  400. uap->id = id;
  401. uap->regbase = ulUartBase[id];
  402. if (id < UART_ID3)
  403. uap->fifosize = 16;
  404. else
  405. uap->fifosize = 128;
  406. irq = UART0_IRQn + id;
  407. if (uap->id < UART_ID3)
  408. request_irq(irq, 0, vUartIntHandler, uap);
  409. else
  410. request_irq(irq, 0, vUart485IntHandler, uap);
  411. return pxUartPort[id] = uap;
  412. err:
  413. if (uap->txbuf.buf)
  414. vPortFree(uap->txbuf.buf);
  415. if (uap->rxbuf.buf)
  416. vPortFree(uap->rxbuf.buf);
  417. vPortFree(uap);
  418. return NULL;
  419. };
  420. void vUartInit(UartPort_t *uap, uint32_t baud, uint32_t flags)
  421. {
  422. unsigned int lcr_h, quot, cr;
  423. int count = 0;
  424. /* soft reset */
  425. sys_soft_reset(softreset_uart0 + uap->id - UART_ID0);
  426. if (uap->id < UART_ID3) {
  427. if (baud > UART_CLK / 16)
  428. quot = (UART_CLK * 8 + baud / 2) / baud;
  429. else
  430. quot = (UART_CLK * 4 + baud / 2) / baud;
  431. switch (flags & CSIZE) {
  432. case CS5:
  433. lcr_h = UART_LCRH_WLEN_5;
  434. break;
  435. case CS6:
  436. lcr_h = UART_LCRH_WLEN_6;
  437. break;
  438. case CS7:
  439. lcr_h = UART_LCRH_WLEN_7;
  440. break;
  441. default: // CS8
  442. lcr_h = UART_LCRH_WLEN_8;
  443. break;
  444. }
  445. if (flags & CSTOPB)
  446. lcr_h |= UART_LCRH_STP2;
  447. if (flags & PARENB) {
  448. lcr_h |= UART_LCRH_PEN;
  449. if (!(flags & PARODD))
  450. lcr_h |= UART_LCRH_EPS;
  451. if (flags & CMSPAR)
  452. lcr_h |= UART_LCRH_SPS;
  453. }
  454. lcr_h |= UART_LCRH_FEN;
  455. /* Provoke TX FIFO interrupt into asserting */
  456. cr = UART_CR_UARTEN | UART_CR_TXE | UART_CR_LBE;
  457. reconfig:
  458. writel(cr, uap->regbase + UART_CR);
  459. writel(0, uap->regbase + UART_FBRD);
  460. writel(1, uap->regbase + UART_IBRD);
  461. writel(0, uap->regbase + UART_LCRH);
  462. writel(0, uap->regbase + UART_DR);
  463. while (readl(uap->regbase + UART_FR) & UART_FR_BUSY);
  464. if (count++ < 10 && !(readl(uap->regbase + UART_RIS) & UART_TXIS)) {
  465. printf("ERROR! Uart status wrong.\n");
  466. goto reconfig;
  467. }
  468. /* first, disable everything */
  469. writel(0, uap->regbase + UART_CR);
  470. cr = UART_CR_RXE | UART_CR_TXE;
  471. if (flags & CRTSCTS)
  472. cr |= UART_CR_CTSEN | UART_CR_RTSEN;
  473. /* Set baud rate */
  474. writel(quot & 0x3f, uap->regbase + UART_FBRD);
  475. writel(quot >> 6, uap->regbase + UART_IBRD);
  476. writel(UART_RTIM | UART_RXIM, uap->regbase + UART_IMSC);
  477. writel(UART_IFLS_RX4_8 | UART_IFLS_TX4_8, uap->regbase + UART_IFLS);
  478. writel(lcr_h, uap->regbase + UART_LCRH);
  479. writel(cr | UART_CR_UARTEN, uap->regbase + UART_CR);
  480. } else {
  481. //set modem
  482. writel(0, uap->regbase + UART485_MCR);
  483. //wait not busy
  484. while (readl(uap->regbase + UART485_USR) & 1) {
  485. if (count++ < 100) {
  486. udelay(100);
  487. } else {
  488. printf("Error! Uart%d wait busy fail.\n", uap->id);
  489. return;
  490. }
  491. }
  492. // baud = clk/(16*U_DLL)
  493. //set baud rate
  494. writel(readl(uap->regbase + UART485_LCR) | (1 << 7), uap->regbase + UART485_LCR);
  495. writel(UART_CLK / (16 * baud), uap->regbase + UART485_DLL);
  496. writel(0, uap->regbase + UART485_DLH);
  497. writel(readl(uap->regbase + UART485_LCR) & ~(1 << 7), uap->regbase + UART485_LCR);
  498. cr = readl(uap->regbase + UART485_LCR);
  499. //校验
  500. cr &= ~(7 << 3);
  501. if (flags & PARENB) {
  502. cr |= (1 << 3);
  503. if (!(flags & PARODD))
  504. cr |= (1 << 4);
  505. if (flags & CMSPAR)
  506. cr |= (1 << 5);
  507. }
  508. //停止位
  509. if (flags & CSTOPB)
  510. cr |= (1 << 2);
  511. else
  512. cr &= ~(1 << 2);
  513. //数据位
  514. cr &= ~(3 << 0);
  515. switch (flags & CSIZE) {
  516. case CS5:
  517. break;
  518. case CS6:
  519. cr |= 1;
  520. break;
  521. case CS7:
  522. cr |= 2;
  523. break;
  524. default: // CS8
  525. cr |= 3;
  526. break;
  527. }
  528. writel(cr, uap->regbase + UART485_LCR);
  529. //set fifo
  530. writel((2 << 6) | (3 << 4) | 7, uap->regbase + UART485_FCR);
  531. //enable rx and err interrupt
  532. writel((1 << 4) | 1, uap->regbase + UART485_IER);
  533. //设置通信模式全双工还是半双工
  534. //485mode disable
  535. writel(0, uap->regbase + UART485_TCR);
  536. }
  537. }
  538. void vUartClose(UartPort_t *uap)
  539. {
  540. if (uap == NULL) return;
  541. if (uap->id < UART_ID3) {
  542. writel(0, uap->regbase + UART_IMSC);
  543. writel(0, uap->regbase + UART_CR);
  544. } else {
  545. }
  546. vSemaphoreDelete(uap->xSend);
  547. vSemaphoreDelete(uap->xRev);
  548. vSemaphoreDelete(uap->xMutex);
  549. vPortFree(uap->rxbuf.buf);
  550. uap->rxbuf.tail = uap->rxbuf.head = 0;
  551. vPortFree(uap->txbuf.buf);
  552. uap->rxbuf.tail = uap->rxbuf.head = 0;
  553. vPortFree(uap);
  554. pxUartPort[uap->id] = NULL;
  555. }
  556. int iUartWrite(UartPort_t *uap, uint8_t *buf, size_t len, TickType_t xBlockTime)
  557. {
  558. int c, ret = 0;
  559. TickType_t timeout = xBlockTime;
  560. TickType_t starttime = xTaskGetTickCount();
  561. TickType_t sptime;
  562. while (len) {
  563. xSemaphoreTakeRecursive(uap->xMutex, portMAX_DELAY);
  564. c = CIRC_SPACE_TO_END(uap->txbuf.head, uap->txbuf.tail, UART_BUF_SIZE);
  565. if (len < c)
  566. c = len;
  567. if (c <= 0) {
  568. xSemaphoreGiveRecursive(uap->xMutex);
  569. sptime = xTaskGetTickCount() - starttime;
  570. if (timeout > sptime) {
  571. xSemaphoreTake(uap->xSend, timeout - sptime);
  572. continue;
  573. } else {
  574. break;
  575. }
  576. }
  577. memcpy(uap->txbuf.buf + uap->txbuf.head, buf, c);
  578. uap->txbuf.head = (uap->txbuf.head + c) & (UART_BUF_SIZE - 1);
  579. buf += c;
  580. len -= c;
  581. ret += c;
  582. xSemaphoreGiveRecursive(uap->xMutex);
  583. }
  584. if (uap->id < UART_ID3)
  585. vUartStartTx(uap);
  586. else
  587. vUart485StartTx(uap);
  588. return ret;
  589. }
  590. int iUartRead(UartPort_t *uap, uint8_t *buf, size_t len, TickType_t xBlockTime)
  591. {
  592. int c, ret = 0;
  593. TickType_t timeout = xBlockTime;
  594. TickType_t starttime = xTaskGetTickCount();
  595. TickType_t sptime;
  596. while (len) {
  597. xSemaphoreTakeRecursive(uap->xMutex, portMAX_DELAY);
  598. c = CIRC_CNT_TO_END(uap->rxbuf.head, uap->rxbuf.tail, UART_BUF_SIZE);
  599. if (len < c)
  600. c = len;
  601. if (c <= 0) {
  602. xSemaphoreGiveRecursive(uap->xMutex);
  603. sptime = xTaskGetTickCount() - starttime;
  604. if (timeout > sptime) {
  605. xSemaphoreTake(uap->xRev, timeout - sptime);
  606. continue;
  607. } else {
  608. break;
  609. }
  610. }
  611. memcpy(buf, uap->rxbuf.buf + uap->rxbuf.tail, c);
  612. uap->rxbuf.tail = (uap->rxbuf.tail + c) & (UART_BUF_SIZE - 1);
  613. buf += c;
  614. len -= c;
  615. ret += c;
  616. xSemaphoreGiveRecursive(uap->xMutex);
  617. }
  618. return ret;
  619. }
  620. void vDebugConsoleInitialise(void)
  621. {
  622. UartPort_t *uap = xUartOpen(UART_DEBUG_PORT);
  623. if (uap != NULL) {
  624. vUartInit(uap, 115200, 0);
  625. }
  626. }
  627. /* retarget printf function */
  628. int32_t putchar(int32_t ch)
  629. {
  630. while (readl(REGS_UART0_BASE + UART_FR) & UART_FR_TXFF);
  631. writel(ch, REGS_UART0_BASE + UART_DR);
  632. return ch;
  633. }
  634. xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
  635. {
  636. return pxUartPort[UART_DEBUG_PORT];
  637. }
  638. signed portBASE_TYPE xSerialPutChar( xComPortHandle pxPort, signed char cOutChar, TickType_t xBlockTime )
  639. {
  640. if (iUartWrite(pxPort, (uint8_t *)&cOutChar, 1, xBlockTime) == 1)
  641. return pdPASS;
  642. return pdFAIL;
  643. }
  644. void vSerialPutString( xComPortHandle pxPort, const signed char * const pcString, unsigned short usStringLength )
  645. {
  646. signed char *pxNext;
  647. /* NOTE: This implementation does not handle the queue being full as no
  648. block time is used! */
  649. /* The port handle is not required as this driver only supports UART0. */
  650. ( void ) pxPort;
  651. ( void ) usStringLength;
  652. /* Send each character in the string, one at a time. */
  653. pxNext = ( signed char * ) pcString;
  654. while( *pxNext )
  655. {
  656. xSerialPutChar( pxPort, *pxNext, UART_NO_BLOCK );
  657. pxNext++;
  658. }
  659. }
  660. signed portBASE_TYPE xSerialGetChar( xComPortHandle pxPort, signed char *pcRxedChar, TickType_t xBlockTime )
  661. {
  662. if (iUartRead(pxPort, (uint8_t *)pcRxedChar, 1, xBlockTime) == 1)
  663. return pdPASS;
  664. return pdFAIL;
  665. }
  666. #define UUP_PACKET_SIZE 128
  667. #define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
  668. #define UUP_RX_FRAME_NUM 16
  669. static unsigned char uup_rx_buf[UUP_RX_FRAME_NUM][UUP_MAX_FRAME_LEN];
  670. static unsigned char *uup_rx_ptr;
  671. static int uup_rx_rev_len = 0;
  672. static int uup_rx_head = 0;
  673. static int uup_rx_tail = 0;
  674. static int uup_rx_state = 0;
  675. static int uup_rx_data_len = 0;
  676. static void uart_tx_demo_thread(void *param)
  677. {
  678. UartPort_t *uap = param;
  679. uint8_t uarttx[32] = "hello, i am amt630h";
  680. for (;;) {
  681. iUartWrite(uap, uarttx, strlen((char*)uarttx), pdMS_TO_TICKS(100));
  682. vTaskDelay(1000);
  683. }
  684. }
  685. static void uart_rx_demo_thread(void *param)
  686. {
  687. UartPort_t *uap = xUartOpen(UART_MCU_PORT);
  688. uint8_t uartrx[16];
  689. int len;
  690. int i;
  691. if (!uap) {
  692. printf("open uart %d fail.\n", UART_MCU_PORT);
  693. vTaskDelete(NULL);
  694. return;
  695. }
  696. vUartInit(uap, 115200, 0);
  697. if (xTaskCreate(uart_tx_demo_thread, "uartsend", configMINIMAL_STACK_SIZE, uap,
  698. configMAX_PRIORITIES / 3, NULL) != pdPASS) {
  699. printf("create uart tx demo task fail.\n");
  700. vTaskDelete(NULL);
  701. return;
  702. }
  703. for (;;) {
  704. len = iUartRead(uap, uartrx, 16, pdMS_TO_TICKS(100));
  705. for (i = 0; i < len; i++) {
  706. switch (uup_rx_state) {
  707. case 0:
  708. if (uartrx[i] == 0x55) {
  709. uup_rx_state++;
  710. uup_rx_rev_len = 0;
  711. uup_rx_ptr = &uup_rx_buf[uup_rx_head][0];
  712. }
  713. break;
  714. case 1:
  715. if (uartrx[i] == 0x81)
  716. uup_rx_state++;
  717. else
  718. uup_rx_state = 0;
  719. *uup_rx_ptr++ = uartrx[i];
  720. break;
  721. case 2:
  722. if (uartrx[i] == 0xc6)
  723. uup_rx_state++;
  724. else
  725. uup_rx_state = 0;
  726. *uup_rx_ptr++ = uartrx[i];
  727. break;
  728. case 3:
  729. uup_rx_data_len = uartrx[i];
  730. if (uup_rx_data_len <= 0 || uup_rx_data_len > UUP_PACKET_SIZE) {
  731. printf("Invalid frame len %d, discard.\n", uup_rx_data_len);
  732. uup_rx_state = 0;
  733. } else {
  734. uup_rx_state++;
  735. *uup_rx_ptr++ = uartrx[i];
  736. }
  737. break;
  738. case 4:
  739. *uup_rx_ptr++ = uartrx[i];
  740. if (++uup_rx_rev_len == uup_rx_data_len)
  741. uup_rx_state++;
  742. break;
  743. case 5:
  744. *uup_rx_ptr++ = uartrx[i];
  745. uup_rx_head = (uup_rx_head + 1) % UUP_RX_FRAME_NUM;
  746. uup_rx_state = 0;
  747. break;
  748. }
  749. }
  750. if (uup_rx_tail != uup_rx_head) {
  751. unsigned char *buf;
  752. unsigned char checksum = 0;
  753. buf = &uup_rx_buf[uup_rx_tail][0];
  754. len = buf[2];
  755. for (i = 0; i < len + 3; i++)
  756. checksum ^= buf[i];
  757. if (checksum == buf[len + 3]) {
  758. if (buf[3] == 0) {
  759. SysInfo *sysinfo = GetSysInfo();
  760. printf("receive uart update cmd, updating...\n");
  761. sysinfo->update_media_type = UPDATE_MEDIA_UART;
  762. sysinfo->update_status = UPDATE_STATUS_START;
  763. SaveSysInfo();
  764. wdt_cpu_reboot();
  765. }
  766. } else {
  767. printf("rev frame checksum err.\n");
  768. }
  769. uup_rx_tail = (uup_rx_tail + 1) % UUP_RX_FRAME_NUM;
  770. }
  771. }
  772. }
  773. int uart_rx_demo(void)
  774. {
  775. /* Create a task to process uart rx data */
  776. if (xTaskCreate(uart_rx_demo_thread, "uartdemo", configMINIMAL_STACK_SIZE, NULL,
  777. configMAX_PRIORITIES / 3, NULL) != pdPASS) {
  778. printf("create uart rx demo task fail.\n");
  779. return -1;
  780. }
  781. return 0;
  782. }