3-Wire SPI, Bidirectional, Half-Duplex Issue

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I am having an issue with an attempt to get 3-Wire SPI working.  First the vitals:

   

uC: CYBC4247LQI-BL483

   

IDE: PSoC Creator v4.0 Update 1 (4.0.0.432)

   

SPI Component: SPIM_1 created with the SPI Master Bidirecional mode Macro (v 2.50)

   

Device being communicated with: STMicro LSM303C (Datasheet)

   

 

   

Issue:

   

After I use SPIM_1_TxDisable() to disable the SPI output from the PSoC device sdat line, I then call a dummy write to generate the required clock cycles to cause the slave device to shift its information out of its registers while also maintaining the CS line low.  What I am finding when I watch the signal buss with a logic analyzer is that the dummy write that I do is actually not just generating a dummy value, but seems to be being sent to the RX buffer when I call SPIM_1_ReadRxData() to pull the returned data out of the read buffer it actually seems to be pulling the value from 2 previous reads (still, though being the dummy value).

   

I have checked this with two different logic analyzers to confirm what is going on.  When I use the logic analyzer I see that actually the value that is being transmitted back appears to be just a repeat of what ever the dummy write byte is.  For tracking purposes, I am using just a repeat of the register value that I was trying to read.  So on the logic analyzer, I am getting a straight 1 for 1 correlation to the register that I am trying to read being pinged back to me as the "read" value, but when I am using the debugging register view, I see that what I pull from the register as the read value was the register of the slave device that I was trying to read two reads ago. 

   

In trying to solve this, I though that perhaps in the 4 byte min sided buffer that some values were behaving strangely, so I call both SPIM_1_ClearRxBuffer() and SPIM_1_ClearFIFO().  These did not change the behavior of what was happening.  I currently cannot upload the entire project, but I will see if I can extract the key parts into a new project and then upload it.  I have inserted some of the code that I am using that is causing the issue as well as a screen shot of the logic analyzer capture.

   

I have also uploaded screen shots of the SPIM component configuration for clarity till I can break this out into a separate project that I can upload.

   

 

   

for(;;)
{

   

    AccelRead();
    CyDelay(1);

   

}

   

 

   

uint8_t ReadSPI(uint8_t regValue)
{
    uint8_t returnVal;
    
    SPIM_1_ClearRxBuffer();
    SPIM_1_ClearTxBuffer();
    SPIM_1_TxEnable();
    SPIM_1_WriteTxData((regValue | 0b10000000));
   

   

    //Begin the read process by disabling the Transmit, but write dummy value to cycle the clock

   

    SPIM_1_TxDisable();
    SPIM_1_ClearRxBuffer();
    SPIM_1_ClearFIFO();
    SPIM_1_WriteTxData((regValue | 0b10000000));
    returnVal = SPIM_1_ReadRxData();
    SPIM_1_TxEnable();
     
    return returnVal;
}

   

 

   

double AccelRead(void)
{
    volatile int16_t valueX;
    volatile int16_t valueY;
    volatile int16_t valueZ;
    volatile double magnitude;
    volatile uint8_t whoAmI;
    
    //TODO Need to add register information and function definitions
    valueX = ReadSPI(0x28);
    CyDelay(1);
    valueX = valueX << 8 | ReadSPI(0x29);
    CyDelay(1);
    
    valueY = ReadSPI(0x2A);
    CyDelay(1);
    valueY = valueY << 8 | ReadSPI(0x2B);
    CyDelay(1);
    
    valueZ = ReadSPI(0x2C);
    CyDelay(1);
    valueZ = valueZ << 8 | ReadSPI(0x2D);
    CyDelay(1);
    
    whoAmI = ReadSPI(0b00001111);
    
    magnitude = sqrt(valueX * valueX + valueY * valueY + valueZ * valueZ);
    return 0;
}

0 Likes
1 Solution
Anonymous
Not applicable

I ran into a similar issue when setting up the SPI component to communicate with a Microchip SPI device; I ran into the issue where the data was delayed by several bytes being sent/received for an echo-test program I wrote. It seems like the SPI component has an internal FIFO buffer for both input and output, which could be why you are having a delay between seeing the byte on the physical line, and seeing it in the RX buffer in the component. I ended up rewriting my communications protocol to be ignorant of timing by introducing start/end of data sequences that allow me to merely send a data message and ignore all data until a response comes in. This allowed a more or less polling of the data until the next message start sequence.

View solution in original post

0 Likes
1 Reply
Anonymous
Not applicable

I ran into a similar issue when setting up the SPI component to communicate with a Microchip SPI device; I ran into the issue where the data was delayed by several bytes being sent/received for an echo-test program I wrote. It seems like the SPI component has an internal FIFO buffer for both input and output, which could be why you are having a delay between seeing the byte on the physical line, and seeing it in the RX buffer in the component. I ended up rewriting my communications protocol to be ignorant of timing by introducing start/end of data sequences that allow me to merely send a data message and ignore all data until a response comes in. This allowed a more or less polling of the data until the next message start sequence.

0 Likes