Files
ninlight-w600/sdk/Platform/Drivers/iouart/wm_iouart.c
T
Michael Sauer 1b0501179d build: W600-SDK importiert, Firmware-Build und Hello am EVK
Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet,
Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont
gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs
(EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
2026-09-11 12:52:26 +02:00

271 lines
7.0 KiB
C

/**
* @file wm_iouart.c
*
* @brief IO uart Driver Module
*
* @author dave
*
* Copyright (c) 2015 Winner Microelectronics Co., Ltd.
*/
#include <string.h>
#include "wm_iouart.h"
#include "wm_debug.h"
#include "wm_irq.h"
#include "wm_config.h"
#include "wm_mem.h"
#include "wm_gpio.h"
#include "wm_timer.h"
#if 1//TLS_CONFIG_IOUART
struct tls_io_uart io_uart;
#if !IO_UART_FOR_PRINT
void iouart0_timer_cb(void)
{
int i = 0;
static u8 ch = 0;
// if(io_uart.ifrx)
{
if (0 == io_uart.bitnum) // 起始位
{
io_uart.bit[io_uart.bitcnt] = tls_gpio_read(IO_UART_RX);
if (io_uart.bit[io_uart.bitcnt++] != 0)
{
io_uart.bitcnt = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
// if(io_uart.bitcnt == IO_UART_ONEBITE_SAMPLE_NUM)
{
io_uart.bitcnt = 0;
io_uart.bitnum ++;
ch = 0;
}
}
else if (io_uart.bitnum >= 1 && io_uart.bitnum <= 8) // 数据位
{
io_uart.bit[io_uart.bitcnt++] = tls_gpio_read(IO_UART_RX);
if(io_uart.bitcnt == IO_UART_ONEBITE_SAMPLE_NUM)
{
for(i=0; i<(IO_UART_ONEBITE_SAMPLE_NUM-1); i++)
{
if(io_uart.bit[i] != io_uart.bit[i+1])
{
io_uart.bitcnt = 0;
io_uart.bitnum = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
}
if(io_uart.bit[0])
{
ch |= (1 << (io_uart.bitnum - 1));
}
io_uart.bitnum ++;
io_uart.bitcnt = 0;
}
}
else if (9 == io_uart.bitnum) // 停止位
{
io_uart.bit[io_uart.bitcnt++] = tls_gpio_read(IO_UART_RX);
if(io_uart.bitcnt == IO_UART_ONEBITE_SAMPLE_NUM)
{
if(io_uart.bit[i] != io_uart.bit[i+1])
{
io_uart.bitcnt = 0;
io_uart.bitnum = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
}
if(io_uart.bit[0] == 0)
{
io_uart.bitcnt = 0;
io_uart.bitnum = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
return;
}
io_uart.recv.buf[io_uart.recv.head] = ch;
io_uart.recv.head =(io_uart.recv.head + 1) & (TLS_IO_UART_RX_BUF_SIZE -1);
io_uart.bitnum = 0;
io_uart.bitcnt = 0;
ch = 0;
io_uart.ifrx = 0;
tls_timer_stop(io_uart.timerid);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
}
}
}
void iouart0_gpio_isr_callback(void *context)
{
u16 ret;
ret = tls_get_gpio_irq_status(IO_UART_RX);
if(ret)
{
tls_clr_gpio_irq_status(IO_UART_RX);
ret = tls_gpio_read(IO_UART_RX);
if(ret == 0)
{
io_uart.ifrx = 1;
tls_gpio_irq_disable(IO_UART_RX);
tls_timer_start(io_uart.timerid);
}
}
}
#endif
void iouart_tx_byte(u8 datatoSend)
{
u8 i, tmp;
u32 cpu_sr = 0;
cpu_sr = tls_os_set_critical(); // 发送一个byte的过程中不能被打断,否则可能会有错误码
/* Start bit */
tls_gpio_write(IO_UART_TX, 0);
tls_delay_via_timer(io_uart.timercnt+1, 0);
for (i = 0; i < 8; i++)
{
tmp = (datatoSend >> i) & 0x01;
if (tmp == 0)
{
tls_gpio_write(IO_UART_TX, 0);
}
else
{
tls_gpio_write(IO_UART_TX, 1);
}
tls_delay_via_timer(io_uart.timercnt+1, 0);
}
tls_gpio_write(IO_UART_TX, 1);
tls_delay_via_timer(io_uart.timercnt+1, 0);
tls_os_release_critical(cpu_sr);
}
int tls_iouart_init(int bandrate)
{
char *bufrx;
memset(&io_uart, 0, sizeof(struct tls_io_uart));
#if !IO_UART_FOR_PRINT
bufrx = tls_mem_alloc(TLS_IO_UART_RX_BUF_SIZE);
if (!bufrx)
return WM_FAILED;
memset(bufrx, 0, TLS_IO_UART_RX_BUF_SIZE);
io_uart.recv.buf = (u8 *) bufrx;
io_uart.recv.head = 0;
io_uart.recv.tail = 0;
#endif
tls_gpio_cfg(IO_UART_TX, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
tls_gpio_write(IO_UART_TX, 1);
tls_gpio_cfg(IO_UART_RX, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_PULLHIGH);
tls_gpio_isr_register(IO_UART_RX, iouart0_gpio_isr_callback, NULL);
tls_gpio_irq_enable(IO_UART_RX, WM_GPIO_IRQ_TRIG_LOW_LEVEL);
io_uart.timercnt = 1000000 / bandrate;
#if !IO_UART_FOR_PRINT
struct tls_timer_cfg timer_cfg;
timer_cfg.unit = TLS_TIMER_UNIT_US;
timer_cfg.timeout = io_uart.timercnt/IO_UART_ONEBITE_SAMPLE_NUM;
timer_cfg.is_repeat = 1;
timer_cfg.callback = (tls_timer_irq_callback)iouart0_timer_cb;
timer_cfg.arg = NULL;
io_uart.timerid = tls_timer_create(&timer_cfg);
#endif
return WM_SUCCESS;
}
int tls_iouart_destroy(void)
{
tls_gpio_irq_disable(IO_UART_RX);
tls_timer_destroy(io_uart.timerid);
io_uart.timerid = 0xFF;
tls_mem_free(io_uart.recv.buf);
return WM_SUCCESS;
}
int tls_iouart_read(u8 * buf, int bufsize)
{
int data_cnt, buflen, bufcopylen;
if (NULL == buf)
return WM_FAILED;
data_cnt =
CIRC_CNT(io_uart.recv.head, io_uart.recv.tail, TLS_IO_UART_RX_BUF_SIZE);
if (data_cnt >= bufsize)
{
buflen = bufsize;
}
else
{
buflen = data_cnt;
}
if ((io_uart.recv.tail + buflen) > TLS_IO_UART_RX_BUF_SIZE)
{
bufcopylen = (TLS_IO_UART_RX_BUF_SIZE - io_uart.recv.tail);
MEMCPY(buf, io_uart.recv.buf + io_uart.recv.tail, bufcopylen);
MEMCPY(buf + bufcopylen, io_uart.recv.buf, buflen - bufcopylen);
}
else
{
MEMCPY(buf, io_uart.recv.buf + io_uart.recv.tail, buflen);
}
io_uart.recv.tail = (io_uart.recv.tail + buflen) & (TLS_IO_UART_RX_BUF_SIZE - 1);
return buflen;
}
int tls_iouart_write(u8 * buf, int bufsize)
{
if (NULL == buf || bufsize <= 0 || 1 == io_uart.ifrx)
return WM_FAILED;
io_uart.iftx = 1;
while (bufsize)
{
iouart_tx_byte(*buf);
bufsize--;
buf++;
}
io_uart.iftx = 0;
return WM_SUCCESS;
}
int tls_iouart_output_char(int ch)
{
if(ch == '\n')
iouart_tx_byte('\r');
iouart_tx_byte((char)ch);
return ch;
}
#endif //TLS_CONFIG_IOUART