⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_uart_gpio.cpp

📁 PNX1500系列没有串口
💻 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 + -