cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303VC : SPI1 (Master) SPI2 (Slave)

AT.8
Associate II

Hello Everyone,

I am trying to establish communication between SPI1 and SPI2 on the STM32F303 Discovery board.

I have configured SPI1 as Master and SPI2 as Slave. I am receiving 0xFF when a Receive interrupt is fired in SPI2.

SPI1 Master module is configured so:

  /**
     * PA4 - NSS   PB12 - NSS
     * PA5 - SCK   PB13 - SCK
     * PA6 - MISO  PB15 - M0SI
     * PA7 - MOSI  PB14 - MISO
     */
    __HAL_RCC_SPI1_CLK_ENABLE();
 
    LL_SPI_InitTypeDef SPI1InitStruct;
 
    SPI1InitStruct.BaudRate          = LL_SPI_BAUDRATEPRESCALER_DIV4;
    SPI1InitStruct.ClockPhase        = LL_SPI_PHASE_2EDGE;
    SPI1InitStruct.ClockPolarity     = LL_SPI_POLARITY_HIGH;
    SPI1InitStruct.CRCCalculation    = LL_SPI_CRCCALCULATION_DISABLE;
    SPI1InitStruct.DataWidth         = LL_SPI_DATAWIDTH_8BIT;
    SPI1InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
    SPI1InitStruct.BitOrder          = LL_SPI_MSB_FIRST;
    SPI1InitStruct.Mode              = LL_SPI_MODE_MASTER;
    SPI1InitStruct.NSS               = LL_SPI_NSS_HARD_OUTPUT;
 
    LL_SPI_Init(SPI1, &SPI1InitStruct);
 
    LL_SPI_Enable(SPI1);

SPI1 GPIO is configured so:

/**   MASTER        SLAVE
     * **********        **********
     * PA4 - NSS     PB12 - NSS
     * PA5 - SCK     PB13 - SCK
     * PA6 - MISO   PB15 - M0SI
     * PA7 - MOSI   PB14 - MISO
     */
 
    if (RESET == __HAL_RCC_GPIOA_IS_CLK_ENABLED())
    {
        __HAL_RCC_GPIOA_CLK_ENABLE();
    }
 
    LL_GPIO_InitTypeDef gpioSPIInitStr;
 
    gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
    gpioSPIInitStr.Pin       =  LL_GPIO_PIN_5 | LL_GPIO_PIN_7;
    gpioSPIInitStr.Mode      = LL_GPIO_MODE_ALTERNATE;
    gpioSPIInitStr.Speed     = LL_GPIO_SPEED_FREQ_HIGH;
    gpioSPIInitStr.Pull      = LL_GPIO_PULL_UP; 
    gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
 
    LL_GPIO_Init(GPIOA, &gpioSPIInitStr);
 
    /* Pin A6 (MISO) must be configured as as input pull-up*/
        LL_GPIO_StructInit(&gpioSPIInitStr);
        gpioSPIInitStr.Pin   = LL_GPIO_PIN_6;
        gpioSPIInitStr.Mode  = LL_GPIO_MODE_INPUT; //LL_GPIO_MODE_ALTERNATE;
        gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
        LL_GPIO_Init(GPIOA, &gpioSPIInitStr);
 
    /*NSS Pin Config */
    LL_GPIO_InitTypeDef SPI_SSPIN_Struct;
 
    SPI_SSPIN_Struct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    SPI_SSPIN_Struct.Pin        = LL_GPIO_PIN_4;
    SPI_SSPIN_Struct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
 
    LL_GPIO_Init(GPIOA, &SPI_SSPIN_Struct);
    LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_4);

