uart.c 27 KB

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