This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP432P401R:由外部 ADC 数据触发的 DMAE0外部触发准备就绪(&T);SPI 启动

Guru**** 2345010 points
Other Parts Discussed in Thread: ADS131A02
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/704661/msp432p401r-dmae0-external-trigger-by-external-adc-data-ready---spi-starts

器件型号:MSP432P401R

您好!

我正在尝试获取外部 DMA 触发器以使用 SPI 读取 ADC 数据。

那么、这就是我要尝试执行的操作。 我正在使用 ADS131A02、并希望通过 MSP432上的 SPI 读取32位值。

ADS131A02的 DRDY 引脚连接到 MSP432的 P7.0。 该端口配置为 PM_DMAE0。

每次 ADC 具有新值时、外部 DMA 都应触发 DMA 写入 SPI TX 缓冲区、512个事务后、DMA RX 应触发中断来唤醒 MSP432。

此时 DMAE0正在工作、并触发 DMA TX、将值写入 SPI TX 缓冲区。 这只能运行一次、下一个 DMAE0中断被忽略。

这是我的代码:

include "ADS131A02.h"

#include 

/* DMA 控制表*/
#ifdef ewarm
#pragma DATA_ALIGNing=256
#else
#pragma DATA_ALIGN (controlTable、256)
#endif
uint8_t controlTable[256];
uint8_t DMA_recBuffer[9];
uint8_t DMA_recBuffer[9];uint8_length







= 0x000_translation_reatile、0x000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000

GPIO_setAsOutputPin (GPIO_PORT_P3、GPIO_PIN0);
GPIO_setAsOutputPin (GPIO_PORT_P3、GPIO_PIN6);
GPIO_setAsInputPinWithPullUpResistor (GPIO_PORT_P7、GPIO_PIN0);

GPIO_setOutputHighOnPin (GPIO_PORT_P3、GPIO_PIN0); // CS 禁用
GPIO_setOutputHighOnPin (GPIO_PORT_P3、GPIO_PIN6); //重置禁用

// SPI 主配置参数
const eUSCI_SPI_MasterConfig spiMasterConfig =
{
EUSCI_A_SPI_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
48000000、 // SMCLK = HFXT = 48Mhz
24000000、 // SPICLK =12000000
EUSCI_A_SPI_MSB_FIRST、 // MSB 优先
EUSCI_SPI_PHASE_DATA_Changed_ONFIRST_captured_on_next、 //相位 EUSCI_SPI_PHASE_DATA_Changed_ONFIRST_Capted_on_next / EUSCI_SPI_PHASE_DATA_Capted_ONFIRST_Changed_on_next
EUSCI_A_SPI_CLOCKPOLARITY_INACT_LOW、 //高极性
EUSCI_A_SPI_3引脚

};

/*在 SPI 模式下选择 P1.5 P1.6和 P1.7 */
GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P1、GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7、GPIO_PRIMARY_MODULE_FUNCTION);

//在 DMAE0中选择引脚7.0
GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P7、GPIO_PIN0、GPIO_PRIMARY_MODULE_Function);

/*在3线主控模式下配置 SPI */
SPI_initMaster (EUSCI_B0_BASE、&spiMasterConfig);
SPI_enableModule (USCI_B0_BASE);

/*启用中断*/
GPIO_clearInterruptFlag (GPIO_PORT_P7、GPIO_PIN0);
GPIO_enableInterrupt (GPIO_PORT_P7、GPIO_PIN0);
GPIO_interruptEdgeSelect (GPIO_PORT_P7、GPIO_PIN0、GPIO_LOW_TO_HIGH_TRANSITION);
//中断_enableInterrupt (INT_PORT7);
SPI_clearInterruptFlag (EUSCI_B0_BASE、EUSCI_B_SPI_Transmit _INTERRUPT);

}