SPI2 Slave module is configured so:

    /** MASTER      SLAVE
     * **********   **********
     * PA4 - NSS    PB12 - NSS
     * PA5 - SCK    PB13 - SCK
     * PA6 - MISO   PB15 - M0SI
     * PA7 - MOSI   PB14 - MISO
     */
    __HAL_RCC_SPI2_CLK_ENABLE();
 
    LL_SPI_InitTypeDef SPI_SlaveInitStruct;
    SPI_SlaveInitStruct.BaudRate          = LL_SPI_BAUDRATEPRESCALER_DIV4;
    SPI_SlaveInitStruct.ClockPhase        = LL_SPI_PHASE_2EDGE;
    SPI_SlaveInitStruct.ClockPolarity     = LL_SPI_POLARITY_HIGH;
    SPI_SlaveInitStruct.CRCCalculation    = LL_SPI_CRCCALCULATION_DISABLE;
    SPI_SlaveInitStruct.DataWidth         = LL_SPI_DATAWIDTH_8BIT;
    SPI_SlaveInitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
    SPI_SlaveInitStruct.BitOrder          = LL_SPI_MSB_FIRST;
    SPI_SlaveInitStruct.Mode              = LL_SPI_MODE_SLAVE;
    SPI_SlaveInitStruct.NSS               = LL_SPI_NSS_HARD_INPUT;
 
    LL_SPI_Init(SPI2, &SPI_SlaveInitStruct);
    LL_SPI_Enable(SPI2);
 
    LL_I2S_EnableIT_RXNE(SPI2);
    HAL_NVIC_SetPriority(SPI2_IRQn, 0 , 0 );
    HAL_NVIC_EnableIRQ(SPI2_IRQn);

Slave GPIO is configured so:

  /** MASTER      SLAVE
     * **********   **********
     * PA4 - NSS    PB12 - NSS
     * PA5 - SCK    PB13 - SCK
     * PA6 - MISO   PB15 - M0SI
     * PA7 - MOSI   PB14 - MISO
     */
	if (RESET == __HAL_RCC_GPIOB_IS_CLK_ENABLED())
	{
	     __HAL_RCC_GPIOB_CLK_ENABLE();
	}
 
	LL_GPIO_InitTypeDef gpioSPIInitStr;
 
	gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
	gpioSPIInitStr.Pin       =  LL_GPIO_PIN_13  | LL_GPIO_PIN_15;
	gpioSPIInitStr.Mode      = LL_GPIO_MODE_ALTERNATE;
	gpioSPIInitStr.Speed     = LL_GPIO_SPEED_FREQ_HIGH;
	gpioSPIInitStr.Pull      = LL_GPIO_PULL_UP; 
	gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
 
	LL_GPIO_Init(GPIOB, &gpioSPIInitStr);
 
	gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
	gpioSPIInitStr.Pin       =  LL_GPIO_PIN_14;
	gpioSPIInitStr.Mode      = LL_GPIO_MODE_ALTERNATE;
	gpioSPIInitStr.Speed     = LL_GPIO_SPEED_FREQ_HIGH;
	gpioSPIInitStr.Pull      = LL_GPIO_PULL_UP; 
	gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
 
	LL_GPIO_Init(GPIOB, &gpioSPIInitStr);
 
	gpioSPIInitStr.Alternate = LL_GPIO_AF_5;
	gpioSPIInitStr.Pin       =  LL_GPIO_PIN_12; //NSS
	gpioSPIInitStr.Mode      = LL_GPIO_MODE_INPUT;	
	gpioSPIInitStr.Pull      = LL_GPIO_PULL_NO;
	gpioSPIInitStr.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
 
	LL_GPIO_Init(GPIOB, &gpioSPIInitStr);

This is what i do forever in main function:

SPI_Master_Tx_Data(0xA5);
Delay_us(100);
 
SPI_Master_Tx_Data(0xCF);
Delay_us(100);

The Interrupt handler looks very rudimentary at the moment, i am reading 0xFF in the SPI2 Data Register when i debug everytime while i expect 0xA5 and 0xCF:

void SPI2_IRQHandler( void ) {
	uint8_t irq_var1= 0 ;
	irq_var1 = SPI2->DR;
}

Transmit function from master looks so:

  SPI_MASTER_CHIP_SEL_LOW();
 
 while (!LL_SPI_IsActiveFlag_TXE(SPI1))
      ; // wait while not empty
 LL_SPI_TransmitData8(SPI1, TXData); //send data.
 
 while (LL_SPI_IsActiveFlag_BSY(SPI1))
          ; // wait until the bus is no longer busy
 
 SPI_MASTER_CHIP_SEL_HIGH(); // slave deselect (high)

This is what i see on the Oscilloscope. Also the Slave signal looks very strange.

0693W00000KbH2cQAF.png 

Can someone please point out or give helpful tips why this is not working as expected?

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> SPI1_MISO (PA6) is connected to SPI2_MOSI(PB15).

