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

📄 p_uart_gpio_in.cpp

📁 PNX1500系列没有串口
💻 CPP
字号:
#include <tmPCSW.h>
#include "mmio1500.h"
#include "board_bsp.h"
//#include "ir.h"
#include "log_api.h"
#include "os.h"
#include "uart_gpio_in.h"
#include "list.h"

#define RESTRICT restrict

/*
	IR Filter功能要打开
	载波在红外接收头处就处理了,出来的是无载波的波形
*/

#define IR_PIN      4           // 红外遥控器输入pin
#define INTERVAL_VAL 0x3FF      // 间隔时间: 多少个13.5MHz cycles后,无输入,本DMA buf ready.

#define DMA_BUF_BITS 8
#define DMA_BUF_LEN (1<<DMA_BUF_BITS)
#define DMA_BUF_WORDS (DMA_BUF_LEN>>2)
#define DMA_BUF_NUM 32

static U8 s_buf[256 + (DMA_BUF_LEN+128) * DMA_BUF_NUM];
static UartBuf s_UartBuf[DMA_BUF_NUM];
static UartBuf *s_dma_buf1, *s_dma_buf2;
volatile int UartIn_underflow;   

static UartBuf *s_firstFree;
static UartBuf *s_firstFull;

UartBuf *GetUartBuf()
{
#pragma TCS_atomic 
	UartBuf *p;
	list_remove_head(s_firstFull, p);
	return p;
}

void FreeUartBuf(UartBuf *p)
{
#pragma TCS_atomic 
	my_cache_invalidate_atomic(p->buf, DMA_BUF_LEN);
	list_add_tail(s_firstFree, p);
}

volatile U32 uart_in_isr_num;

static void uart_in_isr()
{
#pragma TCS_handler
#pragma TCS_atomic 
	uart_in_isr_num++;
	U32 stat = MMIO(GPIO_INT_STAT2);
	if(stat & BUF1_RDY) {
		if(s_firstFree) {
			s_dma_buf1->n_dwords = (stat >> 14) + 1;
			list_add_tail(s_firstFull, s_dma_buf1);
			list_remove_head(s_firstFree, s_dma_buf1);
			MMIO(GPIO_BASE1_PTR2) = (U32)s_dma_buf1->buf;
		}
		else
			UartIn_underflow++;
		MMIO(GPIO_INT_CLR2) = 1;         // clear BUF1 Ready 
	}
	else if(stat & BUF2_RDY) {
		if(s_firstFree) {
			s_dma_buf2->n_dwords = (stat >> 14) + 1;
			list_add_tail(s_firstFull, s_dma_buf2);
			list_remove_head(s_firstFree, s_dma_buf2);
			MMIO(GPIO_BASE2_PTR2) = (U32)s_dma_buf2->buf;
		}
		else
			UartIn_underflow++;
		MMIO(GPIO_INT_CLR2) = 2;         // clear BUF2 Ready 
	}
}


int uart_in_init()
{
	int i;
	// setup buffers
	U8 *p = (U8 *)( (((U32)s_buf + 127) & ~127) + 128 );
	my_cache_invalidate(p, DMA_BUF_LEN * DMA_BUF_NUM);
	s_firstFree = s_firstFull = 0;

	for(i=0; i<DMA_BUF_NUM; i++) {
		s_UartBuf[i].buf = (U32 *)p;
		p += DMA_BUF_LEN + 128;
		if(i >= 2) // 前2个buf作为当前接收的DMA buf
			list_add_tail(s_firstFree, &s_UartBuf[i]);
	}
	s_dma_buf1 = &s_UartBuf[0];
	s_dma_buf2 = &s_UartBuf[1];

	// setup registers
    GPIOSetMode (IR_PIN, GpioModeGPIO);
    GPIOSelectDataSetting (IOD0_15, 0, (1<<IR_PIN));  // mask=0, IOD=1: 输入

	MMIO(GPIO_EV2) = 0;  // defalut
	MMIO(GPIO_SEL2) = IR_PIN;     // 低8位: source
	MMIO(GPIO_BASE1_PTR2) = (U32)s_dma_buf1->buf;
	MMIO(GPIO_BASE2_PTR2) = (U32)s_dma_buf2->buf;
	MMIO(GPIO_SIZE2) = (DMA_BUF_LEN >> 6); // size in 64 bytes
	MMIO(GPIO_DIVIDER_SIZE2) = 0;
	MMIO(GPIO_EV2) = EV_INTERVAL(INTERVAL_VAL) | EVENT_MODE_CAP_BOTH_EDGE | FIFO_MODE_EVT_TIMESTAMP;
	MMIO(GPIO_INT_CLR2) = 0xf;

	// setup interrupt
#ifdef _PSOS_
	intInstanceSetup_t setup;
	
	if(intOpen(intGPIO_INT2))
		halt("intOpen(intGPIO_INT0) failed.\n");

	setup.enabled         = True;
	setup.handler         = uart_in_isr;
	setup.level_triggered = True;
	setup.priority        = intPRIO_5;
	if(intInstanceSetup(intGPIO_INT2, &setup))
		halt("intInstanceSetup(intGPIO10) failed.\n");
#else
	SetupInterrupt(intGPIO_INT2, (U32)uart_in_isr, 5, 1);
	EnableInterrupt(intGPIO_INT2);
#endif

	MMIO(GPIO_INT_EN2) = BUF2_RDY | BUF1_RDY;  // enable BUF1/2 RDY interrupt

	return 0;
}

/*
	硬件buf前都加128字节. 避免hardware prefetch带来的问题. 1700兼容. 
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -