cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI Setup

i_
Associate II
Posted on May 02, 2013 at 12:36

Hi all,

New to the stm32 range and so far all is well. I am having a couple of problems setting up SPI on my stm32vldiscovery board and was hoping to get some help. I'm sure I must be missing something very small but can't seem to find it. I have probed portB with a scope but havn't got any visible output.

I have a couple of theories on what may be the problem, perhaps you can help.

The lines:

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

Will not compile, I get an error: GPIO_AF_SPI2 is undeclared. To compile I have been commenting these out.

I have not setup any clock preferences?

Thanks again, please see attached code below. (apologies for messy code, still just getting bits working!)

Ian

/**

******************************

******************************

******************

  * @file    main.c

  * @author  icooper

  * @version V1.0.0

  * @date    29/04//2013

  * @brief   Main program body.

******************************

******************************

******************

  * File Description:

  * Just messing around with some io

  */

/* Includes ------------------------------

------------------------------

------*/

&sharpinclude ''stm32f10x.h''

&sharpinclude ''stm32f10x_rcc.h''

&sharpinclude ''stm32f10x_gpio.h''

&sharpinclude ''stm32f10x_usart.h''

&sharpinclude ''stm32f10x_spi.h''

&sharpinclude ''stdint.h''

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

SPI_InitTypeDef SPI_InitStructure;

void Delay(uint32_t nTime);

int main(void)

{

    //Enable Peripheral Clocks, GPIOC, GPIOA, USART1, Alternative Function(AF), SPI2

    RCC_APB2PeriphClockCmd(RCC_

APB

2Periph_GPIOC |

                           RCC_APB2Periph_GPIOA |

                           RCC_APB2Periph_GPIOB |

                           //RCC_APB2Periph_USART1 |

                           RCC_APB2Periph_AFIO ,

                           ENABLE);

    RCC_APB1PeriphClockCmd(RCC_

APB

1Periph_SPI2 , ENABLE);

    //Configure Pins for CS for SPI

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //GPIO_Pin is a bit vector

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //Output Push Pull

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Set Speed

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //confugre spi - CLK PA5, MOSI PA7

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Alternative function - push pull

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //Set Speed

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

    //Configure SysTickTimer

    if    (SysTick_Config(

SystemCoreClo

ck / 1000))

    while(1);

    SPI_Cmd(SPI2, DISABLE);

    //configure spi

    SPI_InitStructure.SPI_

Directio

n = SPI_Direction_2Lines_

FullDuple

x;

    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_

BaudRate

Prescaler = SPI_BaudRatePrescaler_16;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_InitStructure.SPI_

CRCPolyn

omial = 7;

    SPI_Init(SPI2, &SPI_InitStructure);

    SPI_Cmd(SPI2, ENABLE);

  while (1)

  {

      Delay(50); //wait 50ms

      sendbyte_spi_lcd('c');

      Delay(50); //wait 50ms

  }

}

void sendbyte_spi_lcd(unsigned char byte){

    GPIO_WriteBit(GPIOA, GPIO_Pin_4, 0);

    GPIO_WriteBit(GPIOC, GPIO_Pin_8, 1);

    SPI_I2S_SendData(SPI2, byte);

    //while(SPI_I2S_GetFlagStatus(

SPI2, SPI_I2S_FLAG_BSY) == SET);

}

//Delay loop

static __IO uint32_t TimingDelay;

void Delay(uint32_t nTime){

    TimingDelay = nTime;

    while(TimingDelay != 0);

}

void SysTick_Handler(void){

    if (TimingDelay != 0x00)

        TimingDelay--;

}

#stm32 #spi
13 REPLIES 13
shankar
Associate II
Posted on November 22, 2013 at 10:35

