This repository has been archived on 2023-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
bl_mcu_sdk/bsp/bsp_common/usb/uart_interface.c
2021-08-26 12:26:34 +08:00

182 lines
5.5 KiB
C

/**
* @file uart_interface.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "hal_gpio.h"
#include "uart_interface.h"
#include "hal_usb.h"
#include "hal_dma.h"
#define USB_OUT_RINGBUFFER_SIZE (8 * 1024)
#define UART_RX_RINGBUFFER_SIZE (8 * 1024)
#define UART_TX_DMA_SIZE (4095)
uint8_t usb_rx_mem[USB_OUT_RINGBUFFER_SIZE] __attribute__((section(".system_ram")));
uint8_t uart_rx_mem[UART_RX_RINGBUFFER_SIZE] __attribute__((section(".system_ram")));
uint8_t src_buffer[UART_TX_DMA_SIZE] __attribute__((section(".tcm_code")));
struct device *uart1;
struct device *dma_ch2;
Ring_Buffer_Type usb_rx_rb;
Ring_Buffer_Type uart1_rx_rb;
void uart_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
if (state == UART_EVENT_RX_FIFO) {
if (size && size < Ring_Buffer_Get_Empty_Length(&uart1_rx_rb)) {
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
} else {
MSG("RF OV\r\n");
}
} else if (state == UART_EVENT_RTO) {
if (size && size < Ring_Buffer_Get_Empty_Length(&uart1_rx_rb)) {
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
} else {
MSG("RTO OV\r\n");
}
} else if (state == UART_RX_FER_IT) {
MSG("RX ERR\r\n");
}
}
void uart1_init(void)
{
uart_register(UART1_INDEX, "uart1");
uart1 = device_find("uart1");
if (uart1) {
// device_open(uart1, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
// device_set_callback(uart1, uart_irq_callback);
// device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
}
dma_register(DMA0_CH2_INDEX, "ch2");
dma_ch2 = device_find("ch2");
if (dma_ch2) {
device_open(dma_ch2, 0);
}
}
void uart1_config(uint32_t baudrate, uart_databits_t databits, uart_parity_t parity, uart_stopbits_t stopbits)
{
device_close(uart1);
UART_DEV(uart1)->baudrate = baudrate;
UART_DEV(uart1)->stopbits = stopbits;
UART_DEV(uart1)->parity = parity;
UART_DEV(uart1)->databits = (databits - 5);
device_open(uart1, DEVICE_OFLAG_DMA_TX | DEVICE_OFLAG_INT_RX);
device_set_callback(uart1, uart_irq_callback);
device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
Ring_Buffer_Reset(&usb_rx_rb);
Ring_Buffer_Reset(&uart1_rx_rb);
}
static uint8_t uart1_dtr;
static uint8_t uart1_rts;
void uart1_set_dtr_rts(uint8_t dtr, uint8_t rts)
{
uart1_dtr = dtr;
uart1_rts = rts;
}
void uart1_dtr_init(void)
{
gpio_set_mode(uart1_dtr, GPIO_OUTPUT_MODE);
}
void uart1_rts_init(void)
{
gpio_set_mode(uart1_rts, GPIO_OUTPUT_MODE);
}
void uart1_dtr_deinit(void)
{
gpio_set_mode(uart1_dtr, GPIO_INPUT_MODE);
}
void uart1_rts_deinit(void)
{
gpio_set_mode(uart1_rts, GPIO_INPUT_MODE);
}
void dtr_pin_set(uint8_t status)
{
gpio_write(uart1_dtr, status);
}
void rts_pin_set(uint8_t status)
{
gpio_write(uart1_rts, status);
}
void ringbuffer_lock()
{
__disable_irq();
}
void ringbuffer_unlock()
{
__enable_irq();
}
void uart_ringbuffer_init(void)
{
/* init mem for ring_buffer */
memset(usb_rx_mem, 0, USB_OUT_RINGBUFFER_SIZE);
memset(uart_rx_mem, 0, UART_RX_RINGBUFFER_SIZE);
/* init ring_buffer */
Ring_Buffer_Init(&usb_rx_rb, usb_rx_mem, USB_OUT_RINGBUFFER_SIZE, ringbuffer_lock, ringbuffer_unlock);
Ring_Buffer_Init(&uart1_rx_rb, uart_rx_mem, UART_RX_RINGBUFFER_SIZE, ringbuffer_lock, ringbuffer_unlock);
}
static dma_control_data_t uart_dma_ctrl_cfg = {
.bits.fix_cnt = 0,
.bits.dst_min_mode = 0,
.bits.dst_add_mode = 0,
.bits.SI = 1,
.bits.DI = 0,
.bits.SWidth = DMA_TRANSFER_WIDTH_8BIT,
.bits.DWidth = DMA_TRANSFER_WIDTH_8BIT,
.bits.SBSize = 0,
.bits.DBSize = 0,
.bits.I = 0,
.bits.TransferSize = 4095
};
static dma_lli_ctrl_t uart_lli_list = {
.src_addr = (uint32_t)src_buffer,
.dst_addr = DMA_ADDR_UART1_TDR,
.nextlli = 0
};
void uart_send_from_ringbuffer(void)
{
if (Ring_Buffer_Get_Length(&usb_rx_rb)) {
if (!device_control(dma_ch2, DMA_CHANNEL_GET_STATUS, NULL)) {
uint32_t avalibleCnt = Ring_Buffer_Read(&usb_rx_rb, src_buffer, UART_TX_DMA_SIZE);
if (avalibleCnt) {
dma_channel_stop(dma_ch2);
uart_dma_ctrl_cfg.bits.TransferSize = avalibleCnt;
memcpy(&uart_lli_list.cfg, &uart_dma_ctrl_cfg, sizeof(dma_control_data_t));
device_control(dma_ch2, DMA_CHANNEL_UPDATE, (void *)((uint32_t)&uart_lli_list));
dma_channel_start(dma_ch2);
}
}
}
}