cancel
Showing results for 
Search instead for 
Did you mean: 

How to use the fpu in stm32f4xx ?

manes6969
Associate II
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
15 REPLIES 15
Posted on July 13, 2012 at 14:41

I'm not aware of an issue, but will try to confirm later.

0x12345 won't fit in a 16-bit int, but I'm not sure that's the issue here.

How about 'float foo = 1234.5' ?

The FPU code generation can be turned on/off in the Options->Target pane.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dannym
Associate II
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 II
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.

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
Up vote any posts that you find helpful, it shows what's working..
dannym
Associate II
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 II
Posted on June 15, 2014 at 05:35

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