uart.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <stdint.h>
  16. #include <stdlib.h>
  17. #include "atomic.h"
  18. #include "plic.h"
  19. #include "syscalls.h"
  20. #include "sysctl.h"
  21. #include "uart.h"
  22. #include "utils.h"
  23. #include "iomem.h"
  24. #define __UART_BRATE_CONST 16
  25. volatile uart_t *const uart[3] =
  26. {
  27. (volatile uart_t *)UART1_BASE_ADDR,
  28. (volatile uart_t *)UART2_BASE_ADDR,
  29. (volatile uart_t *)UART3_BASE_ADDR};
  30. #define UART_INTERRUPT_SEND 0x02U
  31. #define UART_INTERRUPT_RECEIVE 0x04U
  32. #define UART_INTERRUPT_CHARACTER_TIMEOUT 0x0CU
  33. typedef struct _uart_interrupt_instance
  34. {
  35. plic_irq_callback_t callback;
  36. void *ctx;
  37. } uart_interrupt_instance_t;
  38. typedef struct _uart_instance
  39. {
  40. uart_interrupt_instance_t uart_receive_instance;
  41. uart_interrupt_instance_t uart_send_instance;
  42. uint32_t uart_num;
  43. } uart_instance_t;
  44. uart_instance_t g_uart_instance[3];
  45. typedef struct _uart_dma_instance
  46. {
  47. uint8_t *buffer;
  48. size_t buf_len;
  49. uint32_t *malloc_buffer;
  50. uart_interrupt_mode_t int_mode;
  51. dmac_channel_number_t dmac_channel;
  52. uart_device_number_t uart_num;
  53. uart_interrupt_instance_t uart_int_instance;
  54. } uart_dma_instance_t;
  55. uart_dma_instance_t uart_send_dma_instance[3];
  56. uart_dma_instance_t uart_recv_dma_instance[3];
  57. typedef struct _uart_instance_dma
  58. {
  59. uart_device_number_t uart_num;
  60. uart_interrupt_mode_t transfer_mode;
  61. dmac_channel_number_t dmac_channel;
  62. plic_instance_t uart_int_instance;
  63. spinlock_t lock;
  64. } uart_instance_dma_t;
  65. static uart_instance_dma_t g_uart_send_instance_dma[3];
  66. static uart_instance_dma_t g_uart_recv_instance_dma[3];
  67. volatile int g_write_count = 0;
  68. static int uart_irq_callback(void *param)
  69. {
  70. uart_instance_t *uart_instance = (uart_instance_t *)param;
  71. uint32_t v_channel = uart_instance->uart_num;
  72. uint8_t v_int_status = uart[v_channel]->IIR & 0xF;
  73. if(v_int_status == UART_INTERRUPT_SEND && g_write_count != 0)
  74. {
  75. if(uart_instance->uart_send_instance.callback != NULL)
  76. uart_instance->uart_send_instance.callback(uart_instance->uart_send_instance.ctx);
  77. } else if(v_int_status == UART_INTERRUPT_RECEIVE || v_int_status == UART_INTERRUPT_CHARACTER_TIMEOUT)
  78. {
  79. if(uart_instance->uart_receive_instance.callback != NULL)
  80. uart_instance->uart_receive_instance.callback(uart_instance->uart_receive_instance.ctx);
  81. }
  82. return 0;
  83. }
  84. static uart_device_number_t s_uart_debug_channel = UART_DEVICE_3;
  85. static int uart_channel_putc(char c, uart_device_number_t channel)
  86. {
  87. while(uart[channel]->LSR & (1u << 5))
  88. continue;
  89. uart[channel]->THR = c;
  90. return c & 0xff;
  91. }
  92. static int uart_channel_getc(uart_device_number_t channel)
  93. {
  94. /* If received empty */
  95. if(!(uart[channel]->LSR & 1))
  96. return EOF;
  97. else
  98. return (char)(uart[channel]->RBR & 0xff);
  99. }
  100. static int uart_debug_putchar(char c)
  101. {
  102. return uart_channel_putc(c, s_uart_debug_channel);
  103. }
  104. static int uart_debug_getchar(void)
  105. {
  106. return uart_channel_getc(s_uart_debug_channel);
  107. }
  108. void uart_debug_init(uart_device_number_t uart_channel)
  109. {
  110. volatile bool v_uart_reset_flag = false;
  111. if(uart_channel >= UART_DEVICE_1 && uart_channel <= UART_DEVICE_3)
  112. {
  113. s_uart_debug_channel = uart_channel;
  114. v_uart_reset_flag = true;
  115. }
  116. uart_init(s_uart_debug_channel);
  117. uart_configure(s_uart_debug_channel, 115200, 8, UART_STOP_1, UART_PARITY_NONE);
  118. uart_set_receive_trigger(s_uart_debug_channel, UART_RECEIVE_FIFO_1);
  119. if(v_uart_reset_flag)
  120. {
  121. sys_register_getchar(uart_debug_getchar);
  122. sys_register_putchar(uart_debug_putchar);
  123. } else
  124. {
  125. if(sys_getchar == NULL)
  126. sys_register_getchar(uart_debug_getchar);
  127. if(sys_putchar == NULL)
  128. sys_register_putchar(uart_debug_putchar);
  129. }
  130. }
  131. static int uart_dma_callback(void *ctx)
  132. {
  133. uart_dma_instance_t *v_uart_dma_instance = (uart_dma_instance_t *)ctx;
  134. dmac_channel_number_t dmac_channel = v_uart_dma_instance->dmac_channel;
  135. dmac_irq_unregister(dmac_channel);
  136. if(v_uart_dma_instance->int_mode == UART_RECEIVE)
  137. {
  138. size_t v_buf_len = v_uart_dma_instance->buf_len;
  139. uint8_t *v_buffer = v_uart_dma_instance->buffer;
  140. uint32_t *v_recv_buffer = v_uart_dma_instance->malloc_buffer;
  141. for(size_t i = 0; i < v_buf_len; i++)
  142. {
  143. v_buffer[i] = v_recv_buffer[i];
  144. }
  145. }
  146. #if FIX_CACHE
  147. iomem_free(v_uart_dma_instance->malloc_buffer);
  148. #else
  149. free(v_uart_dma_instance->malloc_buffer);
  150. #endif
  151. v_uart_dma_instance->malloc_buffer = NULL;
  152. if(v_uart_dma_instance->uart_int_instance.callback)
  153. v_uart_dma_instance->uart_int_instance.callback(v_uart_dma_instance->uart_int_instance.ctx);
  154. return 0;
  155. }
  156. int uart_receive_data(uart_device_number_t channel, char *buffer, size_t buf_len)
  157. {
  158. size_t i = 0;
  159. for(i = 0; i < buf_len; i++)
  160. {
  161. if(uart[channel]->LSR & 1)
  162. buffer[i] = (char)(uart[channel]->RBR & 0xff);
  163. else
  164. break;
  165. }
  166. return i;
  167. }
  168. void uart_receive_data_dma(uart_device_number_t uart_channel, dmac_channel_number_t dmac_channel, uint8_t *buffer, size_t buf_len)
  169. {
  170. #if FIX_CACHE
  171. uint32_t *v_recv_buf = (uint32_t *)iomem_malloc(buf_len * sizeof(uint32_t));
  172. #else
  173. uint32_t *v_recv_buf = (uint32_t *)malloc(buf_len * sizeof(uint32_t));
  174. #endif
  175. configASSERT(v_recv_buf != NULL);
  176. sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_RX_REQ + uart_channel * 2);
  177. dmac_set_single_mode(dmac_channel, (void *)(&uart[uart_channel]->RBR), v_recv_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
  178. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, buf_len);
  179. dmac_wait_done(dmac_channel);
  180. for(uint32_t i = 0; i < buf_len; i++)
  181. {
  182. buffer[i] = (uint8_t)(v_recv_buf[i] & 0xff);
  183. }
  184. #if FIX_CACHE
  185. iomem_free(v_recv_buf);
  186. #else
  187. free(v_recv_buf);
  188. #endif
  189. }
  190. void uart_receive_data_dma_irq(uart_device_number_t uart_channel, dmac_channel_number_t dmac_channel,
  191. uint8_t *buffer, size_t buf_len, plic_irq_callback_t uart_callback,
  192. void *ctx, uint32_t priority)
  193. {
  194. #if FIX_CACHE
  195. uint32_t *v_recv_buf = (uint32_t *)iomem_malloc(buf_len * sizeof(uint32_t));
  196. #else
  197. uint32_t *v_recv_buf = (uint32_t *)malloc(buf_len * sizeof(uint32_t));
  198. #endif
  199. configASSERT(v_recv_buf != NULL);
  200. uart_recv_dma_instance[uart_channel].dmac_channel = dmac_channel;
  201. uart_recv_dma_instance[uart_channel].uart_num = uart_channel;
  202. uart_recv_dma_instance[uart_channel].malloc_buffer = v_recv_buf;
  203. uart_recv_dma_instance[uart_channel].buffer = buffer;
  204. uart_recv_dma_instance[uart_channel].buf_len = buf_len;
  205. uart_recv_dma_instance[uart_channel].int_mode = UART_RECEIVE;
  206. uart_recv_dma_instance[uart_channel].uart_int_instance.callback = uart_callback;
  207. uart_recv_dma_instance[uart_channel].uart_int_instance.ctx = ctx;
  208. dmac_irq_register(dmac_channel, uart_dma_callback, &uart_recv_dma_instance[uart_channel], priority);
  209. sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_RX_REQ + uart_channel * 2);
  210. dmac_set_single_mode(dmac_channel, (void *)(&uart[uart_channel]->RBR), v_recv_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
  211. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, buf_len);
  212. }
  213. int uart_send_data(uart_device_number_t channel, const char *buffer, size_t buf_len)
  214. {
  215. g_write_count = 0;
  216. while(g_write_count < buf_len)
  217. {
  218. uart_channel_putc(*buffer++, channel);
  219. g_write_count++;
  220. }
  221. return g_write_count;
  222. }
  223. void uart_send_data_dma(uart_device_number_t uart_channel, dmac_channel_number_t dmac_channel, const uint8_t *buffer, size_t buf_len)
  224. {
  225. #if FIX_CACHE
  226. uint32_t *v_send_buf = iomem_malloc(buf_len * sizeof(uint32_t));
  227. #else
  228. uint32_t *v_send_buf = malloc(buf_len * sizeof(uint32_t));
  229. #endif
  230. configASSERT(v_send_buf != NULL);
  231. for(uint32_t i = 0; i < buf_len; i++)
  232. v_send_buf[i] = buffer[i];
  233. sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_TX_REQ + uart_channel * 2);
  234. dmac_set_single_mode(dmac_channel, v_send_buf, (void *)(&uart[uart_channel]->THR), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
  235. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, buf_len);
  236. dmac_wait_done(dmac_channel);
  237. #if FIX_CACHE
  238. iomem_free((void *)v_send_buf);
  239. #else
  240. free((void *)v_send_buf);
  241. #endif
  242. }
  243. void uart_send_data_dma_irq(uart_device_number_t uart_channel, dmac_channel_number_t dmac_channel,
  244. const uint8_t *buffer, size_t buf_len, plic_irq_callback_t uart_callback,
  245. void *ctx, uint32_t priority)
  246. {
  247. #if FIX_CACHE
  248. uint32_t *v_send_buf = iomem_malloc(buf_len * sizeof(uint32_t));
  249. #else
  250. uint32_t *v_send_buf = malloc(buf_len * sizeof(uint32_t));
  251. #endif
  252. configASSERT(v_send_buf != NULL);
  253. uart_send_dma_instance[uart_channel] = (uart_dma_instance_t){
  254. .dmac_channel = dmac_channel,
  255. .uart_num = uart_channel,
  256. .malloc_buffer = v_send_buf,
  257. .buffer = (uint8_t *)buffer,
  258. .buf_len = buf_len,
  259. .int_mode = UART_SEND,
  260. .uart_int_instance.callback = uart_callback,
  261. .uart_int_instance.ctx = ctx,
  262. };
  263. for(uint32_t i = 0; i < buf_len; i++)
  264. v_send_buf[i] = buffer[i];
  265. dmac_irq_register(dmac_channel, uart_dma_callback, &uart_send_dma_instance[uart_channel], priority);
  266. sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_TX_REQ + uart_channel * 2);
  267. dmac_set_single_mode(dmac_channel, v_send_buf, (void *)(&uart[uart_channel]->THR), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
  268. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, buf_len);
  269. }
  270. void uart_configure(uart_device_number_t channel, uint32_t baud_rate, uart_bitwidth_t data_width, uart_stopbit_t stopbit, uart_parity_t parity)
  271. {
  272. configASSERT(data_width >= 5 && data_width <= 8);
  273. if(data_width == 5)
  274. {
  275. configASSERT(stopbit != UART_STOP_2);
  276. } else
  277. {
  278. configASSERT(stopbit != UART_STOP_1_5);
  279. }
  280. uint32_t stopbit_val = stopbit == UART_STOP_1 ? 0 : 1;
  281. uint32_t parity_val;
  282. switch(parity)
  283. {
  284. case UART_PARITY_NONE:
  285. parity_val = 0;
  286. break;
  287. case UART_PARITY_ODD:
  288. parity_val = 1;
  289. break;
  290. case UART_PARITY_EVEN:
  291. parity_val = 3;
  292. break;
  293. default:
  294. configASSERT(!"Invalid parity");
  295. break;
  296. }
  297. uint32_t freq = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  298. uint32_t divisor = freq / baud_rate;
  299. uint8_t dlh = divisor >> 12;
  300. uint8_t dll = (divisor - (dlh << 12)) / __UART_BRATE_CONST;
  301. uint8_t dlf = divisor - (dlh << 12) - dll * __UART_BRATE_CONST;
  302. /* Set UART registers */
  303. uart[channel]->LCR |= 1u << 7;
  304. uart[channel]->DLH = dlh;
  305. uart[channel]->DLL = dll;
  306. uart[channel]->DLF = dlf;
  307. uart[channel]->LCR = 0;
  308. uart[channel]->LCR = (data_width - 5) | (stopbit_val << 2) | (parity_val << 3);
  309. uart[channel]->LCR &= ~(1u << 7);
  310. uart[channel]->IER |= 0x80; /* THRE */
  311. uart[channel]->FCR = UART_RECEIVE_FIFO_1 << 6 | UART_SEND_FIFO_8 << 4 | 0x1 << 3 | 0x1;
  312. }
  313. void __attribute__((weak, alias("uart_configure")))
  314. uart_config(uart_device_number_t channel, uint32_t baud_rate, uart_bitwidth_t data_width, uart_stopbit_t stopbit, uart_parity_t parity);
  315. void uart_init(uart_device_number_t channel)
  316. {
  317. sysctl_clock_enable(SYSCTL_CLOCK_UART1 + channel);
  318. sysctl_reset(SYSCTL_RESET_UART1 + channel);
  319. }
  320. void uart_set_send_trigger(uart_device_number_t channel, uart_send_trigger_t trigger)
  321. {
  322. uart[channel]->STET = trigger;
  323. }
  324. void uart_set_receive_trigger(uart_device_number_t channel, uart_receive_trigger_t trigger)
  325. {
  326. uart[channel]->SRT = trigger;
  327. }
  328. void uart_irq_register(uart_device_number_t channel, uart_interrupt_mode_t interrupt_mode, plic_irq_callback_t uart_callback, void *ctx, uint32_t priority)
  329. {
  330. if(interrupt_mode == UART_SEND)
  331. {
  332. uart[channel]->IER |= 0x2;
  333. g_uart_instance[channel].uart_send_instance.callback = uart_callback;
  334. g_uart_instance[channel].uart_send_instance.ctx = ctx;
  335. } else if(interrupt_mode == UART_RECEIVE)
  336. {
  337. uart[channel]->IER |= 0x1;
  338. g_uart_instance[channel].uart_receive_instance.callback = uart_callback;
  339. g_uart_instance[channel].uart_receive_instance.ctx = ctx;
  340. }
  341. g_uart_instance[channel].uart_num = channel;
  342. plic_set_priority(IRQN_UART1_INTERRUPT + channel, priority);
  343. plic_irq_register(IRQN_UART1_INTERRUPT + channel, uart_irq_callback, &g_uart_instance[channel]);
  344. plic_irq_enable(IRQN_UART1_INTERRUPT + channel);
  345. }
  346. void uart_irq_unregister(uart_device_number_t channel, uart_interrupt_mode_t interrupt_mode)
  347. {
  348. if(interrupt_mode == UART_SEND)
  349. {
  350. uart[channel]->IER &= ~(0x2);
  351. g_uart_instance[channel].uart_send_instance.callback = NULL;
  352. g_uart_instance[channel].uart_send_instance.ctx = NULL;
  353. } else if(interrupt_mode == UART_RECEIVE)
  354. {
  355. uart[channel]->IER &= ~(0x1);
  356. g_uart_instance[channel].uart_receive_instance.callback = NULL;
  357. g_uart_instance[channel].uart_receive_instance.ctx = NULL;
  358. }
  359. if(uart[channel]->IER == 0)
  360. {
  361. plic_irq_unregister(IRQN_UART1_INTERRUPT + channel);
  362. }
  363. }
  364. int uart_dma_irq(void *ctx)
  365. {
  366. uart_instance_dma_t *v_instance = (uart_instance_dma_t *)ctx;
  367. dmac_irq_unregister(v_instance->dmac_channel);
  368. if(v_instance->transfer_mode == UART_SEND)
  369. {
  370. while(!(uart[v_instance->uart_num]->LSR & (1u << 6)))
  371. ;
  372. }
  373. spinlock_unlock(&v_instance->lock);
  374. if(v_instance->uart_int_instance.callback)
  375. {
  376. v_instance->uart_int_instance.callback(v_instance->uart_int_instance.ctx);
  377. }
  378. return 0;
  379. }
  380. void uart_handle_data_dma(uart_device_number_t uart_channel, uart_data_t data, plic_interrupt_t *cb)
  381. {
  382. configASSERT(uart_channel < UART_DEVICE_MAX);
  383. if(data.transfer_mode == UART_SEND)
  384. {
  385. configASSERT(data.tx_buf && data.tx_len && data.tx_channel < DMAC_CHANNEL_MAX);
  386. spinlock_lock(&g_uart_send_instance_dma[uart_channel].lock);
  387. if(cb)
  388. {
  389. g_uart_send_instance_dma[uart_channel].uart_int_instance.callback = cb->callback;
  390. g_uart_send_instance_dma[uart_channel].uart_int_instance.ctx = cb->ctx;
  391. g_uart_send_instance_dma[uart_channel].dmac_channel = data.tx_channel;
  392. g_uart_send_instance_dma[uart_channel].transfer_mode = UART_SEND;
  393. dmac_irq_register(data.tx_channel, uart_dma_irq, &g_uart_send_instance_dma[uart_channel], cb->priority);
  394. }
  395. sysctl_dma_select((sysctl_dma_channel_t)data.tx_channel, SYSCTL_DMA_SELECT_UART1_TX_REQ + uart_channel * 2);
  396. dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&uart[uart_channel]->THR), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
  397. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.tx_len);
  398. if(!cb)
  399. {
  400. dmac_wait_done(data.tx_channel);
  401. while(!(uart[uart_channel]->LSR & (1u << 6)))
  402. ;
  403. spinlock_unlock(&g_uart_send_instance_dma[uart_channel].lock);
  404. }
  405. } else
  406. {
  407. configASSERT(data.rx_buf && data.rx_len && data.rx_channel < DMAC_CHANNEL_MAX);
  408. spinlock_lock(&g_uart_recv_instance_dma[uart_channel].lock);
  409. if(cb)
  410. {
  411. g_uart_recv_instance_dma[uart_channel].uart_int_instance.callback = cb->callback;
  412. g_uart_recv_instance_dma[uart_channel].uart_int_instance.ctx = cb->ctx;
  413. g_uart_recv_instance_dma[uart_channel].dmac_channel = data.rx_channel;
  414. g_uart_recv_instance_dma[uart_channel].transfer_mode = UART_RECEIVE;
  415. dmac_irq_register(data.rx_channel, uart_dma_irq, &g_uart_recv_instance_dma[uart_channel], cb->priority);
  416. }
  417. sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_UART1_RX_REQ + uart_channel * 2);
  418. dmac_set_single_mode(data.rx_channel, (void *)(&uart[uart_channel]->RBR), data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
  419. DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len);
  420. if(!cb)
  421. {
  422. dmac_wait_done(data.rx_channel);
  423. spinlock_unlock(&g_uart_recv_instance_dma[uart_channel].lock);
  424. }
  425. }
  426. }
  427. void uart_set_work_mode(uart_device_number_t uart_channel, uart_work_mode_t work_mode)
  428. {
  429. volatile uart_tcr_t *tcr;
  430. switch(work_mode)
  431. {
  432. case UART_IRDA:
  433. uart[uart_channel]->MCR |= (1 << 6);
  434. break;
  435. case UART_RS485_FULL_DUPLEX:
  436. tcr = (uart_tcr_t *)&uart[uart_channel]->TCR;
  437. tcr->xfer_mode = 0;
  438. tcr->rs485_en = 1;
  439. break;
  440. case UART_RS485_HALF_DUPLEX:
  441. tcr = (uart_tcr_t *)&uart[uart_channel]->TCR;
  442. tcr->xfer_mode = 2;
  443. tcr->rs485_en = 1;
  444. uart[uart_channel]->DE_EN = 1;
  445. uart[uart_channel]->RE_EN = 1;
  446. break;
  447. default:
  448. uart[uart_channel]->MCR &= ~(1 << 6);
  449. uart[uart_channel]->TCR &= ~(1 << 0);
  450. break;
  451. }
  452. }
  453. void uart_set_rede_polarity(uart_device_number_t uart_channel, uart_rs485_rede_t rede, uart_polarity_t polarity)
  454. {
  455. volatile uart_tcr_t *tcr = (uart_tcr_t *)&uart[uart_channel]->TCR;
  456. switch(rede)
  457. {
  458. case UART_RS485_DE:
  459. tcr->de_pol = polarity;
  460. break;
  461. case UART_RS485_RE:
  462. tcr->re_pol = polarity;
  463. break;
  464. default:
  465. tcr->de_pol = polarity;
  466. tcr->re_pol = polarity;
  467. break;
  468. }
  469. }
  470. void uart_set_rede_enable(uart_device_number_t uart_channel, uart_rs485_rede_t rede, bool enable)
  471. {
  472. switch(rede)
  473. {
  474. case UART_RS485_DE:
  475. uart[uart_channel]->DE_EN = enable;
  476. break;
  477. case UART_RS485_RE:
  478. uart[uart_channel]->RE_EN = enable;
  479. break;
  480. default:
  481. uart[uart_channel]->DE_EN = enable;
  482. uart[uart_channel]->RE_EN = enable;
  483. break;
  484. }
  485. }
  486. void uart_set_det(uart_device_number_t uart_channel, uart_det_mode_t det_mode, size_t time)
  487. {
  488. volatile uart_det_t *det = (uart_det_t *)&uart[uart_channel]->DET;
  489. uint32_t freq = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  490. uint32_t v_clk_cnt = time * freq / 1e9 + 1;
  491. if(v_clk_cnt > 255)
  492. v_clk_cnt = 255;
  493. switch(det_mode)
  494. {
  495. case UART_DE_ASSERTION:
  496. det->de_assertion_time = v_clk_cnt;
  497. break;
  498. case UART_DE_DE_ASSERTION:
  499. det->de_de_assertion_time = v_clk_cnt;
  500. break;
  501. default:
  502. det->de_assertion_time = v_clk_cnt;
  503. det->de_de_assertion_time = v_clk_cnt;
  504. break;
  505. }
  506. }
  507. void uart_set_tat(uart_device_number_t uart_channel, uart_tat_mode_t tat_mode, size_t time)
  508. {
  509. volatile uart_tat_t *tat = (uart_tat_t *)&uart[uart_channel]->TAT;
  510. uint32_t freq = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  511. uint32_t v_clk_cnt = time * freq / 1e9 + 1;
  512. if(v_clk_cnt > 65536)
  513. v_clk_cnt = 65536;
  514. switch(tat_mode)
  515. {
  516. case UART_DE_TO_RE:
  517. tat->de_to_re = v_clk_cnt - 1;
  518. break;
  519. case UART_RE_TO_DE:
  520. tat->re_to_de = v_clk_cnt - 1;
  521. break;
  522. default:
  523. tat->de_to_re = v_clk_cnt - 1;
  524. tat->re_to_de = v_clk_cnt - 1;
  525. break;
  526. }
  527. }