Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
#include "commands.h"
#include "hal.h"
#include "math.h"
#include "defines.h"
#include "angle.h"
#include "setup.h"
#include "usbd_cdc_if.h"
#define INPUT_REF (OP_REF * OP_R_OUT_LOW / (OP_R_OUT_HIGH + OP_R_OUT_LOW))
#define INPUT_GAIN (OP_R_FEEDBACK / OP_R_INPUT * OP_R_OUT_LOW / (OP_R_OUT_HIGH + OP_R_OUT_LOW))
#define V_DIFF(ADC, OVER) ((((float)(ADC)) / (float)(OVER) / ADC_RES * ADC_REF - INPUT_REF) / INPUT_GAIN)
#define TERM_NUM_WAVES 8
HAL_COMP(adc);
HAL_PIN(sin0); //sin output
HAL_PIN(cos0); //cos output
HAL_PIN(sin0l); //sin output, last group only
HAL_PIN(cos0l); //cos output, last group only
HAL_PIN(quad); //quadrant of sin/cos
HAL_PIN(amp0);
HAL_PIN(sin1); //sin output
HAL_PIN(cos1); //cos output
HAL_PIN(sin1l); //sin output, last group only
HAL_PIN(cos1l); //cos output, last group only
HAL_PIN(amp1);
HAL_PIN(res_mode); //polarity flip mode for resolvers
HAL_PIN(sin_gain);
HAL_PIN(cos_gain);
HAL_PIN(sin_offset);
HAL_PIN(cos_offset);
HAL_PIN(send_step); //15.0;
HAL_PINA(offset, 8);
HAL_PINA(gain, 8);
struct adc_ctx_t {
volatile float txbuf[8][ADC_SAMPLES_IN_RT];
volatile uint32_t txbuf_raw[ADC_SAMPLES_IN_RT];
uint32_t txpos;
uint32_t send_counter; //send_step counter
volatile uint32_t send; //send buffer state 0=filling, 1=sending
};
static void nrt_init(void *ctx_ptr, hal_pin_inst_t *pin_ptr) {
struct adc_ctx_t *ctx = (struct adc_ctx_t *)ctx_ptr;
struct adc_pin_ctx_t *pins = (struct adc_pin_ctx_t *)pin_ptr;
PINA(gain, 0) = 150;
PINA(gain, 1) = 150;
PINA(gain, 2) = 150;
PINA(gain, 3) = 150;
PINA(gain, 4) = 80;
PIN(sin_gain) = 1.0;
PIN(cos_gain) = 1.0;
ctx->txpos = 0;
ctx->send_counter = 0;
ctx->send = 0;
}
static void rt_func(float period, void *ctx_ptr, hal_pin_inst_t *pin_ptr) {
struct adc_ctx_t *ctx = (struct adc_ctx_t *)ctx_ptr;
struct adc_pin_ctx_t *pins = (struct adc_pin_ctx_t *)pin_ptr;
//scaled values for each group
float si0[ADC_GROUPS];
float co0[ADC_GROUPS];
//integral per group
uint32_t sii0;
uint32_t coi0;
//scaled, all groups
float sin0all = 0.0;
float cos0all = 0.0;
#ifdef FB1
float co1[ADC_GROUPS];
float si1[ADC_GROUPS];
uint32_t sii1;
uint32_t coi1;
//scaled, all groups
float sin1all = 0.0;
float cos1all = 0.0;
#endif
float s_o = PIN(sin_offset);
float c_o = PIN(cos_offset);
float s_g = PIN(sin_gain);
float c_g = PIN(cos_gain);
volatile uint32_t *ADC_DMA_Buffer;
if(DMA_GetCurrentMemoryTarget(DMA2_Stream0)) {
ADC_DMA_Buffer = ADC_DMA_Buffer0;
} else {
ADC_DMA_Buffer = ADC_DMA_Buffer1;
}
int flip;
int n = PIN(res_mode);
for(int i = 0; i < ADC_GROUPS; i++) { //each adc sampling group
if(n > 0 && i % (2 * n) >= n) {
flip = -1;
} else {
flip = 1;
}
sii0 = 0;
coi0 = 0;
for(int j = 0; j < ADC_OVER_FB0; j++) { //each adc sample of fb0
sii0 += ADC_DMA_Buffer[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] & 0x0000ffff;
coi0 += ADC_DMA_Buffer[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] >> 16;
}
si0[i] = flip * s_g * V_DIFF(sii0, ADC_OVER_FB0) + s_o;
co0[i] = flip * c_g * V_DIFF(coi0, ADC_OVER_FB0) + c_o;
sin0all += si0[i];
cos0all += co0[i];
#ifdef FB1
sii1 = 0;
coi1 = 0;
for(int j = ADC_OVER_FB0; j < ADC_OVER_FB0 + ADC_OVER_FB1; j++) { //each adc sample of fb1
sii1 += ADC_DMA_Buffer[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] & 0x0000ffff;
coi1 += ADC_DMA_Buffer[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] >> 16;
}
si1[i] = s_g * V_DIFF(sii1, ADC_OVER_FB1) + s_o;
co1[i] = c_g * V_DIFF(coi1, ADC_OVER_FB1) + c_o;
sin1all += si1[i];
cos1all += co1[i];
#endif
}
if(ctx->send == 0) {
memcpy((void *)(ctx->txbuf_raw), (void *)ADC_DMA_Buffer, ADC_SAMPLES_IN_RT * 4);
ctx->send = 1;
}
float s = V_DIFF(ADC_DMA_Buffer[0] & 0x0000ffff, 1);
float c = V_DIFF(ADC_DMA_Buffer[0] >> 16, 1);
PIN(sin0l) = si0[ADC_GROUPS - 1];
PIN(cos0l) = co0[ADC_GROUPS - 1];
PIN(sin0) = sin0all / (float)ADC_GROUPS;
PIN(cos0) = cos0all / (float)ADC_GROUPS;
PIN(amp0) = PIN(amp0) * 0.99 + sqrtf(s * s + c * c) * 0.01;
#ifdef FB1
s = V_DIFF(ADC_DMA_Buffer[ADC_OVER_FB0] & 0x0000ffff, 1);
c = V_DIFF(ADC_DMA_Buffer[ADC_OVER_FB0] >> 16, 1);
PIN(sin1l) = si1[ADC_GROUPS - 1];
PIN(cos1l) = co1[ADC_GROUPS - 1];
PIN(sin1) = sin1all / (float)ADC_GROUPS;
PIN(cos1) = cos1all / (float)ADC_GROUPS;
PIN(amp1) = PIN(amp1) * 0.99 + sqrtf(s * s + c * c) * 0.01;
#endif
// if(PIN(res_en) > 0.0) {
// s = (si0[3] - si0[2] + si0[1] - si0[0]) / 4.0;
// c = (co0[3] - co0[2] + co0[1] - co0[0]) / 4.0;
// } else {
// s = (si0[3] + si0[2] + si0[1] + si0[0]) / 4.0;
// c = (co0[3] + co0[2] + co0[1] + co0[0]) / 4.0;
// }
//calculate quadrant for sin/cos interpolation
if(si0[ADC_GROUPS - 1] >= 0) {
if(co0[ADC_GROUPS - 1] > 0)
PIN(quad) = 1;
else
PIN(quad) = 2;
} else {
if(co0[ADC_GROUPS - 1] > 0)
PIN(quad) = 4;
else
PIN(quad) = 3;
}
}
static void nrt_func(void *ctx_ptr, hal_pin_inst_t *pin_ptr) {
struct adc_ctx_t *ctx = (struct adc_ctx_t *)ctx_ptr;
struct adc_pin_ctx_t *pins = (struct adc_pin_ctx_t *)pin_ptr;
int tmp = 0;
uint8_t buf[TERM_NUM_WAVES + 3];
int n = PIN(res_mode); //n gruppen pro halbwelle 1-12
int flip;
if(ctx->send == 1 && ctx->send_counter++ >= PIN(send_step) - 1 && PIN(send_step) > 0) {
ctx->send_counter = 0;
for(int i = 0; i < ADC_GROUPS; i++) { //each adc sampling group
if(n > 0 && i % (2 * n) >= n) {
flip = -1;
} else {
flip = 1;
}
for(int j = 0; j < ADC_OVER_FB0; j++) { //each adc sample of fb0
ctx->txbuf[0][ctx->txpos] = flip * V_DIFF(ctx->txbuf_raw[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] & 0x0000ffff, 1);
ctx->txbuf[1][ctx->txpos] = flip * V_DIFF(ctx->txbuf_raw[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] >> 16, 1);
ctx->txbuf[2][ctx->txpos] = 0;
ctx->txbuf[3][ctx->txpos] = 0;
ctx->txbuf[4][ctx->txpos] = flip;
ctx->txpos++;
}
#ifdef FB1
for(int j = ADC_OVER_FB0; j < ADC_OVER_FB0 + ADC_OVER_FB1; j++) { //each adc sample of fb1
ctx->txbuf[0][ctx->txpos] = 0;
ctx->txbuf[1][ctx->txpos] = 0;
ctx->txbuf[2][ctx->txpos] = V_DIFF(ctx->txbuf_raw[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] & 0x0000ffff, 1);
ctx->txbuf[3][ctx->txpos] = V_DIFF(ctx->txbuf_raw[i * (ADC_OVER_FB0 + ADC_OVER_FB1) + j] >> 16, 1);
ctx->txbuf[4][ctx->txpos] = flip;
ctx->txpos++;
}
#endif
}
ctx->txpos = 0;
buf[0] = 255; //start of waves
for(int k = 0; k < ADC_SAMPLES_IN_RT; k++) { //each sample
for(int i = 0; i < TERM_NUM_WAVES; i++) { //each wave
tmp = (ctx->txbuf[i][k] + PINA(offset, i)) * PINA(gain, i) + 128;
buf[i + 1] = CLAMP(tmp, 1, 254);
}
cdc_tx(buf, 9);
}
buf[0] = 0xfe; //trigger servoterm
cdc_tx(buf, 1);
ctx->send = 0;
}
}
hal_comp_t adc_comp_struct = {
.name = "adc",
.nrt = nrt_func,
.rt = rt_func,
.frt = 0,
.nrt_init = nrt_init,
.rt_start = 0,
.frt_start = 0,
.rt_stop = 0,
.frt_stop = 0,
.ctx_size = sizeof(struct adc_ctx_t),
.pin_count = sizeof(struct adc_pin_ctx_t) / sizeof(struct hal_pin_inst_t),
};
4fca5f20eThis file is pinned to the selected release. Download the original to open it in your design tool.