Hello Clive, I changed the code as per your inputs and is as below. With this code I am just looking for sending Clock and Data out signals to a slave from SPI1 pins. Or you can say on PORTA_SPI1 pins. This is also not working.. Using the debugger, I can see that, the execution is getting stuck in Function/line ''while (SPI_I2S_GetFlagStatus

(

SPI1, SPI_I2S_FLAG_TXE) == RESET);''

I have added this function definition below this code.

int

main

(

void)

{

  /*!< At this stage the

microcontroller

clock setting is already configured, 

       

this

is done through SystemInit

(

) function which is called from startup

       

file

(startup_stm32f10x_xx

.

s) before to branch to application main.

       To reconfigure the default setting of SystemInit

(

) function, refer to

       system_stm32f10x

.

c file

     */     

       

  /* System clocks configuration ---------------------------------------------*/

  SPI_RCC_Configuration

(

);

  /* 1st phase: SPIy Master and SPIz Slave */

  /* GPIO configuration ------------------------------------------------------*/

  SPI_GPIO_Configuration

(

SPI_Mode_Master, SPI_Mode_Slave);

  

  /*

SPIy

Config -------------------------------------------------------------*/

  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_2Edge;

  SPI_InitStructure

.

SPI_NSS = SPI_NSS_Soft;

  SPI_InitStructure

.

SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;

  SPI_InitStructure

.

SPI_FirstBit = SPI_FirstBit_LSB;

  SPI_InitStructure

.

SPI_CRCPolynomial = 7;

  SPI_Init

(

SPI1, &SPI_InitStructure);

  /* Enable

SPIy

*/

  SPI_Cmd

(

SPI1, ENABLE);

SPI_I2S_SendData

(

SPI1, SPIy_Buffer_Tx

[

TxIdx++]);

while

(TxIdx <

BufferSize

)

{

Millisecond_delay

(

10);

/* Wait for SPIy

Tx

buffer empty */

while

(SPI_I2S_GetFlagStatus

(

SPI1, SPI_I2S_FLAG_TXE) == RESET);

/* Send SPIy data */

SPI_I2S_SendData

(

SPI1, SPIy_Buffer_Tx

[

TxIdx++]);

/* Wait for SPIy data reception */

      

Millisecond_delay

(

10);

Millisecond_delay

(

10);

Millisecond_delay

(

10);

}

}  //

main

end

/**

  * @brief  Configures the different system clocks.

  * @param  None

  * @retval None

  */

void

SPI_RCC_Configuration

(

void)

{

  /* PCLK2 = HCLK/2 */

  RCC_PCLK2Config

(

RCC_HCLK_Div2); 

/* Enable peripheral clocks --------------------------------------------------*/

  /* Enable GPIO clock for SPIy */

  RCC_APB2PeriphClockCmd

(

RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

  /* Enable

SPIy

Periph clock */

  RCC_APB1PeriphClockCmd

(

RCC_APB2Periph_SPI1, ENABLE);

}

/**

  * @brief  Configures the different SPIy and

SPIz

GPIO ports.

  * @param  SPIy_Mode: Specifies the SPIy operating mode. 

  *            This parameter can be:

  *              -  SPIy_Mode_Master

  *              -  SPIy_Mode_Slave                 

  * @param  SPIz_Mode: Specifies the SPIz operating mode. 

  *            This parameter can be:

  *              -  SPIz_Mode_Master

  *              -  SPIz_Mode_Slave 

  * @retval None

  */

void

SPI_GPIO_Configuration

(

uint16_t SPIy_Mode, uint16_t SPIz_Mode)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure

SPIy

pins: SCK, MISO and MOSI ---------------------------------*/

  GPIO_InitStructure

.

GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;

  GPIO_InitStructure

.

GPIO_Speed = GPIO_Speed_50MHz;

 

if

(

SPIy_Mode == SPI_Mode_Master)

  {

    /* Configure SCK and MOSI pins as Alternate Function Push Pull */

    GPIO_InitStructure

.

GPIO_Mode = GPIO_Mode_AF_PP;

  }

 

else

  {

/* Configure SCK and MOSI pins as Input Floating */

GPIO_InitStructure

.

GPIO_Mode = GPIO_Mode_IN_FLOATING;

  }

  GPIO_Init

(

GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure

.

GPIO_Pin = GPIO_Pin_6;

 

if

(

SPIy_Mode == SPI_Mode_Master)

  {

    /* Configure MISO pin as Input Floating  */

    GPIO_InitStructure

.

GPIO_Mode = GPIO_Mode_IN_FLOATING;

  }

 

else

  {

    /* Configure MISO pin as Alternate Function Push Pull */

    GPIO_InitStructure

.

GPIO_Mode = GPIO_Mode_AF_PP;

  }

  GPIO_Init

(

GPIOA, &GPIO_InitStructure);

}

In this below function, the ''

bitstatus

'' is becoming

TRUE

which is returned. But when I added the address SPI1 in Watch window, the

vaue

at ''SPIx->SR'' = 0. If this is the condition then ''

bitstatus

'' must be FALSE after the end of

Function

, which is not happening. Do

u

have any explanation. This is very strange for me..

FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)

