Skip to main content
manes6969
Associate
December 13, 2011
Question

How to use the fpu in stm32f4xx ?

  • December 13, 2011
  • 15 replies
  • 3729 views
Posted on December 13, 2011 at 21:24

Hi,

How do I exactly use the fpu after enabled it ?

How do I for example put 5.5 into it and add 3.25 for example

Dooes my software have to do the conversion and just let the fpu cdo the addition , or is the fpu also capable of doing the conversion from 5.5 integer to float ?

Is there any good reference on this subject ?

Thanks!

Ronny Suy

#fpu-vfp
    This topic has been closed for replies.

    15 replies

    dannym
    Associate III
    July 13, 2012
    Posted on July 13, 2012 at 20:14

    Ooops, I was paraphrasing the problem in the code.  A 16-bit signed int has a value from elsewhere in the code and that Watch window reflects that.  But once it's recast as a float and placed in a float variable, it is zero.

    dannym
    Associate III
    July 13, 2012
    Posted on July 13, 2012 at 21:36

    Looks like it throws a Hard Fault on a basic constant assign myFloat= 1234.5;

    Hmm, if I DISABLE the hardware FPU, the code works.

    Tesla DeLorean
    Guru
    July 13, 2012
    Posted on July 13, 2012 at 23:09

    Make sure the FPU is enabled either in Reset_Handler or SystemInit()

    Reset_Handler PROC
    EXPORT Reset_Handler [WEAK]
    IMPORT SystemInit
    IMPORT __main
    ;FPU settings
    LDR R0, =0xE000ED88 ; Enable CP10,CP11
    LDR R1,[R0]
    ORR R1,R1,#(0xF << 20)
    STR R1,[R0]
    LDR R0, =SystemInit
    BLX R0
    LDR R0, =__main
    BX R0
    ENDP

    void SystemInit(void)
    {
    /* FPU settings ------------------------------------------------------------*/
    #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
    #endif

    And the required defines set.

    // STM32 USART2 (Tx PA.2, Rx PA.3) STM32F4 Discovery - sourcer32@gmail.com
    #include <
    stdio.h
    >
    #include <
    stdlib.h
    >
    #include ''stm32f4_discovery.h''
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
    /* --------------------------- System Clocks Configuration -----------------*/
    /* USART2 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    /* GPIOA clock enable */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    /*-------------------------- GPIO Configuration ----------------------------*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Connect USART pins to AF */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); // USART2_TX
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // USART2_RX
    }
    /**************************************************************************************/
    void USART2_Configuration(void)
    {
    USART_InitTypeDef USART_InitStructure;
    /* USARTx configuration ------------------------------------------------------*/
    /* USARTx configured as follow:
    - BaudRate = 115200 baud
    - Word Length = 8 Bits
    - One Stop Bit
    - No parity
    - Hardware flow control disabled (RTS and CTS signals)
    - Receive and transmit enabled
    */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART2, &USART_InitStructure);
    USART_Cmd(USART2, ENABLE);
    }
    /**************************************************************************************/
    int main(void)
    {
    RCC_Configuration();
    GPIO_Configuration();
    USART2_Configuration();
    {
    int16_t myInt=0x1234;
    float myFloat;
    myFloat=(float)myInt; //gets zero
    printf(''myFloat %f
    '', myFloat);
    }
    while(1); // Don't want to exit
    }
    //******************************************************************************
    // Hosting of stdio functionality through USART2
    //******************************************************************************
    #include <
    rt_misc.h
    >
    #pragma import(__use_no_semihosting_swi)
    struct __FILE { int handle; /* Add whatever you need here */ };
    FILE __stdout;
    FILE __stdin;
    int fputc(int ch, FILE *f)
    {
    static int last;
    if ((ch == (int)'
    ') && (last != (int)'
    '))
    {
    last = (int)'
    ';
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    USART_SendData(USART2, last);
    }
    else
    last = ch;
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    USART_SendData(USART2, ch);
    return(ch);
    }
    int fgetc(FILE *f)
    {
    char ch;
    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET);
    ch = USART_ReceiveData(USART2);
    return((int)ch);
    }
    int ferror(FILE *f)
    {
    /* Your implementation of ferror */
    return EOF;
    }
    void _ttywrch(int ch)
    {
    static int last;
    if ((ch == (int)'
    ') && (last != (int)'
    '))
    {
    last = (int)'
    ';
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    USART_SendData(USART2, last);
    }
    else
    last = ch;
    while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
    USART_SendData(USART2, ch);
    }
    void _sys_exit(int return_code)
    {
    label: goto label; /* endless loop */
    }
    /**************************************************************************************/
    #ifdef USE_FULL_ASSERT
    /**
    * @brief Reports the name of the source file and the source line number
    * where the assert_param error has occurred.
    * @param file: pointer to the source file name
    * @param line: assert_param error line source number
    * @retval None
    */
    void assert_failed(uint8_t* file, uint32_t line)
    {
    /* User can add his own implementation to report the file name and line number,
    ex: printf(''Wrong parameters value: file %s on line %d
    
    '', file, line) */
    /* Infinite loop */
    while (1)
    {
    }
    }
    #endif
    /**
    * @}
    */

    myFloat 46000000 

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    dannym
    Associate III
    July 14, 2012
    Posted on July 14, 2012 at 10:05

    Well you nailed it.  

    (__FPU_PRESENT == 1) && (__FPU_USED  == 1) is already true- the project defined them as 1.

    I looked in 

    C:\Keil\STM32F4-Discovery_FW_V1.1.0\Project\hello\system_stm32f4xx.c

    SystemInit() is there, but has nothing about FPU CP10 & CP11.  I added what you suggested:

    #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

      #endif

    Into systemInit and it works!  Now why wouldn't this BE there already??  It's the init for an stm32f4, says that right in the filename, those have an FPU core.  Using the #defines as switches means it's flexible and will follow your configuration.

    doantrungnghia05
    Associate
    June 15, 2014
    Posted on June 15, 2014 at 05:35

    Bravo sir, thank you a lot !!!!!!!!