This is a dsPIC33FJ12MC201 (should that be relevant). I'm running a test that returns amongst other things the position of a servo motor which is controlled by the PIC running as an SPI slave.
The SPI data (MISO) sent in response to the first of a sequence of 0xEBEB (Request_PID_Tune) messages should(for this test) always have the value 0x0046 - like this LA trace fragment:
Time [s],Packet ID,MOSI,MISO
4.836107562500000,0,0xEBEB,0x3004 <== response to previous message from master
4.836192937500000,0,0xEBEB,0x0046 <== response to 1st 0xEBEB
4.836286250000000,0,0xEBEB,0x9DEE
4.836379625000000,0,0xEBEB,0x02C9
4.836475687500000,0,0xEBEB,0x01C7
4.836569000000000,0,0xFFFF,0x00A5
Sometimes however I get this:
Time [s],Packet ID,MOSI,MISO
4.839946000000000,0,0xEBEB,0x11EE
4.840031312500000,0,0xEBEB,0x11EE <== WHAT ON EARTH?
4.840127375000000,0,0xEBEB,0x9EAD
4.840220750000000,0,0xEBEB,0x02B0
4.840314062500000,0,0xEBEB,0x01D3
4.840407437500000,0,0xFFFF,0x00A3
My code is simple enough:
//==============================================================================
// SPI1 Interrupt data has been received.
//==============================================================================
void _ISR _SPI1Interrupt(void)
{
uint16_t reply = 0; // Reply
:
static uint8_t pidState = 0;
:
SPI_Received = SPI1BUF; // Read SPI input into buffer
:
if (Request_PID_Tune == SPI_Received)
{
switch(pidState)
{
case (0): // First PID tune msg received
pollPosCount = posCount; // Save position counter
reply = (pollPosCount & 0xFFFF0000) >> 16;
++pidState;
break;
case (1):
reply = pollPosCount & 0x0000FFFF;
++pidState;
break;
case (2):
reply = PWM_Output;
++pidState;
break;
case (3):
reply = currentSpeed;
++pidState;
break;
case (4):
reply = speedPID;
blockLoop = false;
pidState = 0;
break;
}
:
:
}
//
// Wait for the transmit buffer to be available
//
while(_SPITBF);
SPI1BUF = reply;
IFS0bits.SPI1IF = 0; // Clear the interrupt flag
}
What's wrong ?
Thanks