0

I am working with the following evaluation board: SZWB-sail, STM32f103VET6 KIT v3.1

I want to use the stm32f103 usart in synchronous mode, and I used STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\Synchronous

I modified the code in an attempt to use USART2/SPI1, as opposed to the working code provided via STMicro, which uses USART1/SPI1.

The README for this example states that:

"USARTy and SPIy can be USART1 and SPI1 or USART2 and SPI3, depending on the STMicroelectronics EVAL board you are using."

Despite this, I attempted to physically connect USART2 Tx/Rx/Ck pins (PA2,PA3,PA4) to SPI1 SCK/MISO/MOSI (PA5,PA6,PA7). Is there a software reason for why this won't work? Or might it be hardware connections on the eval board?

Here is my code:

int main(void)
{
    SystemInit();
    Init_NVIC();
    /* System Clocks Configuration */
    RCC_Configuration();
    /* Configure the GPIO ports */
    GPIO_Configuration();
    SPI_Configuration();
    USART_Configuration();


    while(NbrOfDataToRead2--)
    {

        USART2_Send_Byte(TxBuffer1[TxCounter1++]);

        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
        {
        }
        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
        {
        }

        RxBuffer2[RxCounter2++] = SPI_I2S_ReceiveData(SPI1);
    }


    USART2_Receive_Byte();

    while(NbrOfDataToRead1--)
    {

        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)== RESET)
        {
        }
        SPI_I2S_SendData(SPI1, TxBuffer2[TxCounter2++]);


        USART2_Send_Byte(DYMMY_BYTE);

        while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET)
        {
        }

        while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)
        {
        }

        RxBuffer1[RxCounter1++] = USART2_Receive_Byte();
    }


    TransferStatus1 = Buffercmp(TxBuffer1, RxBuffer2, TxBufferSize1);

    TransferStatus2 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2);


    while(1)
    {
    }
}

void Init_NVIC(void)
{
    NVIC_InitTypeDef    NVIC_InitStructure;

    #ifdef  VECT_TAB_RAM

    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else

    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    #endif
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
void RCC_Configuration(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE );
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);
}
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure1,GPIO_InitStructure2;
    GPIO_InitTypeDef  GPIO_InitStructure3,GPIO_InitStructure4,GPIO_InitStructure5,GPIO_InitStructure6;

    /* Configure USART1 Rx as input floating */
    GPIO_InitStructure1.GPIO_Pin =GPIO_Pin_10;
    GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure1);

    /* Configure USART1 Tx as alternate function push-pull */
    GPIO_InitStructure2.GPIO_Pin =GPIO_Pin_9;
    GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure2);

    /* Configure USART2 Rx as input floating */
    GPIO_InitStructure3.GPIO_Pin =GPIO_Pin_3;
    GPIO_InitStructure3.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure3.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure3);

    /* Configure USART2 Tx as alternate function push-pull */
    GPIO_InitStructure4.GPIO_Pin =GPIO_Pin_2;
    GPIO_InitStructure4.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure4.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure4);

    /* Configure USART2 Ck as alternate function push-pull */
    GPIO_InitStructure5.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure5.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure5.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure5);

    /* Configure SPI1 pins: SCK, MISO and MOSI */
    GPIO_InitStructure6.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_Init(GPIOA, &GPIO_InitStructure6);

}
void USART_Configuration(void)
{
    USART_InitTypeDef USART_InitStructure1,USART_InitStructure2;
    USART_ClockInitTypeDef USART_ClkInitStructure;

    USART_InitStructure1.USART_BaudRate = 115200;
    USART_InitStructure1.USART_WordLength =USART_WordLength_8b ;
    USART_InitStructure1.USART_StopBits = USART_StopBits_1;
    USART_InitStructure1.USART_Parity = USART_Parity_No;
    USART_InitStructure1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure1.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    /* Configure USART1 */
    USART_Init(USART1,&USART_InitStructure1);

    //USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    /* Enable the USART1 */
    USART_Cmd(USART1,ENABLE);

    USART_ClkInitStructure.USART_Clock=USART_Clock_Enable;
    USART_ClkInitStructure.USART_CPOL=USART_CPOL_High;
    USART_ClkInitStructure.USART_CPHA=USART_CPHA_2Edge;
    USART_ClkInitStructure.USART_LastBit=USART_LastBit_Enable;
    USART_ClockInit(USART2, &USART_ClkInitStructure);

    USART_InitStructure2.USART_BaudRate = 115200;
    USART_InitStructure2.USART_WordLength =USART_WordLength_8b ;
    USART_InitStructure2.USART_StopBits = USART_StopBits_1;
    USART_InitStructure2.USART_Parity = USART_Parity_No;
    USART_InitStructure2.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure2.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

    /* Configure USART2 */
    USART_Init(USART2,&USART_InitStructure2);

    //USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
    /* Enable the USART2 */
    USART_Cmd(USART2,ENABLE);
}
void SPI_Configuration(void)
{
    SPI_InitTypeDef SPI_InitStructure;

    SPI_StructInit(&SPI_InitStructure);

    SPI_I2S_DeInit(SPI1);

    /* SPIy Config */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
    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_FirstBit = SPI_FirstBit_LSB;

    /* Configure SPIy */
    SPI_Init(SPI1, &SPI_InitStructure);

    SPI_I2S_ITConfig(SPI1,SPI_I2S_IT_RXNE,ENABLE);
    /* SPIy enable */
    SPI_Cmd(SPI1, ENABLE);
}
bunkerdive
  • 2,031
  • 1
  • 25
  • 28
