TC264 DMA相关部分代码

DMA计脉冲数

需要注意不要摄像头的中断冲突,优点就是不会占用cpu的时序,虽然影响也不是很大。

//dma计脉冲数
uint32 dummy = 0;//工具人参数
static IfxDma_Dma_Channel dmaChn_cnt_left;
static IfxDma_Dma_Channel dmaChn_cnt_right;

void dma_cnt_pin(ERU_PIN_enum pin, uint8 l_or_r)
{
    
    
	boolean interrupt_state = disableInterrupts();
	IfxScu_Req_In *reqPin;

	reqPin = eru_mux(pin);

	IfxScuEru_initReqPin(reqPin, IfxPort_InputMode_pullUp);

	IfxScuEru_InputChannel inputChannel = (IfxScuEru_InputChannel)reqPin->channelId;

	IfxScuEru_InputNodePointer triggerSelect = (IfxScuEru_InputNodePointer)(pin/3);
	IfxScuEru_OutputChannel    outputChannel = (IfxScuEru_OutputChannel)(pin/3);

	IfxScuEru_enableFallingEdgeDetection(inputChannel);
	IfxScuEru_enableRisingEdgeDetection(inputChannel);		//统计上升下降沿

	IfxScuEru_enableTriggerPulse(inputChannel);
	IfxScuEru_connectTrigger(inputChannel, triggerSelect);

	//使能中断
	IfxScuEru_setFlagPatternDetection(outputChannel, inputChannel, TRUE);
	IfxScuEru_enablePatternDetectionTrigger(outputChannel);
	IfxScuEru_setInterruptGatingPattern(outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);

	//配置中断
	volatile Ifx_SRC_SRCR *src = &MODULE_SRC.SCU.SCU.ERU[(int)outputChannel % 4];
	if (l_or_r)
	{
    
    
		IfxSrc_init(src, IfxSrc_Tos_dma, dma_cnt_ch_left);
	}
	else
	{
    
    
		IfxSrc_init(src, IfxSrc_Tos_dma, dma_cnt_ch_right);
	}

	IfxSrc_enable(src);

    restoreInterrupts(interrupt_state);
}
//任意两个有外部外部中断功能的引脚
void dma_cnt_init(ERU_PIN_enum pin_eru, uint8 l_or_r)
{
    
    
	dma_cnt_pin(pin_eru, l_or_r);

//	配置dma
	IfxDma_Dma_Config dmaConfig;
	IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);

	IfxDma_Dma dma;
	IfxDma_Dma_initModule(&dma, &dmaConfig);

	IfxDma_Dma_ChannelConfig cfg;
	IfxDma_Dma_initChannelConfig(&cfg, &dma);

	cfg.transferCount = 10000;
	cfg.moveSize = IfxDma_ChannelMoveSize_8bit;
	cfg.blockMode = IfxDma_ChannelMove_1;

	cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest;

	cfg.hardwareRequestEnabled = TRUE;

	cfg.operationMode = IfxDma_ChannelOperationMode_continuous;


	/*************** 源地址和目标地址 ***************/

	cfg.sourceCircularBufferEnabled = TRUE;
	cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none;

	cfg.destinationCircularBufferEnabled = TRUE;
	cfg.destinationAddressCircularRange = IfxDma_ChannelIncrementCircular_none;

	/*************** Channel specific configurations ***************/
	if (l_or_r)
		cfg.channelId = (IfxDma_ChannelId)dma_cnt_ch_left;
	else
		cfg.channelId = (IfxDma_ChannelId)dma_cnt_ch_right;
	cfg.busPriority = IfxDma_ChannelBusPriority_low;
	cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &dummy);

	cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &dummy);

	//禁用中断
	cfg.channelInterruptEnabled = FALSE;
	cfg.channelInterruptPriority = 0;
	if (l_or_r)
		IfxDma_Dma_initChannel(&dmaChn_cnt_left, &cfg);
	else
		IfxDma_Dma_initChannel(&dmaChn_cnt_right, &cfg);
}

int16 dma_cnt_read(uint8 l_or_r)
{
    
    
	Ifx_DMA_CH *ch;
	int16 speed;
	if (l_or_r)
	{
    
    
		ch = dmaChn_cnt_left.channel;
		speed = 10000 - ch->CHCSR.B.TCOUNT;
		speed = speed == 10000 ? 0 : speed;
		MODULE_DMA.TSR[dmaChn_cnt_left.channelId].B.RST = 1;
		ch->CHCFGR.B.TREL = 10000;
		MODULE_DMA.TSR[dmaChn_cnt_left.channelId].B.ECH = 1;
	}
	else
	{
    
    
		ch = dmaChn_cnt_right.channel;
		speed = 10000 - ch->CHCSR.B.TCOUNT;
		speed = speed == 10000 ? 0 : speed;
		MODULE_DMA.TSR[dmaChn_cnt_right.channelId].B.RST = 1;
		ch->CHCFGR.B.TREL = 10000;
		MODULE_DMA.TSR[dmaChn_cnt_right.channelId].B.ECH = 1;
	}
//	printf("%d\n", speed);
	return speed;
}

DMA处理UART中断

尽量只用一个DMA通道进行传输,数据可能会错位。

