Electrical – stm32f10x cmsis spi driver

cmsisspistm32stm32f10x

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 []

Best Answer

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.