5.3 CORDIC Guide
This chapter describes the file composition and 11 public functions of the CORDIC driver in the N32H49x standard peripheral library, together with 3 examples. The CORDIC is a hardware coordinate rotation digital computer built into the chip that accelerates trigonometric and hyperbolic functions, magnitude and arctangent; for the data width, scale factor and output limiting settings, see the “Coordinate rotation digital computer (CORDIC)” chapter of the user manual.
5.3.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32h49x_std_periph_driver/inc/n32h49x_cordic.h |
Defines the function, data width, scale and limit options and the register masks, and declares the 11 public functions |
firmware/n32h49x_std_periph_driver/src/n32h49x_cordic.c |
Implements the 11 functions above: initialization and structure defaults, interrupt and DMA request control, data register address retrieval and read/write, and status flag read and clear |
projects/n32h49x_EVAL/examples/CORDIC/ |
CORDIC example root directory, containing the 3 examples CORDIC_Fixed_Sin_DMA, CORDIC_Fixed_Sin_IT and CORDIC_Float_Sin_IT |
projects/n32h49x_EVAL/examples/CORDIC/CORDIC_Fixed_Sin_DMA/ |
Project directory composition of this example: MDK-ARM/, EWARM/, inc/, src/, readme.txt |
projects/n32h49x_EVAL/bsp/ |
Common board files referenced by this example: the UART log function |
5.3.2 API reference
The following 11 public functions are listed in the declaration order of n32h49x_cordic.h in 4 groups; each entry gives a summary and the original comment above the function in n32h49x_cordic.c.
Initialization and reset
CORDIC_DeInit, CORDIC_Init, CORDIC_StructInit
Interrupt and DMA request
CORDIC_InterruptCmd, CORDIC_DMAReadRequestCmd, CORDIC_DMAWriteRequestCmd
Data read and write
CORDIC_GetRegisterAddr, CORDIC_WriteData, CORDIC_ReadData
Status and flags
CORDIC_GetFlagStatus, CORDIC_ClearStatusFlag
void CORDIC_DeInit(void)DeInitializes the CORDIC peripheral.
name CORDIC_DeInit.
fun DeInitializes the CORDIC peripheral.
param none
return none
void CORDIC_Init(CORDIC_InitType* CORDIC_InitParam)Initialize the CORDIC module with CORDIC_InitParam of type CORDIC_InitType.
name CORDIC_Init.
fun Initialize the CORDIC module with CORDIC_InitParam of type CORDIC_InitType.
param CORDIC_InitParam :
- Pointer to the CORDIC_InitType structure which will be initialized.
return none
void CORDIC_StructInit(CORDIC_InitType* CORDIC_InitParam)Initializes the structure parameter of type CORDIC_InitType used to initialize CORDIC. This function is usually called before initializing a parameter of type CORDIC_InitType.
name CORDIC_StructInit.
fun Initializes the structure parameter of type CORDIC_InitType used to
initialize CORDIC. This function is usually called before initializing
a parameter of type CORDIC_InitType.
param CORDIC_InitParam :
- Pointer to the CORDIC_InitType structure which will be initialized.
return none
void CORDIC_InterruptCmd(uint32_t Interrupt, FunctionalStatus Cmd)Enables or disables the specified CORDIC interrupts.
name CORDIC_InterruptCmd.
fun Enables or disables the specified CORDIC interrupts.
param Interrupt (The input parameters must be the following values):
- CORDIC_INT
- CORDIC_INT_INOVERFLOW
param Cmd (The input parameters must be the following values):
- ENABLE
- DISABLE
return none
void CORDIC_DMAReadRequestCmd(FunctionalStatus Cmd)Enables or disables the CORDIC DMA read request.
name CORDIC_DMAReadRequestCmd.
fun Enables or disables the CORDIC DMA read request.
param Cmd (The input parameters must be the following values):
- ENABLE
- DISABLE
return none
void CORDIC_DMAWriteRequestCmd(FunctionalStatus Cmd)Enables or disables the CORDIC DMA write request.
name CORDIC_DMAWriteRequestCmd.
fun Enables or disables the CORDIC DMA write request.
param Cmd (The input parameters must be the following values):
- ENABLE
- DISABLE
return none
uint32_t CORDIC_GetRegisterAddr(uint32_t Direction)Get the CORDIC data register address used for DMA transfer.
name CORDIC_GetRegisterAddr.
fun Get the CORDIC data register address used for DMA transfer.
param Direction (The input parameters must be the following values):
- CORDIC_AS_DMA_SRCADDR
- CORDIC_AS_DMA_DSTADDR
return Address of data register.
void CORDIC_WriteData(uint32_t *pInData)Write 32-bit input data for the CORDIC processing.
name CORDIC_WriteData.
fun Write 32-bit input data for the CORDIC processing.
param pInData :
- Points to the address of input data
return none
void CORDIC_ReadData(uint32_t *pOutData)Return 32-bit output data of CORDIC processing.
name CORDIC_ReadData.
fun Return 32-bit output data of CORDIC processing.
param pOutData :
- Points to the address where the output data is stored
return 32-bit output data of CORDIC processing.
FlagStatus CORDIC_GetFlagStatus(uint32_t Flag)Checks whether the specified CORDIC flag is set or not.
name CORDIC_GetFlagStatus.
fun Checks whether the specified CORDIC flag is set or not.
param Flag (The input parameters must be the following values):
- CORDIC_FLAG_RRF
- CORDIC_FLAG_INOVF
- CORDIC_FLAG_DMAWENF
- CORDIC_FLAG_DMARENF
- CORDIC_FLAG_INTENF
return SET or RESET
void CORDIC_ClearStatusFlag(uint32_t Flag)Clears the pending flag for the CORDIC.
name CORDIC_ClearStatusFlag.
fun Clears the pending flag for the CORDIC.
param Flag (The input parameters must be the following values):
- CORDIC_FLAG_INOVF
- CORDIC_FLAG_DMAWENF
- CORDIC_FLAG_DMARENF
- CORDIC_FLAG_INTENF
return none
note The RRF flag cannot be cleared by a call to this function;
the RRF flag is cleared by hardware when reading the data
register is complete.
5.3.3 Demo descriptions
This section describes the 3 CORDIC examples: CORDIC_Fixed_Sin_DMA moves the fixed-point sine inputs and outputs by DMA, CORDIC_Fixed_Sin_IT reads the fixed-point results by interrupt, and CORDIC_Float_Sin_IT reads the floating-point results by interrupt.
5.3.3.1 CORDIC_Fixed_Sin_DMA fixed-point sine over DMA
Example directory: projects/n32h49x_EVAL/examples/CORDIC/CORDIC_Fixed_Sin_DMA/
Configure the CORDIC and DMA1 clocks→Reset the CORDIC and set up the sine parameters→Fetch the CORDIC read and write register addresses→Configure the DMA channels and enable the DMA requests→Wait for the result-ready flag and compare with the reference sines
| Item | Source analysis |
|---|---|
| Function | Computes 64 points of sine in Q1.31 fixed-point format; the CORDIC is set to the sine function with 6-cycle precision and both coordinate and phase limits are enabled; the DMA read channel moves CORDIC_RDAT results into aCalResult and the write channel moves aInData into CORDIC_WDAT;after the transfer every point is compared against aRefResult. |
| Source files | src/main.c: main, RCC_Configuration, NVIC_Configuration, DMA_ReadConfiguration, DMA_WriteConfiguration, CheckResidualError;inc/n32h49x_it.h, src/n32h49x_it.c: interrupt vectors and exception handlers;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: the CORDIC and DMA1 clocks are enabled and RCC_ConfigPeriphClk(RCC_PERIPH_HCLK_DIV2) is called;CORDIC: CORDIC_FUNCTION_SINE, CORDIC_PRECISION_6CYCLES, CORDIC_CODIN_LIMIT_ENABLE and CORDIC_PHASE_LIMIT_ENABLE;read channel: DMA1_CH1 remapped with DMA_REMAP_CORDIC_RD;write channel: DMA1_CH2 remapped with DMA_REMAP_CORDIC_WR, both WORD wide with memory increment and a length of 64. |
| Program and data path | main calls RCC_Configuration, NVIC_Configuration and CORDIC_DeInit in turn;CORDIC_GetRegisterAddr returns the CORDIC_RDAT and CORDIC_WDAT addresses and CORDIC_Init selects the sine function;after the read request is enabled DMA_ReadConfiguration moves results into aCalResult, and after the write request is enabled DMA_WriteConfiguration moves aInData into the CORDIC;once CORDIC_FLAG_RRF is set, every point is compared with aRefResult through CheckResidualError. |
| Main APIs | CORDIC_DeInit, CORDIC_GetRegisterAddr, CORDIC_Init, CORDIC_DMAReadRequestCmd, CORDIC_DMAWriteRequestCmd, CORDIC_GetFlagStatus |
| Verification | After building, downloading and running, the UART prints “CORDIC demo success!!!” when all 64 points are within tolerance; if a point deviates by more than MAX_RESIDUAL_ERROR_18, “Error[i]” is printed and the program stays in while(1). |
| Use note | When the CORDIC is enabled the HCLK must be set to DIV2; input data is Q1.31 fixed point, incrementing from 0 to 2*pi; this example has no standalone main.h;its inc/ directory only holds the interrupt header. |
Core-code walkthrough and porting
The example uses two DMA channels to move the 64 fixed-point inputs into the CORDIC and the results out, and finally compares every point against the reference sines.
Data path: RCC_Configuration enables the CORDIC and DMA1 clocks and sets the HCLK to DIV2 → CORDIC_DeInit resets the module → CORDIC_GetRegisterAddr returns the CORDIC_RDAT and CORDIC_WDAT addresses → CORDIC_Init selects the sine function → the DMA read and write channels move aInData into the CORDIC and the results into aCalResult → after CORDIC_FLAG_RRF is set, every point is compared with aRefResult
1. Configure the CORDIC and DMA1 clocks. RCC_Configuration enables the CORDIC and DMA1 clocks and sets the HCLK to DIV2, which is required when the CORDIC is enabled.
void RCC_Configuration()
{
/* Enable DMA1 and CORDIC clock */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_CORDIC | RCC_AHB_PERIPHEN_DMA1, ENABLE);
/* When enabling CORDIC, HCLK DIV2 must be configured */
RCC_ConfigPeriphClk(RCC_PERIPH_HCLK_DIV2);
}
When porting to another model only the CORDIC and the used DMA clocks are needed; RCC_PERIPH_HCLK_DIV2 cannot be omitted.
2. Fetch the data register addresses and select the sine function. main first calls CORDIC_GetRegisterAddr for the read and write data register addresses used by the DMA, then configures the CORDIC for sine with 6-cycle precision and enables the coordinate and phase limits through the structure.
/* Get CORDIC read register (CORDIC_RDAT) address */
rRegAddr = CORDIC_GetRegisterAddr(CORDIC_AS_DMA_SRCADDR);
/* Get CORDIC write register (CORDIC_WDAT) address */
wRegAddr = CORDIC_GetRegisterAddr(CORDIC_AS_DMA_DSTADDR);
CORDIC_StructInit(&CORDIC_InitStructure);
/* Select sine function */
CORDIC_InitStructure.Function = CORDIC_FUNCTION_SINE;
/* Set max precision for Q1.31 sine */
CORDIC_InitStructure.Precision = CORDIC_PRECISION_6CYCLES;
/* Enable Coordinate Limit */
CORDIC_InitStructure.CodinLimit = CORDIC_CODIN_LIMIT_ENABLE;
/* Enable Phase Limit */
CORDIC_InitStructure.PhaseLimit = CORDIC_PHASE_LIMIT_ENABLE;
/* Configure CORDIC */
CORDIC_Init(&CORDIC_InitStructure);
For another function or precision only Function and Precision change; the read and write register addresses are told apart by the Direction argument.
3. Configure the DMA channels and enable the DMA requests. DMA_ReadConfiguration sets the peripheral address to CORDIC_RDAT and the memory address to aCalResult, and remaps the channel to the CORDIC read request; main then enables both DMA requests, and the write side moves aInData into CORDIC_WDAT through DMA_WriteConfiguration.
/* Reset DMA1 channel 1 */
DMA_DeInit(DMA1_CH1);
/* Initialize the DMA parameter structure */
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.PeriphAddr = SrcAddr;
DMA_InitStructure.MemAddr = (uint32_t)DstAddr;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = DataLen;
DMA_InitStructure.MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_WORD;
DMA_InitStructure.MemDataSize = DMA_MEM_DATA_WIDTH_WORD;
/* Initialize DMA1 channel 1 */
DMA_Init(DMA1_CH1, &DMA_InitStructure);
/* CORDIC read channel mapping */
DMA_RequestRemap(DMA_REMAP_CORDIC_RD, DMA1_CH1, ENABLE);
/* Enable DMA1 channel 1 transfer completion interrupt */
DMA_ConfigInt(DMA1_CH1, DMA_INT_TXC, ENABLE);
/* Enable DMA1 channel 1 */
DMA_EnableChannel(DMA1_CH1, ENABLE);
/* Configure DMA read channel */
DMA_ReadConfiguration(rRegAddr, aCalResult, ARRAY_SIZE);
/* Enable CORDIC DMA read request */
CORDIC_DMAReadRequestCmd(ENABLE);
/* Configure DMA write channel */
DMA_WriteConfiguration(aInData, wRegAddr, ARRAY_SIZE);
/* Enable CORDIC DMA write request */
CORDIC_DMAWriteRequestCmd(ENABLE);
When porting, the request remap of the two channels must match the actual transfer direction; in DMA mode the CPU must not access the CORDIC data register directly.
4. Wait for the result and compare with the reference. After the computation starts main polls CORDIC_FLAG_RRF and, once it is set, compares every point with the reference sine through CheckResidualError.
while (CORDIC_GetFlagStatus(CORDIC_FLAG_RRF) == RESET)
{
/* Do nothing */
}
/* Compare CORDIC results to the reference values */
for (i = 0; i < ARRAY_SIZE; i++)
{
/* Check the data results sequentially */
if (CheckResidualError(aCalResult[i], aRefResult[i], MAX_RESIDUAL_ERROR_18) == 0U)
{
log_info("Error[%d]\n", i);
while (1);
}
}
The tolerance constant follows the precision: at 6-cycle precision the sine residual error is about 2^-18.
Corresponding source files: src/main.c
5.3.3.2 CORDIC_Fixed_Sin_IT fixed-point sine read by interrupt
Example directory: projects/n32h49x_EVAL/examples/CORDIC/CORDIC_Fixed_Sin_IT/
Configure the CORDIC clock→Reset and set up the sine parameters→Enable the CORDIC interrupt→Write the Q1.31 input points one by one→Read the results back in the interrupt and compare with the reference sines
| Item | Source analysis |
|---|---|
| Function | Computes 64 points of sine in Q1.31 fixed-point format; the input is written point by point into CORDIC_WDAT by the main loop and every ready result triggers the Cordic_IRQn interrupt;Cordic_IRQ_IRQHandler reads the results back into aCalResult, and the main loop then compares every point against aRefResult. |
| Source files | src/main.c: main, RCC_Configuration, NVIC_Configuration, CheckResidualError, Cordic_IRQ_IRQHandler;inc/n32h49x_it.h, src/n32h49x_it.c: interrupt vectors and exception handlers;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: the CORDIC clock is enabled and RCC_ConfigPeriphClk(RCC_PERIPH_HCLK_DIV2) is called;CORDIC: CORDIC_FUNCTION_SINE, CORDIC_PRECISION_6CYCLES, CORDIC_CODIN_LIMIT_ENABLE and CORDIC_PHASE_LIMIT_ENABLE, with CORDIC_InterruptCmd(CORDIC_INT, ENABLE) called;NVIC: priority group 0 with Cordic_IRQn enabled. |
| Program and data path | main calls RCC_Configuration, NVIC_Configuration, CORDIC_DeInit and CORDIC_Init in turn;after the interrupt is enabled a for loop writes each point of aInData with CORDIC_WriteData;every finished computation makes Cordic_IRQ_IRQHandler check CORDIC_FLAG_RRF and read CORDIC_RDAT into aCalResult with CORDIC_ReadData;the main loop compares every point with aRefResult through CheckResidualError. |
| Main APIs | CORDIC_DeInit, CORDIC_Init, CORDIC_InterruptCmd, CORDIC_WriteData, CORDIC_ReadData, CORDIC_GetFlagStatus |
| Verification | After building, downloading and running, the UART prints “CORDIC demo success!!!” when all 64 points are within tolerance; if a point deviates by more than MAX_RESIDUAL_ERROR_18, “Error[i]” is printed and the program stays in while(1). |
| Use note | When the CORDIC is enabled the HCLK must be set to DIV2; reading the result register inserts a bus wait until the computation finishes, so CORDIC_ReadData can be called directly in the interrupt;reading the data register clears CORDIC_FLAG_RRF in hardware. |
Core-code walkthrough and porting
The example writes the 64 fixed-point inputs into the CORDIC point by point; every ready result is read back by the Cordic_IRQn interrupt, and the results are finally compared with the reference sines.
Data path: RCC_Configuration enables the CORDIC clock and sets the HCLK to DIV2 → CORDIC_DeInit resets the module → CORDIC_Init selects the sine function → CORDIC_InterruptCmd enables the interrupt → the main loop writes aInData with CORDIC_WriteData → Cordic_IRQ_IRQHandler reads CORDIC_RDAT into aCalResult → the main loop compares with aRefResult
1. Configure the CORDIC clock. RCC_Configuration enables the CORDIC clock and sets the HCLK to DIV2.
void RCC_Configuration()
{
/* Enable CORDIC clock */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_CORDIC, ENABLE);
/* When enabling CORDIC, HCLK DIV2 must be configured */
RCC_ConfigPeriphClk(RCC_PERIPH_HCLK_DIV2);
}
RCC_PERIPH_HCLK_DIV2 is required when the CORDIC is enabled and cannot be omitted when porting.
2. Set up the sine function and enable the interrupt. main configures the CORDIC for sine with 6-cycle precision and the coordinate and phase limits, and enables the CORDIC interrupt.
CORDIC_StructInit(&CORDIC_InitStructure);
/* Select sine function */
CORDIC_InitStructure.Function = CORDIC_FUNCTION_SINE;
/* Set max precision for Q1.31 sine */
CORDIC_InitStructure.Precision = CORDIC_PRECISION_6CYCLES;
/* Enable Coordinate Limit */
CORDIC_InitStructure.CodinLimit = CORDIC_CODIN_LIMIT_ENABLE;
/* Enable Phase Limit */
CORDIC_InitStructure.PhaseLimit = CORDIC_PHASE_LIMIT_ENABLE;
/* Configure CORDIC */
CORDIC_Init(&CORDIC_InitStructure);
/* Enable CORDIC interrupt */
CORDIC_InterruptCmd(CORDIC_INT, ENABLE);
The interrupt scheme suits reading results as they are produced, so the CPU does not poll the completion flag.
3. Write the input points one by one. With the interrupt enabled main writes every point of aInData into the data register, and the hardware starts computing right away.
for (wArrayIndex = 0; wArrayIndex < ARRAY_SIZE; wArrayIndex++)
{
/* Write data to be calculated */
CORDIC_WriteData((uint32_t *)&aInData[wArrayIndex]);
}
The Q1.31 input is spread evenly from 0 to 2*pi, and the write order is the read order of the results.
4. Read the results back in the interrupt. Cordic_IRQ_IRQHandler checks CORDIC_FLAG_RRF and, when it is set, reads the data register into aCalResult; the read also clears the flag in hardware.
void Cordic_IRQ_IRQHandler(void)
{
if (CORDIC_GetFlagStatus(CORDIC_FLAG_RRF) != RESET)
{
/* Read calculation results */
/* The RRF flag will be cleared after reading the data register */
CORDIC_ReadData((uint32_t *)&aCalResult[rArrayIndex++]);
}
}
When combining several channels or DMA, remember that CORDIC_RDAT must not be read by the CPU once the DMA read channel is enabled.
Corresponding source files: src/main.c
5.3.3.3 CORDIC_Float_Sin_IT floating-point sine read by interrupt
Example directory: projects/n32h49x_EVAL/examples/CORDIC/CORDIC_Float_Sin_IT/
Configure the CORDIC clock→Reset and set up the floating-point sine parameters→Enable the CORDIC interrupt→Generate and write random inputs→Read the floating-point results back in the interrupt and compare
| Item | Source analysis |
|---|---|
| Function | Computes 64 points of sine in floating-point format;rand generates inputs in the range -1.0 to 1.0 and sinf computes the software reference;the CORDIC is set for floating-point input and output, and the results read back by interrupt are compared with the reference. |
| Source files | src/main.c: main, RCC_Configuration, NVIC_Configuration, CheckResidualError, Cordic_IRQ_IRQHandler;inc/n32h49x_it.h, src/n32h49x_it.c: interrupt vectors and exception handlers;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: the CORDIC clock is enabled and RCC_ConfigPeriphClk(RCC_PERIPH_HCLK_DIV2) is called;CORDIC: CORDIC_FUNCTION_SINE, CORDIC_PRECISION_6CYCLES, CORDIC_INPUT_FLOAT and CORDIC_OUTPUT_FLOAT, with the coordinate and phase limits enabled;NVIC: priority group 0 with Cordic_IRQn enabled. |
| Program and data path | main initializes the clock, the NVIC and the CORDIC in turn;a for loop fills aInData with rand and computes aRefResult with sinf;the inputs are then written point by point with CORDIC_WriteData and Cordic_IRQ_IRQHandler reads aCalResult back;the main loop compares them with CheckResidualError. |
| Main APIs | CORDIC_DeInit, CORDIC_Init, CORDIC_InterruptCmd, CORDIC_WriteData, CORDIC_ReadData, CORDIC_GetFlagStatus |
| Verification | The UART prints “CORDIC demo success!!!” when all floating-point results are within tolerance; if a point deviates by more than MAX_RESIDUAL_ERROR_18, “Error[i]” is printed and the program stays in while(1). |
| Use note | The floating-point input must stay in the range -1.0 to 1.0; the sinf reference is computed as the sine of the input multiplied by pi, matching the CORDIC convention;the HCLK must also be set to DIV2 when the CORDIC is enabled. |
Core-code walkthrough and porting
The example drives the CORDIC with random floating-point inputs and compares the results read back by interrupt with the reference computed by sinf.
Data path: RCC_Configuration enables the CORDIC clock and sets the HCLK to DIV2 → CORDIC_DeInit resets the module → CORDIC_Init selects the floating-point sine → CORDIC_InterruptCmd enables the interrupt → a loop fills aInData and aRefResult and writes with CORDIC_WriteData → Cordic_IRQ_IRQHandler reads CORDIC_RDAT into aCalResult → the main loop compares
1. Configure the CORDIC clock. As in the fixed-point example, RCC_Configuration enables the CORDIC clock and sets the HCLK to DIV2.
void RCC_Configuration(void)
{
/* Enable CORDIC clock */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_CORDIC, ENABLE);
/* When enabling CORDIC, HCLK DIV2 must be configured */
RCC_ConfigPeriphClk(RCC_PERIPH_HCLK_DIV2);
}
The divider setting matches the fixed-point example and can be reused directly.
2. Set up the floating-point sine and enable the interrupt. The structure matches the fixed-point example, with floating-point input and output selected as well.
CORDIC_StructInit(&CORDIC_InitStructure);
/* Select sine function */
CORDIC_InitStructure.Function = CORDIC_FUNCTION_SINE;
/* Set max precision for Q1.31 sine */
CORDIC_InitStructure.Precision = CORDIC_PRECISION_6CYCLES;
/* Select floating-point input */
CORDIC_InitStructure.InSelect = CORDIC_INPUT_FLOAT;
/* Select floating-point output */
CORDIC_InitStructure.OutSelect = CORDIC_OUTPUT_FLOAT;
/* Enable Coordinate Limit */
CORDIC_InitStructure.CodinLimit = CORDIC_CODIN_LIMIT_ENABLE;
/* Enable Phase Limit */
CORDIC_InitStructure.PhaseLimit = CORDIC_PHASE_LIMIT_ENABLE;
/* Configure CORDIC */
CORDIC_Init(&CORDIC_InitStructure);
/* Enable CORDIC interrupt */
CORDIC_InterruptCmd(CORDIC_INT, ENABLE);
In floating-point mode both input and output are interpreted as single-precision floats and no Q1.31 conversion is performed.
3. Generate the random inputs and the reference. The main loop generates inputs from -1.0 to 1.0 with rand and computes the software reference with sinf.
for (i = 0; i < ARRAY_SIZE; i++)
{
/* Random generation of input data */
aInData[i] = -1.0f + ((float)(rand() % 1999)) * 0.001f;
/* Software calculation results */
aRefResult[i] = sinf(aInData[i] * PI);
}
The generated range matches the hardware phase input range, so points outside the range would be limited and are not part of the correctness check.
4. Write the inputs and read the results back in the interrupt. As in the fixed-point example, the write side calls CORDIC_WriteData point by point and the read side reads the data register in Cordic_IRQ_IRQHandler.
void Cordic_IRQ_IRQHandler(void)
{
if (CORDIC_GetFlagStatus(CORDIC_FLAG_RRF) != RESET)
{
/* Read calculation results */
/* The RRF flag will be cleared after reading the data register */
CORDIC_ReadData((uint32_t *)&aCalResult[rArrayIndex++]);
}
}
The floating-point results are compared with aRefResult directly, and the tolerance is again controlled by MAX_RESIDUAL_ERROR_18.
Corresponding source files: src/main.c
5.3.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| Result read and wait | Once a computation has started, reading the result register inserts a bus wait until the computation finishes, so the program does not need to poll the completion flag. | User manual |
| Output limiting | CODINLIMIT clamps the coordinate outputs to ±1 and PHASELIMIT clamps the phase output to ±π;limiting changes results that fall outside the range. |
User manual |
| Angle range | The valid range of the phase input is [-1, 1), which is the actual angle divided by pi. | User manual |
| Input range and scaling | When the magnitudes of x and y are outside the allowed range, both x and y must be scaled by the same factor before they are supplied. | User manual |
| 16-bit result packing | With INSIZE = 1, NUMWRITE must be 0;with OUTSIZE = 1, NUMREAD must be 0 and the result register is read only once. |
User manual |
| DMA and CPU access | After the DMA read channel is enabled, CORDIC_RDAT must not be accessed by the CPU;after the DMA write channel is enabled, CORDIC_WDAT must not be accessed by the CPU. |
User manual |
| Scale factor and DMA | The SCALE factor must not be changed while a DMA transfer is in progress. |
User manual |
| DMA for repeated operations only | The CORDIC has no DMA request for programming CTRLSTS, so DMA mode suits only repeated computations with the same function and settings. |
User manual |
| Writing the configuration register | Writing CTRLSTS discards data that has been stored but not yet computed. |
User manual |
| Scaling precision | The scale factor introduces truncation error, and the loss of precision grows with the number of scaled bits. | User manual |