2013-05-02 03:36 AM
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 #spi2013-11-22 01:35 AM
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 themicrocontroller
clock setting is already configured,this
is done through SystemInit(
) function which is called from startupfile
(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); /* EnableSPIy
*/ SPI_Cmd(
SPI1, ENABLE); SPI_I2S_SendData(
SPI1, SPIy_Buffer_Tx[
TxIdx++]);while
(TxIdx <BufferSize
) { Millisecond_delay(
10); /* Wait for SPIyTx
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); /* EnableSPIy
Periph clock */ RCC_APB1PeriphClockCmd(
RCC_APB2Periph_SPI1, ENABLE);}/** * @brief Configures the different SPIy andSPIz
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; /* ConfigureSPIy
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 becomingTRUE
which is returned. But when I added the address SPI1 in Watch window, thevaue
at ''SPIx->SR'' = 0. If this is the condition then ''bitstatus
'' must be FALSE after the end ofFunction
, which is not happening. Dou
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 Shankar2013-11-22 07:32 AM
/* Enable
SPIy
Periph clock */RCC_APB1PeriphClockCmd
(
RCC_APB2Periph_SPI1, ENABLE); APB2 APB22013-11-26 04:28 AM
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=false2013-11-26 07:06 AM
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.