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.

[参考译文] MSP432E401Y:如何严格控制从 ADC 传输的 QSSI DMA 数据的时序?

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/876400/msp432e401y-method-for-tightly-controlling-timing-of-qssi-dma-data-transfer-from-adc

器件型号:MSP432E401Y
主题中讨论的其他器件:ADS8910B

我们使用 MSP432E401Y 连接 TI ADS8910B ADC、并尝试采样@ 1MSPS。 我们将 QSSI 与 ADS8910B 一起在四路数据模式下使用。 ADC CONVST 信号连接到 MSP432上的 PWM 引脚、运行周期为1us。 在每个转换周期后、我们都将硬件中断设置为该 PWM 信号的最高优先级、以便从 ADC 读取数据。  

我们能够使 QSSI 接口在不使用 DMA 的情况下工作@ 500kSPS (2us PWM 间隔)。 然而、在1us 采样时、我们的时序变得更加关键、我们决定使用 UDMA 来处理来自 ADC 的 QSSI 数据传输。  

从 ADS8910B 数据表中可以看出、在 CONVST 上升沿之前30ns 和之后20ns 的窗口中、数字信号无法切换。 这是 ADC 对输入信号进行采样的时间、在此期间切换的数字信号可能会将噪声耦合到正在进行的转换中。 由于这一要求、我们需要对 QSSI 数据传输发生的时间进行严格的时序控制。 请参阅下面的 SSI DMA 初始化和 PWM IRQ 处理程序代码以了解我们当前的实现:

void initSSIuDMA (void)
{
MAP_SysCtlPeripheralEnable (SYSCTL_Periph_UDMA);
map_uDMAEnable();

map_uDMAControlBaseSet (pui8ControlTable);

//从 udma_demo.c 中提取并仅针对 SSI2 RX 进行修改
MAP_SSIDMAEnable (SSI2_base、SSI_DMA_RX | SSI_DMA_TX);

MAP_uDMAChannelAttributeDisable (UDMA_CH12_SSI2RX、
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);

//启用以保持数据流动
MAP_uDMAChannelAttributeEnable (UDMA_CH12_SSI2RX、UDMA_ATTR_USEBURST);

MAP_uDMAChannelControlSet (UDMA_CH12_SSI2RX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_1 | UDMA_NEW_USEBURST);

MAP_uDMAChannelTransferSet (UDMA_CH12_SSI2RX | UDMA_PRI_SELECT、
UDMA_MODE_BASIC、
(空*)(&SSI2->DR)、
Receive_data、3);


MAP_uDMAChannelAttributeDisable (UDMA_CH13_SSI2TX、
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIOR|
UDMA_ATTR_REQMASK);

//启用以保持数据流动
MAP_uDMAChannelAttributeEnable (UDMA_CH13_SSI2TX、UDMA_ATTR_USEBURST);

MAP_uDMAChannelControlSet (UDMA_CH13_SSI2TX | UDMA_PRI_SELECT、
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_1 | UDMA_NEW_USEBURST);

MAP_uDMAChannelTransferSet (UDMA_CH13_SSI2TX | UDMA_PRI_SELECT、
UDMA_MODE_BASIC、
SEND_DATA、
(void *)(&SSI2->DR)、3);

MAP_uDMAChannelAssign (UDMA_CH12_SSI2RX);
MAP_uDMAChannelEnable (UDMA_CH12_SSI2RX);

MAP_uDMAChannelAssign (UDMA_CH13_SSI2TX);
MAP_uDMAChannelEnable (UDMA_CH13_SSI2TX);
} 

