Skip to main content
Associate
June 14, 2024
Solved

CORDIC COS gives negative result

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.
pimatyBest answer
Associate
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.

1 reply

pimatyAuthorBest answer
Associate
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.