diff --git a/G4:G431/CORDIC/astro.c b/G4:G431/CORDIC/astro.c new file mode 100644 index 0000000..ae4796e --- /dev/null +++ b/G4:G431/CORDIC/astro.c @@ -0,0 +1,204 @@ +/* + * This file is part of the cordic project. + * Copyright 2026 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "astro.h" +#include "cordic.h" + +static int sincosflag = 0; // math.h +// longitude/latitude + in rad/hrs +//static float longitude = 41.44143375f, latitude = 43.6535278f; +static float lat_rad = 43.6535278f * M_PIf / 180.f; +static float long_hrs = 41.44143375f / 15.f; + +static void sincosf_m(float angle, float *s, float *c){ + if(s) *s = sin(angle); + if(c) *c = cos(angle); +} + +static void (*sincosf)(float, float*, float*) = sincosf_m; + +void set_sincos(int iscordic){ + if(iscordic) sincosf = cordic_sincos; + else sincosf = sincosf_m; + sincosflag = iscordic; +} + +int get_sincos(){ return sincosflag; } + +/* Helper functions for angle normalization (single precision) */ +static float normalize_degrees(float angle){ + angle = fmodf(angle, 360.0f); + if (angle < 0.0f) angle += 360.0f; + return angle; +} + +static float normalize_hours(float hours){ + hours = fmodf(hours, 24.0f); + if (hours < 0.0f) hours += 24.0f; + return hours; +} + +/* 1. Compute Modified Julian Date from UNIX time (seconds since 1970-01-01 00:00:00 UTC) */ +float MJD_from_unix(uint32_t t){ + return 40587.f + (float)t / 86400.0f; +} + +float LST_from_unix(uint32_t t){ + uint32_t days = t / 86400; + uint32_t sec = t % 86400; + + float mjd_int = 40587.0f + (float)days; + + float T = (mjd_int - 51544.5f) / 36525.0f, T2 = T*T, T3 = T2*T; + float gmst0_sec = 24110.54841f + 8640184.812866f*T + 0.093104f*T2 - 6.2e-6f*T3; + float ut1_sec = (float)sec * 1.00273790935f; + float gmst_sec = gmst0_sec + ut1_sec; + float lst_hours = gmst_sec / 3600.0f + long_hrs; + return normalize_hours(lst_hours); +} + +/* 3. Convert Hour Angle (HA) to Right Ascension (RA) and vice versa. + All angles in degrees. LST is Local Sidereal Time in degrees. */ +float ha_to_ra(float ha, float lst){ + float ra = lst - ha; + return normalize_degrees(ra); +} + +float ra_to_ha(float ra, float lst){ + float ha = lst - ra; + // Hour angle is usually in range [-180,180) + ha = normalize_degrees(ha); + if (ha > 180.0f) ha -= 360.0f; + return ha; +} + +/* 4. Convert Altitude-Azimuth coordinates to Equatorial (Hour Angle, Declination) + and back. All angles in degrees. Azimuth is measured from North through East. */ +void altaz_to_hadec(float alt_deg, float az_deg, float *ha_deg, float *dec_deg){ + float alt = alt_deg * M_PIf / 180.0f; + float az = az_deg * M_PIf / 180.0f; + + float sin_alt, cos_alt, sin_az, cos_az, sin_lat, cos_lat; + sincosf(alt, &sin_alt, &cos_alt); + sincosf(az, &sin_az, &cos_az); + sincosf(lat_rad, &sin_lat, &cos_lat); + + /* Declination */ + float sin_dec = sin_alt * sin_lat + cos_alt * cos_lat * cos_az; + float dec = asinf(sin_dec); + + /* Hour angle (using atan2f for sign determination) */ + float x = sin_alt * cos_lat - cos_alt * sin_lat * cos_az; + float y = -cos_alt * sin_az; + float ha = atan2f(y, x); // radians + + *ha_deg = ha * 180.0f / M_PIf; + *dec_deg = dec * 180.0f / M_PIf; +} + +void hadec_to_altaz(float ha_deg, float dec_deg, float *alt_deg, float *az_deg){ + float ha = ha_deg * M_PIf / 180.0f; + float dec = dec_deg * M_PIf / 180.0f; + + float sin_dec, cos_dec, sin_ha, cos_ha, sin_lat, cos_lat; + sincosf(dec, &sin_dec, &cos_dec); + sincosf(ha, &sin_ha, &cos_ha); + sincosf(lat_rad, &sin_lat, &cos_lat); + + /* Altitude */ + float sin_alt = sin_lat * sin_dec + cos_lat * cos_dec * cos_ha; + float alt = asinf(sin_alt); + + /* Azimuth (from North through East) */ + float x = sin_dec * cos_lat - cos_dec * sin_lat * cos_ha; + float y = -cos_dec * sin_ha; + float az = atan2f(y, x); // radians, [-Ï€, Ï€] + + *alt_deg = alt * 180.0f / M_PIf; + *az_deg = az * 180.0f / M_PIf; + if (*az_deg < 0.0f) *az_deg += 360.0f; +} + +/** + * @brief Calculate refraction constants A and B for the model dZ = A*tan(Z) + B*tan^3(Z) + * + * This is a single-precision adaptation of the SOFA iauRefco / ERFA eraRefco function. + * Optimized for microcontrollers without hardware double-precision support (e.g., STM32G431). + * + * @param phpa Pressure at the observer (hPa = mbar) + * @param tc Ambient temperature at the observer (degrees C) + * @param rh Relative humidity at the observer (range 0-1) + * @param wl Wavelength (micrometers). Use 0.55 for optical, >100 for radio. + * @param refa Output: tan(Z) coefficient (radians) + * @param refb Output: tan^3(Z) coefficient (radians) + */ +static void refco_f32(float phpa, float tc, float rh, float wl, float *refa, float *refb) { + // Restrict input parameters to safe values (clamp) + float t = tc; + if(t < -150.0f) t = -150.0f; + if(t > 200.0f) t = 200.0f; + + float p = phpa; + if(p < 0.0f) p = 0.0f; + if(p > 10000.0f) p = 10000.0f; + + float r = rh; + if(r < 0.0f) r = 0.0f; + if(r > 1.0f) r = 1.0f; + + float w = wl; + if(w < 0.1f) w = 0.1f; + if(w > 10.0f) w = 10.0f; + + // Water vapour pressure at the observer + float pw = 0.0f; + if(p > 0.0f){ + // Saturation vapour pressure (empirical formula) + float ps = powf(10.0f, (0.7859f + 0.03477f * t) / (1.0f + 0.00412f * t)) + * (1.0f + p * (4.5e-6f + 6e-10f * t * t)); + pw = r * ps / (1.0f - (1.0f - r) * ps / p); + } + + // Temperature in Kelvin + float tk = t + 273.15f; + + // Refractive index minus 1 at the observer (gamma = (n - 1) at the observer) + float gamma; + // Optical/IR: wavelength-dependent formula + float wlsq = w * w; + gamma = ((77.53484e-6f + (4.39108e-7f + 3.666e-9f / wlsq) / wlsq) * p + - 11.2684e-6f * pw) / tk; + + // Beta coefficient (from Stone, with empirical adjustments) + float beta = 4.4474e-6f * tk; + + // Refraction constants (from Green) + if(refa) *refa = gamma * (1.0f - beta); + if(refb) *refb = -gamma * (beta - gamma / 2.0f); +} + +//alt_corrected = alt_apparent + refraction +float refraction(float phpa, float tc, float rh, float Z_rad){ + float A, B; + refco_f32(phpa, tc, rh, 0.55, &A, &B); + float tanZ = tanf(Z_rad); + return A * tanZ + B * tanZ * tanZ * tanZ; +} diff --git a/G4:G431/CORDIC/astro.h b/G4:G431/CORDIC/astro.h new file mode 100644 index 0000000..bae29a8 --- /dev/null +++ b/G4:G431/CORDIC/astro.h @@ -0,0 +1,32 @@ +/* + * This file is part of the cordic project. + * Copyright 2026 Edward V. Emelianov . + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +void set_sincos(int iscordic); +int get_sincos(); +float MJD_from_unix(uint32_t t); +//float LST_from_mjd(float mjd); +float LST_from_unix(uint32_t t); +float ha_to_ra(float ha, float lst); +float ra_to_ha(float ra, float lst); +void altaz_to_hadec(float alt_deg, float az_deg, float *ha_deg, float *dec_deg); +void hadec_to_altaz(float ha_deg, float dec_deg, float *alt_deg, float *az_deg); +float refraction(float phpa, float tc, float rh, float Z_rad); diff --git a/G4:G431/CORDIC/commproto.cpp b/G4:G431/CORDIC/commproto.cpp index 6d071fa..6d86e7a 100644 --- a/G4:G431/CORDIC/commproto.cpp +++ b/G4:G431/CORDIC/commproto.cpp @@ -19,9 +19,12 @@ #include extern "C"{ +#include #include +#include "astro.h" #include "commproto.h" +#include "cordic.h" #include "hardware.h" #include "strfunc.h" #include "test.h" @@ -42,8 +45,11 @@ extern volatile uint32_t Tms; // list of all commands and handlers #define COMMAND_TABLE \ COMMAND(help, "show this help") \ + COMMAND(sets, "set sin-cos to cordic (1) or math (0)") \ + COMMAND(sincos, "calculate sin/cos for given angle in degrees") \ + COMMAND(testc, "test CORDIC function: sincos, sin, cos, atan, sqrt, log") \ COMMAND(testm, "test math function: sin, cos, atan, sqrt, log") \ - COMMAND(testc, "test CORDIC function: sin, cos, atan, sqrt, log") + COMMAND(time, "show MJD and LST for given UNIX-time") \ typedef struct { @@ -103,7 +109,6 @@ static char *splitargs(char *args, int32_t *parno){ return next; } -#if 0 /** * @brief argsvals - split `args` into `parno` and setter's value * @param args - rest of string after command @@ -122,7 +127,6 @@ static bool argsvals(char *args, int32_t *parno, int32_t *parval){ } return false; } -#endif static errcodes_t cmd_help(const char*, char*){ SEND(REPOURL); @@ -134,8 +138,8 @@ static errcodes_t cmd_help(const char*, char*){ return ERR_AMOUNT; } -static const char* parse_func_name(char *args, int32_t *parno){ - char *setter = splitargs(args, parno); +static const char* parse_func_name(char *args){ + char *setter = splitargs(args, NULL); if(!setter) return nullptr; // remove trailing spaces char *p = setter; @@ -144,10 +148,25 @@ static const char* parse_func_name(char *args, int32_t *parno){ return setter; } +// calculate sin/cos +static errcodes_t cmd_sincos(const char *, char *args){ + char *setter = splitargs(args, NULL); + float f; + if(!setter || !getfloat(setter, &f)) return ERR_BADVAL; + f = f/180.f * M_PIf; + SEND("mathsin="); SEND(float2str(sinf(f), 7)); + SEND("\nmathcos="); SEND(float2str(cosf(f), 7)); + float s, c; + cordic_sincos(f, &s, &c); + SEND("\ncordicsin="); SEND(float2str(s, 7)); + SEND("\ncordiccos="); SEND(float2str(c, 7)); + SEND("\n"); + return ERR_AMOUNT; +} + // test math function static errcodes_t cmd_testm(const char*, char *args){ - int32_t parno; - const char *fname = parse_func_name(args, &parno); + const char *fname = parse_func_name(args); if(!fname) return ERR_BADPAR; uint32_t elapsed = 0; bool ok = true; @@ -174,12 +193,14 @@ static errcodes_t cmd_testm(const char*, char *args){ // test CORDIC function static errcodes_t cmd_testc(const char*, char *args){ - int32_t parno; - const char *fname = parse_func_name(args, &parno); + const char *fname = parse_func_name(args); if(!fname) return ERR_BADPAR; uint32_t elapsed = 0; bool ok = true; - if(strcmp(fname, "sin") == 0){ + if(strcmp(fname, "sincos") == 0){ + elapsed = test_cordic_sincos(); + } + else if(strcmp(fname, "sin") == 0){ elapsed = test_cordic_sin(); }else if(strcmp(fname, "cos") == 0){ elapsed = test_cordic_cos(); @@ -199,6 +220,27 @@ static errcodes_t cmd_testc(const char*, char *args){ return ERR_AMOUNT; } +static errcodes_t cmd_time(const char *, char *args){ + char *setter = splitargs(args, NULL); + if(!setter) return ERR_BADVAL; + uint32_t unix_time; + if(setter == getnum(setter, &unix_time)) return ERR_BADVAL; + float mjd = MJD_from_unix(unix_time); + SEND("MJD="); SEND(float2str(mjd, 7)); + SEND("\nLST="); SEND(float2str(LST_from_unix(unix_time), 7)); + SEND("\n"); + return ERR_AMOUNT; +} + +static errcodes_t cmd_sets(const char *cmd, char *args){ + int32_t val; + if(argsvals(args, NULL, &val)) set_sincos(val); + CMDEQ(); + if(get_sincos()) SEND("CORDIC\n"); + else SEND("MATH\n"); + return ERR_AMOUNT; +} + constexpr uint32_t hash(const char* str, uint32_t h = 0){ return *str ? hash(str + 1, h + ((h << 7) ^ *str)) : h; } diff --git a/G4:G431/CORDIC/cordic.bin b/G4:G431/CORDIC/cordic.bin index eea0d95..678d43f 100755 Binary files a/G4:G431/CORDIC/cordic.bin and b/G4:G431/CORDIC/cordic.bin differ diff --git a/G4:G431/CORDIC/cordic.c b/G4:G431/CORDIC/cordic.c index 1d74445..359de15 100644 --- a/G4:G431/CORDIC/cordic.c +++ b/G4:G431/CORDIC/cordic.c @@ -33,17 +33,12 @@ static void cordic_enable(void){ static int32_t float_to_q31(float x){ if(x >= 1.0f) x = 1.0f - 1e-6f; if(x <= -1.0f) x = -1.0f + 1e-6f; - return (int32_t)(x * 2147483648.0f); + return (int32_t)(x * Q31_BASE); } // Convert Q1.31 to float static float q31_to_float(int32_t q){ - return (float)q / 2147483648.0f; -} - -// Wait CORDIC ready -static void cordic_wait_ready(void){ - while(!(CORDIC->CSR & CORDIC_CSR_RRDY)); + return (float)q / Q31_BASE; } static void cordic_init(void){ @@ -72,28 +67,40 @@ static float cordic_scalar(uint32_t func_mode, float x, int arg_count){ } #endif +// sincos +void cordic_sincos(float angle, float *s, float *c){ + float norm = angle / M_PIf; + if(norm > 1.0f) norm = 1.0f; + if(norm < -1.0f) norm = -1.0f; + cordic_init(); + CORDIC->CSR = (CORDIC_CSR_FUNC_SIN << CORDIC_CSR_FUNC_Pos) | CORDIC_CSR_DEF | CORDIC_CSR_NRES; + CORDIC->WDATA = float_to_q31(norm); + int32_t res = CORDIC->RDATA; + if(s) *s = q31_to_float(res); + res = CORDIC->RDATA; + if(c) *c = q31_to_float(res); +} + // sin float cordic_sin(float angle){ - float norm = angle / 3.141592653589793f; + float norm = angle / M_PIf; if(norm > 1.0f) norm = 1.0f; if(norm < -1.0f) norm = -1.0f; cordic_init(); CORDIC->CSR = (CORDIC_CSR_FUNC_SIN << CORDIC_CSR_FUNC_Pos) | CORDIC_CSR_DEF; CORDIC->WDATA = float_to_q31(norm); - cordic_wait_ready(); - int32_t res = CORDIC->RDATA; // ÐÅÒ×ÏÅ ÞÔÅÎÉÅ -> sin + int32_t res = CORDIC->RDATA; return q31_to_float(res); } // cos float cordic_cos(float angle){ - float norm = angle / 3.141592653589793f; + float norm = angle / M_PIf; if(norm > 1.0f) norm = 1.0f; if(norm < -1.0f) norm = -1.0f; cordic_init(); CORDIC->CSR = (CORDIC_CSR_FUNC_COS << CORDIC_CSR_FUNC_Pos) | CORDIC_CSR_DEF; CORDIC->WDATA = float_to_q31(norm); - cordic_wait_ready(); int32_t res = CORDIC->RDATA; // cos return q31_to_float(res); } @@ -104,9 +111,8 @@ float cordic_atan(float val){ cordic_init(); CORDIC->CSR = (CORDIC_CSR_FUNC_ATAN << CORDIC_CSR_FUNC_Pos) | CORDIC_CSR_DEF; CORDIC->WDATA = float_to_q31(val); - cordic_wait_ready(); int32_t res = CORDIC->RDATA; - return q31_to_float(res) * 3.141592653589793f; + return q31_to_float(res) * M_PIf; } // sqrt @@ -123,7 +129,6 @@ float cordic_sqrt(float x){ cordic_init(); CORDIC->CSR = (CORDIC_CSR_FUNC_SQRT << CORDIC_CSR_FUNC_Pos) | CORDIC_CSR_DEF; CORDIC->WDATA = float_to_q31(x); - cordic_wait_ready(); int32_t res = CORDIC->RDATA; return scale * q31_to_float(res); } @@ -141,7 +146,6 @@ float cordic_log(float x){ cordic_init(); CORDIC->CSR = (CORDIC_CSR_FUNC_LOG << CORDIC_CSR_FUNC_Pos) | CORDIC_CSR_DEF; CORDIC->WDATA = float_to_q31(x); - cordic_wait_ready(); int32_t res = CORDIC->RDATA; return q31_to_float(res) * 0.6931471805599453f + add; } diff --git a/G4:G431/CORDIC/cordic.files b/G4:G431/CORDIC/cordic.files index a700edc..3f705b7 100644 --- a/G4:G431/CORDIC/cordic.files +++ b/G4:G431/CORDIC/cordic.files @@ -1,3 +1,5 @@ +astro.c +astro.h commproto.cpp commproto.h cordic.c diff --git a/G4:G431/CORDIC/cordic.h b/G4:G431/CORDIC/cordic.h index 05849bc..4d4e26d 100644 --- a/G4:G431/CORDIC/cordic.h +++ b/G4:G431/CORDIC/cordic.h @@ -20,6 +20,12 @@ #include +#ifndef M_PIf +#define M_PIf 3.141592653589793f +#endif + +#define Q31_BASE 2147483648.0f + // functions enum { CORDIC_CSR_FUNC_COS = 0, @@ -33,6 +39,7 @@ enum { CORDIC_CSR_FUNC_SQRT }; +void cordic_sincos(float angle, float *s, float *c); float cordic_sin(float angle); float cordic_cos(float angle); float cordic_atan(float val); diff --git a/G4:G431/CORDIC/strfunc.c b/G4:G431/CORDIC/strfunc.c index cc39bb7..809ac23 100644 --- a/G4:G431/CORDIC/strfunc.c +++ b/G4:G431/CORDIC/strfunc.c @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include // isnan/isinf #include #include @@ -262,3 +263,116 @@ char *getint(char *txt, int32_t *I){ *I = sign * (int32_t)U; return nxt; } + +// be careful: if pow10 would be bigger you should change str[] size! +static const float pwr10[] = {1.f, 10.f, 100.f, 1000.f, 10000.f, 100000.f, 1000000.f, 10000000.f}; +static const float rounds[] = {0.5f, 0.05f, 0.005f, 0.0005f, 0.00005f, 0.000005f, 0.0000005f, 0.00000005f}; +#define P10L (sizeof(pwr10)/sizeof(float) - 1) +char *float2str(float x, uint8_t prec){ + static char str[16] = {0}; // -117.5494E-36\0 - 14 symbols max! + if(prec > P10L) prec = P10L; + if(isnan(x)){ memcpy(str, "NAN", 4); return str;} + else{ + int i = isinf(x); + if(i){memcpy(str, "-INF", 5); if(i == 1) return str+1; else return str;} + } + char *s = str + 14; // go to end of buffer + uint8_t minus = 0; + if(x < 0){ + x = -x; + minus = 1; + } + int pow = 0; // xxxEpow + // now convert float to 1.xxxE3y + while(x > 1000.f){ + x /= 1000.f; + pow += 3; + } + if(x > 0.) while(x < 1.){ + x *= 1000.f; + pow -= 3; + } + // print Eyy + if(pow){ + uint8_t m = 0; + if(pow < 0){pow = -pow; m = 1;} + while(pow){ + int p10 = pow/10; + *s-- = '0' + (pow - 10*p10); + pow = p10; + } + if(m) *s-- = '-'; + *s-- = 'E'; + } + // now our number is in [1, 1000] + uint32_t units; + if(prec){ + units = (uint32_t) x; + uint32_t decimals = (uint32_t)((x-units+rounds[prec])*pwr10[prec]); + // print decimals + while(prec){ + int d10 = decimals / 10; + *s-- = '0' + (decimals - 10*d10); + decimals = d10; + --prec; + } + // decimal point + *s-- = '.'; + }else{ // without decimal part + units = (uint32_t) (x + 0.5); + } + // print main units + if(units == 0) *s-- = '0'; + else while(units){ + uint32_t u10 = units / 10; + *s-- = '0' + (units - 10*u10); + units = u10; + } + if(minus) *s-- = '-'; + return s+1; +} + +char *getfloat(char *str, float *f){ + str = omit_spaces(str); + int isminus = 0; + if(*str == '-'){ + isminus = 1; + ++str; + }else if (*str == '+'){ + ++str; + } + float result = 0.0f; + while(*str >= '0' && *str <= '9'){ + result = result * 10.0f + (float)(*str - '0'); + ++str; + } + if(*str != '.') goto retn; + + ++str; // omit point + float frac = 0.0f; + float divisor = 1.0f; + + while(*str >= '0' && *str <= '9'){ + divisor *= 10.0f; + frac = frac * 10.0f + (float)(*str - '0'); + ++str; + } + + if(divisor > 1.0f){ + result += frac / divisor; + } + + if(*str == 'e' || *str == 'E'){ // exp + ++str; + int32_t E; + if(str != getint(str, &E)){ + if(E > 0) while(E-- > 0) result *= 10.f; + else while(E++ < 0) result /= 10.f; + } + } + +retn: + if(f) *f = (isminus) ? -result : result; + return str; +} + diff --git a/G4:G431/CORDIC/strfunc.h b/G4:G431/CORDIC/strfunc.h index bd1950c..1e7cce2 100644 --- a/G4:G431/CORDIC/strfunc.h +++ b/G4:G431/CORDIC/strfunc.h @@ -19,12 +19,13 @@ #include +char *omit_spaces(char *buf); void hexdump(int (*sendfun)(const char*), uint8_t *arr, uint16_t len); char *u2str(uint32_t val); char *i2str(int32_t i); +char *float2str(float x, uint8_t prec); char *uhex2str(uint32_t val); char *gethex(const char *buf, uint32_t *N); char *getnum(char *txt, uint32_t *N); -char *omit_spaces(char *buf); char *getint(char *txt, int32_t *I); - +char *getfloat(char *str, float *f); diff --git a/G4:G431/CORDIC/test.c b/G4:G431/CORDIC/test.c index aae3602..12472f0 100644 --- a/G4:G431/CORDIC/test.c +++ b/G4:G431/CORDIC/test.c @@ -32,7 +32,7 @@ static float arr[N_TESTS]; // RNG static uint32_t rand_state = 123456789; -static uint32_t next_rand(void){ +static uint32_t next_rand(){ rand_state = rand_state * 1664525 + 1013904223; return rand_state; } @@ -76,36 +76,52 @@ static uint32_t run_test(void (*gen)(), float (*func)(float)){ return timer_read(); } +static uint32_t run_test2(void (*gen)(), void (*func)(float, float*, float*)){ + gen(); + volatile float result1 = 0.f, result2 = 0.f; // don't let gcc to optimize this cycle + timer_start(); + for(int i = 0; i < N_TESTS; ++i){ + func(arr[i], (float*)&result1, (float*)&result2); + (void) result1; + (void) result2; + } + timer_stop(); + return timer_read(); +} + // ------------- math.h tests ------------- -uint32_t test_math_sin(void){ +uint32_t test_math_sin(){ return run_test(fill_random_sin_cos, sinf); } -uint32_t test_math_cos(void){ +uint32_t test_math_cos(){ return run_test(fill_random_sin_cos, cosf); } -uint32_t test_math_atan(void){ +uint32_t test_math_atan(){ return run_test(fill_random_atan, atanf); } -uint32_t test_math_sqrt(void){ +uint32_t test_math_sqrt(){ return run_test(fill_random_sqrt, sqrtf); } -uint32_t test_math_log(void){ +uint32_t test_math_log(){ return run_test(fill_random_log, logf); } // ------------- CORDIC tests ------------- -uint32_t test_cordic_sin(void){ +uint32_t test_cordic_sincos(){ + return run_test2(fill_random_sin_cos, cordic_sincos); +} +uint32_t test_cordic_sin(){ return run_test(fill_random_sin_cos, cordic_sin); } -uint32_t test_cordic_cos(void){ +uint32_t test_cordic_cos(){ return run_test(fill_random_sin_cos, cordic_cos); } -uint32_t test_cordic_atan(void){ +uint32_t test_cordic_atan(){ return run_test(fill_random_atan, cordic_atan); } -uint32_t test_cordic_sqrt(void){ +uint32_t test_cordic_sqrt(){ return run_test(fill_random_sqrt, cordic_sqrt); } -uint32_t test_cordic_log(void){ +uint32_t test_cordic_log(){ return run_test(fill_random_log, cordic_log); } diff --git a/G4:G431/CORDIC/test.h b/G4:G431/CORDIC/test.h index fe6d095..b84248a 100644 --- a/G4:G431/CORDIC/test.h +++ b/G4:G431/CORDIC/test.h @@ -28,6 +28,7 @@ uint32_t test_math_sqrt(); uint32_t test_math_log(); // CORDIC tests +uint32_t test_cordic_sincos(); uint32_t test_cordic_sin(); uint32_t test_cordic_cos(); uint32_t test_cordic_atan(); diff --git a/G4:G431/CORDIC/version.inc b/G4:G431/CORDIC/version.inc index d8c9689..7630c46 100644 --- a/G4:G431/CORDIC/version.inc +++ b/G4:G431/CORDIC/version.inc @@ -1,2 +1,2 @@ -#define BUILD_NUMBER "19" -#define BUILD_DATE "2026-08-04" +#define BUILD_NUMBER "48" +#define BUILD_DATE "2026-08-12"