0
\$\begingroup\$

I'm trying to connect raspberry pi with stm32f103 over SPI where stm is a slave.

I'm not really like SPL and also I found awesome cmsis drivers for peripheral from Keil so I decided to use them.

Well, the problem is that I can't send any data to RPi. Reading works nice: everything I send from RPi is caught by STM but nothing is on the MISO line.

Here is my SPI initialization and some used definitions:

#define FRAME_START_POS             0
#define FRAME_TYPE_POS              1
#define FRAME_DATA_POS              2

#define FRAME_START_BYTE            0x1B
#define FRAME_TYPE_START            0x01
#define FRAME_TYPE_DATA             0x02

#define FRAME_HEADER_SIZE           2

#define RPI_SPI                     Driver_SPI2


void SpiInit(void)
{
    out_data[FRAME_START_POS] = FRAME_START_BYTE;
    out_data[FRAME_TYPE_POS] = FRAME_TYPE_DATA;

    if(RPI_SPI.Initialize(RpiSpiCb) != 0)
    {
        LOGGING_Error("Can not initialize SPI");
    }

    if(RPI_SPI.PowerControl(ARM_POWER_FULL) != 0)
    {
        LOGGING_Error("Can't set SPI power");
    }

    int status = RPI_SPI.Control(ARM_SPI_MODE_SLAVE    |
                                 ARM_SPI_SS_SLAVE_HW   |
                                 ARM_SPI_CPOL0_CPHA0   |
                                 ARM_SPI_DATA_BITS(8U) |
                                 ARM_SPI_MSB_LSB,       RPI_SPI_BUS_SPEED);

    if(status == -1)
    {
        System_ErrorLedOn();
        LOGGING_Error("Can't set SPI control");
    }
}


static void transfer_headers(void)
{
    /* 
     * out_data[0] and out_data[1] are never seen 
     *  on the MISO line but in_data is filled.
     */
    if(RPI_SPI.Transfer((void*)out_data, (void*)in_data, FRAME_HEADER_SIZE) != 0)
    {
        LOGGING_Error("Can't transfer data over SPI");
    }

    state = READ_HEADER;
}

I can't find out what I'm missing here. Maybe sending data when you are a slave is tricky but I haven't found anything about that?

P.S. Using RPI_SPI.Send() instead of Transfer() also does not work.

UPDATE

Here is function that is used to send data from RPi:

def __send_data(self, data):
    ans = self.stm.xfer2(data)

    if ((ans[FRAME_START_POS] != FRAME_START_BYTE) or
       (ans[FRAME_TYPE_POS] != FRAME_TYPE_DATA)):

        raise IOError("Wrong bytes in header from stm: 0x%02x 0x%02x" %
                      (ans[FRAME_START_POS], ans[FRAME_TYPE_POS]))

    if len(ans) > FRAME_HEADER_SIZE:
        return ans[FRAME_HEADER_SIZE:]

    return []
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The concept of SPI includes, that the slave never drives the clock. This means, that your RasPi, as it acts as the bus master, needs to shake the clock, if it wants to receive something. Try to periodically call a "receive-method" on the RasPi.

\$\endgroup\$
2
  • \$\begingroup\$ This I understand clearly. Also I know that to receive byte over SPI you should send byte over SPI(see post update). How it should work in my mind: I send 2 header bytes from RPI, stm catch first and send one byte as an answer, then i catches second and send one more byte. \$\endgroup\$
    – Long Smith
    Nov 6, 2016 at 10:16
  • \$\begingroup\$ It seems I get why you said "slave never drives the clock". RPI_BUS_SPEED is passed as an option just because I can't leave that parameter empty. It does not play any role in initialization. Sorry for mess. \$\endgroup\$
    – Long Smith
    Nov 6, 2016 at 10:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.