/**************************************************************************** * apps/examples/foc/foc_intf.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 #include #include #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON # include #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC # include # include #endif #include "foc_thr.h" #include "foc_adc.h" #include "foc_intf.h" #include "foc_debug.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #if defined(CONFIG_EXAMPLES_FOC_HAVE_ADC) || \ defined(CONFIG_EXAMPLES_FOC_HAVE_BUTTON) || \ defined(CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL) # define FOC_HAVE_INTF #endif /* Button init state */ #if CONFIG_EXAMPLES_FOC_STATE_INIT == 1 # define STATE_BUTTON_I (0) #elif CONFIG_EXAMPLES_FOC_STATE_INIT == 2 # define STATE_BUTTON_I (2) #elif CONFIG_EXAMPLES_FOC_STATE_INIT == 3 # define STATE_BUTTON_I (1) #elif CONFIG_EXAMPLES_FOC_STATE_INIT == 4 # define STATE_BUTTON_I (3) #else # error #endif /**************************************************************************** * Private Type Definition ****************************************************************************/ #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /* Button interface data */ struct foc_intf_btn_s { int fd; }; #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC /* ADC interface data */ struct foc_intf_adc_s { int fd; bool adc_trigger; }; #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL /* Character control interface data */ struct foc_intf_chc_s { int fd; }; #endif /**************************************************************************** * Private Data ****************************************************************************/ #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /* Example state */ static const int g_state_list[5] = { FOC_EXAMPLE_STATE_FREE, FOC_EXAMPLE_STATE_CW, FOC_EXAMPLE_STATE_STOP, FOC_EXAMPLE_STATE_CCW, 0 }; #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /* Button interface data */ static struct foc_intf_btn_s g_btn_intf; #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC /* ADC interface data */ static struct foc_intf_adc_s g_adc_intf; #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL /* Character control interface data */ static struct foc_intf_chc_s g_chc_intf; #endif /**************************************************************************** * Private Functions ****************************************************************************/ #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /**************************************************************************** * Name: foc_button_init ****************************************************************************/ static int foc_button_init(FAR struct foc_intf_btn_s *intf) { int ret = 0; DEBUGASSERT(intf); /* Open button driver */ intf->fd = open(CONFIG_EXAMPLES_FOC_BUTTON_DEVPATH, (O_RDONLY | O_NONBLOCK)); if (intf->fd < 0) { PRINTF("ERROR: failed to open %s %d\n", CONFIG_EXAMPLES_FOC_BUTTON_DEVPATH, errno); ret = -errno; goto errout; } errout: return ret; } /**************************************************************************** * Name: foc_button_deinit ****************************************************************************/ static int foc_button_deinit(FAR struct foc_intf_btn_s *intf) { DEBUGASSERT(intf); if (intf->fd > 0) { close(intf->fd); } return OK; } /**************************************************************************** * Name: foc_button_update ****************************************************************************/ static int foc_button_update(FAR struct foc_intf_btn_s *intf, FAR struct foc_intf_data_s *data) { static int state_i = STATE_BUTTON_I; btn_buttonset_t b_sample = 0; int ret = OK; DEBUGASSERT(intf); DEBUGASSERT(data); /* Get button state */ ret = read(intf->fd, &b_sample, sizeof(btn_buttonset_t)); if (ret < 0) { if (errno != EAGAIN) { PRINTF("ERROR: read button failed %d\n", errno); ret = -errno; goto errout; } else { ret = OK; } } /* Next state */ if (b_sample & (1 << 0)) { state_i += 1; if (g_state_list[state_i] == 0) { state_i = 0; } data->state = g_state_list[state_i]; data->state_update = true; PRINTF("BUTTON STATE %" PRIu32 "\n", data->state); } errout: return ret; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC /**************************************************************************** * Name: foc_adc_init ****************************************************************************/ static int foc_adc_init(FAR struct foc_intf_adc_s *intf) { int ret = OK; DEBUGASSERT(intf); /* Open ADC device */ intf->fd = open(CONFIG_EXAMPLES_FOC_ADC_DEVPATH, (O_RDONLY | O_NONBLOCK)); if (intf->fd <= 0) { PRINTF("ERROR: failed to open %s %d\n", CONFIG_EXAMPLES_FOC_ADC_DEVPATH, errno); ret = -errno; goto errout; } /* Initial ADC trigger */ ret = ioctl(intf->fd, ANIOC_TRIGGER, 0); if (ret < 0) { PRINTF("ERROR: ANIOC_TRIGGER ioctl failed: %d\n", errno); ret = -errno; goto errout; } /* Make sure that conversion is done before first read form ADC device */ usleep(10000); /* Read ADC data if the first loop cylce */ intf->adc_trigger = false; errout: return ret; } /**************************************************************************** * Name: foc_adc_deinit ****************************************************************************/ static int foc_adc_deinit(FAR struct foc_intf_adc_s *intf) { DEBUGASSERT(intf); if (intf->fd > 0) { close(intf->fd); } return OK; } /**************************************************************************** * Name: foc_adc_update ****************************************************************************/ static int foc_adc_update(FAR struct foc_intf_adc_s *intf, FAR struct foc_intf_data_s *data) { struct adc_msg_s adc_sample[ADC_SAMPLES]; int ret = OK; DEBUGASSERT(intf); DEBUGASSERT(data); if (intf->adc_trigger == true) { /* Issue the software trigger to start ADC conversion */ ret = ioctl(intf->fd, ANIOC_TRIGGER, 0); if (ret < 0) { PRINTF("ERROR: ANIOC_TRIGGER ioctl failed: %d\n", errno); ret = -errno; goto errout; } /* No ADC trigger next cycle */ intf->adc_trigger = false; } else { /* Get ADC samples */ ret = read(intf->fd, adc_sample, (ADC_SAMPLES * sizeof(struct adc_msg_s))); if (ret < 0) { if (errno != EAGAIN) { PRINTF("ERROR: adc read failed %d\n", errno); ret = -errno; goto errout; } else { ret = OK; } } else { /* Verify we have received the configured number of samples */ if (ret != ADC_SAMPLES * sizeof(struct adc_msg_s)) { PRINTF("ERROR: adc read invalid read %d != %d\n", ret, ADC_SAMPLES * sizeof(struct adc_msg_s)); ret = -EINVAL; goto errout; } #ifdef CONFIG_EXAMPLES_FOC_VBUS_ADC /* Get raw VBUS */ data->vbus_raw = adc_sample[VBUS_ADC_SAMPLE].am_data; data->vbus_update = true; #endif #ifdef CONFIG_EXAMPLES_FOC_SETPOINT_ADC /* Get raw VEL */ data->sp_raw = adc_sample[SETPOINT_ADC_SAMPLE].am_data; data->sp_update = true; #endif /* ADC trigger next cycle */ intf->adc_trigger = true; } } errout: return ret; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL /**************************************************************************** * Name: foc_charctrl_help ****************************************************************************/ static void foc_charctrl_help(void) { PRINTF("\nCHARCTRL commands:\n" " h - print this message\n" " u - increase setpoint\n" " d - decrease setpoint\n" " q - quit\n" " 1..4 - change example state\n\n"); } /**************************************************************************** * Name: foc_charctrl_init ****************************************************************************/ static int foc_charctrl_init(FAR struct foc_intf_chc_s *intf) { int ret = 0; DEBUGASSERT(intf); /* Character control interface on STDIN */ intf->fd = 0; /* Print help msg */ PRINTF("\nCHARCTRL mode enabled\n"); foc_charctrl_help(); /* Configure input to not blocking */ fcntl(intf->fd, F_SETFL, O_NONBLOCK); return ret; } /**************************************************************************** * Name: foc_charctrl_deinit ****************************************************************************/ static int foc_charctrl_deinit(FAR struct foc_intf_chc_s *intf) { DEBUGASSERT(intf); if (intf->fd > 0) { close(intf->fd); } return OK; } /**************************************************************************** * Name: foc_charctrl_update ****************************************************************************/ static int foc_charctrl_update(FAR struct foc_intf_chc_s *intf, FAR struct foc_intf_data_s *data) { char c = 0; int ret = OK; DEBUGASSERT(intf); DEBUGASSERT(data); ret = read(intf->fd, &c, 1); if (ret < 0) { if (errno != EAGAIN) { PRINTF("ERROR: read char failed %d\n", errno); ret = -errno; goto errout; } else { ret = OK; } } else { switch (c) { #ifdef CONFIG_EXAMPLES_FOC_SETPOINT_CHAR case 'u': { data->sp_raw += CONFIG_EXAMPLES_FOC_CHAR_SETPOINT_STEP; if (data->sp_raw > CONFIG_EXAMPLES_FOC_SETPOINT_MAX) { data->sp_raw = CONFIG_EXAMPLES_FOC_SETPOINT_MAX; } PRINTF(">> sp=%" PRIu32 "\n", data->sp_raw); data->sp_update = true; break; } case 'd': { data->sp_raw -= CONFIG_EXAMPLES_FOC_CHAR_SETPOINT_STEP; if (data->sp_raw < 0) { data->sp_raw = 0; } PRINTF(">> sp=%" PRIu32 "\n", data->sp_raw); data->sp_update = true; break; } #endif /* CONFIG_EXAMPLES_FOC_SETPOINT_CHAR */ case 'h': { foc_charctrl_help(); break; } case 'q': { PRINTF(">> QUIT\n"); data->terminate = true; break; } case '1': case '2': case '3': case '4': { data->state = c - '1' + 1; PRINTF(">> state=%" PRIu32 "\n", data->state); data->state_update = true; break; } default: { PRINTF("ERROR: invalid cmd=%d\n", c); break; } } } errout: return ret; } #endif /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: foc_intf_init ****************************************************************************/ int foc_intf_init(void) { int ret = OK; #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC /* Initialize ADC interface */ ret = foc_adc_init(&g_adc_intf); if (ret < 0) { PRINTF("ERROR: failed to initialize adc interface %d\n", ret); goto errout; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /* Initialize button interface */ ret = foc_button_init(&g_btn_intf); if (ret < 0) { PRINTF("ERROR: failed to initialize button interface %d\n", ret); goto errout; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL /* Initialize character control interface */ ret = foc_charctrl_init(&g_chc_intf); if (ret < 0) { PRINTF("ERROR: failed to initialize char interface %d\n", ret); goto errout; } #endif #ifdef FOC_HAVE_INTF errout: #endif return ret; } /**************************************************************************** * Name: foc_intf_deinit ****************************************************************************/ int foc_intf_deinit(void) { int ret = OK; #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC /* De-initialize adc interface */ ret = foc_adc_deinit(&g_adc_intf); if (ret < 0) { PRINTF("ERROR: foc_adc_deinit failed %d\n", ret); goto errout; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /* De-initialize button interface */ ret = foc_button_deinit(&g_btn_intf); if (ret < 0) { PRINTF("ERROR: foc_button_deinit failed %d\n", ret); goto errout; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL /* De-initialize character interface */ ret = foc_charctrl_deinit(&g_chc_intf); if (ret < 0) { PRINTF("ERROR: foc_charctrl_deinit failed %d\n", ret); goto errout; } #endif #ifdef FOC_HAVE_INTF errout: #endif return ret; } /**************************************************************************** * Name: foc_intf_update ****************************************************************************/ int foc_intf_update(FAR struct foc_intf_data_s *data) { int ret = OK; DEBUGASSERT(data); #ifdef CONFIG_EXAMPLES_FOC_HAVE_CHARCTRL /* Update charctrl */ ret = foc_charctrl_update(&g_chc_intf, data); if (ret < 0) { PRINTF("ERROR: foc_charctrl_update failed: %d\n", ret); goto errout; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_BUTTON /* Update button */ ret = foc_button_update(&g_btn_intf, data); if (ret < 0) { PRINTF("ERROR: button update failed %d\n", ret); goto errout; } #endif #ifdef CONFIG_EXAMPLES_FOC_HAVE_ADC /* Update ADC */ ret = foc_adc_update(&g_adc_intf, data); if (ret < 0) { PRINTF("ERROR: adc update failed %d\n", ret); goto errout; } #endif #ifdef FOC_HAVE_INTF errout: #endif return ret; }