主题中讨论的其他器件: ADS125H02、 HALCOGEN
我已将 SPI2配置为从器件、MIBSPI1配置为主器件、两者都使用 DMA。 当 MIBSPI1未被使用时、SPI2工作正常、但是当 MIBSPI1开始数据传输时、SPI2通信失败。 据我所见、DMA 缓冲区中的数据被移位了几位。
有3个 ADC 芯片连接到 MIBSPI 端口、MCU 以7.2K 的采样率从每个 ADC 芯片读取数据。 SPI2和 MIBSPI1分别使用 BTC 和 FTC DMA 中断。 我还更改了 sys_dma.c 中的 dmaFTCAInterrupt 函数、并在触发 FTC 中断时调用另一个函数。
另一件事是 SPI2的数据大小不是固定的。 它首先接收3个16位字作为标头。 此报头包含封装尺寸、然后 MCU 将 DMA 缓冲区尺寸更改为发送/接收报头中定义的字节数。
当 SPI2配置为 ISR 模式时、它在高达4MHz 的频率下正常工作。
#define CONFIG_SPI_TX_DMA_CH DMA_CH13
#define CONFIG_SPI_RX_DMA_CH DMA_CH12
#define CONFIG_SPI_TX_DMA_REQ 3ul
#define CONFIG_SPI_RX_DMA_REQ 2ul
#define CONFIG_SPI_HEADER_SIZE 3
#define CONFIG_SPI_PORT spiREG2
#define CONFIG_SPI_TX_ADDR ((uint32_t)(&(CONFIG_SPI_PORT->DAT1)) + 2)
#define CONFIG_SPI_RX_ADDR ((uint32_t)(&(CONFIG_SPI_PORT->BUF)) + 2)
void dmaConfigSPICtrlTxPacket(g_dmaCTRL * g_dmaCTRLPKT_TX, uint32 sadd, uint32 dadd, uint16 FrameCnt)
{
g_dmaCTRLPKT_TX->SADD = sadd; /* source address */
g_dmaCTRLPKT_TX->DADD = dadd; /* destination address */
g_dmaCTRLPKT_TX->CHCTRL = 0; /* channel control */
g_dmaCTRLPKT_TX->FRCNT = FrameCnt; /* frame count */
g_dmaCTRLPKT_TX->ELCNT = 1; /* element count */
g_dmaCTRLPKT_TX->ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT_TX->ELSOFFSET = 0; /* element source offset */
g_dmaCTRLPKT_TX->FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT_TX->FRSOFFSET = 0; /* frame source offset */
g_dmaCTRLPKT_TX->PORTASGN = 4; /* port b */
g_dmaCTRLPKT_TX->RDSIZE = ACCESS_16_BIT; /* read size */
g_dmaCTRLPKT_TX->WRSIZE = ACCESS_16_BIT; /* write size */
g_dmaCTRLPKT_TX->TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT_TX->ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT_TX->ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT_TX->AUTOINIT = AUTOINIT_ON; /* autoinit */
}
void dmaConfigSPICtrlRxPacket(g_dmaCTRL * g_dmaCTRLPKT_RX, uint32 sadd, uint32 dadd, uint16 FrameCnt)
{
g_dmaCTRLPKT_RX->SADD = sadd; /* source address */
g_dmaCTRLPKT_RX->DADD = dadd; /* destination address */
g_dmaCTRLPKT_RX->CHCTRL = 0; /* channel control */
g_dmaCTRLPKT_RX->FRCNT = FrameCnt; /* frame count */
g_dmaCTRLPKT_RX->ELCNT = 1; /* element count */
g_dmaCTRLPKT_RX->ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT_RX->ELSOFFSET = 0; /* element source offset */
g_dmaCTRLPKT_RX->FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT_RX->FRSOFFSET = 0; /* frame source offset */
g_dmaCTRLPKT_RX->PORTASGN = 4; /* port b */
g_dmaCTRLPKT_RX->RDSIZE = ACCESS_16_BIT; /* read size */
g_dmaCTRLPKT_RX->WRSIZE = ACCESS_16_BIT; /* write size */
g_dmaCTRLPKT_RX->TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT_RX->ADDMODERD = ADDR_FIXED; /* address mode read */
g_dmaCTRLPKT_RX->ADDMODEWR = ADDR_INC1; /* address mode write */
g_dmaCTRLPKT_RX->AUTOINIT = AUTOINIT_ON; /* autoinit */
}
void setConfigSPIDMA(void)
{
g_dmaCTRL g_dmaCTRLPKT;
dmaEnableInterrupt(CONFIG_SPI_RX_DMA_CH, BTC); //Block transfer complete
dmaReqAssign(CONFIG_SPI_RX_DMA_CH, CONFIG_SPI_RX_DMA_REQ); //SPI2 RX
dmaReqAssign(CONFIG_SPI_TX_DMA_CH, CONFIG_SPI_TX_DMA_REQ); //SPI2 TX
dmaConfigSPICtrlTxPacket(&g_dmaCTRLPKT, (uint32_t)&ResponseData, CONFIG_SPI_TX_ADDR, CONFIG_SPI_HEADER_SIZE);
dmaSetCtrlPacket(CONFIG_SPI_TX_DMA_CH, g_dmaCTRLPKT);
dmaConfigSPICtrlRxPacket(&g_dmaCTRLPKT, CONFIG_SPI_RX_ADDR, (uint32_t)&RX_Data.PacketArray, CONFIG_SPI_HEADER_SIZE);
dmaSetCtrlPacket(CONFIG_SPI_RX_DMA_CH, g_dmaCTRLPKT);
dmaSetChEnable(CONFIG_SPI_RX_DMA_CH, DMA_HW); //SPI2 RX, hardware triggering
dmaSetChEnable(CONFIG_SPI_TX_DMA_CH, DMA_HW); //SPI2 TX, hardware triggering
dmaSetPriority(CONFIG_SPI_RX_DMA_CH, HIGHPRIORITY);
dmaSetPriority(CONFIG_SPI_TX_DMA_CH, HIGHPRIORITY);
CONFIG_SPI_PORT->GCR1 = (CONFIG_SPI_PORT->GCR1 & 0xFFFFFFFFU) | (0x1 << 24); //Enable SPI
CONFIG_SPI_PORT->INT0 = (0x1 << 16); //SPI_DMAREQ; Enable DMA REQ only after setting the SPIEN bit to 1.
}
void sendAndGetSPIData(uint32_t outputBuffer, uint32_t inputBuffer, uint32_t ucDataLength)
{
dmaRAMREG->PCP[CONFIG_SPI_TX_DMA_CH].ISADDR = outputBuffer;
dmaRAMREG->PCP[CONFIG_SPI_TX_DMA_CH].IDADDR = CONFIG_SPI_TX_ADDR;
dmaRAMREG->PCP[CONFIG_SPI_TX_DMA_CH].ITCOUNT = (ucDataLength << 16U) | 1;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].IDADDR = inputBuffer;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ISADDR = CONFIG_SPI_RX_ADDR;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ITCOUNT = (ucDataLength << 16U) | 1;
dmaSetChEnable(CONFIG_SPI_RX_DMA_CH, DMA_HW); //SPI2 RX, hardware triggering
dmaSetChEnable(CONFIG_SPI_TX_DMA_CH, DMA_HW); //SPI2 TX, hardware triggering
CONFIG_SPI_PORT->GCR1 = (CONFIG_SPI_PORT->GCR1 & 0xFFFFFFFFU) | (0x1 << 24); //Enable SPI
CONFIG_SPI_PORT->INT0 = (0x1 << 16); //SPI_DMAREQ; Enable DMA REQ only after setting the SPIEN bit to 1.
while((dmaREG->PEND & (1ul << 0)) != 0ul);
}
void getConfigSPIData(uint32_t buffer, uint32_t ucDataLength)
{
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].IDADDR = buffer;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ISADDR = CONFIG_SPI_RX_ADDR;
dmaRAMREG->PCP[CONFIG_SPI_RX_DMA_CH].ITCOUNT = (ucDataLength << 16U) | 1;
dmaSetChEnable(CONFIG_SPI_RX_DMA_CH, DMA_HW); //SPI2 RX, hardware triggering
dmaSetChEnable(CONFIG_SPI_TX_DMA_CH, DMA_HW); //SPI2 TX, hardware triggering
CONFIG_SPI_PORT->GCR1 = (CONFIG_SPI_PORT->GCR1 & 0xFFFFFFFFU) | (0x1 << 24); //Enable SPI
CONFIG_SPI_PORT->INT0 = (0x1 << 16); //SPI_DMAREQ; Enable DMA REQ only after setting the SPIEN bit to 1.
while((dmaREG->PEND & (1ul << 0)) != 0ul);
}
void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
{
CONFIG_SPI_PORT->INT0 &= ~(1ul << 16);
CONFIG_SPI_PORT->GCR1 &= ~(0x1 << 24);
ProcessSPI2();
}
void dmaFTCAInterrupt(void)
{
uint32 offset = dmaREG->FTCAOFFSET;
if (offset != 0U)
{
dmaGroupANotificationFTC(FTC, offset - 1U);
}
}
void dmaBTCAInterrupt(void)
{
uint32 offset = dmaREG->BTCAOFFSET;
if (offset != 0U)
{
dmaGroupANotification(BTC, offset - 1U);
}
}