This is incorrect.

MISO (Master In Slave Out) is an input for the master and output for slave. Don't cross them like you would for UART.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

8 REPLIES 8
TDK
Guru

> * PA4 - NSS PB12 - NSS

> * PA5 - SCK PB13 - SCK

> * PA6 - MISO PB15 - M0SI

> * PA7 - MOSI PB14 - MISO

How are the signals connected to each other? From the layout it looks like you may have MOSI and MISO crossed.

> STM32F303 Discovery board

Also ensure that these pins are free on this board and not being used by other chips.

If you feel a post has answered your question, please click "Accept as Solution".
AT.8
Associate II

I am not sure I understand what you mean by "crossed". The signals are connected via female to female jumper wires on the Eval Board.

0693W00000KbOBbQAN.jpg0693W00000KbODwQAN.jpg 

From the schematic, it looks like PA4 to PA7 are connected to SWD via Solder bridges. They need to be desoldered from the board, correct?

0693W00000KbOCFQA3.jpg

TDK
Guru

> I am not sure I understand what you mean by "crossed". The signals are connected via female to female jumper wires on the Eval Board.

Yes, but is SPI1_MISO (PA6) connected to SPI12_MISO (PB14) or SPI2_MOSI (PB15)? As I said earlier, the table you present suggests you are connecting MISO to MOSI if each row lists a connected pair.

> From the schematic, it looks like PA4 to PA7 are connected to SWD via Solder bridges. They need to be desoldered from the board, correct?

You are looking at the ST-Link chip, not the target MCU. Also, PA4 on there is free/disconnected. The signal name is above the signal as a convention, so T_JTCK is on PA5. The "X" on the PA4 net indicates it's not connected to anything else on the board. Same for PB1.

If you feel a post has answered your question, please click "Accept as Solution".
AT.8
Associate II

Yes, but is SPI1_MISO (PA6) connected to SPI12_MISO (PB14) or SPI2_MOSI (PB15)? 

SPI1_MISO (PA6) is connected to SPI2_MOSI(PB15). Is this incorrect?

You are looking at the ST-Link chip, not the target MCU. Also, PA4 on there is free/disconnected. The signal name is above the signal as a convention, so T_JTCK is on PA5. The "X" on the PA4 net indicates it's not connected to anything else on the board. Same for PB1.

Yes i had a closer look at the schematic, you're right. In that case, I believe the SPI (Master+Slave) Pins are available for use.

TDK
Guru

> SPI1_MISO (PA6) is connected to SPI2_MOSI(PB15).

This is incorrect.

MISO (Master In Slave Out) is an input for the master and output for slave. Don't cross them like you would for UART.

If you feel a post has answered your question, please click "Accept as Solution".
AT.8
Associate II

Yes, now i see the expected bytes. If i were to use a another chip as slave, then it would have to be crossed, correct? "Data In" Pin on the Slave Chip would be connected to "MOSI" line of Master Chip.

Okay, then my understanding was incorrect. Thank you.

MOSI is always connected to MOSI. If a pin is “data in�? then it depends on if that chip is master or slave. Slave “data in�? is MOSI.

If you feel a post has answered your question, please click "Accept as Solution".
AT.8
Associate II

Ok, I have another question.

Is it possible to send data from SPI2 to SPI1 ? SPI2 being the slave. In SPI, Master initiates the communication, correct ?

This is how i do it:

When the Slave SPI2 receives a byte from SPI1, i set a flag, and i check for this flag in main context.

If this flag is set, i send a dummy byte from Master and wait for the interrupt in SPI1 IRQ Handler (configured for RXNE interrupt).

if( Slave_Rx_Flag == 1 ){
 
     SPI_Master_Tx_Data(0x00); //Dummy byte
     SPI_Slave_Tx_Data(0x5D);
     Delay_us(50);
      Slave_Rx_Flag = 0;
}

My transmit function for slave looks so:

while (!LL_SPI_IsActiveFlag_TXE(SPI2))
     ; // wait while not empty
LL_SPI_TransmitData8(SPI2, byte); // NO EFFECT ??

void SPI1_IRQHandler( void ) {
 
	Master_Rx_Flag =1;
	uint8_t spi2_data ;
	spi2_data = SPI1->DR;
}

I am reading 0x00 when i expect 0x5D.