Check FPU function using Cos & Sin calculation

main.cpp

Committer:
kenjiArai
Date:
2017-08-31
Revision:
0:c46022441981
Child:
1:a8ba417b1717

File content as of revision 0:c46022441981:

/*
 * Check FPU function using Cos & Sin calculation 
 *
 * Copyright (c) 2017 Kenji Arai / JH1PJL
 *  http://www.page.sannet.ne.jp/kenjia/index.html
 *  http://mbed.org/users/kenjiArai/
 *      Modify:     August    31st, 2017
 *      Revised:    August    31st, 2017
 */

/*==============================================================================
    ------------------------ My boards result -------------------------------
                STM32F446RE                     STM32F411RE
    Sys Clock       180 MHz                          100 MHz
    double          24074 nS                         39751 nS
    ratio(double/float)  20.02                            21.85
    float            1102 nS                          1986 nS
    ratio(F411/F446 double)           1.65
    ratio(F411/F446 float)            1.80                              
  ============================================================================*/

//  Include --------------------------------------------------------------------
#include "mbed.h"

//  Definition -----------------------------------------------------------------
#if defined(TARGET_STM32F446RE) || defined(TARGET_STM32F411xE)
#define BUF_SIZE    7000
#else
#error "You need modify your program for your specific target CPU"
#endif

//  Constractor ----------------------------------------------------------------
Serial  pc(USBTX, USBRX);
DigitalIn   sw(USER_BUTTON);
Timer   t;

//  RAM ------------------------------------------------------------------------
float   buf0[BUF_SIZE];
double  buf1[BUF_SIZE];

//  ROM / Constant data --------------------------------------------------------
 
//  Function prototypes --------------------------------------------------------
void test_FPU_0(float  *buf0);
void test_FPU_1(double *buf1);

//------------------------------------------------------------------------------
//  Control Program
//------------------------------------------------------------------------------
int main()
{
    pc.printf("\r\nSystem Clock = %d Hz\r\n", HAL_RCC_GetSysClockFreq());
    // Check FPU settings
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    // Mbed compiler set CP10 and CP11 Full Access
    //      SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
    pc.printf("Use FPU function (compiler enables FPU)\r\n");
    pc.printf("SCB->CPACR(0x%08x) = 0x%08x\r\n", &SCB->CPACR, SCB->CPACR);
#else
    #warning "NOT use FPU in your setting"
#endif
    pc.printf("Buf size in RAM = %d + %d = %d bytes\r\n",
                sizeof(buf0), sizeof(buf1), sizeof(buf0) + sizeof(buf1));
    pc.printf("Repeat number = %d\r\n", BUF_SIZE);
    pc.printf("\r\nHit any key or push USER SW then show buffer content\r\n");
    pc.printf("Following time is average calculate time Sin()+Cos()\r\n");
    pc.printf("  (float)       (double)\r\n");
    while (true) {
        uint32_t t0, t1;

        t.reset();
        t.start();
        test_FPU_0(buf0);
        t0 = t.read_us();
        t.reset();
        t.start();
        test_FPU_1(buf1);
        t1 = t.read_us();
        pc.printf("t0 =%.3f uS, t1 =%.3f uS\r\n",
                 (float)t0 / (float)BUF_SIZE, (float)t1 / (float)BUF_SIZE);
        if ((sw == 0) || (pc.readable())){
            for (uint16_t n = 0; n < BUF_SIZE; n++){
                pc.printf("%+8.6f,%+8.6lf,%+8.6lf\r\n",
                           buf0[n], buf1[n], (double)buf0[n] - buf1[n]);
            }
            while (pc.readable()){ pc.getc();}
        }
        wait(1.0f);
    }
}

void test_FPU_0(float *buf0)
{
    int32_t i;
    volatile float d, d0, d1;
    float step;

    step = ((2.0f * PI) + 0.1f) / (float)BUF_SIZE;
    d = 0.0f;
    for(i = 0; i < BUF_SIZE; i++){
        d0 = sin(d);
        d1 = cos(d);
        d += step;
        buf0[i] = d0;
    }
}

void test_FPU_1(double *buf1)
{
    int32_t i;
    volatile double d, d0, d1;
    double step;

    step = ((2.0f * PI) + 0.1f) / (double)BUF_SIZE;
    d = 0.0f;
    for(i = 0; i < BUF_SIZE; i++){
        d0 = sin(d);
        d1 = cos(d);
        d += step;
        buf1[i] = d0;
    }
}