Ifx_ASCLIN *DMA_UART_NUM 	 	= &MODULE_ASCLIN2;
#define DMA_UART_TX_DB       	((uint8*)&(DMA_UART_NUM->TXDATA))
#define DMA_UART_TX_SB       	((uint8*)&My_Send_Data)
static IfxDma_Dma_Channel dmaChn_uart;
uint32 time = 0;
static uint8 uart2_tx_buffer[UART2_TX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
static uint8 uart2_rx_buffer[UART2_RX_BUFFER_SIZE + sizeof(Ifx_Fifo) + 8];
uint8 transfer_finish_flag = 0;
IFX_INTERRUPT(uart2_dma_tx_isr, 0, INTPRIO_DMA_UART)
{
    
    
	//禁用dma
	enableInterrupts();
	transfer_finish_flag  = 1;
	IfxDma_disableChannelTransaction(&MODULE_DMA, dmaChn_uart.channelId);
	IfxDma_clearChannelInterrupt(&MODULE_DMA, dmaChn_uart.channelId);
}

//内部调用
void transfer_init_uart(void)
{
    
    
	/* Initialize an instance of IfxAsclin_Asc_Config with default values */
	IfxAsclin_Asc_Config ascConfig;
	IfxAsclin_Asc_initModuleConfig(&ascConfig, &MODULE_ASCLIN2);

	/* Set the desired baud rate */
	ascConfig.baudrate.baudrate = data_uart_baud;

	/* ISR priorities and interrupt service provider */
	ascConfig.interrupt.txPriority = data_uart_dma_ch;
	ascConfig.interrupt.rxPriority = UART2_RX_INT_PRIO;
	ascConfig.interrupt.typeOfService = IfxSrc_Tos_dma;

	/* FIFO configuration */
	ascConfig.txBuffer = &uart2_tx_buffer;
	ascConfig.txBufferSize = UART2_TX_BUFFER_SIZE;

	ascConfig.rxBuffer = &uart2_rx_buffer;
	ascConfig.rxBufferSize = UART2_RX_BUFFER_SIZE;

	/* Pin configuration */
	const IfxAsclin_Asc_Pins pins =
	{
    
    
		NULL_PTR,       			IfxPort_InputMode_pullUp,    /* CTS port pin not used   */
		&IfxAsclin2_RXE_P33_8_IN,   IfxPort_InputMode_pullUp,    /* RX port pin             */
		NULL_PTR,       			IfxPort_OutputMode_pushPull, /* RTS port pin not used   */
		&IfxAsclin2_TX_P33_9_OUT,   IfxPort_OutputMode_pushPull, /* TX port pin             */
		IfxPort_PadDriver_cmosAutomotiveSpeed1
	};
	ascConfig.pins = &pins;

	IfxAsclin_Asc_initModule(&uart2_handle, &ascConfig); /* Initialize module with above parameters                  */

	volatile Ifx_SRC_SRCR *src;
	src = IfxAsclin_getSrcPointerTx(ascConfig.asclin);

	IfxSrc_init(src, IfxSrc_Tos_dma, data_uart_dma_ch);

	IfxAsclin_enableTxFifoFillLevelFlag(ascConfig.asclin, TRUE);
	IfxSrc_enable(src);
}

void transfer_init_dma(void)
{
    
    
	//配置dma
	IfxDma_Dma_Config dmaConfig;
	IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);

	IfxDma_Dma dma;
	IfxDma_Dma_initModule(&dma, &dmaConfig);

	IfxDma_Dma_ChannelConfig cfg;
	IfxDma_Dma_initChannelConfig(&cfg, &dma);

	cfg.transferCount = Send_Data_Len;														//传输总字节数
	cfg.moveSize = IfxDma_ChannelMoveSize_8bit;												//每次传输字节数
	cfg.blockMode = IfxDma_ChannelMove_1;													//每次只用一个dma

	cfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest;						//完整传输完后中断请求

	cfg.hardwareRequestEnabled = TRUE;														//UART触发

	cfg.operationMode = IfxDma_ChannelOperationMode_single;									//触发一次


	/*************** 源地址和目标地址 ***************/

	cfg.sourceCircularBufferEnabled = FALSE;												//每次+1
	cfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_none;
	cfg.sourceAddressIncrementStep = IfxDma_ChannelIncrementStep_1;							//一个字节

	cfg.destinationCircularBufferEnabled = TRUE;											//目标地址不变化
	cfg.destinationAddressCircularRange = IfxDma_ChannelIncrementCircular_none;

	/*************** Channel specific configurations ***************/
	cfg.channelId = (IfxDma_ChannelId) data_uart_dma_ch;									//选择通道

	cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), DMA_UART_TX_SB);			//传输的源地址

	cfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), DMA_UART_TX_DB);		//目标地址

	cfg.channelInterruptEnabled = TRUE;

	/* DMA triggers an interrupt once the full transaction is done */
	cfg.channelInterruptControl = IfxDma_ChannelInterruptControl_thresholdLimitMatch;

	/* Priority of the channel interrupt trigger */
	cfg.channelInterruptPriority = INTPRIO_DMA_UART;

	/* Interrupt service provider */
	cfg.channelInterruptTypeOfService = IfxSrc_Tos_cpu0;

	IfxDma_Dma_initChannel(&dmaChn_uart, &cfg);
}

void My_Data_Uart_Init(void)
{
    
    
	transfer_init_uart();
	transfer_init_dma();
}

void send_to_computer(void)
{
    
    
	Ifx_DMA_CH *ch = dmaChn_uart.channel;

	ch->SADR.U = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), DMA_UART_TX_SB);
	ch->CHCFGR.B.TREL = Send_Data_Len;

	//tx中断
	IfxDma_enableChannelTransaction(&MODULE_DMA, dmaChn_uart.channelId);
	DMA_UART_NUM->FLAGSSET.B.TFLS = 1;
}

猜你喜欢

转载自blog.csdn.net/qq_43550173/article/details/109308001
tc
264
DMA