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?
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.
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 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?
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 cb1_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!