📄 p_uart_gpio_in.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 + -