void PWM0_0_IRQHandler (UARg 参数)
{
// PWM 中的时序 INT:340ns
// GPIOP->data |= 0x01;

//获取中断状态
getIntStatus = HWREG (PWM0_ADDR + PWM_O_X_ISC);

//清除 FSSHLD 以使 CS 无效
HWREG (SSI2_base + SSI_O_CR1)&=~(SSI_CR1_FSSHLDFRM);

reads[buff ->writeIndex+]=(receive_data[2]<< 16)|(receive_data[1]<< 8)|(receive_data[0]);
//以下行执行下面注释的 if 语句代码。 这可以在380ns 至340ns 范围内节省10%的时间
//参考:swrp146"使用 MSP432讲座进行软件设计"
buff ->writeIndex =((((((((((()->size == buff ->writeIndex )<<31 )>> 31)&0)|((((((!(buff ->size == buff ->writeIndex )<<31 )>1)&buff ->writeIndex);
// if (buff ->writeIndex>/)

bux->writeIndex = 0;
//}

//为下一个事务重置 DMA
pui8ControlTable[216]= 0x29;// TX
pui8ControlTable[200]= 0x29;// RX
HWREG (UDMA_ENASET)= 0x3000;//重新启用这两个

//清除中断
HWREG (PWM0_ADDR + PWM_O_X_ISC)= getIntStatus;

//将 FSSHLD 设置为使整个数据传输帧的 CS 有效
HWREG (SSI2_base + SSI_O_CR1)|= SSI_CR1_FSSHLDFRM;

// GPIOP->DATA &&~(0x01);
} 

在上述实现中、控制 QSSI 数据传输的时序时遇到问题。 请参阅以下示波器捕获、了解使用上述代码的 QSSI 信号的时序。 QSSI 数据传输发生在转换周期的末尾、切换过于接近下一个 CONVST 上升沿的开始、因此我们违反了 ADS8910B 规范。

在 PWM 中断中复位 DMA 后、QSSI 控制器和 DMA 控制器接管并完成数据传输。 我已经尝试移动中断内复位 DMA 的3行代码、但这并没有产生兼容的时序、 在最坏的情况下、如果我将复位移到中断处理程序的顶部附近、则某些转换周期不会发生数据传输。

我遇到的另一个问题是 CS 信号。 我们希望 CS 信号在传输开始时(当 CLK 开始切换时)置为低电平、并在传输完成后立即取消置为高电平。 当我们在没有 DMA 的情况下实现 QSSI 时、这不是一个问题、但是对于 DMA、我们一直很难让 CS 按照我们想要的方式运行。 当 FFSHLDFRM = 1时、CS 信号为恒定低电平。 当 FSSHLDFRM = 0时、CS 信号在传输的每个字节之间失效(参见下面的捕捉):

我们使用的权变措施是设置和清除 PWM 中断中的 FSSHLDFRM 位。 我在 FSSHLDFRM = 1的情况下尝试设置 SSICR1中的 EOM 位、但成功的机会有限、因为我不能完全确定 DMA 何时完成数据传输。  

关于这个问题,我有两个主要问题:

  1. 是否有办法可以更好地控制使用 DMA 进行的 QSSI 数据传输?
  2. 是否有办法控制 CS 信号、以便在数据传输开始时将其置为低电平、并在数据传输结束后立即取消置位?

我们已经考虑过使用 QSSI 中断来判断数据传输何时完成、但我们的时序预算对于1us 采样非常严格、我认为我们没有足够的时序裕度来处理另一个中断。 PWM 中断的中断延迟+中断服务时间为700ns、不包括中断终止时间、因此 PWM 中断占用了70%以上的 CPU 时间。  

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

    您好、Michael、

    我将深入研究这一点、并在下周结束前再次与您进行讨论。

    谢谢、

    Alexis

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

    您好、Michael、

    因此、看起来您必须使用 EOT 和 EOM 位。 从 TRM 中的第23.3.3节可以看到、

    "当数据首次写入 TX FIFO 时、SSInFss 将置为低电平、表示帧开始。 在 EOT 上、TX FIFO 中最后一个数据单元的第12位表示一个帧是否结束。 当 EOM 位为1时、表示报文结束(EOM 或 STOP 帧)、SSInFss 随后强制拉高。 在完成对 TXFIFO 的写操作的同时、SSICR1寄存器的 EOM 位也将清零。 EOM 位值为0表示发送无变化。 如果 TX FIFO 被清空并且 SSInFSS 仍然置为低电平、则它保持低电平、但 SSInCLK 不会脉冲。 同样、如果在 TX FIFO 为空时 SSInFss 为高电平、则它将保持高电平。"  


    FSSHLDFRM 需要设置为1。  

    谢谢、

    Alexis

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

    您好、Alexis、

    感谢您能就这个问题再次与我取得合作。 我确实认为使用 EOT 和 EOM 位是在 FSSHLDFRM = 1时控制 CS 信号的正确方法、但是由于 DMA 正在控制传输、所以我在中断中设置/清除这些位的确切位置上遇到了一些问题。 在进一步审查之后、我怀疑唯一正确实现这一目标的方法是使用 DMA 中断来指示传输完成、否则我们不知道传输何时完成。  

    我们尝试避免添加另一个中断、因为我们以1us 的间隔为 ADC 提供服务的硬件中断当前占用了~70%的 MCU 处理时间、剩下的~30%不足以处理我们询问 MCU 的所有其他任务。 此后、我们已停止尝试在此 MCU 上推送1us 采样、并正在评估多核和更快的 MCU 选项、以便我们可以有一个专用于以1us 的间隔服务 ADC 的内核。

    谢谢、

    Mike