stm32: cordic: add new peripheral
Review-URL: https://github.com/libopencm3/libopencm3/pull/1418 Reviewed-by: Karl Palsson <karlp@tweak.net.au> Edits: removed non-existant u5 code, squished to a single commit, whitespace cleanup.
This commit is contained in:
169
include/libopencm3/stm32/common/cordic_common_v1.h
Normal file
169
include/libopencm3/stm32/common/cordic_common_v1.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/** @addtogroup cordic_defines
|
||||
|
||||
@author @htmlonly © @endhtmlonly 2022 Oskar H. Maier <ohma@posteo.de>
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* Copyright (C) 2022 Oskar H. Maier <ohma@posteo.de>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**@{*/
|
||||
|
||||
/* THIS FILE SHOULD NOT BE INCLUDED DIRECTLY, BUT ONLY VIA CORDIC.H
|
||||
The order of header inclusion is important. cordic.h includes the device
|
||||
specific memorymap.h header before including this header file.*/
|
||||
|
||||
/** @cond */
|
||||
#ifdef LIBOPENCM3_CORDIC_H
|
||||
/** @endcond */
|
||||
#ifndef LIBOPENCM3_CORDIC_COMMON_V1_H
|
||||
#define LIBOPENCM3_CORDIC_COMMON_V1_H
|
||||
|
||||
/** @defgroup cordic_registers CORDIC registers
|
||||
@{*/
|
||||
/* ----- CORDIC registers ----- */
|
||||
/** CORDIC control/status register */
|
||||
#define CORDIC_CSR MMIO32(CORDIC_BASE + 0x00)
|
||||
/** CORDIC argument register */
|
||||
#define CORDIC_WDATA MMIO32(CORDIC_BASE + 0x04)
|
||||
/** CORDIC result register */
|
||||
#define CORDIC_RDATA MMIO32(CORDIC_BASE + 0x08)
|
||||
/**@}*/
|
||||
|
||||
/* ----- Register values ----- */
|
||||
|
||||
/* ----- CORDIC_CSR Values ----- */
|
||||
/** @defgroup cordic_csr CSR CORDIC control/status register
|
||||
@{*/
|
||||
/** RRDY: result ready flag */
|
||||
#define CORDIC_CSR_RRDY (0x1 << 31)
|
||||
/** ARGSIZE: Width of input data */
|
||||
#define CORDIC_CSR_ARGSIZE (0x1 << 22)
|
||||
/** RESSIZE: Width of result data */
|
||||
#define CORDIC_CSR_RESSIZE (0x1 << 21)
|
||||
/** NARGS: Number of input data writes */
|
||||
#define CORDIC_CSR_NARGS (0x1 << 20)
|
||||
/** NRES: Number of result data reads */
|
||||
#define CORDIC_CSR_NRES (0x1 << 19)
|
||||
/** DMAWEN: DMA write enable */
|
||||
#define CORDIC_CSR_DMAWEN (0x1 << 18)
|
||||
/** DMAREN: DMA write enable */
|
||||
#define CORDIC_CSR_DMAREN (0x1 << 17)
|
||||
/** DMAREN: Interrupt enable */
|
||||
#define CORDIC_CSR_IEN (0x1 << 16)
|
||||
|
||||
/** @defgroup cordic_csr_scale SCALE: Scaling factor
|
||||
@{*/
|
||||
#define CORDIC_CSR_SCALE_1 (0x0)
|
||||
#define CORDIC_CSR_SCALE_2 (0x1)
|
||||
#define CORDIC_CSR_SCALE_4 (0x2)
|
||||
#define CORDIC_CSR_SCALE_8 (0x3)
|
||||
#define CORDIC_CSR_SCALE_16 (0x4)
|
||||
#define CORDIC_CSR_SCALE_32 (0x5)
|
||||
#define CORDIC_CSR_SCALE_64 (0x6)
|
||||
#define CORDIC_CSR_SCALE_128 (0x7)
|
||||
/**@}*/
|
||||
#define CORDIC_CSR_SCALE_SHIFT (8)
|
||||
#define CORDIC_CSR_SCALE_MASK (0x7 << CORDIC_CSR_SCALE_SHIFT)
|
||||
|
||||
/** @defgroup cordic_csr_precision PRECISION: Precision of CORDIC operation (number of iterations)
|
||||
@{*/
|
||||
#define CORDIC_CSR_PRECISION_ITER_04 (0x1)
|
||||
#define CORDIC_CSR_PRECISION_ITER_08 (0x2)
|
||||
#define CORDIC_CSR_PRECISION_ITER_12 (0x3)
|
||||
#define CORDIC_CSR_PRECISION_ITER_16 (0x4)
|
||||
#define CORDIC_CSR_PRECISION_ITER_20 (0x5)
|
||||
#define CORDIC_CSR_PRECISION_ITER_24 (0x6)
|
||||
#define CORDIC_CSR_PRECISION_ITER_28 (0x7)
|
||||
#define CORDIC_CSR_PRECISION_ITER_32 (0x8)
|
||||
#define CORDIC_CSR_PRECISION_ITER_36 (0x9)
|
||||
#define CORDIC_CSR_PRECISION_ITER_40 (0xA)
|
||||
#define CORDIC_CSR_PRECISION_ITER_44 (0xB)
|
||||
#define CORDIC_CSR_PRECISION_ITER_48 (0xC)
|
||||
#define CORDIC_CSR_PRECISION_ITER_52 (0xD)
|
||||
#define CORDIC_CSR_PRECISION_ITER_56 (0xE)
|
||||
#define CORDIC_CSR_PRECISION_ITER_60 (0xF)
|
||||
/**@}*/
|
||||
#define CORDIC_CSR_PRECISION_SHIFT (4)
|
||||
#define CORDIC_CSR_PRECISION_MASK (0xF << CORDIC_CSR_PRECISION_SHIFT)
|
||||
|
||||
/** @defgroup cordic_csr_function FUNCTION: CORDIC operation to be performed
|
||||
@{*/
|
||||
#define CORDIC_CSR_FUNC_COS (0x0)
|
||||
#define CORDIC_CSR_FUNC_SIN (0x1)
|
||||
#define CORDIC_CSR_FUNC_PHASE (0x2)
|
||||
#define CORDIC_CSR_FUNC_MODULUS (0x3)
|
||||
#define CORDIC_CSR_FUNC_ATAN (0x4)
|
||||
#define CORDIC_CSR_FUNC_COSH (0x5)
|
||||
#define CORDIC_CSR_FUNC_SINH (0x6)
|
||||
#define CORDIC_CSR_FUNC_ATANH (0x7)
|
||||
#define CORDIC_CSR_FUNC_COSINE (0x8)
|
||||
#define CORDIC_CSR_FUNC_SQRT (0x9)
|
||||
/**@}*/
|
||||
#define CORDIC_CSR_FUNC_SHIFT (0)
|
||||
#define CORDIC_CSR_FUNC_MASK (0xF << CORDIC_CSR_FUNC_SHIFT)
|
||||
|
||||
/**@}*/
|
||||
|
||||
/* --- Function prototypes ------------------------------------------------- */
|
||||
|
||||
BEGIN_DECLS
|
||||
|
||||
bool cordic_is_result_ready(void);
|
||||
void cordic_set_argument_width_32bit(void);
|
||||
void cordic_set_argument_width_16bit(void);
|
||||
void cordic_set_result_width_32bit(void);
|
||||
void cordic_set_result_width_16bit(void);
|
||||
void cordic_set_number_of_arguments_1(void);
|
||||
void cordic_set_number_of_arguments_2(void);
|
||||
void cordic_set_number_of_results_1(void);
|
||||
void cordic_set_number_of_results_2(void);
|
||||
void cordic_enable_dma_write(void);
|
||||
void cordic_disable_dma_write(void);
|
||||
void cordic_enable_dma_read(void);
|
||||
void cordic_disable_dma_read(void);
|
||||
void cordic_enable_interrupt(void);
|
||||
void cordic_set_scaling_factor(uint8_t n);
|
||||
void cordic_set_precision(uint8_t precision);
|
||||
void cordic_set_function(uint8_t function);
|
||||
void cordic_write_16bit_argument(uint16_t argument);
|
||||
void cordic_write_16bit_arguments(uint16_t argument1, uint16_t argument2);
|
||||
void cordic_write_32bit_argument(uint32_t argument);
|
||||
uint16_t cordic_read_16bit_result(void);
|
||||
void cordic_read_16bit_results(uint16_t *result1, uint16_t *result2);
|
||||
uint32_t cordic_read_32bit_result(void);
|
||||
void cordic_configure_for_cos_16bit(void);
|
||||
void cordic_configure_for_cos_32bit(void);
|
||||
void cordic_configure_for_sin_16bit(void);
|
||||
void cordic_configure_for_sin_32bit(void);
|
||||
int16_t cordic_cos_16bit(int16_t x);
|
||||
int32_t cordic_cos_32bit(int32_t x);
|
||||
int16_t cordic_sin_16bit(int16_t x);
|
||||
int32_t cordic_sin_32bit(int32_t x);
|
||||
void cordic_cos_16bit_async(int16_t x);
|
||||
void cordic_cos_32bit_async(int32_t x);
|
||||
void cordic_sin_16bit_async(int16_t x);
|
||||
void cordic_sin_32bit_async(int32_t x);
|
||||
END_DECLS
|
||||
|
||||
#endif
|
||||
/** @cond */
|
||||
#endif
|
||||
/** @endcond */
|
||||
/**@}*/
|
||||
29
include/libopencm3/stm32/cordic.h
Normal file
29
include/libopencm3/stm32/cordic.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* This provides unification of code over STM32 subfamilies */
|
||||
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libopencm3/cm3/common.h>
|
||||
#include <libopencm3/stm32/memorymap.h>
|
||||
|
||||
#if defined(STM32G4)
|
||||
# include <libopencm3/stm32/g4/cordic.h>
|
||||
#elif defined(STM32U5)
|
||||
# include <libopencm3/stm32/u5/cordic.h>
|
||||
#else
|
||||
# error "stm32 family not defined."
|
||||
#endif
|
||||
34
include/libopencm3/stm32/g4/cordic.h
Normal file
34
include/libopencm3/stm32/g4/cordic.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/** @defgroup cordic_defines CORDIC Defines
|
||||
*
|
||||
* @brief <b>Defined Constants and Types for the STM32G4xx CORDIC</b>
|
||||
*
|
||||
* @ingroup STM32G4xx_defines
|
||||
*
|
||||
* @version 1.0.0
|
||||
*
|
||||
* LGPL License Terms @ref lgpl_license
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LIBOPENCM3_CORDIC_H
|
||||
#define LIBOPENCM3_CORDIC_H
|
||||
|
||||
#include <libopencm3/stm32/common/cordic_common_v1.h>
|
||||
|
||||
#endif
|
||||
486
lib/stm32/common/cordic_common_v1.c
Normal file
486
lib/stm32/common/cordic_common_v1.c
Normal file
@@ -0,0 +1,486 @@
|
||||
/** @addtogroup cordic_file CORDIC peripheral API
|
||||
@ingroup peripheral_apis
|
||||
|
||||
@author @htmlonly © @endhtmlonly
|
||||
2022 Oskar H. Maier <ohma@posteo.de>
|
||||
|
||||
This library supports the CORDIC co-processor in the STM32 series of
|
||||
ARM Cortex Microcontrollers by ST Microelectronics. This peripheral
|
||||
computes trigonometric and hyperbolic functions and converts between
|
||||
cartesian and polar coordinates.
|
||||
|
||||
|
||||
|
||||
LGPL License Terms @ref lgpl_license
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* Copyright (C) 2022 Oskar H. Maier <ohma@posteo.de>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**@{*/
|
||||
|
||||
#include <libopencm3/stm32/cordic.h>
|
||||
|
||||
|
||||
/** @brief Read CORDIC result ready flag
|
||||
*
|
||||
* This flag is set by hardware when a CORDIC operation completes.
|
||||
* It is automatically cleared when all results have been read.
|
||||
*
|
||||
* @returns Result ready flag.
|
||||
*/
|
||||
bool cordic_is_result_ready(void) {
|
||||
return CORDIC_CSR & CORDIC_CSR_RRDY;
|
||||
}
|
||||
|
||||
/** @brief Set CORDIC to 32 bit argument data width.
|
||||
*
|
||||
* When configured this way, argument(s) are expected with 32 bit width.
|
||||
* Two write operations are required for operations with two arguments.
|
||||
*
|
||||
*/
|
||||
void cordic_set_argument_width_32bit(void) {
|
||||
CORDIC_CSR &= ~CORDIC_CSR_ARGSIZE;
|
||||
}
|
||||
|
||||
/** @brief Set CORDIC to 16 bit argument data width.
|
||||
*
|
||||
* When configured this way, argument(s) are expected with 16 bit width.
|
||||
* Only one 32 bit write operation is required even for operations with two arguments
|
||||
* (in this case lower 16 bits contain argument 1, higher 16 bits contain argument 2).
|
||||
*
|
||||
*/
|
||||
void cordic_set_argument_width_16bit(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_ARGSIZE;
|
||||
}
|
||||
|
||||
/** @brief Set CORDIC to 32 bit result data width.
|
||||
*
|
||||
* When configured this way, results(s) are written with 32 bit width.
|
||||
* Two read operations are required for operations with two results.
|
||||
*
|
||||
*/
|
||||
void cordic_set_result_width_32bit(void) {
|
||||
CORDIC_CSR &= ~CORDIC_CSR_RESSIZE;
|
||||
}
|
||||
|
||||
/** @brief Set CORDIC to 16 bit result data width.
|
||||
*
|
||||
* When configured this way, results are written with 16 bit width.
|
||||
* Only one 32 bit read operation is required even for operations with two results
|
||||
* (in this case lower 16 bits contain result 1, higher 16 bits contain result 2).
|
||||
*
|
||||
*/
|
||||
void cordic_set_result_width_16bit(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_RESSIZE;
|
||||
}
|
||||
|
||||
/** @brief Set number of CORDIC arguments to one 32 bit argument or two 16 bit arguments.
|
||||
*
|
||||
* Use this option for CORDIC operations with only one argument and CORDIC operations
|
||||
* with two 16 bit arguments. In this case the operation is triggered
|
||||
* as soon as one 32bit write to the CORDIC_WDATA register occurred.
|
||||
*
|
||||
*/
|
||||
void cordic_set_number_of_arguments_1(void) {
|
||||
CORDIC_CSR &= ~CORDIC_CSR_NARGS;
|
||||
}
|
||||
|
||||
/** @brief Set number of CORDIC arguments to two 32 bit arguments.
|
||||
*
|
||||
* Use this option for CORDIC operations with two 32 bit arguments.
|
||||
* In this case the operation is triggered as soon as two 32bit
|
||||
* writes to the CORDIC_WDATA register occurred.
|
||||
*
|
||||
*/
|
||||
void cordic_set_number_of_arguments_2(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_NARGS;
|
||||
}
|
||||
|
||||
/** @brief Set number of CORDIC results to one 32 bit result or two 16 bit results.
|
||||
*
|
||||
* Use this option for CORDIC operations with only one result and CORDIC operations
|
||||
* with two 16 bit results. In this case the result ready flag is cleared and a new operation
|
||||
* can be started as soon as one 32bit read from the CORDIC_RDATA register occurred.
|
||||
*
|
||||
*/
|
||||
void cordic_set_number_of_results_1(void) {
|
||||
CORDIC_CSR &= ~CORDIC_CSR_NRES;
|
||||
}
|
||||
|
||||
/** @brief Set number of CORDIC results to two 32 bit results.
|
||||
*
|
||||
* Use this option for CORDIC operations with two 32 bit results.
|
||||
* In this case the result ready flag is cleared and a new operation can be started
|
||||
* as soon as two 32 bit reads from the CORDIC_RDATA register occurred.
|
||||
*
|
||||
*/
|
||||
void cordic_set_number_of_results_2(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_NRES;
|
||||
}
|
||||
|
||||
/** @brief Enable DMA for writes to CORDIC_WDATA
|
||||
*
|
||||
* When enabled, the peripheral will continue to generate DMA requests
|
||||
* when new arguments can be loaded into the CORDIC_WDATA register.
|
||||
*
|
||||
*/
|
||||
void cordic_enable_dma_write(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_DMAWEN;
|
||||
}
|
||||
|
||||
/** @brief Disable DMA for writes to CORDIC_WDATA
|
||||
*
|
||||
* When disabled, the peripheral will not generate DMA requests
|
||||
* when new arguments can be loaded into the CORDIC_WDATA register.
|
||||
*
|
||||
*/
|
||||
void cordic_disable_dma_write(void) {
|
||||
CORDIC_CSR &= ~CORDIC_CSR_DMAWEN;
|
||||
}
|
||||
|
||||
/** @brief Enable DMA for read from CORDIC_RDATA
|
||||
*
|
||||
* When enabled, the peripheral will continue to generate DMA requests
|
||||
* when new results can be read from the CORDIC_RDATA register.
|
||||
*
|
||||
*/
|
||||
void cordic_enable_dma_read(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_DMAREN;
|
||||
}
|
||||
|
||||
/** @brief Disable DMA for read from CORDIC_RDATA
|
||||
*
|
||||
* When disabled, the peripheral will not generate DMA requests
|
||||
* when new results can be read from the CORDIC_RDATA register.
|
||||
*
|
||||
*/
|
||||
void cordic_disable_dma_read(void) {
|
||||
CORDIC_CSR &= ~CORDIC_CSR_DMAREN;
|
||||
}
|
||||
|
||||
/** @brief Enable interrupt when result is ready
|
||||
*
|
||||
* When enabled, the peripheral will generate an interrupt
|
||||
* when the CORDIC_CSR_RRDY flag is set.
|
||||
*
|
||||
*/
|
||||
void cordic_enable_interrupt(void) {
|
||||
CORDIC_CSR |= CORDIC_CSR_IEN;
|
||||
}
|
||||
|
||||
/** @brief Set scaling factor for CORDIC operations
|
||||
*
|
||||
* For some operations, the arguments can be multiplied by a factor of 2^-n
|
||||
* to fit in the argument range. The result must then be multiplied by 2^n.
|
||||
* @param[in] n scaling factor of type @ref cordic_csr_scale
|
||||
*
|
||||
*/
|
||||
void cordic_set_scaling_factor(uint8_t n) {
|
||||
CORDIC_CSR = (CORDIC_CSR & ~CORDIC_CSR_SCALE_MASK) | (n << CORDIC_CSR_SCALE_SHIFT);
|
||||
}
|
||||
|
||||
/** @brief Set precision for CORDIC operations
|
||||
*
|
||||
* The speed of CORDIC operations can be increased by lowering the
|
||||
* number of iterations. This will decrease precision.
|
||||
* @param[in] precision precision of type @ref cordic_csr_precision
|
||||
*
|
||||
*/
|
||||
void cordic_set_precision(uint8_t precision) {
|
||||
CORDIC_CSR = (CORDIC_CSR & ~CORDIC_CSR_PRECISION_MASK) | (precision << CORDIC_CSR_PRECISION_SHIFT);
|
||||
}
|
||||
|
||||
/** @brief Set CORDIC operation type
|
||||
*
|
||||
* Select what operation the CORDIC peripheral performs.
|
||||
* @param[in] function function of type @ref cordic_csr_function
|
||||
*
|
||||
*/
|
||||
void cordic_set_function(uint8_t function) {
|
||||
CORDIC_CSR = (CORDIC_CSR & ~CORDIC_CSR_FUNC_MASK) | (function << CORDIC_CSR_FUNC_SHIFT);
|
||||
}
|
||||
|
||||
/** @brief Write single 16 bit argument
|
||||
*
|
||||
* Use this function to set one single 16 bit argument.
|
||||
* The upper 16 bit of the 32 bit result register
|
||||
* (that is the second argument) will be set to zero.
|
||||
* @param[in] argument argument
|
||||
*
|
||||
*/
|
||||
void cordic_write_16bit_argument(uint16_t argument) {
|
||||
CORDIC_WDATA = argument;
|
||||
}
|
||||
|
||||
/** @brief Write two 16 bit arguments
|
||||
*
|
||||
* Use this function to set write 16 bit arguments to the 32 bit CORDIC_WDATA register.
|
||||
* @param[in] argument1 argument1
|
||||
* @param[in] argument2 argument2
|
||||
*
|
||||
*/
|
||||
void cordic_write_16bit_arguments(uint16_t argument1, uint16_t argument2) {
|
||||
CORDIC_WDATA = argument2 << 16 | argument1;
|
||||
}
|
||||
|
||||
/** @brief Write single 32 bit argument
|
||||
*
|
||||
* Use this function to write a 32 bit argument to the CORDIC_WDATA register.
|
||||
* If the operation needs two arguments call cordic_set_number_of_arguments_2()
|
||||
* before and then use this function twice to write both arguments.
|
||||
* @param[in] argument argument
|
||||
*
|
||||
*/
|
||||
void cordic_write_32bit_argument(uint32_t argument) {
|
||||
CORDIC_WDATA = argument;
|
||||
}
|
||||
|
||||
/** @brief Read single 16 bit result
|
||||
*
|
||||
* Use this function to read one single 16 bit result contained
|
||||
* in the lower 16 bit of the CORDIC_RDATA register.
|
||||
* @returns result
|
||||
*
|
||||
*/
|
||||
uint16_t cordic_read_16bit_result(void) {
|
||||
return CORDIC_RDATA;
|
||||
}
|
||||
|
||||
/** @brief Read two 16 bit results
|
||||
*
|
||||
* Use this function to read both 16 bit results contained
|
||||
* in the 32 bit CORDIC_RDATA register.
|
||||
* @param[out] result1 First result is written to this address
|
||||
* @param[out] result2 Second result is written to this address
|
||||
*
|
||||
*/
|
||||
void cordic_read_16bit_results(uint16_t *result1, uint16_t *result2) {
|
||||
uint32_t temp = CORDIC_RDATA;
|
||||
*result1 = temp;
|
||||
*result2 = temp >> 16;
|
||||
}
|
||||
|
||||
/** @brief Read 32 bit result
|
||||
*
|
||||
* Use this function to read the 32 bit CORDIC_RDATA register.
|
||||
* @returns result
|
||||
*
|
||||
*/
|
||||
uint32_t cordic_read_32bit_result(void) {
|
||||
return CORDIC_RDATA;
|
||||
}
|
||||
|
||||
/** @brief Configure cordic for 16 bit cosine
|
||||
*
|
||||
* Configures cordic peripheral to perform 16 bit cosine operation without triggering it
|
||||
*
|
||||
*/
|
||||
void cordic_configure_for_cos_16bit(void) {
|
||||
cordic_set_function(CORDIC_CSR_FUNC_COS);
|
||||
cordic_set_precision(CORDIC_CSR_PRECISION_ITER_20);
|
||||
cordic_set_argument_width_16bit();
|
||||
cordic_set_result_width_16bit();
|
||||
cordic_set_number_of_arguments_1();
|
||||
cordic_set_number_of_results_1();
|
||||
/* scale is not applicable for cos */
|
||||
}
|
||||
|
||||
/** @brief Configure cordic for 32 bit cosine
|
||||
*
|
||||
* Configures cordic peripheral to perform 32 bit cosine operation without triggering it
|
||||
*
|
||||
*/
|
||||
void cordic_configure_for_cos_32bit(void) {
|
||||
cordic_set_function(CORDIC_CSR_FUNC_COS);
|
||||
cordic_set_precision(CORDIC_CSR_PRECISION_ITER_28);
|
||||
cordic_set_argument_width_32bit();
|
||||
cordic_set_result_width_32bit();
|
||||
cordic_set_number_of_arguments_1();
|
||||
cordic_set_number_of_results_1();
|
||||
/* scale is not applicable for cos */
|
||||
}
|
||||
|
||||
/** @brief Configure cordic for 16 bit sine
|
||||
*
|
||||
* Configures cordic peripheral to perform 16 bit sine operation without triggering it
|
||||
*
|
||||
*/
|
||||
void cordic_configure_for_sin_16bit(void) {
|
||||
cordic_set_function(CORDIC_CSR_FUNC_SIN);
|
||||
cordic_set_precision(CORDIC_CSR_PRECISION_ITER_20);
|
||||
cordic_set_argument_width_16bit();
|
||||
cordic_set_result_width_16bit();
|
||||
cordic_set_number_of_arguments_1();
|
||||
cordic_set_number_of_results_1();
|
||||
/* scale is not applicable for sin */
|
||||
}
|
||||
|
||||
/** @brief Configure cordic for 32 bit sine
|
||||
*
|
||||
* Configures cordic peripheral to perform 32 bit sine operation without triggering it
|
||||
*
|
||||
*/
|
||||
void cordic_configure_for_sin_32bit(void) {
|
||||
cordic_set_function(CORDIC_CSR_FUNC_SIN);
|
||||
cordic_set_precision(CORDIC_CSR_PRECISION_ITER_28);
|
||||
cordic_set_argument_width_32bit();
|
||||
cordic_set_result_width_32bit();
|
||||
cordic_set_number_of_arguments_1();
|
||||
cordic_set_number_of_results_1();
|
||||
/* scale is not applicable for sin */
|
||||
}
|
||||
|
||||
/** @brief Compute 16 bit cosine using CORDIC (blocking)
|
||||
*
|
||||
* Convenience function to calculate 32767*cos(x/32767*pi).
|
||||
* This implementation can be sped up in most applications by configuring the peripheral only once
|
||||
* and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register.
|
||||
* Additionally, sine and cosine are always computed in a single operation.
|
||||
* Read the second result to obtain the other value.
|
||||
* @param[in] x argument
|
||||
* @returns result
|
||||
*
|
||||
*/
|
||||
int16_t cordic_cos_16bit(int16_t x) {
|
||||
cordic_configure_for_cos_16bit();
|
||||
cordic_write_16bit_arguments((uint16_t) x, 0x7FFF);
|
||||
|
||||
/* this while loop can be omitted but that will stall the
|
||||
processor while it waits for the CORDIC_RDATA register */
|
||||
while(!cordic_is_result_ready());
|
||||
|
||||
return cordic_read_16bit_result();
|
||||
}
|
||||
|
||||
/** @brief Compute 16 bit cosine using CORDIC (non blocking)
|
||||
*
|
||||
* Convenience function to calculate 32767*cos(x/32767*pi).
|
||||
* Result can be obtained from result register using cordic_read_16bit_result().
|
||||
*
|
||||
* @param[in] x argument
|
||||
*
|
||||
*/
|
||||
void cordic_cos_16bit_async(int16_t x) {
|
||||
cordic_configure_for_cos_16bit();
|
||||
cordic_write_16bit_arguments((uint16_t) x, 0x7FFF);
|
||||
}
|
||||
|
||||
/** @brief Compute 32 bit cosine using CORDIC (blocking)
|
||||
*
|
||||
* Convenience function to calculate 2147483647*cos(x/2147483647*pi).
|
||||
* This implementation can be sped up in most applications by configuring the peripheral only once
|
||||
* and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register.
|
||||
* Additionally, sine and cosine are always computed in a single operation.
|
||||
* Read the second result to obtain the other value.
|
||||
* @param[in] x argument
|
||||
* @returns result
|
||||
*
|
||||
*/
|
||||
int32_t cordic_cos_32bit(int32_t x) {
|
||||
cordic_configure_for_cos_32bit();
|
||||
cordic_write_32bit_argument((uint32_t) x);
|
||||
|
||||
while(!cordic_is_result_ready());
|
||||
|
||||
return cordic_read_32bit_result();
|
||||
}
|
||||
|
||||
/** @brief Compute 32 bit cosine using CORDIC (non blocking)
|
||||
*
|
||||
* Convenience function to calculate 2147483647*cos(x/2147483647*pi).
|
||||
* Result can be obtained from result register using cordic_read_32bit_result().
|
||||
*
|
||||
* @param[in] x argument
|
||||
*
|
||||
*/
|
||||
void cordic_cos_32bit_async(int32_t x) {
|
||||
cordic_configure_for_cos_32bit();
|
||||
cordic_write_32bit_argument((uint32_t) x);
|
||||
}
|
||||
|
||||
/** @brief Compute 16 bit sine using CORDIC (blocking)
|
||||
*
|
||||
* Convenience function to calculate 32767*sin(x/32767*pi).
|
||||
* This implementation can be sped up in most applications by configuring the peripheral only once
|
||||
* and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register.
|
||||
* Additionally, sine and cosine are always computed in a single operation.
|
||||
* Read the second result to obtain the other value.
|
||||
* @param[in] x argument
|
||||
* @returns result
|
||||
*
|
||||
*/
|
||||
int16_t cordic_sin_16bit(int16_t x) {
|
||||
cordic_configure_for_sin_16bit();
|
||||
cordic_write_16bit_arguments((uint16_t) x, 0x7FFF);
|
||||
|
||||
/* this while loop can be omitted but that will stall the
|
||||
processor while it waits for the CORDIC_RDATA register */
|
||||
while(!cordic_is_result_ready());
|
||||
|
||||
return cordic_read_16bit_result();
|
||||
}
|
||||
|
||||
/** @brief Compute 16 bit sine using CORDIC (non blocking)
|
||||
*
|
||||
* Convenience function to calculate 32767*sin(x/32767*pi).
|
||||
* Result can be obtained from result register using cordic_read_16bit_result().
|
||||
*
|
||||
* @param[in] x argument
|
||||
*
|
||||
*/
|
||||
void cordic_sin_16bit_async(int16_t x) {
|
||||
cordic_configure_for_sin_16bit();
|
||||
cordic_write_16bit_arguments((uint16_t) x, 0x7FFF);
|
||||
}
|
||||
|
||||
/** @brief Compute 32 bit sine using CORDIC (blocking)
|
||||
*
|
||||
* Convenience function to calculate 2147483647*sin(x/2147483647*pi).
|
||||
* This implementation can be sped up in most applications by configuring the peripheral only once
|
||||
* and then trigger subsequent operations by writing new arguments to the CORDIC_WDATA register.
|
||||
* Additionally, sine and cosine are always computed in a single operation.
|
||||
* Read the second result to obtain the other value.
|
||||
* @param[in] x argument
|
||||
* @returns result
|
||||
*
|
||||
*/
|
||||
int32_t cordic_sin_32bit(int32_t x) {
|
||||
cordic_configure_for_sin_32bit();
|
||||
cordic_write_32bit_argument((uint32_t) x);
|
||||
|
||||
/* this while loop can be omitted but that will stall the
|
||||
processor while it waits for the CORDIC_RDATA register */
|
||||
while(!cordic_is_result_ready());
|
||||
|
||||
return cordic_read_32bit_result();
|
||||
}
|
||||
|
||||
/** @brief Compute 32 bit sine using CORDIC (non blocking)
|
||||
*
|
||||
* Convenience function to calculate 2147483647*sin(x/2147483647*pi).
|
||||
* Result can be obtained from result register using cordic_read_32bit_result().
|
||||
*
|
||||
* @param[in] x argument
|
||||
*
|
||||
*/
|
||||
void cordic_sin_32bit_async(int32_t x) {
|
||||
cordic_configure_for_sin_32bit();
|
||||
cordic_write_32bit_argument((uint32_t) x);
|
||||
}
|
||||
@@ -36,6 +36,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS)
|
||||
ARFLAGS = rcs
|
||||
|
||||
OBJS += adc.o adc_common_v2.o adc_common_v2_multi.o
|
||||
OBJS += cordic_common_v1.o
|
||||
OBJS += crs_common_all.o
|
||||
OBJS += crc_common_all.o crc_v2.o
|
||||
OBJS += dac_common_all.o dac_common_v2.o
|
||||
|
||||
Reference in New Issue
Block a user