Mahtab
  • 107
  • 3
  • 14
  • 1
    Did you checked the signal you are generating with a scope or a logic analyser ? That will allow you to know if the problem is in the sender or in the receiver. Then try first without using the interruptions, then when it works enable them. – Nicolas Defranoux Jul 13 '14 at 17:57
  • Thanks for your reply . Yes i checked. I think problem is in receiver because SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) never changed and always is RESET and when i enable the spi receive interrupt it never works. did i forget something in my code??? – Mahtab Jul 14 '14 at 06:50

2 Answers2

1

You are mixing polling mode with interrupt mode. This SPI configuration code is intended for SPI interrupt mode. Hence, SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) should not be used, because this is a function intended for Polling-Mode.

Instead, I believe you can use SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT); in conjunction with SPI_I2S_ReceiveData(SPI_TypeDef* SPIx) and SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT) (to clear any potential Error pending bits, just in-case).

Also, you might want to post your USART2_Send_Byte() code so we know what exactly it's doing, and whether it's calling any other functions...but go ahead and try this first to see if it fixes your problem.

bunkerdive
  • 2,031
  • 1
  • 25
  • 28
  • Thanks i changed my code in the above and it worked for USART1 and SPI1 . BUT BUT when i changed it to USART2 it didnt work!!!! DO u know why? i explain more about my changes in the above. under my codes. – Mahtab Jul 16 '14 at 09:56
  • I think there is a problem in APB1 and APB2. right? – Mahtab Jul 16 '14 at 09:59
  • 1
    Please don't ask a new question by editing your first question after the first one has been answered. If this answer answered your first question you should accept it. (green arrow on the left). – Étienne Jul 16 '14 at 17:43
  • Well you still have `USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);` and `USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);` commented out. If you have USART1 working, then I would create two versions of the code: one with all USART2 references/code removed, and an equivalent for USART1 so that you don't confuse the config process. Then, once fully working, work from there to integrate both. – bunkerdive Jul 17 '14 at 13:45
  • @Étienne I didnt ask new question and my problem is still unsolved. I had problem in communication between SPI and Usart and Jesse's answer was useful but didnt solve my problem so I used +1 that means answer was useful. I still couldnt have communication between SPI1 and USART2. – Mahtab Jul 20 '14 at 09:46
  • @Jesse Thanks .i edited my code to explicit one here but now i see it turned to previous one and i dont know how!! but i edited it to a version that each time, settings and configuration was for just one of the usart1 or usart2 cause the config process didnt confuse, but still usart2 couldnt have a success communication with SPI1. – Mahtab Jul 20 '14 at 09:59
  • @Mahtab You didn't use +1, I did it and it is the only +1 on this answer ;) You should rather post the relevant code on the [new question you asked](http://stackoverflow.com/questions/24778183/communication-between-usart-and-spi) than edit this one, otherwise the first answer you got won't make any sense any more. – Étienne Jul 20 '14 at 10:47
  • yes :) because i cant use +1 , its not permitted for me by requirements so i think Jesse made a mistake about me. In addition about the new question, you are right i accept and sorry about that.I didnt understand what you said at the first, I thought you said i asked a new question in current topic. – Mahtab Jul 20 '14 at 13:19
  • I thought maybe the new question is more clear to answer. But still no ones hadnt been answered. :( – Mahtab Jul 20 '14 at 13:30
  • @Mahtab - if this worked for USART1, then that means your USART1 Tx/Rx/Clk pins are tied to your SPI MOSI/MISO/SCK pins (in that order). So if you're trying to get this working for USART2, have you disconnected USART1, and connected USART2 pins to SPI1 pins? Did you verify the ports/pins you're using don't have alternate functions which require disconnected 0Ohm resistors? What board are you using (Eval board, Custom PCB, etc)? – bunkerdive Jul 21 '14 at 01:03
  • Yes Jesse, I changed the connections for USART2. I used eval board SZWB-sail STM32f103VET6 KIT v3.1 (http://www.aliexpress.com/store/product/Development-board-ARM-Crotex-M3-STM32F103VET6-board-7-TFT-MP3-CAN-485-Internet-support-Wireless/217299_643786417.html) – Mahtab Jul 21 '14 at 07:33
  • If that is the board you are using, I am going to assume that there is no way they would leave two sets of USART pins completely disconnected (prob only USART1). The datasheet and board manual are not available online (avail in print?), otherwise I could check to see if you're getting contention on the USART2 line from alternate function connections. This is most likely the case, and the documentation should tell you what to disconnect in order to utilize PA2/PA3/PA4 (e.g. they might be connected to CAN etc., requiring disconnect of a 0Ohm resistor somewhere) – bunkerdive Jul 23 '14 at 18:00
  • The README for that project states the following: "This example provides a basic communication between USARTy (Synchronous mode) and SPIy using flags. USARTy and SPIy can be USART1 and SPI1 or USART2 and SPI3, depending on the STMicroelectronics EVAL board you are using." This means that the built-in support requires USART2 to be used with SPI3. That would explain why you're able to get it working with USART1 and SPI1, but not USART2 & SPI1. If you have physically connected USART2 pins to SPI1 pins, then you will probably have issues due to contention w/SPI3/USART2 pins. – bunkerdive Jul 23 '14 at 18:05
0

SPI1 conflicts with USART2 synchronization mode. SPI2 conflicts with USART3 synchronization mode. There is no conflict between SPI1/2 and USART1 synchronization modes.

Tony
  • 1
  • 2