📄 p_uart_gpio.cpp
字号:
#ifdef _GPIO_UART_
#include <tmPCSW.h>
#include "mmio1500.h"
#include "board_bsp.h"
#include "log_api.h"
#include "os.h"
#include "uart_gpio.h"
#include "uart_gpio_tab.h"
#ifdef MY_LIBC
#include "string2.h"
#else
#include <string.h>
#endif
#define RESTRICT restrict
/*
只用于串口输出,用于打印调试信息
*/
#define UART_IN_PIN 4
#define UART_OUT_PIN 5
#define OUT_BUF_LEN (8*1024) // 输出缓冲区
//#define OUT_BUF_LEN (128) // 输出缓冲区
#define OUT_DMA_BUF_LEN (OUT_BUF_LEN*2) // 必须是4倍,保证一次发送完所有buf内容
static U8 s_buf[256 + OUT_BUF_LEN + OUT_DMA_BUF_LEN];
static volatile int s_out_len;
static U8 *RESTRICT s_out_buf;
static U16 *RESTRICT s_out_dma_buf;
static volatile int s_is_buf2;
static volatile int s_uart_sending; // 硬件是否在跑
// 把s_out_buf的数据拷贝到s_out_dma_buf, 并开始发送
static void StartSend()
{
#pragma TCS_atomic
int i, len = s_out_len;
for(i=0; i<(len&~1); i+=2) {
s_out_dma_buf[i] = reverse_tab[s_out_buf[i+1]];
s_out_dma_buf[i+1] = reverse_tab[s_out_buf[i]];
}
if(len & 1) {
s_out_dma_buf[i] = 0xFFFF;
s_out_dma_buf[i+1] = reverse_tab[s_out_buf[i]];
len++;
i += 2;
}
if(len & 0x1F) {
s_out_dma_buf[i] = 0xFFFF;
s_out_dma_buf[i+1] = 0xFFFF;
len += 2;
}
else {
s_out_dma_buf[i] = 0xFFFF;
s_out_dma_buf[i+1] = 0xFFFF;
s_out_dma_buf[i+2] = 0xFFFF;
s_out_dma_buf[i+3] = 0xFFFF;
len += 4;
}
my_cache_flush_atomic(s_out_dma_buf, len<<1); // in bytes
MMIO(GPIO_PG_BUF_CTL1) = (len>>1) - 1; // in dwords
MMIO(GPIO_INT_CLR1) = (s_is_buf2 ? BUF2_RDY_CLR : BUF1_RDY_CLR) | FIFO_OE_CLR | INT_OE_CLR; // clear BUF1 Ready
MMIO(GPIO_INT_EN1) = s_is_buf2 ? BUF2_RDY_EN : BUF1_RDY_EN; // enable BUF1/2 RDY interrupt
s_is_buf2 = !s_is_buf2;
s_out_len = 0;
s_uart_sending = 1;
}
static int CopyToLocalBuf(U8 *buf, int len)
{
#pragma TCS_atomic
int i;
int outLen = s_out_len;
int inLen = 0;
for(i=0; i<len; i++) {
inLen++;
if(buf[i]=='\r')
continue;
if(buf[i]=='\n')
s_out_buf[outLen++] = '\r';
s_out_buf[outLen++] = buf[i];
if(outLen >= OUT_BUF_LEN-32)
break;
}
s_out_len = outLen;
return inLen;
}
static int CopyToLocalBufRaw(U8 *buf, int len)
{
#pragma TCS_atomic
int i;
int outLen = s_out_len;
int inLen = 0;
for(i=0; i<len; i++) {
inLen++;
s_out_buf[outLen++] = buf[i];
if(outLen >= OUT_BUF_LEN-32)
break;
}
s_out_len = outLen;
return inLen;
}
int uart_try_write(U8 *buf, int len)
{
#pragma TCS_atomic
int ret = CopyToLocalBuf(buf, len);
if(s_out_len && !s_uart_sending)
StartSend();
return ret;
}
int uart_try_write_raw(U8 *buf, int len)
{
#pragma TCS_atomic
int ret = CopyToLocalBufRaw(buf, len);
if(s_out_len && !s_uart_sending)
StartSend();
return ret;
}
static void out_isr()
{
#pragma TCS_handler
#pragma TCS_atomic
if(s_out_len>0)
StartSend();
else {
s_uart_sending = 0;
MMIO(GPIO_INT_EN1) = 0;
}
}
int UartGPIO_Init()
{
// setup buffers
U8 *p = (U8 *)( (((U32)s_buf + 127) & ~127) );
s_out_buf = p;
s_out_dma_buf = (U16 *)(p + OUT_BUF_LEN + 128);
s_out_len = 0;
s_is_buf2 = 0;
// setup registers
GPIOSetMode (UART_OUT_PIN, GpioModeGPIO);
GPIOSelectDataSetting (IOD0_15, (1<<UART_OUT_PIN), (0<<UART_OUT_PIN)); // mask=1, IOD=0: 输出
MMIO(GPIO_EV1) = 0; // defalut
MMIO(GPIO_SEL1) = UART_OUT_PIN; // 低8位: source
MMIO(GPIO_BASE1_PTR1) = (U32)s_out_dma_buf;
MMIO(GPIO_BASE2_PTR1) = (U32)s_out_dma_buf;
MMIO(GPIO_SIZE1) = (OUT_DMA_BUF_LEN >> 6); // size in 64 bytes
MMIO(GPIO_DIVIDER_SIZE1) = 2812>>2; // 2812.5 = 108MHz / 38.4 KHz
MMIO(GPIO_EV1) = FIFO_MODE_PAT_GEN_SAMPLES;
MMIO(GPIO_INT_EN1) = 0;
//#ifndef _BOOT_
// setup interrupt
#ifdef _PSOS_
intInstanceSetup_t setup;
if(intOpen(intGPIO_INT1))
halt("intOpen(intGPIO_INT1) failed.\n");
setup.enabled = True;
setup.handler = out_isr;
setup.level_triggered = True;
setup.priority = intPRIO_5;
if(intInstanceSetup(intGPIO_INT1, &setup))
halt("intInstanceSetup(intGPIO11) failed.\n");
#else
SetupInterrupt(intGPIO_INT1, (U32)out_isr, 5, 1);
EnableInterrupt(intGPIO_INT1);
#endif
//#endif // _BOOT_
return 0;
}
int UartGPIO_Deinit()
{
MMIO(GPIO_EV1) = 0; // defalut
#ifdef _PSOS_
intClose(intGPIO_INT1);
#else
DisableInterrupt(intGPIO_INT1);
#endif
return 0;
}
void UartGPIO_WriteChar(char c)
{
while(uart_try_write((U8 *)&c, 1)==0);
}
// return 1, ok. 0, fifo full
int UartGPIO_TryWriteChar(unsigned char data)
{
return uart_try_write(&data, 1);
}
void UartGPIO_WriteBuf(unsigned char *data, int len)
{
while(len > 0) {
int ret = uart_try_write(data, len);
data += ret;
len -= ret;
if(len > 0)
Sleep(10);
}
}
void UartGPIO_WriteBufRaw(unsigned char *data, int len)
{
while(len > 0) {
int ret = uart_try_write_raw(data, len);
data += ret;
len -= ret;
if(len > 0)
Sleep(10);
}
}
void UartGPIO_WriteString(unsigned char *data)
{
UartGPIO_WriteBuf(data, strlen((char *)data));
}
static inline void GetChar(unsigned char v,
unsigned char *c1,
unsigned char *c2)
{
unsigned char v1 = v>>4;
v = v & 0xf;
if(v1<10)
*c1 = '0' + v1;
else
*c1 = 'A' + v1 - 10;
if(v<10)
*c2 = '0' + v;
else
*c2 = 'A' + v - 10;
}
void UartGPIO_WriteU32(unsigned long v)
{
unsigned char buf[8];
GetChar(v>>24, buf, buf+1);
GetChar((v>>16)&0xFF, buf+2, buf+3);
GetChar((v>>8)&0xFF, buf+4, buf+5);
GetChar(v&0xFF, buf+6, buf+7);
UartGPIO_WriteBuf(buf, 8);
}
#endif //_GPIO_UART_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -