uart.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /*
  2. * File : uart.c
  3. * Copyright (C) 2013 - 2016, Espressif Systems
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of version 3 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "ets_sys.h"
  18. #include "osapi.h"
  19. #include "driver/uart.h"
  20. #include "osapi.h"
  21. #include "driver/uart_register.h"
  22. #include "mem.h"
  23. #include "os_type.h"
  24. // UartDev is defined and initialized in rom code.
  25. extern UartDevice UartDev;
  26. LOCAL struct UartBuffer* pTxBuffer = NULL;
  27. LOCAL struct UartBuffer* pRxBuffer = NULL;
  28. /*uart demo with a system task, to output what uart receives*/
  29. /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
  30. /*it might conflict with your task, if so,please arrange the priority of different task, or combine it to a different event in the same task. */
  31. #define uart_recvTaskPrio 0
  32. #define uart_recvTaskQueueLen 10
  33. os_event_t uart_recvTaskQueue[uart_recvTaskQueueLen];
  34. #define DBG
  35. #define DBG1 uart1_sendStr_no_wait
  36. #define DBG2 os_printf
  37. LOCAL void uart0_rx_intr_handler(void *para);
  38. /******************************************************************************
  39. * FunctionName : uart_config
  40. * Description : Internal used function
  41. * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
  42. * UART1 just used for debug output
  43. * Parameters : uart_no, use UART0 or UART1 defined ahead
  44. * Returns : NONE
  45. *******************************************************************************/
  46. LOCAL void ICACHE_FLASH_ATTR
  47. uart_config(uint8 uart_no)
  48. {
  49. if (uart_no == UART1){
  50. PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
  51. }else{
  52. /* rcv_buff size if 0x100 */
  53. ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff));
  54. PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
  55. PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
  56. #if UART_HW_RTS
  57. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //HW FLOW CONTROL RTS PIN
  58. #endif
  59. #if UART_HW_CTS
  60. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //HW FLOW CONTROL CTS PIN
  61. #endif
  62. }
  63. uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));//SET BAUDRATE
  64. WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) //SET BIT AND PARITY MODE
  65. | ((UartDev.parity & UART_PARITY_M) <<UART_PARITY_S )
  66. | ((UartDev.stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S)
  67. | ((UartDev.data_bits & UART_BIT_NUM) << UART_BIT_NUM_S));
  68. //clear rx and tx fifo,not ready
  69. SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); //RESET FIFO
  70. CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
  71. if (uart_no == UART0){
  72. //set rx fifo trigger
  73. WRITE_PERI_REG(UART_CONF1(uart_no),
  74. ((100 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
  75. #if UART_HW_RTS
  76. ((110 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
  77. UART_RX_FLOW_EN | //enbale rx flow control
  78. #endif
  79. (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
  80. UART_RX_TOUT_EN|
  81. ((0x10 & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S));//wjl
  82. #if UART_HW_CTS
  83. SET_PERI_REG_MASK( UART_CONF0(uart_no),UART_TX_FLOW_EN); //add this sentense to add a tx flow control via MTCK( CTS )
  84. #endif
  85. SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |UART_FRM_ERR_INT_ENA);
  86. }else{
  87. WRITE_PERI_REG(UART_CONF1(uart_no),((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));//TrigLvl default val == 1
  88. }
  89. //clear all interrupt
  90. WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
  91. //enable rx_interrupt
  92. SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_OVF_INT_ENA);
  93. }
  94. /******************************************************************************
  95. * FunctionName : uart1_tx_one_char
  96. * Description : Internal used function
  97. * Use uart1 interface to transfer one char
  98. * Parameters : uint8 TxChar - character to tx
  99. * Returns : OK
  100. *******************************************************************************/
  101. STATUS uart_tx_one_char(uint8 uart, uint8 TxChar)
  102. {
  103. while (true){
  104. uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
  105. if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
  106. break;
  107. }
  108. }
  109. WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
  110. return OK;
  111. }
  112. /******************************************************************************
  113. * FunctionName : uart1_write_char
  114. * Description : Internal used function
  115. * Do some special deal while tx char is '\r' or '\n'
  116. * Parameters : char c - character to tx
  117. * Returns : NONE
  118. *******************************************************************************/
  119. LOCAL void ICACHE_FLASH_ATTR
  120. uart1_write_char(char c)
  121. {
  122. if (c == '\n'){
  123. uart_tx_one_char(UART1, '\r');
  124. uart_tx_one_char(UART1, '\n');
  125. }else if (c == '\r'){
  126. }else{
  127. uart_tx_one_char(UART1, c);
  128. }
  129. }
  130. //os_printf output to fifo or to the tx buffer
  131. LOCAL void ICACHE_FLASH_ATTR
  132. uart0_write_char_no_wait(char c)
  133. {
  134. #if UART_BUFF_EN //send to uart0 fifo but do not wait
  135. uint8 chr;
  136. if (c == '\n'){
  137. chr = '\r';
  138. tx_buff_enq(&chr, 1);
  139. chr = '\n';
  140. tx_buff_enq(&chr, 1);
  141. }else if (c == '\r'){
  142. }else{
  143. tx_buff_enq(&c,1);
  144. }
  145. #else //send to uart tx buffer
  146. if (c == '\n'){
  147. uart_tx_one_char_no_wait(UART0, '\r');
  148. uart_tx_one_char_no_wait(UART0, '\n');
  149. }else if (c == '\r'){
  150. }
  151. else{
  152. uart_tx_one_char_no_wait(UART0, c);
  153. }
  154. #endif
  155. }
  156. /******************************************************************************
  157. * FunctionName : uart0_tx_buffer
  158. * Description : use uart0 to transfer buffer
  159. * Parameters : uint8 *buf - point to send buffer
  160. * uint16 len - buffer len
  161. * Returns :
  162. *******************************************************************************/
  163. void ICACHE_FLASH_ATTR
  164. uart0_tx_buffer(uint8 *buf, uint16 len)
  165. {
  166. uint16 i;
  167. for (i = 0; i < len; i++)
  168. {
  169. uart_tx_one_char(UART0, buf[i]);
  170. }
  171. }
  172. /******************************************************************************
  173. * FunctionName : uart0_sendStr
  174. * Description : use uart0 to transfer buffer
  175. * Parameters : uint8 *buf - point to send buffer
  176. * uint16 len - buffer len
  177. * Returns :
  178. *******************************************************************************/
  179. void ICACHE_FLASH_ATTR
  180. uart0_sendStr(const char *str)
  181. {
  182. while(*str){
  183. uart_tx_one_char(UART0, *str++);
  184. }
  185. }
  186. void at_port_print(const char *str) __attribute__((alias("uart0_sendStr")));
  187. /******************************************************************************
  188. * FunctionName : uart0_rx_intr_handler
  189. * Description : Internal used function
  190. * UART0 interrupt handler, add self handle code inside
  191. * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
  192. * Returns : NONE
  193. *******************************************************************************/
  194. LOCAL void
  195. uart0_rx_intr_handler(void *para)
  196. {
  197. /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
  198. * uart1 and uart0 respectively
  199. */
  200. uint8 RcvChar;
  201. uint8 uart_no = UART0;//UartDev.buff_uart_no;
  202. uint8 fifo_len = 0;
  203. uint8 buf_idx = 0;
  204. uint8 temp,cnt;
  205. //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
  206. /*ATTENTION:*/
  207. /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
  208. /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
  209. /*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */
  210. if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)){
  211. DBG1("FRM_ERR\r\n");
  212. WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
  213. }else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){
  214. DBG("f");
  215. uart_rx_intr_disable(UART0);
  216. WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
  217. system_os_post(uart_recvTaskPrio, 0, 0);
  218. }else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){
  219. DBG("t");
  220. uart_rx_intr_disable(UART0);
  221. WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
  222. system_os_post(uart_recvTaskPrio, 0, 0);
  223. }else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){
  224. DBG("e");
  225. /* to output uart data from uart buffer directly in empty interrupt handler*/
  226. /*instead of processing in system event, in order not to wait for current task/function to quit */
  227. /*ATTENTION:*/
  228. /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
  229. /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
  230. CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
  231. #if UART_BUFF_EN
  232. tx_start_uart_buffer(UART0);
  233. #endif
  234. //system_os_post(uart_recvTaskPrio, 1, 0);
  235. WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
  236. }else if(UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){
  237. WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);
  238. DBG1("RX OVF!!\r\n");
  239. }
  240. }
  241. /******************************************************************************
  242. * FunctionName : uart_init
  243. * Description : user interface for init uart
  244. * Parameters : UartBautRate uart0_br - uart0 bautrate
  245. * UartBautRate uart1_br - uart1 bautrate
  246. * Returns : NONE
  247. *******************************************************************************/
  248. #if UART_SELFTEST&UART_BUFF_EN
  249. os_timer_t buff_timer_t;
  250. void ICACHE_FLASH_ATTR
  251. uart_test_rx()
  252. {
  253. uint8 uart_buf[128]={0};
  254. uint16 len = 0;
  255. len = rx_buff_deq(uart_buf, 128 );
  256. tx_buff_enq(uart_buf,len);
  257. }
  258. #endif
  259. LOCAL void ICACHE_FLASH_ATTR ///////
  260. uart_recvTask(os_event_t *events)
  261. {
  262. if(events->sig == 0){
  263. #if UART_BUFF_EN
  264. Uart_rx_buff_enq();
  265. #else
  266. uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
  267. uint8 d_tmp = 0;
  268. uint8 idx=0;
  269. for(idx=0;idx<fifo_len;idx++) {
  270. d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
  271. uart_tx_one_char(UART0, d_tmp);
  272. }
  273. WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR);
  274. uart_rx_intr_enable(UART0);
  275. #endif
  276. }else if(events->sig == 1){
  277. #if UART_BUFF_EN
  278. //already move uart buffer output to uart empty interrupt
  279. //tx_start_uart_buffer(UART0);
  280. #else
  281. #endif
  282. }
  283. }
  284. void ICACHE_FLASH_ATTR
  285. uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
  286. {
  287. /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
  288. system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen); //demo with a task to process the uart data
  289. UartDev.baut_rate = uart0_br;
  290. uart_config(UART0);
  291. UartDev.baut_rate = uart1_br;
  292. uart_config(UART1);
  293. ETS_UART_INTR_ENABLE();
  294. #if UART_BUFF_EN
  295. pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE);
  296. pRxBuffer = Uart_Buf_Init(UART_RX_BUFFER_SIZE);
  297. #endif
  298. /*option 1: use default print, output from uart0 , will wait some time if fifo is full */
  299. //do nothing...
  300. /*option 2: output from uart1,uart1 output will not wait , just for output debug info */
  301. /*os_printf output uart data via uart1(GPIO2)*/
  302. //os_install_putc1((void *)uart1_write_char); //use this one to output debug information via uart1 //
  303. /*option 3: output from uart0 will skip current byte if fifo is full now... */
  304. /*see uart0_write_char_no_wait:you can output via a buffer or output directly */
  305. /*os_printf output uart data via uart0 or uart buffer*/
  306. //os_install_putc1((void *)uart0_write_char_no_wait); //use this to print via uart0
  307. #if UART_SELFTEST&UART_BUFF_EN
  308. os_timer_disarm(&buff_timer_t);
  309. os_timer_setfn(&buff_timer_t, uart_test_rx , NULL); //a demo to process the data in uart rx buffer
  310. os_timer_arm(&buff_timer_t,10,1);
  311. #endif
  312. }
  313. void ICACHE_FLASH_ATTR
  314. uart_reattach()
  315. {
  316. uart_init(BIT_RATE_115200, BIT_RATE_115200);
  317. }
  318. /******************************************************************************
  319. * FunctionName : uart_tx_one_char_no_wait
  320. * Description : uart tx a single char without waiting for fifo
  321. * Parameters : uint8 uart - uart port
  322. * uint8 TxChar - char to tx
  323. * Returns : STATUS
  324. *******************************************************************************/
  325. STATUS uart_tx_one_char_no_wait(uint8 uart, uint8 TxChar)
  326. {
  327. uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(uart))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
  328. if (fifo_cnt < 126) {
  329. WRITE_PERI_REG(UART_FIFO(uart) , TxChar);
  330. }
  331. return OK;
  332. }
  333. STATUS uart0_tx_one_char_no_wait(uint8 TxChar)
  334. {
  335. uint8 fifo_cnt = (( READ_PERI_REG(UART_STATUS(UART0))>>UART_TXFIFO_CNT_S)& UART_TXFIFO_CNT);
  336. if (fifo_cnt < 126) {
  337. WRITE_PERI_REG(UART_FIFO(UART0) , TxChar);
  338. }
  339. return OK;
  340. }
  341. /******************************************************************************
  342. * FunctionName : uart1_sendStr_no_wait
  343. * Description : uart tx a string without waiting for every char, used for print debug info which can be lost
  344. * Parameters : const char *str - string to be sent
  345. * Returns : NONE
  346. *******************************************************************************/
  347. void uart1_sendStr_no_wait(const char *str)
  348. {
  349. while(*str){
  350. uart_tx_one_char_no_wait(UART1, *str++);
  351. }
  352. }
  353. #if UART_BUFF_EN
  354. /******************************************************************************
  355. * FunctionName : Uart_Buf_Init
  356. * Description : tx buffer enqueue: fill a first linked buffer
  357. * Parameters : char *pdata - data point to be enqueue
  358. * Returns : NONE
  359. *******************************************************************************/
  360. struct UartBuffer* ICACHE_FLASH_ATTR
  361. Uart_Buf_Init(uint32 buf_size)
  362. {
  363. uint32 heap_size = system_get_free_heap_size();
  364. if(heap_size <=buf_size){
  365. DBG1("no buf for uart\n\r");
  366. return NULL;
  367. }else{
  368. DBG("test heap size: %d\n\r",heap_size);
  369. struct UartBuffer* pBuff = (struct UartBuffer* )os_malloc(sizeof(struct UartBuffer));
  370. pBuff->UartBuffSize = buf_size;
  371. pBuff->pUartBuff = (uint8*)os_malloc(pBuff->UartBuffSize);
  372. pBuff->pInPos = pBuff->pUartBuff;
  373. pBuff->pOutPos = pBuff->pUartBuff;
  374. pBuff->Space = pBuff->UartBuffSize;
  375. pBuff->BuffState = OK;
  376. pBuff->nextBuff = NULL;
  377. pBuff->TcpControl = RUN;
  378. return pBuff;
  379. }
  380. }
  381. //copy uart buffer
  382. LOCAL void Uart_Buf_Cpy(struct UartBuffer* pCur, char* pdata , uint16 data_len)
  383. {
  384. if(data_len == 0) return ;
  385. uint16 tail_len = pCur->pUartBuff + pCur->UartBuffSize - pCur->pInPos ;
  386. if(tail_len >= data_len){ //do not need to loop back the queue
  387. os_memcpy(pCur->pInPos , pdata , data_len );
  388. pCur->pInPos += ( data_len );
  389. pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize );
  390. pCur->Space -=data_len;
  391. }else{
  392. os_memcpy(pCur->pInPos, pdata, tail_len);
  393. pCur->pInPos += ( tail_len );
  394. pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize );
  395. pCur->Space -=tail_len;
  396. os_memcpy(pCur->pInPos, pdata+tail_len , data_len-tail_len);
  397. pCur->pInPos += ( data_len-tail_len );
  398. pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize );
  399. pCur->Space -=( data_len-tail_len);
  400. }
  401. }
  402. /******************************************************************************
  403. * FunctionName : uart_buf_free
  404. * Description : deinit of the tx buffer
  405. * Parameters : struct UartBuffer* pTxBuff - tx buffer struct pointer
  406. * Returns : NONE
  407. *******************************************************************************/
  408. void ICACHE_FLASH_ATTR
  409. uart_buf_free(struct UartBuffer* pBuff)
  410. {
  411. os_free(pBuff->pUartBuff);
  412. os_free(pBuff);
  413. }
  414. //rx buffer dequeue
  415. uint16 ICACHE_FLASH_ATTR
  416. rx_buff_deq(char* pdata, uint16 data_len )
  417. {
  418. uint16 buf_len = (pRxBuffer->UartBuffSize- pRxBuffer->Space);
  419. uint16 tail_len = pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize - pRxBuffer->pOutPos ;
  420. uint16 len_tmp = 0;
  421. len_tmp = ((data_len > buf_len)?buf_len:data_len);
  422. if(pRxBuffer->pOutPos <= pRxBuffer->pInPos){
  423. os_memcpy(pdata, pRxBuffer->pOutPos,len_tmp);
  424. pRxBuffer->pOutPos+= len_tmp;
  425. pRxBuffer->Space += len_tmp;
  426. }else{
  427. if(len_tmp>tail_len){
  428. os_memcpy(pdata, pRxBuffer->pOutPos, tail_len);
  429. pRxBuffer->pOutPos += tail_len;
  430. pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize );
  431. pRxBuffer->Space += tail_len;
  432. os_memcpy(pdata+tail_len , pRxBuffer->pOutPos, len_tmp-tail_len);
  433. pRxBuffer->pOutPos+= ( len_tmp-tail_len );
  434. pRxBuffer->pOutPos= (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize );
  435. pRxBuffer->Space +=( len_tmp-tail_len);
  436. }else{
  437. //os_printf("case 3 in rx deq\n\r");
  438. os_memcpy(pdata, pRxBuffer->pOutPos, len_tmp);
  439. pRxBuffer->pOutPos += len_tmp;
  440. pRxBuffer->pOutPos = (pRxBuffer->pUartBuff + (pRxBuffer->pOutPos- pRxBuffer->pUartBuff) % pRxBuffer->UartBuffSize );
  441. pRxBuffer->Space += len_tmp;
  442. }
  443. }
  444. if(pRxBuffer->Space >= UART_FIFO_LEN){
  445. uart_rx_intr_enable(UART0);
  446. }
  447. return len_tmp;
  448. }
  449. //move data from uart fifo to rx buffer
  450. void Uart_rx_buff_enq()
  451. {
  452. uint8 fifo_len,buf_idx;
  453. uint8 fifo_data;
  454. #if 1
  455. fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
  456. if(fifo_len >= pRxBuffer->Space){
  457. os_printf("buf full!!!\n\r");
  458. }else{
  459. buf_idx=0;
  460. while(buf_idx < fifo_len){
  461. buf_idx++;
  462. fifo_data = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
  463. *(pRxBuffer->pInPos++) = fifo_data;
  464. if(pRxBuffer->pInPos == (pRxBuffer->pUartBuff + pRxBuffer->UartBuffSize)){
  465. pRxBuffer->pInPos = pRxBuffer->pUartBuff;
  466. }
  467. }
  468. pRxBuffer->Space -= fifo_len ;
  469. if(pRxBuffer->Space >= UART_FIFO_LEN){
  470. //os_printf("after rx enq buf enough\n\r");
  471. uart_rx_intr_enable(UART0);
  472. }
  473. }
  474. #endif
  475. }
  476. //fill the uart tx buffer
  477. void ICACHE_FLASH_ATTR
  478. tx_buff_enq(char* pdata, uint16 data_len )
  479. {
  480. CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
  481. if(pTxBuffer == NULL){
  482. DBG1("\n\rnull, create buffer struct\n\r");
  483. pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE);
  484. if(pTxBuffer!= NULL){
  485. Uart_Buf_Cpy(pTxBuffer , pdata, data_len );
  486. }else{
  487. DBG1("uart tx MALLOC no buf \n\r");
  488. }
  489. }else{
  490. if(data_len <= pTxBuffer->Space){
  491. Uart_Buf_Cpy(pTxBuffer , pdata, data_len);
  492. }else{
  493. DBG1("UART TX BUF FULL!!!!\n\r");
  494. }
  495. }
  496. #if 0
  497. if(pTxBuffer->Space <= URAT_TX_LOWER_SIZE){
  498. set_tcp_block();
  499. }
  500. #endif
  501. SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S);
  502. SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
  503. }
  504. //--------------------------------
  505. LOCAL void tx_fifo_insert(struct UartBuffer* pTxBuff, uint8 data_len, uint8 uart_no)
  506. {
  507. uint8 i;
  508. for(i = 0; i<data_len;i++){
  509. WRITE_PERI_REG(UART_FIFO(uart_no) , *(pTxBuff->pOutPos++));
  510. if(pTxBuff->pOutPos == (pTxBuff->pUartBuff + pTxBuff->UartBuffSize)){
  511. pTxBuff->pOutPos = pTxBuff->pUartBuff;
  512. }
  513. }
  514. pTxBuff->pOutPos = (pTxBuff->pUartBuff + (pTxBuff->pOutPos - pTxBuff->pUartBuff) % pTxBuff->UartBuffSize );
  515. pTxBuff->Space += data_len;
  516. }
  517. /******************************************************************************
  518. * FunctionName : tx_start_uart_buffer
  519. * Description : get data from the tx buffer and fill the uart tx fifo, co-work with the uart fifo empty interrupt
  520. * Parameters : uint8 uart_no - uart port num
  521. * Returns : NONE
  522. *******************************************************************************/
  523. void tx_start_uart_buffer(uint8 uart_no)
  524. {
  525. uint8 tx_fifo_len = (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT;
  526. uint8 fifo_remain = UART_FIFO_LEN - tx_fifo_len ;
  527. uint8 len_tmp;
  528. uint16 tail_ptx_len,head_ptx_len,data_len;
  529. //struct UartBuffer* pTxBuff = *get_buff_prt();
  530. if(pTxBuffer){
  531. data_len = (pTxBuffer->UartBuffSize - pTxBuffer->Space);
  532. if(data_len > fifo_remain){
  533. len_tmp = fifo_remain;
  534. tx_fifo_insert( pTxBuffer,len_tmp,uart_no);
  535. SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
  536. }else{
  537. len_tmp = data_len;
  538. tx_fifo_insert( pTxBuffer,len_tmp,uart_no);
  539. }
  540. }else{
  541. DBG1("pTxBuff null \n\r");
  542. }
  543. }
  544. #endif
  545. void uart_rx_intr_disable(uint8 uart_no)
  546. {
  547. #if 1
  548. CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
  549. #else
  550. ETS_UART_INTR_DISABLE();
  551. #endif
  552. }
  553. void uart_rx_intr_enable(uint8 uart_no)
  554. {
  555. #if 1
  556. SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
  557. #else
  558. ETS_UART_INTR_ENABLE();
  559. #endif
  560. }
  561. //========================================================
  562. LOCAL void
  563. uart0_write_char(char c)
  564. {
  565. if (c == '\n') {
  566. uart_tx_one_char(UART0, '\r');
  567. uart_tx_one_char(UART0, '\n');
  568. } else if (c == '\r') {
  569. } else {
  570. uart_tx_one_char(UART0, c);
  571. }
  572. }
  573. void ICACHE_FLASH_ATTR
  574. UART_SetWordLength(uint8 uart_no, UartBitsNum4Char len)
  575. {
  576. SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_BIT_NUM,len,UART_BIT_NUM_S);
  577. }
  578. void ICACHE_FLASH_ATTR
  579. UART_SetStopBits(uint8 uart_no, UartStopBitsNum bit_num)
  580. {
  581. SET_PERI_REG_BITS(UART_CONF0(uart_no),UART_STOP_BIT_NUM,bit_num,UART_STOP_BIT_NUM_S);
  582. }
  583. void ICACHE_FLASH_ATTR
  584. UART_SetLineInverse(uint8 uart_no, UART_LineLevelInverse inverse_mask)
  585. {
  586. CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK);
  587. SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask);
  588. }
  589. void ICACHE_FLASH_ATTR
  590. UART_SetParity(uint8 uart_no, UartParityMode Parity_mode)
  591. {
  592. CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY |UART_PARITY_EN);
  593. if(Parity_mode==NONE_BITS){
  594. }else{
  595. SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode|UART_PARITY_EN);
  596. }
  597. }
  598. void ICACHE_FLASH_ATTR
  599. UART_SetBaudrate(uint8 uart_no,uint32 baud_rate)
  600. {
  601. uart_div_modify(uart_no, UART_CLK_FREQ /baud_rate);
  602. }
  603. void ICACHE_FLASH_ATTR
  604. UART_SetFlowCtrl(uint8 uart_no,UART_HwFlowCtrl flow_ctrl,uint8 rx_thresh)
  605. {
  606. if(flow_ctrl&USART_HardwareFlowControl_RTS){
  607. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
  608. SET_PERI_REG_BITS(UART_CONF1(uart_no),UART_RX_FLOW_THRHD,rx_thresh,UART_RX_FLOW_THRHD_S);
  609. SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
  610. }else{
  611. CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN);
  612. }
  613. if(flow_ctrl&USART_HardwareFlowControl_CTS){
  614. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
  615. SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
  616. }else{
  617. CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN);
  618. }
  619. }
  620. void ICACHE_FLASH_ATTR
  621. UART_WaitTxFifoEmpty(uint8 uart_no , uint32 time_out_us) //do not use if tx flow control enabled
  622. {
  623. uint32 t_s = system_get_time();
  624. while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)){
  625. if(( system_get_time() - t_s )> time_out_us){
  626. break;
  627. }
  628. WRITE_PERI_REG(0X60000914, 0X73);//WTD
  629. }
  630. }
  631. bool ICACHE_FLASH_ATTR
  632. UART_CheckOutputFinished(uint8 uart_no, uint32 time_out_us)
  633. {
  634. uint32 t_start = system_get_time();
  635. uint8 tx_fifo_len;
  636. uint32 tx_buff_len;
  637. while(1){
  638. tx_fifo_len =( (READ_PERI_REG(UART_STATUS(uart_no))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT);
  639. if(pTxBuffer){
  640. tx_buff_len = ((pTxBuffer->UartBuffSize)-(pTxBuffer->Space));
  641. }else{
  642. tx_buff_len = 0;
  643. }
  644. if( tx_fifo_len==0 && tx_buff_len==0){
  645. return TRUE;
  646. }
  647. if( system_get_time() - t_start > time_out_us){
  648. return FALSE;
  649. }
  650. WRITE_PERI_REG(0X60000914, 0X73);//WTD
  651. }
  652. }
  653. void ICACHE_FLASH_ATTR
  654. UART_ResetFifo(uint8 uart_no)
  655. {
  656. SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
  657. CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
  658. }
  659. void ICACHE_FLASH_ATTR
  660. UART_ClearIntrStatus(uint8 uart_no,uint32 clr_mask)
  661. {
  662. WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask);
  663. }
  664. void ICACHE_FLASH_ATTR
  665. UART_SetIntrEna(uint8 uart_no,uint32 ena_mask)
  666. {
  667. SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask);
  668. }
  669. void ICACHE_FLASH_ATTR
  670. UART_SetPrintPort(uint8 uart_no)
  671. {
  672. if(uart_no==1){
  673. os_install_putc1(uart1_write_char);
  674. }else{
  675. /*option 1: do not wait if uart fifo is full,drop current character*/
  676. os_install_putc1(uart0_write_char_no_wait);
  677. /*option 2: wait for a while if uart fifo is full*/
  678. os_install_putc1(uart0_write_char);
  679. }
  680. }
  681. //========================================================
  682. /*test code*/
  683. void ICACHE_FLASH_ATTR
  684. uart_init_2(UartBautRate uart0_br, UartBautRate uart1_br)
  685. {
  686. // rom use 74880 baut_rate, here reinitialize
  687. UartDev.baut_rate = uart0_br;
  688. UartDev.exist_parity = STICK_PARITY_EN;
  689. UartDev.parity = EVEN_BITS;
  690. UartDev.stop_bits = ONE_STOP_BIT;
  691. UartDev.data_bits = EIGHT_BITS;
  692. uart_config(UART0);
  693. UartDev.baut_rate = uart1_br;
  694. uart_config(UART1);
  695. ETS_UART_INTR_ENABLE();
  696. // install uart1 putc callback
  697. os_install_putc1((void *)uart1_write_char);//print output at UART1
  698. }