| nRF5 SDK v12.0.0 |

Choose documentation: | nRF5 SDK | S130 SoftDevice API | S132 SoftDevice API | S212 SoftDevice API | S332 SoftDevice API

All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
FPU
This information applies to the nRF52 Series only.

The FPU module is initialized when the system is powered on. You do not need to initialize it yourself. Hardware access layer and driver layer are not implemented because they are not required to work with this module.

To use this peripheral, simply use floating point instructions and functions.

Important: Remember that the floating point unit that is used in nRF52 supports only the `float` type. The `double` type is not supported by this architecture and can generate slow and inefficient code.

The FPU FFT Example provides sample code that uses the CMSIS DSP library. You can use this example to quickly get started with floating point unit in interrupt and polling modes with error handling.

# Using FPU with the CMSIS DSP library

CMSIS DSP is an efficient mathematical library designed for ARM Cortex cores that allows signal processing. CMSIS code is supported by ARM.

CMSIS DSP precompiled libraries support Keil, IAR, and GCC compilers.

To use the CMSIS DSP library:

1. Include the `arm_math.h` header
2. Add the precompiled library to your project. This step is necessary to link your code with the library code.

# Using FPU in polling mode with error handling

First, you must clear the exception flags in the Floating-point Status Control Register and clear the pending FPU interrupt. Otherwise, MCU cannot go to sleep mode. For example:

math_operation();
// Get Floating-point Status Control Register to check exception flags
uint32_t fpscr_reg = __get_FPSCR();
// Check flags if necessary
if (fpscr_reg & 0x...)
...
// To clear the IDC, IXC, UFC, OFC, DZC, and IOC flags, use 0x0000009F mask on FPSCR register
__set_FPSCR(fpscr_reg & ~(0x0000009F));
(void) __get_FPSCR();
// Clear the pending FPU interrupt. Necessary when the application uses a SoftDevice with sleep modes
NVIC_ClearPendingIRQ(FPU_IRQn);

# Using FPU in interrupt mode with error handling

You must clear exception flags in the FPSCR register and clear the pending FPU interrupt. Otherwise, MCU cannot go to sleep mode.

When using FPU with interrupt handling, remember about the stacked FPU registers and the lazy stacking mechanism.

// Function handles and clears exception flags in FPSCR register and at the stack.
// During interrupt, handler execution FPU registers might be copied to the stack
// (see lazy stacking option) and it is necessary to clear data at the stack
// which will be recovered in the return from interrupt handling.
void FPU_IRQHandler(void)
{
// Prepare pointer to stack address with pushed FPSCR register (0x40 is FPSCR register offset in stacked data)
uint32_t * fpscr = (uint32_t * )(FPU->FPCAR + 0x40);
// Execute FPU instruction to activate lazy stacking
(void)__get_FPSCR();
// Check exception flags
if (*fpscr & 0x...)
...
// Clear flags in stacked FPSCR register. To clear IDC, IXC, UFC, OFC, DZC and IOC flags, use 0x0000009F mask.
*fpscr = *fpscr & ~(0x0000009F);
}
int main(void)
{
...
// Enable FPU interrupt
NVIC_SetPriority(FPU_IRQn, APP_IRQ_PRIORITY_LOW);
NVIC_ClearPendingIRQ(FPU_IRQn);
NVIC_EnableIRQ(FPU_IRQn);
math_operation();
...
}