| 252 | } |
| 253 | |
| 254 | static rt_ssize_t _uart_dma_write(struct rt_serial_device *serial, const void *buffer, rt_size_t size) |
| 255 | { |
| 256 | struct k230_uart_dev *uart_dev = rt_container_of(serial, struct k230_uart_dev, serial); |
| 257 | rt_uint32_t recv_event; |
| 258 | rt_err_t err; |
| 259 | rt_uint8_t ch; |
| 260 | |
| 261 | err = k230_pdma_request_channel(&ch); |
| 262 | if (err != RT_EOK) |
| 263 | { |
| 264 | const char *ptr = buffer; |
| 265 | for (rt_size_t i = 0; i < size; i++) |
| 266 | { |
| 267 | _drv_uart_putc(serial, ptr[i]); |
| 268 | } |
| 269 | return size; |
| 270 | } |
| 271 | |
| 272 | uint32_t len = RT_ALIGN(size, 64); |
| 273 | uint8_t *buf = rt_malloc_align(len, 64); |
| 274 | rt_memcpy(buf, buffer, size); |
| 275 | rt_hw_cpu_dcache_clean((void*)buf, len); |
| 276 | void *buf_pa = rt_kmem_v2p(buf); |
| 277 | uart_dev->dma_ch = ch; |
| 278 | |
| 279 | err = k230_pdma_set_callback(ch, _k230_uart_pdma_call_back); |
| 280 | if (err != RT_EOK) |
| 281 | { |
| 282 | k230_pdma_release_channel(ch); |
| 283 | rt_free_align(buf); |
| 284 | return err; |
| 285 | } |
| 286 | |
| 287 | uart_dev->pdma_cfg.src_addr = buf_pa; |
| 288 | uart_dev->pdma_cfg.line_size = len; |
| 289 | rt_event_control(uart_dev->dma_event, RT_IPC_CMD_RESET, NULL); |
| 290 | |
| 291 | err = k230_pdma_config(ch, &uart_dev->pdma_cfg); |
| 292 | err = k230_pdma_start(ch); |
| 293 | |
| 294 | err = rt_event_recv(uart_dev->dma_event, |
| 295 | K230_UART_PDMA_EVENT_COMPLETE | K230_UART_PDMA_EVENT_TIMEOUT, |
| 296 | RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, |
| 297 | RT_WAITING_FOREVER, |
| 298 | &recv_event); |
| 299 | |
| 300 | k230_pdma_stop(ch); |
| 301 | k230_pdma_release_channel(ch); |
| 302 | uart_dev->dma_ch = PDMA_CH_INVALID; |
| 303 | rt_free_align(buf); |
| 304 | return size; |
| 305 | } |
| 306 | |
| 307 | static rt_ssize_t _uart_dma_tran(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction) |
| 308 | { |
no test coverage detected