{

 

FlagStatus

bitstatus

= RESET;

  /* Check the parameters */

  assert_param

(

IS_SPI_ALL_PERIPH

(

SPIx));

  assert_param

(

IS_SPI_I2S_GET_FLAG

(

SPI_I2S_FLAG));

  /* Check the status of the specified SPI/I2S flag */

 

if

((SPIx->SR & SPI_I2S_FLAG) != (uint16_t

)

RESET)

  {

    /* SPI_I2S_FLAG is set */

   

bitstatus

= SET;

  }

 

else

  {

    /* SPI_I2S_FLAG is reset */

   

bitstatus

= RESET;

  }

  /* Return the SPI_I2S_FLAG status */

 

return

 

bitstatus

;

}

Hope you understood, what I am saying..

Thanks 

Shankar

Posted on November 22, 2013 at 16:32

/* Enable

SPIy

Periph clock */

 

  RCC_APB1PeriphClockCmd

(

RCC_APB2Periph_SPI1, ENABLE);

APB2 APB2
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
shankar
Associate II
Posted on November 26, 2013 at 13:28

Hello Mr Clive,

Thanks for your input/advice..

Actually I tried with bit addressing concept to work on SPI with STM32, interfacing Texas TSC2046 - Touch Screen Driver. Here I didn't use the Internal SPI feature for this purpose. It is working with Bit addressing concept and I am also getting the output..

I tried configuring the SPI1 as per your suggestion. I feel it is working, but I am not able to catch the signals on CRO. This might be because of the signals been sent very fast.

1) Is there any option to slow the clock timings of SPI1?..

2) I am receiving the values as ''FF'', instead of actual value.

3) The code is getting hanged at, ''while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);''...

4) Because it was hanging, I commented the ''while()'' condition of Point ''3)''

With reference to the Data access of TSC2046 - Touch Screen Driver/Controller, (In the attachment, please check the page no. 5)

1) The data is received on the rising edge of the clock .

2) The data is output on the falling edge of the clock.

Please let me know, if the internal SPI1 of STM32 is capable to Transmit & Receive the data bits as per the specification of TSC2

I was keen to use the STM32 SPI1 feature instead of bit addressing concept.

Please guide me.

Thanks

Shankar

________________

Attachments :

Touch_Screen_Driver_tsc2046.pdf : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hzr6&d=%2Fa%2F0X0000000bQP%2FZF.1BNQ.fxBNaXfszntJwnirENt26bU.KEaaqKHDutg&asPdf=false
Posted on November 26, 2013 at 16:06

Reduce the baud rate, perform a repetitive operation, trigger the scope/analyzer appropriately.

The data clocking is controlled by the CPOL/CPHA settings. You'll need to consult documentation for both ends to pick a suitable mode.

I'm not looking to be pulled into your implementation task.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..