/**************************************************************************** * apps/industry/foc/fixed16/foc_handler.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include "industry/foc/foc_log.h" #include "industry/foc/foc_common.h" #include "industry/foc/fixed16/foc_handler.h" /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: foc_handler_init_b16 * * Description: * Initialize the FOC handler (fixed16) * * Input Parameter: * h - pointer to FOC handler * ctrl - pointer to controller operations * mod - pointer to modulation operations * ****************************************************************************/ int foc_handler_init_b16(FAR foc_handler_b16_t *h, FAR struct foc_control_ops_b16_s *ctrl, FAR struct foc_modulation_ops_b16_s *mod) { int ret = OK; DEBUGASSERT(h); DEBUGASSERT(ctrl); DEBUGASSERT(mod); /* Controller ops */ DEBUGASSERT(ctrl->init); DEBUGASSERT(ctrl->deinit); DEBUGASSERT(ctrl->cfg); DEBUGASSERT(ctrl->input_set); DEBUGASSERT(ctrl->voltage_run); DEBUGASSERT(ctrl->current_run); DEBUGASSERT(ctrl->state_get); /* Modulation ops */ DEBUGASSERT(mod->init); DEBUGASSERT(mod->deinit); DEBUGASSERT(mod->cfg); DEBUGASSERT(mod->current); DEBUGASSERT(mod->vbase_get); DEBUGASSERT(mod->run); /* Reset handler */ memset(h, 0, sizeof(foc_handler_b16_t)); /* Connect ops */ h->ops.ctrl = ctrl; h->ops.mod = mod; /* Initialize control handler */ ret = h->ops.mod->init(h); if (ret < 0) { FOCLIBERR("ERROR: mod->init failed %d\n", ret); goto errout; } /* Initialize modulation handler */ ret = h->ops.ctrl->init(h); if (ret < 0) { FOCLIBERR("ERROR: ctrl->init failed %d\n", ret); goto errout; } #ifdef CONFIG_INDUSTRY_FOC_CORDIC /* Open CORDIC device */ h->fd = open(CONFIG_INDUSTRY_FOC_CORDIC_DEVPATH, O_RDWR); if (h->fd < 0) { FOCLIBERR("ERROR: failed to open CORDIC device %s %d\n", CONFIG_INDUSTRY_FOC_CORDIC_DEVPATH, errno); goto errout; } #endif errout: return ret; } /**************************************************************************** * Name: foc_handler_deinit_b16 * * Description: * De-initialize the FOC handler (fixed16) * * Input Parameter: * h - pointer to FOC handler * ****************************************************************************/ int foc_handler_deinit_b16(FAR foc_handler_b16_t *h) { int ret = OK; DEBUGASSERT(h); /* Deinitialize modulation handler */ h->ops.mod->deinit(h); /* Deinitialize control handler */ h->ops.ctrl->deinit(h); #ifdef CONFIG_INDUSTRY_FOC_CORDIC /* Close CORDIC device */ close(h->fd); #endif /* Reset data */ memset(h, 0, sizeof(foc_handler_b16_t)); return ret; } /**************************************************************************** * Name: foc_handler_cfg_b16 * * Description: * Configure the FOC handler (fixed16) * * Input Parameter: * h - pointer to FOC handler * ctrl_cfg - pointer to controller configuration data * mod_cfg - pointer to modulation configuration data * ****************************************************************************/ void foc_handler_cfg_b16(FAR foc_handler_b16_t *h, FAR void *ctrl_cfg, FAR void *mod_cfg) { DEBUGASSERT(h); DEBUGASSERT(ctrl_cfg); DEBUGASSERT(mod_cfg); /* Configure controller */ h->ops.ctrl->cfg(h, ctrl_cfg); /* Configure modulation */ h->ops.mod->cfg(h, mod_cfg); } /**************************************************************************** * Name: foc_handler_run_b16 * * Description: * Run the FOC handler and process the given input data (fixed16) * * Input Parameter: * h - pointer to FOC handler * in - pointer to FOC handler input data * out - pointer to FOC handler output data * ****************************************************************************/ int foc_handler_run_b16(FAR foc_handler_b16_t *h, FAR struct foc_handler_input_b16_s *in, FAR struct foc_handler_output_b16_s *out) { ab_frame_b16_t v_ab_mod; b16_t vbase = 0; int ret = OK; DEBUGASSERT(h); DEBUGASSERT(in); DEBUGASSERT(out); /* Do nothing if control mode not specified yet. * This also protects against initial state when the controller is * started but input data has not yet been provided. */ if (in->mode <= FOC_HANDLER_MODE_INIT) { ret = -EINVAL; goto errout; } /* Correct current samples according to modulation state */ h->ops.mod->current(h, in->current); /* Get VBASE */ h->ops.mod->vbase_get(h, in->vbus, &vbase); /* Feed controller with phase currents */ h->ops.ctrl->input_set(h, in->current, vbase, in->angle); /* Call controller */ switch (in->mode) { /* IDLE */ case FOC_HANDLER_MODE_IDLE: { /* Do nothing and set duty to zeros */ ret = OK; goto errout; } /* FOC current mode - control DQ-current */ case FOC_HANDLER_MODE_CURRENT: { /* Current controller */ h->ops.ctrl->current_run(h, in->dq_ref, in->vdq_comp, &v_ab_mod); break; } /* FOC voltage mode - control DQ-voltage */ case FOC_HANDLER_MODE_VOLTAGE: { /* Voltage controller */ h->ops.ctrl->voltage_run(h, in->dq_ref, &v_ab_mod); break; } /* Otherwise - we should not be here */ default: { ret = -EINVAL; goto errout; } } /* Duty cycle modulation */ h->ops.mod->run(h, &v_ab_mod, out->duty); return ret; errout: /* Set duty to zeros */ memset(out->duty, 0, sizeof(b16_t) * CONFIG_MOTOR_FOC_PHASES); return ret; } /**************************************************************************** * Name: foc_handler_state_b16 * * Description: * Get FOC handler state (fixed16) * * Input Parameter: * h - pointer to FOC handler * state - pointer to FOC state data * ****************************************************************************/ void foc_handler_state_b16(FAR foc_handler_b16_t *h, FAR struct foc_state_b16_s *state) { DEBUGASSERT(h); DEBUGASSERT(state); h->ops.ctrl->state_get(h, state); } #ifdef CONFIG_INDUSTRY_FOC_HANDLER_PRINT /**************************************************************************** * Name: foc_handler_state_print_b16 * * Description: * Print FOC handler state (fixed16) * * Input Parameter: * state - pointer to FOC state data * ****************************************************************************/ void foc_handler_state_print_b16(FAR struct foc_state_b16_s *state) { DEBUGASSERT(state); #if CONFIG_MOTOR_FOC_PHASES == 3 FOCLIBLOG("curr = [%.2f %.2f %.2f]\n", b16tof(state->curr[0]), b16tof(state->curr[1]), b16tof(state->curr[2])); FOCLIBLOG("volt = [%.2f %.2f %.2f]\n", b16tof(state->volt[0]), b16tof(state->volt[1]), b16tof(state->volt[2])); #else # error TODO #endif FOCLIBLOG("iab = [%.2f %.2f]\n", b16tof(state->iab.a), b16tof(state->iab.b)); FOCLIBLOG("vab = [%.2f %.2f]\n", b16tof(state->vab.a), b16tof(state->vab.b)); FOCLIBLOG("idq = [%.2f %.2f]\n", b16tof(state->idq.d), b16tof(state->idq.q)); FOCLIBLOG("vdq = [%.2f %.2f]\n", b16tof(state->vdq.d), b16tof(state->vdq.q)); } #endif