ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
dsps_cplx_gen_init.c
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8#include "dsps_cplx_gen.h"
9#include "dsp_common.h"
10#include "esp_log.h"
11#include <math.h>
12#include <malloc.h>
13
14#define Q15_MAX INT16_MAX
15
16static const char *TAG = "dsps_cplx_gen";
17
18esp_err_t dsps_cplx_gen_init(cplx_sig_t *cplx_gen, out_d_type d_type, void *lut, int32_t lut_len, float freq, float initial_phase)
19{
20 cplx_gen->lut_len = lut_len;
21 cplx_gen->freq = freq;
22 cplx_gen->lut = lut;
23 cplx_gen->free_status = 0;
24 cplx_gen->d_type = d_type;
25 cplx_gen->phase = initial_phase;
26
27 // length of the LUT must be power of 2
28 if (!dsp_is_power_of_two(lut_len)) {
29 ESP_LOGE(TAG, "The length of the LUT must be power of 2");
31 }
32
33 // LUT length must be in a range from 256 to 8192
34 if ((lut == NULL) && ((cplx_gen->lut_len > 8192) || (cplx_gen->lut_len < 256))) {
35 ESP_LOGE(TAG, "The length of the LUT table out of range. Valid range is 256 to 8192");
37 }
38
39 // frequency is a Nyquist frequency, must be in a range from (-1 to 1)
40 if ((cplx_gen->freq >= 1) || (cplx_gen->freq <= -1)) {
41 ESP_LOGE(TAG, "The frequency is out of range. Valid range is +/- 1. ");
43 }
44
45 // initial phase in a range from (-1 to 1)
46 if ((cplx_gen->phase >= 1) || (cplx_gen->phase <= -1)) {
47 ESP_LOGE(TAG, "The phase is out of range. Valid range is +/- 1. ");
49 }
50
51 // LUT table coefficients generation
52 if (lut == NULL) { // lut has not been provided by an user. Allocate and initialize it
53 cplx_gen->free_status |= 0x0001; // lut has been allocated, free_status indicates that the space must be freed afterwards
54
55 if (cplx_gen->d_type == S16_FIXED) { // Q15 fixed point
56 int16_t *local_lut = (int16_t *)malloc(cplx_gen->lut_len * sizeof(int16_t));
57
58 float term;
59 for (int i = 0 ; i < cplx_gen->lut_len; i++) {
60 term = (2.0 * M_PI) * ((float)(i) / (float)(cplx_gen->lut_len));
61 local_lut[i] = (int16_t)(sin(term) * Q15_MAX); // conversion to Q15 fixed point
62 }
63 cplx_gen->lut = (void *)local_lut;
64 } else if (cplx_gen->d_type == F32_FLOAT) { // Single precision floating point
65 float *local_lut = (float *)malloc(cplx_gen->lut_len * sizeof(float));
66
67 float term;
68 for (int i = 0 ; i < cplx_gen->lut_len; i++) {
69 term = (2.0 * M_PI) * ((float)(i) / (float)(cplx_gen->lut_len));
70 local_lut[i] = (float)sin(term);
71 }
72 cplx_gen->lut = (void *)local_lut;
73 } else {
74 cplx_gen->lut = NULL;
76 }
77 }
78 return ESP_OK;
79}
80
82{
83 if ((freq >= 1) || (freq <= -1)) { // frequency is a Nyquist frequency, must be in a range from (-1 to 1)
84 ESP_LOGE(TAG, "The frequency is out of range. Valid range is +/- 1. ");
86 }
87
88 cplx_gen->freq = freq;
89 return ESP_OK;
90}
91
93{
94 // Check if the structure was initialized
95 if (!dsp_is_power_of_two(cplx_gen->lut_len)) {
96 ESP_LOGE(TAG, "cplx_gen strucure was not initialized");
97 return -2;
98 }
99
100 return (cplx_gen->freq);
101}
102
104{
105 if ((phase >= 1) || (phase <= -1)) { // initial phase in a range from (-1 to 1)
106 ESP_LOGE(TAG, "The phase is out of range. Valid range is +/- 1. ");
108 }
109
110 cplx_gen->phase = phase;
111 return ESP_OK;
112}
113
115{
116 // Check if the structure was initialized
117 if (!dsp_is_power_of_two(cplx_gen->lut_len)) {
118 ESP_LOGE(TAG, "cplx_gen strucure was not initialized");
119 return -2;
120 }
121
122 return (cplx_gen->phase);
123}
124
125esp_err_t dsps_cplx_gen_set(cplx_sig_t *cplx_gen, float freq, float phase)
126{
127 if ((freq >= 1) || (freq <= -1)) { // frequency is a Nyquist frequency, must be in a range from (-1 to 1)
128 ESP_LOGE(TAG, "The frequency is out of range. Valid range is +/- 1. ");
130 }
131
132 if ((phase >= 1) || (phase <= -1)) { // phase in a range from (-1 to 1)
133 ESP_LOGE(TAG, "The phase is out of range. Valid range is +/- 1. ");
135 }
136
137 cplx_gen->phase = phase;
138 cplx_gen->freq = freq;
139 return ESP_OK;
140}
141
143{
144 if (cplx_gen->free_status & 0x0001) {
145 free(cplx_gen->lut);
146 cplx_gen->free_status = 0;
147 }
148}
bool dsp_is_power_of_two(int x)
check power of two The function check if the argument is power of 2. The implementation use ANSI C an...
#define ESP_ERR_DSP_INVALID_PARAM
#define ESP_ERR_DSP_PARAM_OUTOFRANGE
#define ESP_ERR_DSP_INVALID_LENGTH
struct cplx_sig_s cplx_sig_t
Data struct of the complex signal generator.
@ F32_FLOAT
@ S16_FIXED
enum output_data_type out_d_type
Ennum defining output data type of the complex generator.
esp_err_t dsps_cplx_gen_freq_set(cplx_sig_t *cplx_gen, float freq)
function sets the output frequency of the complex generator
esp_err_t dsps_cplx_gen_phase_set(cplx_sig_t *cplx_gen, float phase)
function sets the phase of the complex generator
esp_err_t dsps_cplx_gen_set(cplx_sig_t *cplx_gen, float freq, float phase)
function sets the output frequency and the phase of the complex generator
float dsps_cplx_gen_freq_get(cplx_sig_t *cplx_gen)
function gets the output frequency of the complex generator
esp_err_t dsps_cplx_gen_init(cplx_sig_t *cplx_gen, out_d_type d_type, void *lut, int32_t lut_len, float freq, float initial_phase)
Initialize strucure for complex generator.
float dsps_cplx_gen_phase_get(cplx_sig_t *cplx_gen)
function gets the phase of the complex generator
void cplx_gen_free(cplx_sig_t *cplx_gen)
function frees dynamically allocated memory, which was allocated in the init function
#define Q15_MAX
int esp_err_t
Definition esp_err.h:21
#define ESP_OK
Definition esp_err.h:23
#define M_PI
Definition esp_err.h:26
static const char * TAG
Definition main/main.c:31
int32_t lut_len
out_d_type d_type
int16_t free_status