This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Enable FPU in LM4F232?

Hello everyone,

I am trying to use floating point units, so I am trying to enable the FPU but nothing works..

I included the "driverlib/fpu.h" and used the FPUEnable() func but still nothing works.

Can someone help me?

  • Hi,

    Look in StellarisWare/boards/ek-lm4f323/sine_demo project - it is a good starting point. 

    Petrei.

  • Hi there,

    Thats what I did, in the beginning they enable the FPU with FPUEnable() and they choose for the lazystackingmethod.

    So I did the same in my software but I still can't use any floats. Thats why I'm here.

    Is there maybe something else that I have to set or something like that?

  • Ilias Mansouri said:
    but nothing works...but still nothing works.

    Somewhat difficult to diagnose your problems with so complete a description...  (and you took pains to repeat!)

    Do you fault, get warnings etc, etc...

    Usually - when floating point enters scene - stack size must substantially increase...

    As Petrei guides - you must look intensely @ successful/model project - and insure that you've "modeled" that in your project.   (or - stay w/working model - and add your bits/pieces...)

  • Sorry for repeating myself, I'm a bit tired I gues. I didn't want to include my whole code because it is quite a piece. I'll try to filter unnecessary pieces:

    int main(void)
    {
    tCANMsgObject sCANMessage;
    unsigned char ucMsgData[6];
    int temp = 0;
    int i,x = 0;

    unsigned int DATA_MSB, DATA_LSB;
    unsigned int temp_result=0;
    float temp_result_scaled=0;
    float test_float = 0;


    // Set the clocking
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    FPUEnable();
    ROM_FPULazyStackingEnable();

    // Inits, configures and irrelevant code

    test_float = 15/2;

    UARTprintf("test_float: %f \n", test_float);

    The two last lines are my problem basicaly. Whenever I try to use a float, I get an ERROR on my terminal:

    test_float: ERROR

  • The UARTprintf function has not been updated to support the floating point conversion (%f).  For now, I would suggest using "sprintf" to print the value into a local string, then use UARTprintf to print the string.

    --Bobby

  • Hi,

    No need to repeat yourself - but the operation order is important. In sine_demo.c file I can read this:

    //
    // Enable lazy stacking for interrupt handlers. This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run directly at 50 MHz.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
    SYSCTL_OSC_MAIN);

    You must note the absence of any FPUEnable() call. That's all if you use CCS; for other tool chains, some other settings are made in startup_xxx.c file. And of coarse, the stack size, as cb1-mobile mentioned. 

    Did you run first this program to see it working?

    Petrei

    Edit: one more problem: if using floating point, it is wise to write like this: test_float = 15.0/2.0;

  • Wise always to follow advice of Petrei...  This extract (below) from fpu.c:

    //! Enables the floating-point unit.
    //!
    //! This function enables the floating-point unit, allowing the floating-point
    //! instructions to be executed.  This function must be called prior to
    //! performing any hardware floating-point operations; failure to do so results
    //! in a NOCP usage fault.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    FPUEnable(void)
    {
        //
        // Enable the coprocessors used by the floating-point unit.
        //
        HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) &
                             ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) |
                            NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL);
    }

    And we note that this same code is embedded w/in IAR's: startup_ewarm.c: (and runs upon MCU reset...)

    void
    ResetISR(void)
    {
        //
        // Enable the floating-point unit.  This must be done here to handle the
        // case where main() uses floating-point and the function prologue saves
        // floating-point registers (which will fault if floating-point is not
        // enabled).  Any configuration of the floating-point unit using DriverLib
        // APIs must be done here prior to the floating-point unit being enabled.
        //
        // Note that this does not use DriverLib since it might not be included in
        // this project.
        //
        HWREG(NVIC_CPAC) = ((HWREG(NVIC_CPAC) &
                             ~(NVIC_CPAC_CP10_M | NVIC_CPAC_CP11_M)) |
                            NVIC_CPAC_CP10_FULL | NVIC_CPAC_CP11_FULL);

        //
        // Call the application's entry point.
        //
        __iar_program_start();
    }

    File fpu.c (w/in StellarisWare\driverlib) provides "treasure trove" of helpful float detail...  (and utilization/explanations...)

  • So if I understand it correctly, I have to write this in my main:

    ROM_FPULazyStackingEnable();
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

    In the startup_ccs:

    Enable the Systickhandler and update it in my main.c

    And for the stack I'm not to sure, do I have to go to the ccs.cmd and edit the __STACK_TOP?

  • And there is that assembly code that I found in the datasheet:

    asm(" MOVW R0, #0xE000 \n"
    " MOVT R0, #0xED88 \n"
    " LDR R1, [R0]\n"
    " ORR R1, R1, #(0xF << 20)\n"
    " STR R1, [R0]\n"
    " DSB\n"
    " ISB");

    It seems to do the same as those FPU api's, can I use it instead?

  • Ilias Mansouri said:
    I am trying to use floating point units

    Before moving on to that, how about finishing the thread that you started here: http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/259190.aspx

     

  • I am terribly sorry, I've completely forgot about that thread.
    Many thanks for pointing it out,  the last weeks are terribly charged here so it completely slipped out of my mind.

    I deeply apology 

  • float test_float = 0.00

  • Sub 4 word post brings you "beyond close" to heralded "next level" status - your skill/efforts hereby memorialized and appreciated...

  • I already tried, that doesn't do the trick.
    What I think is that the FPU still isn't enabled, this is how I've done it:

    void SysTickHandler(void)
    {
    //
    // Update our tick counter.
    //
    g_ulTickCount++;
    }

    int main(void)
    {

    float temp_result=0;
    float temp_result_scaled=0;
    float test = 0;
    // Set the clocking
    ROM_FPULazyStackingEnable();
     ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
    //
    // Configure SysTick to generate a periodic time tick interrupt.
    //
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / TICKS_PER_SECOND);
    ROM_SysTickEnable();
    ROM_SysTickIntEnable();
     // Set up the serial console to use for displaying messages.
    InitConsole();

    // Code
    temp_result = Variable // Variable is an integer between 0 and 255
    temp_result_scaled = Scale_255(temp_result); // Scale Variable to 0 - 100%

    UARTprintf("Scaled Result: %f  \n", temp_result_scaled);   // Error       
    sprintf(str, " %f", temp_result_scaled);            // Solution to UARTprintf that Bobby kindly suggested
    UARTprintf("String scaled: %s  \n", str); // If Variable = 255 then %s = 100 else %s = 0

    }

    /*Scaling function */
    float Scale_255 (unsigned int value)
    {
     float temp = 0;
    char str[80];
    unsigned long ulLastTickCount=0;

    // Wait for the next timer tick.

    while(ulLastTickCount == g_ulTickCount)
    {
    }
    ulLastTickCount = g_ulTickCount;
    temp = (value/255)*100;

    return temp;
    }

  • I've found the error.

    It was a combination of multiple errors:

    - printf doesn't print floats -> thanks  Bobby
    - Stacksize wasn't properly set -> thanks  b1_mobile
    - FPU wasn't enabled -> thanks Petrei

    Thanks guys, I've spent more than 9hours straight searching for those stupid errors. 
    I could'nt have found them without your precious help.

    Sincerely,

    Ilias 

  • Rare to see "helped poster" respond w/such gratitude - thank you/appreciated.

    You of course get "lion's share" of credit for persisting - and willingness to accept (and try) suggestions.

    Our group finds that - most always - your efforts will speed, ease and enhance by first "searching for & finding" nearest applicable code-file example.  Best if you can "duplicate this file" (leave original intact/unmodified) and slowly/cautiously add "one bit at a time" (to the duplicated code-file) to extend that program to your specific requirement. 

    Bon chance mon ami - merci... 

  • Ilias Mansouri said:
    printf doesn't print floats ->

    printf() does print floats.  But you were using UARTprintf - which does not!

    UARTprintf  is specifically advertised & documented as a simplified, light-weight version of printf - and one of the simplifications is the omission of support for floats!

  • cb1_mobile,

    Thank you for the accolades.  It is an honor to walk amongst you.

  • @greenja,

    Honor all mine - great to have you back in this Stellaris (moment of silence) re-brand fold...

    (past - many BCal flights: LAX - Gatwick (direct) -> Biggin Hill)  Good times...Again Congrats & Cheers...