Other Parts Discussed in Thread: TCAN4550
Hi,
a customer is using the TCAN4550 with the RM57L843 and is setting up multiple TGs with multiple buffers. The TGs are configured as one-shot. What we are finding is that the last TG points back to the first TG, but even though the TGs are configured as ONESHOT, the Mib-SPI does not stop and loops back to the first TG and so on.
As a workaround the customer is implementing a dummy TG, which is never enabled or initiated. The previous to last TG points to the dummy. With this the ONESHOT sequence of TGs stop at the last one.
Is this a known issue or behavior?
Is the workaround correct?
Thanks,
--Gunter
p.s. here is a snippet of code for the Mib-SPI configuration as reference:
/* Configure multi-buffer, if using */
if (settings->useMib) {
spiDataCtx[bus].useMib = true;
spiReg->MIBSPIE |= SPI_MIBSPIE_ENABLE;
/* Wait for auto initialization of multi-buffer RAM to complete */
uint32_t timeout = SPI_BUFINIT_ACTIVE_TIMEOUT;
while ((spiReg->FLG & SPI_FLG_BUFINITACTIVE) && (--timeout > 0)) {
/* wait */
}
if ((spiReg->FLG & SPI_FLG_BUFINITACTIVE) && (timeout == 0)) {
return DEX_ERR_TIMEOUT;
}
spiDataCtx[bus].numTGs = settings->mibSettings->numTGs;
/* Configure Transfer Groups */
uint8_t bufferCount = 0;
for (uint8_t tg = 0; tg < settings->mibSettings->numTGs; ++tg) {
uint32_t oneShot = (settings->mibSettings->tgConfigs[tg].oneShot)
? SPI_TGCTRL_ONESHOT_ENABLE
: SPI_TGCTRL_ONESHOT_DISABLE;
uint32_t pReset = (settings->mibSettings->tgConfigs[tg].pointerReset)
? SPI_TGCTRL_PRST_ENABLE
: SPI_TGCTRL_PRST_DISABLE;
uint32_t trigEvt = (uint32_t)(settings->mibSettings->tgConfigs[tg].triggerEvent << SPI_TGCTRL_TRIG_EVT_SHIFT);
uint32_t trigSrc = (uint32_t)(settings->mibSettings->tgConfigs[tg].triggerSource << SPI_TGCTRL_TRIG_SRC_SHIFT);
uint32_t startBuf = (uint32_t)(bufferCount << SPI_TGCTRL_PSTART_SHIFT);
bufferCount = bufferCount + settings->mibSettings->tgConfigs[tg].numBuffers;
spiReg->TGCTRL[tg] = oneShot | pReset | trigEvt | trigSrc | startBuf;
}
/* Set end pointer for last TG buffer */
spiReg->LTGPEND = (uint32_t)((bufferCount - 1) << SPI_LTGPEND_LPEND_SHIFT);
MibSpiRam_t *mibRam = SpiGetMibRam(spiReg);
bufferCount = 0;
/* Configure Multi-buffer RAM */
for (uint8_t tg = 0; tg < settings->mibSettings->numTGs; ++tg) {
for (uint8_t buf = 0; buf < settings->mibSettings->tgConfigs[tg].numBuffers; ++buf) {
/* Configure ram settings for this buffer */
mibRam->tx[bufferCount + buf].control = (uint16_t)SPI_TX_RAM_BUFMODE_CONTINUOUS |
(uint16_t)SPI_TX_RAM_WDEL_DISABLE |
(uint16_t)SPI_TX_RAM_DFSEL_0 |
(uint16_t)SpiGetCSNR(settings->chipSelect);
if (buf == settings->mibSettings->tgConfigs[tg].numBuffers - 1) {
/* Release chip select in last buffer and remove lock*/
mibRam->tx[bufferCount + buf].control |= (uint16_t)SPI_TX_RAM_CSHOLD_DISABLE;
mibRam->tx[bufferCount + buf].control |= (uint16_t)SPI_TX_RAM_LOCK_DISABLE;
} else {
/* Hold chip select active and lock operation */
mibRam->tx[bufferCount + buf].control |= (uint16_t)SPI_TX_RAM_CSHOLD_ENABLE;
mibRam->tx[bufferCount + buf].control |= (uint16_t)SPI_TX_RAM_LOCK_ENABLE;
}
}
bufferCount = bufferCount + settings->mibSettings->tgConfigs[tg].numBuffers;
}
for (uint8_t tg = 0; tg < settings->mibSettings->numTGs; ++tg) {
/* Set TG Complete and Suspended interrupts to Level/INT 0 */
spiReg->TGITLVCR |= (uint32_t)((1 << tg) << SPI_TGITLVST_COMPLETE_SHIFT);
spiReg->TGITLVCR |= (uint32_t)((1 << tg) << SPI_TGITLVST_SUSPEND_SHIFT);
/* Enable TG Complete and Suspended interrupts */
spiReg->TGITENST |= (uint32_t)((1 << tg) << SPI_TGITENST_COMPLETE_SHIFT);
spiReg->TGITENST |= (uint32_t)((1 << tg) << SPI_TGITENST_SUSPEND_SHIFT);
}
}