cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3 - ARM Cortex-M4 32-Bit MCU- SPI

love-peace2001
Associate II
Posted on October 07, 2013 at 21:54

Hi,

I am using the Discovery F3, I am trying to interface with an SPI port device which requires a 32 bit transfer and 8 bits for address, in the data sheet, the data size is between 4 and 16 bits.

I would know if there is a way to do this stuff.

Any help would be appreciated.

Thanks

#stm32f3-spi
9 REPLIES 9
Posted on October 08, 2013 at 04:01

You should be able to use 8-bit mode, and simply decompose the 32-bit address into four consecutive transfers. You control the CS pin, the transfers will occur back-to-back, and the data is synchronous.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
love-peace2001
Associate II
Posted on October 08, 2013 at 18:21

Ok, thanks for your replay. This is the code :

#include ''stm32f30x.h''

/**

  * @brief  Configures the different GPIO ports.

  * @param  None

  * @retval None

  */

    

    /* variables ---------------------------------------------------------*/

GPIO_InitTypeDef        GPIO_InitStructure;

SPI_InitTypeDef         SPI_InitStructure;

/* Set up GPIO for SPI */

void SPI_GPIO_init(){

     

    //Disable SPI

    SPI_I2S_DeInit(SPI1);  

     

    // Enable clock for SPI 1

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

     

    // Enable Clock for SPI GPIOA

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

     

    // Set up SCLK, MISO and MOSI pins

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;     // Select pins ( SCLK | MISO | MOSI)

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                                                  // Set as AF mode

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

     

 // Configure GPIO Alternate function as SPI1

    GPIO_PinAFConfig(GPIOA, GPIO_Pin_5, GPIO_AF_5);    // SPI1 SCLK

    GPIO_PinAFConfig(GPIOA, GPIO_Pin_6, GPIO_AF_5);   // SPI1 MISO

    GPIO_PinAFConfig(GPIOA, GPIO_Pin_7, GPIO_AF_5);  // SPI1 MOSI

     

    // Set up CS pin

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;     // PA15 taken as SPI1_NSS

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

    // OType, Speed and PuPd are the same

    GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/* Set up SPI and related parameters */

void SPI_init(){

     

    // Configure SPI

    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

  SPI_InitStructure.SPI_CRCPolynomial = 7;

  SPI_Init(SPI1, &SPI_InitStructure);

     

    // Enable SPI1

    SPI_Cmd(SPI1, ENABLE);

     

    // ensure RXNE is initially clear

    SPI_ReceiveData8(SPI1);

     

}

/**

  * @brief  write data width bytes from SPI interface.

  * @param  passed address & data  

  * @retval None

  */

void write(uint8_t address, uint32_t data )

{

     int x=0;

   uint8_t * txBuffer = (uint8_t*)&data;

    // gpio init

    SPI_GPIO_init();

    

    // Init SPI1

     SPI_init();

   /* Transfer procedure */

 

    /* Wait for SPI1 Tx buffer empty */

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

    

    GPIO_WriteBit( GPIOA,GPIO_Pin_15,Bit_RESET );     // drive the CS line low

    

    /* Send SPI address */

    SPI_SendData8(SPI1, address);

     

    for (x=3; x >= 0 ; x-- ) {

        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

        /* Send SPI data high */

        SPI_SendData8(SPI1, txBuffer[x]);

    }

        

      //wait for last bit to be sent

    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

       GPIO_WriteBit(GPIOA, GPIO_Pin_15,Bit_SET );      // drive the CS line high

   

}

But  SPI_SendData8() doesn't write data to DR register, because it has :

void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)

{

  uint32_t spixbase = 0x00;

  /* Check the parameters */

  assert_param(IS_SPI_ALL_PERIPH(SPIx));

  spixbase = (uint32_t)SPIx;

  spixbase += 0x0C;

 

  *(__IO uint8_t *) spixbase = Data;

}

love-peace2001
Associate II
Posted on October 09, 2013 at 22:13

Hi,

In the User Manual of the STM32F3, in the pin description PA6: SPI1_MISO, PA7:SPI1_MOSI. In the same time PB4: SPI1_MISO, PB5: SPI1_MOSI. How can we choose between the two configuration ?

Thanks in advance for your help

Posted on October 10, 2013 at 04:51

GPIO_PinAFConfig() controls the pin routing, the options are finite, ie not a cross-bar switch, but rather a mux

The SPIx->DR register is at offset 12 (0x0C) from the base of the peripheral.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
love-peace2001
Associate II
Posted on October 10, 2013 at 16:27

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6m7&d=%2Fa%2F0X0000000bv5%2F7hCe9VSt.ygZTup24KYPdlry6lgpASCwWtzZdLqtn2c&asPdf=false
love-peace2001
Associate II
Posted on October 11, 2013 at 15:10

Any help please, i have tried many programs to get work the SPI but i always have 0x0 in the DR register.

Posted on October 11, 2013 at 19:36

I'm not actively using the F3, so best I can offer is a quick static analysis.

GPIO_PinAFConfig(GPIOA, GPIO_Pin_5, GPIO_AF_5);

The second parameter here is wrong (mask), should be using GPIO_PinSource5 (index), see also all other instances. The AF seems valid for the pins being used. There are some mixed comments about SPI2/SPI3, pins/settings valid for SPI3

Also don't look at peripheral registers in the debugger, it will break them, DR is handled differently between a read/write (two unique registers), ie you can't see what you wrote, and reading it clears internal state flags.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
love-peace2001
Associate II
Posted on October 12, 2013 at 20:54

Ok clive1, thanks for you answer.

There are some mixed comments about SPI2/SPI3, pins/settings valid for SPI3: yes because i tried with SPI2, when it doesn't work i change it to SPI3 but not comments:)

Also don't look at peripheral registers in the debugger, it will break them, DR is handled differently between a read/write (two unique registers), ie you can't see what you wrote, and reading it clears internal state flags : so how can i visualize data in this case ?

Posted on October 12, 2013 at 22:53

The debugger can be invasive, you want to look at the peripherals indirectly, ie instrument your output when you already read SR and DR as part of the code flow, or store them in variables you can inspect directly.

Peripherals, and their registers, generally do not behave like memory devices.

You can use the ''Peripheral View/Watch'' to get a general sense of how things are set (baud rate, bit settings, etc), but be cautious that they may set or clear bits you might be interested in, or break downstream code expectations.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..