在线时间19 小时
UID3624646
注册时间2020-3-10
NXP金币0
该用户从未签到
注册会员
- 积分
- 191
- 最后登录
- 2023-4-12
|
本帖最后由 fengqiluoye 于 2022-1-5 15:09 编辑
我在使用定时器输入捕获功能触发dma,并且使用小循环连接到spi的dma中,如果使用捕获功能的dma中断,波形正常,但是会丢掉一组数据。如果使用的是spi接收dma完成中断则数据不正常。不知道是哪里有问题。有人能给我点建议吗?
代码如下(调试代码有点乱):
/*
* Copyright 2017-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "fsl_dmamux.h"
#include "clock_config.h"
#include "board.h"
#include "fsl_qtmr.h"
#include "fsl_edma.h"
#include "fsl_lpspi.h"
#include "fsl_lpspi_edma.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* The QTMR instance/channel used for board */
#define BOARD_QTMR_BASEADDR TMR2
#define BOARD_QTMR_INPUT_CAPTURE_CHANNEL kQTMR_Channel_0
#define BOARD_QTMR_PWM_CHANNEL kQTMR_Channel_1
#define QTMR_CounterInputPin kQTMR_Counter0InputPin
/* Interrupt number and interrupt handler for the QTMR instance used */
#define QTMR_IRQ_ID TMR2_IRQn
#define QTMR_IRQ_HANDLER TMR2_IRQHandler
/* QTMR Clock source divider for Ipg clock source, the value of two macros below should be aligned. */
#define QTMR_PRIMARY_SOURCE (kQTMR_ClockDivide_4)
#define QTMR_CLOCK_SOURCE_DIVIDER (4U)
/* The frequency of the source clock after divided. */
//CLOCK_GetFreq:125MHZ
#define QTMR_SOURCE_CLOCK (CLOCK_GetFreq(kCLOCK_IpgClk) / QTMR_CLOCK_SOURCE_DIVIDER)
/* The frequency of the PWM signal QTMR generated. */
#define QTMR_PWM_OUTPUT_FREQUENCY (500U)
/* The dutycycle of the PTM signal QTMR generated. */
#define QTMR_DUTYCYCLE_PERCENT (50U)
/*DMA base address*/
#define DMA_MUX (DMAMUX)
#define EDMA (DMA0)
/*channel number*/
#define CAPTURE_DMA_CHANNEL (0U)
#define BUFF_LENTH 4U
#define SPI_LENTH 4U
#define ADC_BUFF_LENTH 1024U
//spi
#define EXAMPLE_LPSPI_MASTER_BASEADDR (LPSPI1)
/* Select USB1 PLL PFD0 (720 MHz) as lpspi clock source */
#define EXAMPLE_LPSPI_CLOCK_SOURCE_SELECT (1U)
/* Clock divider for master lpspi clock source */
#define EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER (7U)
/*SPI tx edma channel*/
#define EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL 1U
#define EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL 2U
/* Transfer baudrate - 10M */
#define TRANSFER_BAUDRATE 10000000U
#define LPSPI_MASTER_CLK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER + 1U))
#define TCD_QUEUE_SIZE 1U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
edma_handle_t g_EDMA_Handle_0;
edma_handle_t g_EDMA_Handle_1;
edma_handle_t g_EDMA_Handle_2;
volatile bool qtmrIsrFlag = false;
volatile bool g_Transfer_Done = false;
volatile bool g_Transfer_Done1 = false;
uint16_t captValue = 0;
edma_transfer_config_t transferConfig;
AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcdMemoryPoolPtr[TCD_QUEUE_SIZE + 1], sizeof(edma_tcd_t));
AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcdMemoryPoolPtr1[TCD_QUEUE_SIZE + 1], sizeof(edma_tcd_t));
AT_NONCACHEABLE_SECTION_ALIGN(edma_tcd_t tcdMemoryPoolPtr2[TCD_QUEUE_SIZE + 1], sizeof(edma_tcd_t));
AT_NONCACHEABLE_SECTION_INIT(lpspi_master_edma_handle_t g_m_edma_handle) = {0};
uint32_t disaddr[5*4] ={0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa};
uint32_t sendaddr[5*4] ={0};
/*******************************************************************************
* Code
******************************************************************************/
static int dma_count = 0;
lpspi_transfer_t masterXfer;
uint16_t adc_data[ADC_BUFF_LENTH] = {0};
void EDMA_Callback_0(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
int i;
if (transferDone)
{
////
g_Transfer_Done = true;
// adc_data[dma_count++] = ((sraddr[0] << 8) | sraddr[1]);
EDMA_InstallTCD(EDMA, CAPTURE_DMA_CHANNEL, tcdMemoryPoolPtr);
EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL, tcdMemoryPoolPtr1);
EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL, tcdMemoryPoolPtr2);
EDMA_EnableChannelRequest(EDMA, CAPTURE_DMA_CHANNEL);
}
}
void EDMA_Callback_1(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
int i;
if (transferDone)
{
// PRINTF("1111\r\n");
// g_Transfer_Done = true;
// EDMA_InstallTCD(EDMA, CAPTURE_DMA_CHANNEL, tcdMemoryPoolPtr);
// EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL, tcdMemoryPoolPtr1);
// EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL, tcdMemoryPoolPtr2);
// EDMA_EnableChannelRequest(EDMA, CAPTURE_DMA_CHANNEL);
}
}
void EDMA_Callback_2(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
int i;
if (transferDone)
{
// PRINTF("2222\r\n");
// g_Transfer_Done = true;
// EDMA_InstallTCD(EDMA, CAPTURE_DMA_CHANNEL, tcdMemoryPoolPtr);
// EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL, tcdMemoryPoolPtr1);
// EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL, tcdMemoryPoolPtr2);
// EDMA_EnableChannelRequest(EDMA, CAPTURE_DMA_CHANNEL);
}
}
/*!
* @brief Main function
*/
int main(void)
{
uint32_t srcClock_Hz;
qtmr_config_t qtmrConfig;
edma_config_t userConfig;
lpspi_master_config_t masterConfig;
uint16_t tmp;
int i;
/* Board pin, clock, debug console init */
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
/*Set clock source for LPSPI*/
CLOCK_SetMux(kCLOCK_LpspiMux, EXAMPLE_LPSPI_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_LpspiDiv, EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER);
/*Master config*/
LPSPI_MasterGetDefaultConfig(&masterConfig);
masterConfig.baudRate = TRANSFER_BAUDRATE;
masterConfig.whichPcs = kLPSPI_Pcs0;
masterConfig.cpha = 0;
masterConfig.cpol = 1;
masterConfig.direction = kLPSPI_MsbFirst;
masterConfig.bitsPerFrame = 32;
masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
srcClock_Hz = LPSPI_MASTER_CLK_FREQ;
LPSPI_MasterInit(EXAMPLE_LPSPI_MASTER_BASEADDR, &masterConfig, srcClock_Hz);
LPSPI_EnableDMA(EXAMPLE_LPSPI_MASTER_BASEADDR, (uint32_t)kLPSPI_TxDmaEnable|(uint32_t)kLPSPI_RxDmaEnable);
PRINTF("\r\n****Output PWM example.****\n");
PRINTF("\r\n*********Make sure to connect an oscilloscope.*********\n");
PRINTF("\r\n****A 50% duty cycle PWM wave is observed on an oscilloscope.****\n");
QTMR_GetDefaultConfig(&qtmrConfig);
/* Initial the output channel. */
qtmrConfig.primarySource = QTMR_PRIMARY_SOURCE;
QTMR_Init(BOARD_QTMR_BASEADDR, BOARD_QTMR_PWM_CHANNEL, &qtmrConfig);
/* Generate a 50Khz PWM signal with 50% dutycycle */
QTMR_SetupPwm(BOARD_QTMR_BASEADDR, BOARD_QTMR_PWM_CHANNEL, QTMR_PWM_OUTPUT_FREQUENCY, QTMR_DUTYCYCLE_PERCENT, false,
QTMR_SOURCE_CLOCK);
PRINTF("\r\n******Init capture dma.********\n");
QTMR_Init(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, &qtmrConfig);
/* Setup the input capture */
QTMR_SetupInputCapture(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, QTMR_CounterInputPin, false, true,
kQTMR_FallingEdge);
// /* Enable the input edge flag DMA*/
QTMR_EnableDma(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, kQTMR_InputEdgeFlagDmaEnable);
DMAMUX_Init(DMA_MUX);
/*Set dma channel 0 as input capture and enable*/
DMAMUX_SetSource(DMA_MUX, CAPTURE_DMA_CHANNEL, kDmaRequestMuxQTIMER2CaptTimer0);
DMAMUX_EnableChannel(DMA_MUX, CAPTURE_DMA_CHANNEL);
/*Set dma channel 1 as spi sending and enable*/
DMAMUX_SetSource(DMA_MUX, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL,kDmaRequestMuxLPSPI1Tx);
DMAMUX_EnableChannel(DMA_MUX, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL);
DMAMUX_SetSource(DMA_MUX, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL,kDmaRequestMuxLPSPI1Rx);
DMAMUX_EnableChannel(DMA_MUX, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL);
/* EDMA init */
/*
* userConfig.enableRoundRobinArbitration = false;
* userConfig.enableHaltOnError = true;
* userConfig.enableContinuousLinkMode = false;
* userConfig.enableDebugMode = false;
*/
EDMA_GetDefaultConfig(&userConfig);
EDMA_Init(EDMA, &userConfig);
EDMA_CreateHandle(&g_EDMA_Handle_0, EDMA,CAPTURE_DMA_CHANNEL);
EDMA_SetCallback(&g_EDMA_Handle_0, EDMA_Callback_0, NULL);
EDMA_ResetChannel(g_EDMA_Handle_0.base, g_EDMA_Handle_0.channel);
/*Configure dma channel 0*/
EDMA_PrepareTransfer(&transferConfig,
(uint16_t *)&BOARD_QTMR_BASEADDR->CHANNEL[0].CAPT, 2,
&tmp, 2, 2, BUFF_LENTH*2, kEDMA_PeripheralToMemory);
EDMA_TcdSetTransferConfig(tcdMemoryPoolPtr, &transferConfig, NULL);
EDMA_TcdSetChannelLink(tcdMemoryPoolPtr, kEDMA_MinorLink, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL);
EDMA_TcdEnableInterrupts(tcdMemoryPoolPtr, kEDMA_MajorInterruptEnable);
// EDMA_TcdEnableAutoStopRequest(tcdMemoryPoolPtr, true);
EDMA_InstallTCD(EDMA, CAPTURE_DMA_CHANNEL, tcdMemoryPoolPtr);
/*Configure dma channel 1*/
memset(&tcdMemoryPoolPtr1, 0, sizeof(edma_tcd_t));
EDMA_CreateHandle(&g_EDMA_Handle_1, EDMA,EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL);
EDMA_SetCallback(&g_EDMA_Handle_1, EDMA_Callback_1, NULL);
EDMA_ResetChannel(g_EDMA_Handle_1.base, g_EDMA_Handle_1.channel);
EDMA_PrepareTransfer(&transferConfig,
disaddr, 4,
(uint32_t *)&EXAMPLE_LPSPI_MASTER_BASEADDR->TDR, 4, 4*5, BUFF_LENTH*4*5, kEDMA_MemoryToPeripheral);
EDMA_TcdSetTransferConfig(tcdMemoryPoolPtr1, &transferConfig, NULL);
EDMA_TcdSetChannelLink(tcdMemoryPoolPtr1, kEDMA_MinorLink, 2);
// EDMA_TcdEnableInterrupts(tcdMemoryPoolPtr1, kEDMA_MajorInterruptEnable);
EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL, tcdMemoryPoolPtr1);
EDMA_CreateHandle(&g_EDMA_Handle_2, EDMA,EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL);
EDMA_SetCallback(&g_EDMA_Handle_2, EDMA_Callback_2, NULL);
EDMA_ResetChannel(g_EDMA_Handle_2.base, g_EDMA_Handle_2.channel);
EDMA_PrepareTransfer(&transferConfig,
(uint32_t *)&EXAMPLE_LPSPI_MASTER_BASEADDR->RDR, 4,
sendaddr, 4, 4*5, BUFF_LENTH*4*5, kEDMA_PeripheralToMemory);
EDMA_TcdSetTransferConfig(tcdMemoryPoolPtr2, &transferConfig, NULL);
// EDMA_TcdSetChannelLink(tcdMemoryPoolPtr2, kEDMA_MinorLink, 1);
// EDMA_TcdEnableInterrupts(tcdMemoryPoolPtr2, kEDMA_MajorInterruptEnable);
// EDMA_TcdEnableAutoStopRequest(tcdMemoryPoolPtr2, true);
EDMA_InstallTCD(EDMA, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL, tcdMemoryPoolPtr2);
/* Start the input capture channel to count on rising edge of the primary source clock */
QTMR_StartTimer(BOARD_QTMR_BASEADDR, BOARD_QTMR_INPUT_CAPTURE_CHANNEL, kQTMR_PriSrcRiseEdge);
EDMA_EnableChannelRequest(EDMA, CAPTURE_DMA_CHANNEL);
// EDMA_EnableChannelRequest(EDMA, EXAMPLE_LPSPI_MASTER_DMA_TX_CHANNEL);
// EDMA_EnableChannelRequest(EDMA, EXAMPLE_LPSPI_MASTER_DMA_RX_CHANNEL);
// /* Start the counter */
QTMR_StartTimer(BOARD_QTMR_BASEADDR, BOARD_QTMR_PWM_CHANNEL, kQTMR_PriSrcRiseEdge);
while (1)
{
// PRINTF("RDR:%d\r\n", EXAMPLE_LPSPI_MASTER_BASEADDR->RDR);
/* Wait for EDMA transfer finish */
while (g_Transfer_Done != true)
{
}
g_Transfer_Done = false;
// PRINTF("111\r\n");
// PRINTF("RDR:%d\r\n", EXAMPLE_LPSPI_MASTER_BASEADDR->RDR);
// for(i = 0; i < 4; i++)
// {
// PRINTF("\r\n%d:%x\n", i, sendaddr);
// }
// for(i = 0; i < BUFF_LENTH; i++)
// {
// sraddr = 0;
// }
// PRINTF("count:%d\r\n", dma_count);
// for(i = 0; i < ADC_BUFF_LENTH; i++)
// {
// PRINTF("%d\r\n", adc_data);
// }
}
}
|
|