Thread 中讨论的其他器件: EK-TM4C123GXL
您好、
我不熟悉 TM4C123GH6PGE 系列。 目前、我尝试了解如何进行由中断控制的 FIFO TX 传输。
设计:
我想创建一个发送函数、该函数填充 FIFO 并等待 FIFO 完成。 由于我使用的是 RTOS (Zephir)、所以我想在 FIFO 传输过程中执行一些其他操作。 因此、传输应通过 TX/FIFO 中断进行控制。
我想知道我需要如何设置 FIFO/INTR
我附加了一些"伪代码"。 此代码是从我的 Zephir UART API 实现中编译的、该 API 是一个处理 UART 异步和一些应用函数的中间层。
"setup"和"Send"功能是入口点。
static char * pB;
static int N;
static int uart_tiva_fifo_fill(const struct device *dev, const uint8_t *buf, int len)
{
const struct uart_tiva_config * const cfg = DEV_CFG(dev);
const uint32_t base = cfg->base;
int n = 0;
while (n < len) {
if (false == UARTCharPutNonBlocking(base, buf[n])) {
break;
}
n++;
}
return n;
}
static void uart_tiva_isr(const struct device *dev)
{
const struct uart_tiva_config * const cfg = DEV_CFG(dev);
struct uart_tiva_runtime *const dev_data = DEV_DATA(dev);
const uint32_t base = cfg->base;
const uint32_t UIstatus = UARTIntStatus(base, true);
if (dev_data->cb) {
dev_data->cb(dev, dev_data->cb_data);
}
UARTIntClear(base, UIstatus);
}
static void uart0_fifo_callback(const struct device *dev, void *user_data) {
ARG_UNUSED(user_data);
if (uart_irq_tx_ready(dev) && (N)) {
const uint32_t am = uart_fifo_fill(dev, pB, N);
N -= am;
pB += am;
if (0 == N) {
uart_irq_tx_disable(dev);
k_sem_give(txDone);
}
}
}
void send(char * txt, int len) {
pB = txt;
N = len;
const int n = uart_tiva_fifo_fill(uart0, pB, N);
N -= n;
pB += n;
if (am) {
k_sem_take(txDone, K_FOREVER);
}
}
static int uart_tiva_configure(const struct device *dev, const struct uart_config *cfg) {
const struct uart_tiva_config * const devCfg = DEV_CFG(dev);
const uint32_t base = devCfg->base;
uint32_t tiCfg = 0;
switch(cfg->parity) {
case UART_CFG_PARITY_NONE:
tiCfg = UART_CONFIG_PAR_NONE;
break;
case UART_CFG_PARITY_ODD:
tiCfg = UART_CONFIG_PAR_ODD;
break;
case UART_CFG_PARITY_EVEN:
tiCfg = UART_CONFIG_PAR_EVEN;
break;
case UART_CFG_PARITY_MARK:
case UART_CFG_PARITY_SPACE:
default:
return -ENOTSUP;
break;
};
switch(cfg->stop_bits) {
case UART_CFG_STOP_BITS_1:
tiCfg |= UART_CONFIG_STOP_ONE;
break;
case UART_CFG_STOP_BITS_2:
tiCfg |= UART_CONFIG_STOP_TWO;
break;
case UART_CFG_STOP_BITS_0_5:
case UART_CFG_STOP_BITS_1_5:
default:
return -ENOTSUP;
break;
};
UART9BitDisable(base);
switch(cfg->data_bits) {
case UART_CFG_DATA_BITS_5:
tiCfg |= UART_CONFIG_WLEN_5;
break;
case UART_CFG_DATA_BITS_6:
tiCfg |= UART_CONFIG_WLEN_6;
break;
case UART_CFG_DATA_BITS_7:
tiCfg |= UART_CONFIG_WLEN_7;
break;
case UART_CFG_DATA_BITS_8:
tiCfg |= UART_CONFIG_WLEN_8;
break;
case UART_CFG_DATA_BITS_9:
// ToDo: check how 9bit mode is right fully setup
// tiCfg |= UART_CONFIG_WLEN_8;
// UART9BitEnable(base);
// break;
default:
return -ENOTSUP;
break;
};
UARTEnable(base);
UARTConfigSetExpClk(base, SysCtlClockGet(), cfg->baudrate, tiCfg);
/* Clear all UART interrupts */
UARTIntClear(base,
UART_INT_OE | UART_INT_BE | UART_INT_PE |
UART_INT_FE | UART_INT_RT | UART_INT_TX |
UART_INT_RX | UART_INT_CTS);
switch(cfg->flow_ctrl) {
case UART_CFG_FLOW_CTRL_NONE:
UARTFlowControlSet(base,UART_FLOWCONTROL_NONE);
break;
case UART_CFG_FLOW_CTRL_RTS_CTS:
UARTFlowControlSet(base, UART_FLOWCONTROL_RX | UART_FLOWCONTROL_TX);
break;
case UART_CFG_FLOW_CTRL_DTR_DSR:
default:
return -ENOTSUP;
};
UARTEnable(base);
return 0;
}
void setup(void) {
const struct uart_tiva_config * const cfg = DEV_CFG(dev);
const uint32_t base = cfg->base;
pinmux_tiva_arrayCfg(cfg->pinctrl_list, cfg->pinctrl_list_size);
// switch uart on
sysctl_activatePeripheral(base);
IRQ_CONNECT(DT_INST_IRQN(n),
DT_INST_IRQ(n, priority),
uart_tiva_isr,
DEVICE_DT_INST_GET(n),
0);
UARTIntClear(base, UART_INT_RX | UART_INT_RT);
irq_enable(DT_INST_IRQN(n));
UARTTxIntModeSet(base, UART_TXINT_MODE_EOT);
const struct uart_config uart_cfg = {
.baudrate = cfg->baudrate,
.parity = UART_CFG_PARITY_NONE,
.stop_bits = UART_CFG_STOP_BITS_1,
.data_bits = UART_CFG_DATA_BITS_8,
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};
uart_tiva_configure(dev, &uart_cfg);
}
