Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
9590cb339This file is pinned to the selected release. Download the original to open it in your design tool.
#include "res_comp.h"
#include "commands.h"
#include "hal.h"
#include "math.h"
#include "defines.h"
#include "angle.h"
#include "stm32f4xx_conf.h"
#include "hw/hw.h"
HAL_COMP(res);
HAL_PIN(pos);
HAL_PIN(amp);
HAL_PIN(quad);
HAL_PIN(poles);
HAL_PIN(min_amp);
HAL_PIN(vel); // TODO: vel rev, fb,cmd -> vel0,1 -> rev
HAL_PIN(sin);
HAL_PIN(cos);
HAL_PIN(enable);
HAL_PIN(error);
HAL_PIN(state);
HAL_PIN(phase); //phase adjust
HAL_PIN(res_mode); //resolver mode output, calculated form frequency
HAL_PIN(freq);
// TODO: in hal stop, reset adc dma
struct res_ctx_t {
int lastq; // last quadrant
int abspos; // multiturn position
};
static void nrt_init(void *ctx_ptr, hal_pin_inst_t *pin_ptr) {
// struct res_ctx_t *ctx = (struct res_ctx_t *)ctx_ptr;
struct res_pin_ctx_t *pins = (struct res_pin_ctx_t *)pin_ptr;
PIN(poles) = 1.0;
PIN(phase) = 0.85;
PIN(min_amp) = 0.15;
PIN(freq) = 10000;
}
static void hw_init(void *ctx_ptr, hal_pin_inst_t *pin_ptr) {
struct res_ctx_t *ctx = (struct res_ctx_t *)ctx_ptr;
// struct res_pin_ctx_t *pins = (struct res_pin_ctx_t *)pin_ptr;
ctx->abspos = 0;
ctx->lastq = 0;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
#ifdef V4
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
//timer init for v4, v3 uses slave timer
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = ADC_TRIGGER_FREQ / FRT_FREQ - 1; // 20kHz
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_External1); // Rising edges of the selected trigger (TRGI) clock the counter
TIM_ITRxExternalClockConfig(TIM4, TIM_TS_ITR2); // clk = TIM_MASTER(TIM2) trigger out
TIM_ARRPreloadConfig(TIM4, ENABLE);
TIM_Cmd(TIM4, ENABLE);
#endif
//12-1 40khz
//15-1 35khz
//20-1 30khz 2
//24-1 25khz
//30-1 20khz 3
//40-1 15khz 4
//60-1 10khz 6 default
//120-1 5khz 12
//res_en = ADC_GROUPS/2/(res_freq/rt_freq)
//arr = ADC_TRIGGER_FREQ/2/res_freq
// resolver reference signal OC
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
//ref is always OC3
TIM_OC3Init(FB0_RES_REF_TIM, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(FB0_RES_REF_TIM, TIM_OCPreload_Enable);
TIM_CtrlPWMOutputs(FB0_RES_REF_TIM, ENABLE);
//resolver ref signal generation
GPIO_InitStructure.GPIO_Pin = FB0_RES_REF_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(FB0_RES_REF_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(FB0_RES_REF_PORT, FB0_RES_REF_PIN_SOURCE, FB0_RES_REF_TIM_AF);
//txen
GPIO_InitStructure.GPIO_Pin = FB0_Z_TXEN_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(FB0_Z_TXEN_PORT, &GPIO_InitStructure);
GPIO_SetBits(FB0_Z_TXEN_PORT, FB0_Z_TXEN_PIN);
}
static void rt_func(float period, void *ctx_ptr, hal_pin_inst_t *pin_ptr) {
struct res_ctx_t *ctx = (struct res_ctx_t *)ctx_ptr;
struct res_pin_ctx_t *pins = (struct res_pin_ctx_t *)pin_ptr;
//TODO: arr can change!
uint32_t mult = CLAMP(PIN(freq) / RT_FREQ + 0.5, 1, 4);
PIN(freq) = RT_FREQ * mult;
FB0_RES_REF_TIM->ARR = ADC_TRIGGER_FREQ / 2 / (RT_FREQ * mult) - 1;
FB0_RES_REF_TIM->CCR3 = (int)CLAMP(PIN(phase) * FB0_RES_REF_TIM->ARR, 0, FB0_RES_REF_TIM->ARR - 1);
PIN(res_mode) = ADC_GROUPS / 2 / mult;
float s = 0.0;
float c = 0.0;
float a = 0.0;
s = PIN(sin);
c = PIN(cos);
a = sqrtf(s * s + c * c);
float p = MAX(1.0, PIN(poles));
float pos = atan2f(s, c);
float dpos = PIN(vel) * period / 2.0;
if(a < PIN(min_amp)) {
PIN(error) = 1.0;
PIN(state) = 0.0;
} else {
PIN(error) = 0.0;
PIN(state) = 3.0;
if(p == 1.0f) {
PIN(pos) = mod(pos + dpos);
} else {
int q = PIN(quad); // current quadrant
if(ctx->lastq == 2 && q == 3)
ctx->abspos++;
if(ctx->lastq == 3 && q == 2)
ctx->abspos--;
if(ctx->abspos >= p) {
ctx->abspos = 0;
}
if(ctx->abspos <= -1) {
ctx->abspos = p - 1;
}
ctx->lastq = q;
//TODO: clamp ctx->abspos
float absa = pos + ctx->abspos * M_PI * 2.0f;
PIN(pos) = mod(absa / p + dpos);
}
}
PIN(amp) = a;
}
const hal_comp_t res_comp_struct = {
.name = "res",
.nrt = 0,
.rt = rt_func,
.frt = 0,
.nrt_init = nrt_init,
.hw_init = hw_init,
.rt_start = 0,
.frt_start = 0,
.rt_stop = 0,
.frt_stop = 0,
.ctx_size = sizeof(struct res_ctx_t),
.pin_count = sizeof(struct res_pin_ctx_t) / sizeof(struct hal_pin_inst_t),
};