Hi,
we use an IMU sensor communicating via the MiBSPI interface.
The sensor "sample ready" output is connected to GPIOA0 configured as an interrupt input.
When I write/read the sensor manually it works (getting correct data) but I'm getting corrupt data when I use the
SPI interrupt and a TG trigger source (for sending the command to the sensor).
======================================================
Manually
mibspiSetData(mibSpiReg, 0U, burstReadCmd);
mibspiTransfer(mibSpiReg, 0U);
while (mibspiIsTransferComplete(mibSpiReg, 0U) == false)
{
}
mibspiGetData(mibSpiReg, 0U, (uint16 *) rcvBuf);
The rcvBuf holds correct X,Y,Z acc and gyro values.
======================================================
Auto
////////////////////////////////////////////////
// void mibspiInit(void)
<other MiBSPI setup>
/** enable MIBSPI1 multibuffered mode and enable buffer RAM */
mibspiREG1->MIBSPIE = (mibspiREG1->MIBSPIE & 0xFFFFFFFEU) | 1U;
<snip>
/** - initialize transfer groups */
mibspiREG1->TGCTRL[0U] =
(uint32)((uint32)1U << 31U) /* TG transfer enable. Tx when trigger source */
| (uint32)((uint32)0U << 30U) /* no oneshot */
| (uint32)((uint32)0U << 29U) /* pcurrent reset */
| (uint32)((uint32)TRG_RISING << 20U) /* trigger event */
| (uint32)((uint32)TRG_GIOA0 << 16U) /* trigger source */
| (uint32)((uint32)0U << 8U); /* start buffer */
<snip>
mibspiRAM1->tx[i].control =
/* Using this I don't get overrun but corrupt data anyway */
// (uint16)((uint16)5U << 13U) /* buffer mode */
/* Using this I get overrun and corrupt data */
(uint16)((uint16)4U << 13U) /* buffer mode */
| (uint16)((uint16)1U << 12U) /* chip select hold */
| (uint16)((uint16)0U << 10U) /* enable WDELAY */
| (uint16)((uint16)0U << 11U) /* lock transmission */
| (uint16)((uint16)0U << 8U) /* data format */
/*SAFETYMCUSW 334 S MR:10.5 <APPROVED> "LDRA Tool issue" */
| ((uint16)(~((uint16)0xFFU ^ (uint16)CS_0)) & (uint16)0x00FFU); /* chip select */
<snip>
////////////////////////////////////////////////
// Code that is run after mibspiInit()
mibspiSetData(mibspiREG1, 0U, burstReadCmd);
mibspiEnableGroupNotification(mibspiREG1, 0U, 0U);
////////////////////////////////////////////////
// void mibspi1HighLevelInterrupt(void)
// I get the interrupt and the FLG.TXINTFLG is 1
uint32 mibspiFlags = (mibspiREG1->FLG & 0x0000FFFFU) & (~mibspiREG1->LVL & 0x035FU);
uint32 vec = mibspiREG1->INTVECT0;
if (vec > 0x21U)
{
// Error
mibspiREG1->FLG = (mibspiREG1->FLG & 0xFFFF0000U) | mibspiFlags;
mibspiNotification(mibspiREG1, mibspiFlags & 0xFFU);
}
else
{
// vec == 2 -> INT0
// The TGINTFLG.INTFLGRDY is NOT 0x00010000 (TG0)
if(((((mibspiREG1->TGINTFLG & 0xFFFF0000U) >> 16U) >> 0U /*group*/) & 1U) == 1U)
{
I NEVER GET HERE! IT SEEMS THE INTERRUPT IS FIRED ON THE FIRST WORD TRANSMITTED?
(EXCEPT IF I PUT A BREAKPOINT AT THE "IF" LINE ABOVE AND THEN STEP, BUT THE DATA IS THE SAME CORRUPT DATA)
mibspiREG1->TGINTFLG = (mibspiREG1->TGINTFLG & 0x0000FFFFU) | ((uint32)((uint32) 1U << 0U /*group*/) << 16U);
mibspiGetData(mibspiREG1, 0U, (uint16 *) rcvBuf);
}
IF I READ THE BUFFER IGNORING TGINTFLG IT'S CORRUPT DATA
mibspiGetData(mibspiREG1, 0U, (uint16 *) rcvBuf);
// mibspiSetData(mibspiREG1, 0U, burstReadCmd); // lvw123
// mibspiTransfer(mibspiREG1, 0U);
}
If you can help us soon we would be very thankful since we are working on a prototype which will be demonstrated soon.
We need this fast and self-going SPI <-> sensor communication since we do not want to waste processor time.
Best regards,
Lars von Wachenfeldt
Bombardier Transportation