1
votes

I'm trying to get an SPI connection between two of the above mentioned Boards to work.
The Master seems to work well, I am using a timer Interrupt to periodically send 8bit Information "0xA5". That's what I can confirm at the MOSI Pin with an Oscilloscope. That's basically everything the Master does in my test setup.
I will now include the Initializing Code for the Slave:

void mainInit(void){

    // System Initialisierung
    SystemInit();


    // Strukturen anlegen
    RCC_ClocksTypeDef RCC_Clocks; // Struktur für Clocks anlegen (optional)
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;  //Struktur für SPI. SS: PA8; MOSI:PA7, MISO:PA6; CLK:PA5
    NVIC_InitTypeDef NVIC_InitSPI1;



    // Auslesen der Clocks und Speichern in der Struktur
    RCC_PCLK2Config(RCC_HCLK_Div16); // Timer Clock teilen
    RCC_GetClocksFreq(&RCC_Clocks); // (optional)



    // Enable Clock für Port A, Alternate Functions, SPI1 und Timer2
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


    // Interrupt Initialisieren mit SPI1
    NVIC_InitSPI1.NVIC_IRQChannel = SPI1_IRQn;
    NVIC_InitSPI1.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitSPI1.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitSPI1.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_Init(&NVIC_InitSPI1);


    // Initialisierung CLK PA5
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    // Initialisierung MOSI PA7
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    // Initialisierung MISO PA6
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    // Initialisierung SS PA8
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    // Initialisierung Toggle pin
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);



    // Initialisierung SPI. SPI Write ist in Funktion "TIM2_IRQHandler" in stm32f1xx_it.c
    SPI_I2S_DeInit (SPI1); // Einmal deinitialisieren
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    // SPI1 Enable
    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Cmd(SPI1, ENABLE);

    SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE); // RXNE Interrupt Enable
    //SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE); // TXE Interrupt Enable



}

The pins are connected between the Master and the Slave as following:
* MOSI to MOSI (Pin A7),
* MISO to MISO(Pin A6),
* CLK to CLK (Pin A5),
* CS to CS (PinA8).
MOSI, MISO and CLK are the assigned Pins for SPI1 on the board, but I am using a custom Pin for CS. CS is always pulled to LOW by the Master just before the Transmission begins.

Since I want to work with the SPI Interrupt, when the RXNE Flag is set, I am assuming that the RXNE is never set. But I can't figure out why. I will also show you the interrupt Routine, but since the Interrupt Routine is never called by the µC, the problem should be elsewhere.

void SPI1_IRQHandler(void){
    if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8) == Bit_RESET){
        if (SPI_I2S_ReceiveData(SPI1) == 0xA5){
            GPIO_WriteBit(GPIOA, GPIO_Pin_10, Bit_SET);
        }
    }

}

Thanks for your help and if you need additional information, just let me know.

/* Edit */ I just found out, that my configuration works on a single board. So when I just Connect MOSI to MISO on one board, it runs perfectly. So, do you guys have any hint on where I mess up when it comes to a Master - Slave Connection with two boards?

1
Did you try debugging by setting a break-point inside the IRQHandler?clmno
Yes, that's how i know that the Interrupt Routine is never called by the Slave. Since I am using Atollic TrueStudio, I can have a look at the Special Function Registers while debugging. Here I could see, that in the Special Function Register of SPI1, in the Shift Register (Adress 0x40013008), the value of RXNE is always 0. To my understanding, it should be 1, when Data has been received.user10622651
Thank you, I already checked this thread before I opened this thread. Unfortunately it could not help me with my problem. I tried different Pin configurations on the Slave board. Since I am only trying to receive on the Slave and send on the Master, I did not touch the Master settings, since it works as expected.user10622651

1 Answers

0
votes

Do you know the meaning of MOSI and MISO? MOSI: Master OUT Slave IN. MISO: Master IN Slave OUT. Try if this connection is working.

Are the mosi and miso pins configured as Alternative function? How is "GPIO_Mode_IN_FLOATING" defined?

Please initialize your structures with {0} to be sure the configuration is clear.