void ADS131A02_DMASetup (void)
{

//将 DMA 分配给 SPI 通道
DMA_enableModule();
DMA_setControlBase (controlTable);


DMA_assignChannel (DMA_CH0_EUSCIB0TX0);
DMA_assignChannel (DMA_CH1_EUSCIB0RX0);
DMA_assignChannel (DMA_CH6_EXTERNALPIN);

dma_disableChannelAttribute (dma_CH6_EXTERNALPIN、Udma_attr_ALTSELECT | Udma_attr_USEBURST | Udma_attr_high_priority | Udma_attr_REQMASK);

//设置 TX 传输特性和缓冲区
DMA_setChannelControl (DMA_CH6_EXTERNALPIN | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer (DMA_CH6_EXTERNALPIN | UDMA_PRI_SELECT、UDMA_MODE_BASIC、DATA_ARRAY、(void *) MAP_SPI_getTransmitBufferAddressForDMA (EUSCI_B0_BASE)、1);

DMA_setChannelControl (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
DMA_setChannelTransfer (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT、UDMA_MODE_BASIC、DATA_ARRAY、(void *) MAP_SPI_getTransmitBufferAddressForDMA (EUSCI_B0_BASE)、512);

DMA_setChannelControl (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT、UDMA_MODE_PINGONG、(void *) MAP_SPI_getReceiveBufferAddressForDMA (EUSCI_B0_BASE)、DATA_array1、512);

DMA_setChannelControl (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT、UDMA_MODE_PINGONG、(void *) MAP_SPI_getReceiveBufferAddressForDMA (EUSCI_B0_BASE)、DATA_ARRAY2、512);

DMA_assignInterrupt (DMA_INT1、1);
DMA_clearInterruptFlag (INT_DMA_INT1);
DMA_clearInterruptFlag (1);

INTERRUPT_enableInterrupt (DMA_INT1);
interrupt_enableMaster();
DMA_enableChannel (6);
DMA_enableChannel (0);
DMA_enableChannel (1);
}


void DMA_INT1_IRQHandler (void)
{
DMA_clearInterruptFlag (1);
/*使用 DMA 的交替模式在主缓冲器和备用缓冲器之间切换*/
IF (DMA_getChannelAttribute (1)& UDMA_ATTR_ALTSELECT)
{
DMA_setChannelControl (UDMA_PRI_SELECT | DMA_CH1_EUSCIB0RX0、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer (UDMA_PRI_SELECT | DMA_CH1_EUSCIB0RX0、UDMA_MODE_PINGONG、(void*) MAP_SPI_getReceiveBufferAddressForDMA (EUSCI_B0_BASE)、DATA_array1、SAMPLE_LENGTH);
switch_data = 1;
}
其他
{
DMA_setChannelControl (UDMA_ALT_SELECT | DMA_CH1_EUSCIB0RX0、UDMA_SIZE 8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
DMA_setChannelTransfer (UDMA_ALT_SELECT | DMA_CH1_EUSCIB0RX0、UDMA_MODE_PINGONG、(void*) MAP_SPI_getReceiveBufferAddressForDMA (EUSCI_B0_BASE)、DATA_ARRAY2、SAMPLE_LENGTH);
switch_data = 0;
}
}

DMAE0触发 SPI TX、SPI 将向 ADC 写入511次。 我将获得512个值的 DMA RX 中断、然后更改 pingpong 缓冲区。

之后没有其他事情发生。  

如果我将 SPI TX 从512字节更改为4字节、则 SPI 仅发送4字节、而不会发生任何其他情况。 为什么在发生新的 DMAE0触发后 TX DMA 不会写入 SPI TX?

我是否必须重新配置 DMA TX?  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Michael、

    在 DMA 设置的函数中、您将使用 API 的 DMA_setChannelControl 和 DMA_setChannelTransfer 配置主通道两次。 相反、您需要为主通道配置一次、为备用通道配置一次。

    DMA_setChannelControl (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
    DMA_setChannelTransfer (DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT、UDMA_MODE_PINGONG、(void *) MAP_SPI_getReceiveBufferAddressForDMA (EUSCI_B0_BASE)、DATA_array1、512);

    DMA_setChannelControl (DMA_CH1_EUSCIB0RX0 | UDMA_ALT_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
    DMA_setChannelTransfer (DMA_CH1_EUSCIB0RX0 | UDMA_ALT_SELECT、UDMA_MODE_PINGONG、(void *) MAP_SPI_getReceiveBufferAddressForDMA (EUSCI_B0_BASE)、DATA_ARRAY2、512);
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我这里没有我的材料(我对 driverlib 的描述不是很好)、但是:DMAE0只是启用 SPI (Tx) DMA、还是直接写入(SPI) TXBUF?

    我问、因为我很确定 DMA 会"消耗"驱动它前进的 TXIFG、所以在 DMA 序列后它可能会保留为0。 在这种情况下、仅启用 SPI DMA 不会启动(第二次)、但直接写入 TXBUF 将重新启动级联。 进入此状态时,您可能需要浏览寄存器->USCIB0->UCBIFG。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Amit、您好!

    谢谢。 但该配置会发送512个字节来读取 ADC。 我只需要4个、因此我更改了以下内容:

    //设置 TX 传输特性和缓冲区
    dma_setChannelControl (dma_CH6_EXTERNALPIN | Udma_PRI_SELECT、Udma_SIZE_8 | Udma_SRC_NONE | Udma_dst_spi_none | Udma_translation_dma_dma_translation_dma_dma_translation_dma_dma_translation_dma_dma_dma_translation_rand_detdma_dma_dma_translation_rand_detdma_dma_dma_translation_rand_dateltatel0
    
    
    | Udma_dma_dma_dma_dma_dma_dma_dma_tas_dma_translect_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_translect_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma_dma 

    现在的问题是、每次 DMAE0触发、SPI TX 都会发送4个字节、我必须再次重新配置 DMA。 因此、我实现了这样的中断、以便在每次 TX 完成时重新配置 DMA:

    void dma_int2_IRQHandler (void)
    {
    ADS131A02_CS_Enable();
    DMA_clearInterruptFlag (INT_DMA_INT2);
    
    //设置 TX 传输特性和缓冲区
    DMA_setChannelControl (DMA_CH6_EXTERNALPIN | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE | UDMA_ARB_1);
    DMA_setChannelTransfer (DMA_CH6_EXTERNALPIN | UDMA_PRI_SELECT、UDMA_MODE_BASIC、DATA_ARRAY、(void *) MAP_SPI_getTransmitBufferAddressForDMA (EUSCI_B0_BASE)、1);
    
    DMA_setChannelControl (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT、UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    DMA_setChannelTransfer (DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT、UDMA_MODE_BASIC、DATA_ARRAY、(void *) MAP_SPI_getTransmitBufferAddressForDMA (EUSCI_B0_BASE)、3);
    
    DMA_enableChannel (0);
    DMA_enableChannel (6);
    }
    

    那么、有没有办法可以避免这种情况、还是唯一的办法?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Michael、

    有一种更复杂的外设散聚方法可以自行重新初始化。 但是、相同方法的问题是不会直接生成任何中断。 您需要通过 DMA 切换 IO 以生成 IO 中断。

    请参阅适用于 MSP432P4的 SDK 中的以下示例

    C:\ti\simplelink_msp432p4_sdk_2_20_00_12\examples\nortos\MSP_EXP432P401R\demos\CMSIS_DSPLib_ULP
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Amit、您好!

    外部触发器 DMAE0实际上并不能满足我的需求。
    我现在转到 GPIO 中断、在这里我将 DMA 设置为 TX。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Michael、

    您能否共享为 DMA 的外部触发器所做的配置。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Amit、您好!

    源代码位于第一个问题中。
    外部 DMA 仅发出一个 TX、并触发 DMA SPI TX 以发送更多 TX。
    这需要太长时间。 将简单 GPIO 作为输入中断来设置/CS 和启用 SPI TX DMA 的速度更快。
    我需要读取48kHz 样本、MSP432无法使用外部 DMAE0进行处理。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Michael、
    我认为您看到的问题在以下位置进行了说明: e2e.ti.com/.../1888708 。 GPIO 听起来像更好的实现方式以及定时器捕捉的使用。

    此致、
    Chris