Skip to main content
Explorer II
June 14, 2024
Solved

CORDIC COS gives negative result

  • June 14, 2024
  • 1 reply
  • 927 views

I am testing CORDIC module on STM32H723ZG.

 

The results from CORDIC_FUNCTION_COSINE calculation are consistently negative where they should be positive and vice versa. This holds for 32BIT calculations and for 16BIT as well. Cannot find why this is taking place. The code and example results below.

Has anybody seen this behavior?

For example:

pimaty_0-1718371560565.png

 

The testing part of the code for 32Bit case looks like this:

 

CORDIC_Config_32BIT(sConfig);

printf("***** CORDIC RESULT 32BIT ***** \n");

for (int i = 0; i < 360; i+=1){

q31_angles[i] = f32_to_q31(i / 360.0) << 1; // angle in rad divided by pi,

f32_angles[i] = q31_to_f32(q31_angles[i]);

printf("%lf - %ld - %lf \n", i*2/360.0, q31_angles[i], f32_angles[i]);

}

for (int ii = 0; ii < 360; ii+=20){

CORDIC->WDATA = q31_angles[ii];

CORDIC->WDATA = ((int32_t)0x80000000);

tt1 = (int32_t)CORDIC->RDATA;

tt2 = (int32_t)CORDIC->RDATA;

cor_cos = q31_to_f32(tt1);

cor_sin = q31_to_f32(tt2);

printf("%16ld - %16.3lf - %16ld - %16ld - %16.3lf - %16.3lf \n", \

q31_angles[ii], f32_angles[ii], tt1, tt2, cor_cos, cor_sin);

}

 

 where the CORDIC is set as follows:

 

 

void CORDIC_Config_32BIT(CORDIC_ConfigTypeDef* sConfig){

sConfig->Function = CORDIC_FUNCTION_COSINE;

sConfig->Precision = CORDIC_PRECISION_6CYCLES;

sConfig->Scale = CORDIC_SCALE_0;

sConfig->NbWrite = CORDIC_NBWRITE_2;

sConfig->NbRead = CORDIC_NBREAD_2;

sConfig->InSize = CORDIC_INSIZE_32BITS; /* q1.31 format for output data */

sConfig->OutSize = CORDIC_INSIZE_32BITS; /* q1.31 format for output data */

HAL_CORDIC_Configure(&hcordic, sConfig);

}

 

and for 16Bit case:

 

CORDIC_Config_16BIT(sConfig);

printf("***** CORDIC RESULT 16BIT ***** \n");

for (int i = 0; i < 360; i+=1){

q15_angles[i] = f32_to_q15(i / 360.0f) << 1;

f32_angles[i] = q15_to_f32(q15_angles[i]);

//printf("%10.3f %10d %10u %10.3f \n", i*2 / 360.0f, \

(int16_t)q15_angles[i], q15_angles[i], f32_angles[i]);

}

for (int ii = 0; ii < 360; ii+=20){

CORDIC->WDATA = (((uint32_t)0x8000 << 16) | (q15_angles[ii])); // scaling & angle

tt1 = CORDIC->RDATA;

cor_cos_16 = q15_to_f32(lower_int16(tt1));

cor_sin_16 = q15_to_f32(upper_int16(tt1));

printf(" %10u - %10.3f - %10d - %10d - %10.3f - %10.3f \n", \

q15_angles[ii], f32_angles[ii], lower_int16(tt1), upper_int16(tt1), cor_cos_16, cor_sin_16);

}

 

 where the CORDIC is set as follows:

 

void CORDIC_Config_16BIT(CORDIC_ConfigTypeDef* sConfig){

sConfig->Function = CORDIC_FUNCTION_COSINE;

sConfig->Precision = CORDIC_PRECISION_6CYCLES;

sConfig->Scale = CORDIC_SCALE_0;

sConfig->NbWrite = CORDIC_NBWRITE_1;

sConfig->NbRead = CORDIC_NBREAD_1;

sConfig->InSize = CORDIC_INSIZE_16BITS; /* q1.15 format for input data */

sConfig->OutSize = CORDIC_OUTSIZE_16BITS; /* q1.15 format for input data */

HAL_CORDIC_Configure(&hcordic, sConfig);

}

PM

    This topic has been closed for replies.
    Best answer by pimaty

    Found the error: ((uint32_t)0x8000) sets the scaling argument to -1 (in Q1.15 format), and dso the module does the right thing.

    1 reply

    pimatyAuthorAnswer
    Explorer II
    June 17, 2024

    Found the error: ((uint32_t)0x8000) sets the scaling argument to -1 (in Q1.15 format), and dso the module does the right thing.