diff --git a/Makefile b/Makefile index f415d80fe..9988ce818 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,7 @@ HSE_VALUE ?= 8000000 FEATURES = OFFICIAL_TARGETS = ALIENFLIGHTF3 ALIENFLIGHTF4 ANYFCF7 BETAFLIGHTF3 BLUEJAYF4 CC3D FURYF4 NAZE REVO SIRINFPV SPARKY SPRACINGF3 SPRACINGF3EVO SPRACINGF3NEO SPRACINGF4EVO STM32F3DISCOVERY +SKIP_TARGETS := ALIENWHOOP ALT_TARGETS = $(sort $(filter-out target, $(basename $(notdir $(wildcard $(ROOT)/src/main/target/*/*.mk))))) OPBL_TARGETS = $(filter %_OPBL, $(ALT_TARGETS)) OSD_SLAVE_TARGETS = SPRACINGF3OSD @@ -96,6 +97,7 @@ VALID_TARGETS = $(dir $(wildcard $(ROOT)/src/main/target/*/target.mk)) VALID_TARGETS := $(subst /,, $(subst ./src/main/target/,, $(VALID_TARGETS))) VALID_TARGETS := $(VALID_TARGETS) $(ALT_TARGETS) VALID_TARGETS := $(sort $(VALID_TARGETS)) +VALID_TARGETS := $(filter-out $(SKIP_TARGETS), $(VALID_TARGETS)) GROUP_1_TARGETS := \ AFROMINI \ @@ -108,13 +110,15 @@ GROUP_1_TARGETS := \ ALIENFLIGHTF3 \ ALIENFLIGHTF4 \ ALIENFLIGHTNGF7 \ + ALIENWHOOPF4 \ + ALIENWHOOPF7 \ ANYFCF7 \ BEEBRAIN \ BEEROTORF4 \ BETAFLIGHTF3 \ BLUEJAYF4 \ CC3D \ - CC3D_OPBL \ + CC3D_OPBL GROUP_2_TARGETS := \ CHEBUZZF3 \ @@ -141,7 +145,7 @@ GROUP_2_TARGETS := \ FURYF7 \ IMPULSERCF3 \ IRCFUSIONF3 \ - ISHAPEDF3 \ + ISHAPEDF3 GROUP_3_TARGETS := \ KAKUTEF4 \ @@ -160,6 +164,7 @@ GROUP_3_TARGETS := \ OMNIBUSF4SD \ PLUMF4 \ PODIUMF4 \ + DYSF4PRO GROUP_4_TARGETS := \ RCEXPLORERF3 \ @@ -181,7 +186,7 @@ GROUP_4_TARGETS := \ SPRACINGF4EVO \ SPRACINGF4NEO \ STM32F3DISCOVERY \ - TINYBEEF3 \ + TINYBEEF3 GROUP_OTHER_TARGETS := $(filter-out $(GROUP_1_TARGETS) $(GROUP_2_TARGETS) $(GROUP_3_TARGETS) $(GROUP_4_TARGETS), $(VALID_TARGETS)) diff --git a/src/main/build/debug.c b/src/main/build/debug.c index c218c40bd..a3e963c2e 100644 --- a/src/main/build/debug.c +++ b/src/main/build/debug.c @@ -26,3 +26,28 @@ uint8_t debugMode; #ifdef DEBUG_SECTION_TIMES uint32_t sectionTimes[2][4]; #endif + +const char * const debugModeNames[DEBUG_COUNT] = { + "NONE", + "CYCLETIME", + "BATTERY", + "GYRO", + "ACCELEROMETER", + "MIXER", + "AIRMODE", + "PIDLOOP", + "NOTCH", + "RC_INTERPOLATION", + "VELOCITY", + "DFILTER", + "ANGLERATE", + "ESC_SENSOR", + "SCHEDULER", + "STACK", + "ESC_SENSOR_RPM", + "ESC_SENSOR_TMP", + "ALTITUDE", + "FFT", + "FFT_TIME", + "FFT_FREQ" +}; diff --git a/src/main/build/debug.h b/src/main/build/debug.h index 6df4163ee..120c3b810 100644 --- a/src/main/build/debug.h +++ b/src/main/build/debug.h @@ -70,3 +70,5 @@ typedef enum { DEBUG_FFT_FREQ, DEBUG_COUNT } debugType_e; + +extern const char * const debugModeNames[DEBUG_COUNT]; diff --git a/src/main/cms/cms.c b/src/main/cms/cms.c index bd6039eb3..00fe8d2d3 100644 --- a/src/main/cms/cms.c +++ b/src/main/cms/cms.c @@ -41,6 +41,7 @@ #include "cms/cms_menu_builtin.h" #include "cms/cms_types.h" +#include "common/maths.h" #include "common/typeconversion.h" #include "drivers/system.h" @@ -260,7 +261,8 @@ static void cmsPadToSize(char *buf, int size) static int cmsDrawMenuEntry(displayPort_t *pDisplay, OSD_Entry *p, uint8_t row) { - char buff[10]; + #define CMS_DRAW_BUFFER_LEN 10 + char buff[CMS_DRAW_BUFFER_LEN]; int cnt = 0; switch (p->type) { @@ -306,8 +308,10 @@ static int cmsDrawMenuEntry(displayPort_t *pDisplay, OSD_Entry *p, uint8_t row) case OME_TAB: if (IS_PRINTVALUE(p)) { OSD_TAB_t *ptr = p->data; - //cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay) - 5, row, (char *)ptr->names[*ptr->val]); - cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay), row, (char *)ptr->names[*ptr->val]); + char * str = (char *)ptr->names[*ptr->val]; + memcpy(buff, str, MAX(CMS_DRAW_BUFFER_LEN, strlen(str))); + cmsPadToSize(buff, CMS_DRAW_BUFFER_LEN); + cnt = displayWrite(pDisplay, RIGHT_MENU_COLUMN(pDisplay), row, buff); CLR_PRINTVALUE(p); } break; diff --git a/src/main/cms/cms_menu_misc.c b/src/main/cms/cms_menu_misc.c index 4a7c18561..c0bc5cb4a 100644 --- a/src/main/cms/cms_menu_misc.c +++ b/src/main/cms/cms_menu_misc.c @@ -24,6 +24,7 @@ #ifdef CMS +#include "build/debug.h" #include "build/version.h" #include "drivers/time.h" @@ -38,6 +39,7 @@ #include "config/parameter_group.h" #include "config/parameter_group_ids.h" +#include "fc/config.h" #include "fc/rc_controls.h" #include "flight/mixer.h" @@ -92,6 +94,7 @@ static uint16_t motorConfig_minthrottle; static uint8_t motorConfig_digitalIdleOffsetValue; static uint8_t voltageSensorADCConfig_vbatscale; static uint8_t batteryConfig_vbatmaxcellvoltage; +static debugType_e systemConfig_debug_mode; static long cmsx_menuMiscOnEnter(void) { @@ -99,6 +102,8 @@ static long cmsx_menuMiscOnEnter(void) motorConfig_digitalIdleOffsetValue = motorConfig()->digitalIdleOffsetValue / 10; voltageSensorADCConfig_vbatscale = voltageSensorADCConfig(VOLTAGE_SENSOR_ADC_VBAT)->vbatscale; batteryConfig_vbatmaxcellvoltage = batteryConfig()->vbatmaxcellvoltage; + systemConfig_debug_mode = systemConfig()->debug_mode; + return 0; } @@ -110,6 +115,8 @@ static long cmsx_menuMiscOnExit(const OSD_Entry *self) motorConfigMutable()->digitalIdleOffsetValue = 10 * motorConfig_digitalIdleOffsetValue; voltageSensorADCConfigMutable(VOLTAGE_SENSOR_ADC_VBAT)->vbatscale = voltageSensorADCConfig_vbatscale; batteryConfigMutable()->vbatmaxcellvoltage = batteryConfig_vbatmaxcellvoltage; + systemConfigMutable()->debug_mode = systemConfig_debug_mode; + return 0; } @@ -121,6 +128,7 @@ static OSD_Entry menuMiscEntries[]= { "DIGITAL IDLE", OME_UINT8, NULL, &(OSD_UINT8_t) { &motorConfig_digitalIdleOffsetValue, 0, 200, 1 }, 0 }, { "VBAT SCALE", OME_UINT8, NULL, &(OSD_UINT8_t) { &voltageSensorADCConfig_vbatscale, 1, 250, 1 }, 0 }, { "VBAT CLMAX", OME_UINT8, NULL, &(OSD_UINT8_t) { &batteryConfig_vbatmaxcellvoltage, 10, 50, 1 }, 0 }, + { "DEBUG MODE", OME_TAB, NULL, &(OSD_TAB_t) { &systemConfig_debug_mode, DEBUG_COUNT - 1, debugModeNames }, 0 }, { "RC PREV", OME_Submenu, cmsMenuChange, &cmsx_menuRcPreview, 0}, { "BACK", OME_Back, NULL, NULL, 0}, diff --git a/src/main/drivers/display_ug2864hsweg01.c b/src/main/drivers/display_ug2864hsweg01.c index b337d4998..0d82c5eb8 100644 --- a/src/main/drivers/display_ug2864hsweg01.c +++ b/src/main/drivers/display_ug2864hsweg01.c @@ -186,9 +186,8 @@ static bool i2c_OLED_send_cmd(busDevice_t *bus, uint8_t command) static bool i2c_OLED_send_cmdarray(busDevice_t *bus, const uint8_t *commands, size_t len) { for (size_t i = 0 ; i < len ; i++) { - if (i2c_OLED_send_cmd(bus, commands[i])) { - // XXX Funny, i2cWrite is returning errors!? - // return; + if (!i2c_OLED_send_cmd(bus, commands[i])) { + return false; } } diff --git a/src/main/drivers/pwm_output.c b/src/main/drivers/pwm_output.c index 01c0eb8e9..dd8018e9a 100644 --- a/src/main/drivers/pwm_output.c +++ b/src/main/drivers/pwm_output.c @@ -480,10 +480,9 @@ void pwmToggleBeeper(void) pwmWriteBeeper(!beeperPwm.enabled); } -void beeperPwmInit(IO_t io, uint16_t frequency) +void beeperPwmInit(const ioTag_t tag, uint16_t frequency) { - const ioTag_t tag=IO_TAG(BEEPER); - beeperPwm.io = io; + beeperPwm.io = IOGetByTag(tag); const timerHardware_t *timer = timerGetByTag(tag, TIM_USE_BEEPER); if (beeperPwm.io && timer) { IOInit(beeperPwm.io, OWNER_BEEPER, RESOURCE_INDEX(0)); diff --git a/src/main/drivers/pwm_output.h b/src/main/drivers/pwm_output.h index 9dcea1edb..619dd2952 100644 --- a/src/main/drivers/pwm_output.h +++ b/src/main/drivers/pwm_output.h @@ -179,7 +179,7 @@ void pwmCompleteDshotMotorUpdate(uint8_t motorCount); #ifdef BEEPER void pwmWriteBeeper(bool onoffBeep); void pwmToggleBeeper(void); -void beeperPwmInit(IO_t io, uint16_t frequency); +void beeperPwmInit(const ioTag_t tag, uint16_t frequency); #endif void pwmWriteMotor(uint8_t index, float value); diff --git a/src/main/drivers/sound_beeper.c b/src/main/drivers/sound_beeper.c index ebef30d1d..2e47104ef 100644 --- a/src/main/drivers/sound_beeper.c +++ b/src/main/drivers/sound_beeper.c @@ -69,8 +69,8 @@ void beeperInit(const beeperDevConfig_t *config) } systemBeep(false); } else { - beeperIO = IOGetByTag(config->ioTag); - beeperPwmInit(beeperIO, beeperFrequency); + const ioTag_t beeperTag = config->ioTag; + beeperPwmInit(beeperTag, beeperFrequency); } #else UNUSED(config); diff --git a/src/main/fc/cli.c b/src/main/fc/cli.c index a6581f745..4ef9e8104 100755 --- a/src/main/fc/cli.c +++ b/src/main/fc/cli.c @@ -299,13 +299,34 @@ static void cliPrintLinef(const char *format, ...) va_end(va); } + static void printValuePointer(const clivalue_t *var, const void *valuePointer, bool full) { if ((var->type & VALUE_MODE_MASK) == MODE_ARRAY) { for (int i = 0; i < var->config.array.length; i++) { - uint8_t value = ((uint8_t *)valuePointer)[i]; + switch (var->type & VALUE_TYPE_MASK) { + default: + case VAR_UINT8: + // uint8_t array + cliPrintf("%d", ((uint8_t *)valuePointer)[i]); + break; + + case VAR_INT8: + // int8_t array + cliPrintf("%d", ((int8_t *)valuePointer)[i]); + break; + + case VAR_UINT16: + // uin16_t array + cliPrintf("%d", ((uint16_t *)valuePointer)[i]); + break; + + case VAR_INT16: + // int16_t array + cliPrintf("%d", ((int16_t *)valuePointer)[i]); + break; + } - cliPrintf("%d", value); if (i < var->config.array.length - 1) { cliPrint(","); } @@ -376,7 +397,7 @@ static uint16_t getValueOffset(const clivalue_t *value) return 0; } -static void *getValuePointer(const clivalue_t *value) +STATIC_UNIT_TESTED void *getValuePointer(const clivalue_t *value) { const pgRegistry_t* rec = pgFind(value->pgn); return CONST_CAST(void *, rec->address + getValueOffset(value)); @@ -2637,7 +2658,7 @@ static void cliDefaults(char *cmdline) cliReboot(); } -static void cliGet(char *cmdline) +STATIC_UNIT_TESTED void cliGet(char *cmdline) { const clivalue_t *val; int matchedCommands = 0; @@ -2681,7 +2702,7 @@ static uint8_t getWordLength(char *bufBegin, char *bufEnd) return bufEnd - bufBegin; } -static void cliSet(char *cmdline) +STATIC_UNIT_TESTED void cliSet(char *cmdline) { const uint32_t len = strlen(cmdline); char *eqptr; @@ -2706,16 +2727,17 @@ static void cliSet(char *cmdline) for (uint32_t i = 0; i < valueTableEntryCount; i++) { const clivalue_t *val = &valueTable[i]; + // ensure exact match when setting to prevent setting variables with shorter names - if (strncasecmp(cmdline, valueTable[i].name, strlen(valueTable[i].name)) == 0 && variableNameLength == strlen(valueTable[i].name)) { + if (strncasecmp(cmdline, val->name, strlen(val->name)) == 0 && variableNameLength == strlen(val->name)) { bool valueChanged = false; int16_t value = 0; - switch (valueTable[i].type & VALUE_MODE_MASK) { + switch (val->type & VALUE_MODE_MASK) { case MODE_DIRECT: { int16_t value = atoi(eqptr); - if (value >= valueTable[i].config.minmax.min && value <= valueTable[i].config.minmax.max) { + if (value >= val->config.minmax.min && value <= val->config.minmax.max) { cliSetVar(val, value); valueChanged = true; } @@ -2723,7 +2745,7 @@ static void cliSet(char *cmdline) break; case MODE_LOOKUP: { - const lookupTableEntry_t *tableEntry = &lookupTables[valueTable[i].config.lookup.tableIndex]; + const lookupTableEntry_t *tableEntry = &lookupTables[val->config.lookup.tableIndex]; bool matched = false; for (uint32_t tableValueIndex = 0; tableValueIndex < tableEntry->valueCount && !matched; tableValueIndex++) { matched = strcasecmp(tableEntry->values[tableValueIndex], eqptr) == 0; @@ -2739,41 +2761,67 @@ static void cliSet(char *cmdline) break; case MODE_ARRAY: { - const uint8_t arrayLength = valueTable[i].config.array.length; + const uint8_t arrayLength = val->config.array.length; char *valPtr = eqptr; - uint8_t array[256]; - char curVal[4]; + for (int i = 0; i < arrayLength; i++) { + // skip spaces valPtr = skipSpace(valPtr); - char *valEnd = strstr(valPtr, ","); - if ((valEnd != NULL) && (i < arrayLength - 1)) { - uint8_t varLength = getWordLength(valPtr, valEnd); - if (varLength <= 3) { - strncpy(curVal, valPtr, getWordLength(valPtr, valEnd)); - curVal[varLength] = '\0'; - array[i] = (uint8_t)atoi((const char *)curVal); - valPtr = valEnd + 1; - } else { + // find next comma (or end of string) + char *valEndPtr = strchr(valPtr, ','); + + // comma found or last item? + if ((valEndPtr != NULL) || (i == arrayLength - 1)){ + // process substring [valPtr, valEndPtr[ + // note: no need to copy substrings for atoi() + // it stops at the first character that cannot be converted... + switch (val->type & VALUE_TYPE_MASK) { + default: + case VAR_UINT8: { + // fetch data pointer + uint8_t *data = (uint8_t *)getValuePointer(val) + i; + // store value + *data = (uint8_t)atoi((const char*) valPtr); + } + break; + + case VAR_INT8: { + // fetch data pointer + int8_t *data = (int8_t *)getValuePointer(val) + i; + // store value + *data = (int8_t)atoi((const char*) valPtr); + } + break; + + case VAR_UINT16: { + // fetch data pointer + uint16_t *data = (uint16_t *)getValuePointer(val) + i; + // store value + *data = (uint16_t)atoi((const char*) valPtr); + } + break; + + case VAR_INT16: { + // fetch data pointer + int16_t *data = (int16_t *)getValuePointer(val) + i; + // store value + *data = (int16_t)atoi((const char*) valPtr); + } break; } - } else if ((valEnd == NULL) && (i == arrayLength - 1)) { - array[i] = atoi(valPtr); - - uint8_t *ptr = getValuePointer(val); - memcpy(ptr, array, arrayLength); + // mark as changed valueChanged = true; - } else { - break; + + // prepare to parse next item + valPtr = valEndPtr + 1; } } } - break; - } if (valueChanged) { - cliPrintf("%s set to ", valueTable[i].name); + cliPrintf("%s set to ", val->name); cliPrintVar(val, 0); } else { cliPrintLine("Invalid value"); diff --git a/src/main/fc/settings.c b/src/main/fc/settings.c index e430840f6..c1c8353ab 100644 --- a/src/main/fc/settings.c +++ b/src/main/fc/settings.c @@ -195,31 +195,6 @@ static const char * const lookupTableGyroLpf[] = { "EXPERIMENTAL" }; -static const char * const lookupTableDebug[DEBUG_COUNT] = { - "NONE", - "CYCLETIME", - "BATTERY", - "GYRO", - "ACCELEROMETER", - "MIXER", - "AIRMODE", - "PIDLOOP", - "NOTCH", - "RC_INTERPOLATION", - "VELOCITY", - "DFILTER", - "ANGLERATE", - "ESC_SENSOR", - "SCHEDULER", - "STACK", - "ESC_SENSOR_RPM", - "ESC_SENSOR_TMP", - "ALTITUDE", - "FFT", - "FFT_TIME", - "FFT_FREQ" -}; - #ifdef OSD static const char * const lookupTableOsdType[] = { "AUTO", @@ -290,7 +265,7 @@ const lookupTableEntry_t lookupTables[] = { #ifdef MAG { lookupTableMagHardware, sizeof(lookupTableMagHardware) / sizeof(char *) }, #endif - { lookupTableDebug, sizeof(lookupTableDebug) / sizeof(char *) }, + { debugModeNames, sizeof(debugModeNames) / sizeof(char *) }, { lookupTableSuperExpoYaw, sizeof(lookupTableSuperExpoYaw) / sizeof(char *) }, { lookupTablePwmProtocol, sizeof(lookupTablePwmProtocol) / sizeof(char *) }, { lookupTableRcInterpolation, sizeof(lookupTableRcInterpolation) / sizeof(char *) }, diff --git a/src/main/target/ALIENWHOOP/ALIENWHOOPF4.mk b/src/main/target/ALIENWHOOP/ALIENWHOOPF4.mk new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/target/ALIENWHOOP/ALIENWHOOPF7.mk b/src/main/target/ALIENWHOOP/ALIENWHOOPF7.mk new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/target/ALIENWHOOP/config.c b/src/main/target/ALIENWHOOP/config.c new file mode 100644 index 000000000..c430cc689 --- /dev/null +++ b/src/main/target/ALIENWHOOP/config.c @@ -0,0 +1,86 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + + +/* + + + + + \ | _ _| __| \ |\ \ /| | _ \ _ \ _ \ + _ \ | | _| . | \ \ \ / __ | ( |( |__/ + _/ _\____|___|___|_|\_| \_/\_/ _| _|\___/\___/_| + + + Take me to your leader-board... + + + +*/ + +#include +#include + +#include + +#ifdef TARGET_CONFIG + +#include "common/axis.h" +#include "config/feature.h" +#include "drivers/pwm_esc_detect.h" +#include "flight/mixer.h" +#include "flight/pid.h" +#include "io/serial.h" +#include "rx/rx.h" +#include "sensors/barometer.h" +#include "sensors/boardalignment.h" +#include "sensors/compass.h" + +#ifdef BRUSHED_MOTORS_PWM_RATE +#undef BRUSHED_MOTORS_PWM_RATE +#endif + +#define BRUSHED_MOTORS_PWM_RATE 666 // 666Hz };-)>~ low PWM rate seems to give better power and cooler motors... + + +void targetConfiguration(void) +{ + if (hardwareMotorType == MOTOR_BRUSHED) { + motorConfigMutable()->dev.motorPwmRate = BRUSHED_MOTORS_PWM_RATE; + motorConfigMutable()->minthrottle = 1080; + motorConfigMutable()->maxthrottle = 2000; + pidConfigMutable()->pid_process_denom = 1; + } + + rxConfigMutable()->serialrx_provider = SERIALRX_SBUS; +#if defined(ALIENWHOOPF4) + rxConfigMutable()->sbus_inversion = 0; // TODO: what to do about F4 inversion? +#else + rxConfigMutable()->sbus_inversion = 1; // invert on F7 +#endif + +/* Breadboard-specific settings for development purposes only + */ +#if defined(BREADBOARD) + boardAlignmentMutable()->pitchDegrees = 90; // vertical breakout board + barometerConfigMutable()->baro_hardware = BARO_DEFAULT; // still testing not on V1 or V2 pcb +#endif + + compassConfigMutable()->mag_hardware = MAG_DEFAULT; +} +#endif + diff --git a/src/main/target/ALIENWHOOP/target.c b/src/main/target/ALIENWHOOP/target.c new file mode 100644 index 000000000..c6ca4816e --- /dev/null +++ b/src/main/target/ALIENWHOOP/target.c @@ -0,0 +1,53 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + + +/* + + + + + \ | _ _| __| \ |\ \ /| | _ \ _ \ _ \ + _ \ | | _| . | \ \ \ / __ | ( |( |__/ + _/ _\____|___|___|_|\_| \_/\_/ _| _|\___/\___/_| + + + Take me to your leader-board... + + + +*/ + +#include + +#include +#include "drivers/io.h" + +#include "drivers/timer.h" +#include "drivers/timer_def.h" +#include "drivers/dma.h" + +/* Currently only supporting brushed quad configuration e.g. Tiny Whoop. Care must be + * taken to ensure functionality on both F4 and F7 (STM32F405RGT and STM32F722RET) + */ +const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = { + DEF_TIM(TIM8, CH4, PC9, TIM_USE_MOTOR, TIMER_OUTPUT_STANDARD, 0), + DEF_TIM(TIM3, CH3, PC8, TIM_USE_MOTOR, TIMER_OUTPUT_STANDARD, 0), + DEF_TIM(TIM3, CH2, PC7, TIM_USE_MOTOR, TIMER_OUTPUT_STANDARD, 0), + DEF_TIM(TIM8, CH1, PC6, TIM_USE_MOTOR, TIMER_OUTPUT_STANDARD, 0), +}; + diff --git a/src/main/target/ALIENWHOOP/target.h b/src/main/target/ALIENWHOOP/target.h new file mode 100644 index 000000000..7b1747192 --- /dev/null +++ b/src/main/target/ALIENWHOOP/target.h @@ -0,0 +1,240 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + + +/* + + + + + \ | _ _| __| \ |\ \ /| | _ \ _ \ _ \ + _ \ | | _| . | \ \ \ / __ | ( |( |__/ + _/ _\____|___|___|_|\_| \_/\_/ _| _|\___/\___/_| + + + Take me to your leader-board... + + + +*/ + +#pragma once + +/* Multi-Arch Support for 168MHz or 216MHz ARM Cortex processors - STM32F405RGT or STM32F7RET + */ +#if defined(ALIENWHOOPF4) +#define TARGET_BOARD_IDENTIFIER "AWF4" +#define USBD_PRODUCT_STRING "AlienWhoopF4" +#else +#define TARGET_BOARD_IDENTIFIER "AWF7" +#define USBD_PRODUCT_STRING "AlienWhoopF7" +#endif + +#define TARGET_CONFIG // see config.c for target specific customizations + +#define CONFIG_FASTLOOP_PREFERRED_ACC ACC_DEFAULT +#define BRUSHED_MOTORS +#define BRUSHED_ESC_AUTODETECT + +/* Visual Alerts - SMD LEDs + */ +#define LED0_PIN PC12 // conflicts UART5 +#define LED1_PIN PD2 // conflicts UART5 + +/* Lost Quad Mode and Alerts - RCX03-787 Low Voltage Active Buzzer + */ +#if defined(V2DRAFT) // a few boards exist with older pinout +#define BEEPER PC13 // PC13... limited... current (3 mA)... +#else +#define BEEPER PA2 // PC13... limited... current (3 mA)... +#endif +#define BEEPER_INVERTED // [and] must not be used [to drive LED etc] + +/* Serial Peripheral Interface (SPI) - Up to 50 Mbit/s on F7 + */ +#define USE_SPI +#define USE_SPI_DEVICE_1 // SPI1 can communicate at up to 42 Mbits/s on F4 +#define USE_SPI_DEVICE_2 // SPI2 and SPI3 can communicate at up to 21 Mbit/s on F4 +#define USE_SPI_DEVICE_3 // All SPIs can be served by the DMA controller. +#if defined(ALIENWHOOPF7) +//TODO: +//#define USE_SPI_DEVICE_4 +//#define USE_SPI_DEVICE_5 +#endif + +#define SPI1_NSS_PIN PA4 // LQFP64 pin 20 (PA4) +#define SPI1_SCK_PIN PA5 // LQFP64 pin 21 (PA5) +#define SPI1_MISO_PIN PA6 // LQFP64 pin 22 (PA6) +#define SPI1_MOSI_PIN PA7 // LQFP64 pin 23 (PA7) + +#define SPI2_NSS_PIN PB12 // LQFP64 pin 33 (PB12) +#define SPI2_SCK_PIN PB13 // LQFP64 pin 34 (PB13) +#define SPI2_MISO_PIN PB14 // LQFP64 pin 35 (PB14) +#define SPI2_MOSI_PIN PB15 // LQFP64 pin 36 (PB15) + +#define SPI3_NSS_PIN PA15 // LQFP64 pin 50 (PA15) +//#define SPI3_SCK_PIN PC10 // LQFP64 pin 51 (PC10) +//#define SPI3_MISO_PIN PC11 // LQFP64 pin 52 (PC11) +//#define SPI3_MOSI_PIN PC12 // LQFP64 pin 53 (PC12) +#define SPI3_SCK_PIN PB3 // LQFP64 pin 55 (PB3) +#define SPI3_MISO_PIN PB4 // LQFP64 pin 56 (PB4) +#define SPI3_MOSI_PIN PB5 // LQFP64 pin 57 (PB5) + +#if defined(ALIENWHOOPF7) +//TODO: define SPI4 and SPI5 for F7 target +//#define SPI4_NSS_PIN +//#define SPI4_SCK_PIN +//#define SPI4_MISO_PIN +//#define SPI4_MOSI_PIN +//#define SPI5_NSS_PIN +//#define SPI5_SCK_PIN +//#define SPI5_MISO_PIN +//#define SPI5_MOSI_PIN +#endif + +/* Motion Processing Unit (MPU) - Invensense 6-axis MPU-6500 or 9-axis MPU-9250 + */ +// Interrupt +#define USE_EXTI +#define MPU_INT_EXTI PC14 +// MPU +#define MPU6500_CS_PIN SPI1_NSS_PIN +#define MPU6500_SPI_INSTANCE SPI1 +#define USE_MPU_DATA_READY_SIGNAL +#define ENSURE_MPU_DATA_READY_IS_LOW +// MAG +#define MAG +#define USE_MAG_AK8963 +#define MAG_AK8963_ALIGN CW0_DEG +#define USE_MAG_DATA_READY_SIGNAL +#define ENSURE_MAG_DATA_READY_IS_HIGH +// GYRO +#define GYRO +#define USE_GYRO_SPI_MPU6500 +#define GYRO_MPU6500_ALIGN CW0_DEG +// ACC +#define ACC +#define USE_ACC_SPI_MPU6500 +#define ACC_MPU6500_ALIGN CW0_DEG + +/* Optional Digital Pressure Sensor (barometer) - Bosch BMP280 + * TODO: not implemented on V1 or V2 pcb + */ +#define BARO +#define USE_BARO_BMP280 +#define USE_BARO_SPI_BMP280 +#define BMP280_SPI_INSTANCE SPI3 +#define BMP280_CS_PIN SPI3_NSS_PIN + +/* Serial ports etc. + */ +#define USE_VCP +#define USE_UART1 +#define USE_UART2 +#define USE_UART3 +#define USE_UART4 +#define USE_UART5 + +#define SERIAL_PORT_COUNT 6 + +// USART1 +#define UART1_TX_PIN PA9 // PB1 INCOMPAT F4 -> F7 +#define UART1_RX_PIN PA10 // PB0 INCOMPAT F4 -> F7 + +// USART2 +#define UART2_TX_PIN PA2 //PA12 +#define UART2_RX_PIN PA3 //PA13 + +// USART3 +#define UART3_TX_PIN PC10 // PB10 INCOMPAT F4 -> F7 +#define UART3_RX_PIN PC11 // PB11 INCOMPAT F4 -> F7 + +// UART4 async only on F4 +#define UART4_TX_PIN PA0 // PC10 currently used by USART3 +#define UART4_RX_PIN PA1 // PC11 currently used by USART3 + +// UART5 async only on F4 +//#define UART5_TX_PIN PB3 // PC12 +//#define UART5_RX_PIN PB4 // PD2 + +/* Receiver - e.g. FrSky XM/XM+ or Spektrum/Lemon DSM/DSMX capable of 3.3V + */ +/* Assume Spektrum following defines inherited from common_fc_pre.h: +//#define USE_SERIALRX_SPEKTRUM +//#define USE_SPEKTRUM_BIND +//#define USE_SPEKTRUM_BIND_PLUG +*/ +#if defined(V2DRAFT) // a few of these boards still exist +#define BINDPLUG_PIN PB14 +#define SPEKTRUM_BIND_PIN PA3 +#define SERIALRX_UART SERIAL_PORT_USART2 +#define RX_CHANNELS_AETR // FrSky AETR TAER SpektrumRC +#else +#define BINDPLUG_PIN PC13 // formerly used for beeper (erroneously) on V1 pcb +#define SPEKTRUM_BIND_PIN UART3_RX_PIN +#define SERIALRX_UART SERIAL_PORT_USART3 +#define RX_CHANNELS_TAER //RX_CHANNELS_AETR +#endif +#define SERIALRX_PROVIDER SERIALRX_SPEKTRUM1024 //SERIALRX_SBUS + +/* Defaults - What do we want out of the box? + */ +#if defined(BREADBOARD) +#define DEFAULT_FEATURES (FEATURE_RX_SERIAL | FEATURE_MOTOR_STOP ) +#else +#define DEFAULT_FEATURES (FEATURE_RX_SERIAL | FEATURE_MOTOR_STOP | FEATURE_FAILSAFE) // FEATURE_TELEMETRY changes bind pin from rx to tx +#endif + +#undef VTX_COMMON +#undef VTX_CONTROL +#undef VTX_SMARTAUDIO +#undef VTX_TRAMP + +/* OLED Support + */ +#if defined(BREADBOARD) +#define CMS +#define USE_I2C +#define USE_I2C_DEVICE_1 +#define I2C_DEVICE (I2CDEV_1) +#define USE_I2C_PULLUP +#define I2C1_SCL PB6 +#define I2C1_SDA PB7 +#else +#undef CMS +#undef USE_I2C +#endif + +/* MCU Pin Mapping - LPFQ64 Flags + */ +#define TARGET_IO_PORTA 0xffff +#define TARGET_IO_PORTB 0xffff +#define TARGET_IO_PORTC 0xffff +#if defined(ALIENWHOOPF4) +// STM32F405RGT +#define TARGET_IO_PORTD (BIT(2)) +#else +// STM32F722RET +#define TARGET_IO_PORTD 0xffff +#define TARGET_IO_PORTE 0xffff +#endif + +/* Timers + */ +#define USABLE_TIMER_CHANNEL_COUNT 4 +#define USED_TIMERS ( TIM_N(3) | TIM_N(8) ) + diff --git a/src/main/target/ALIENWHOOP/target.mk b/src/main/target/ALIENWHOOP/target.mk new file mode 100644 index 000000000..2eec8ed06 --- /dev/null +++ b/src/main/target/ALIENWHOOP/target.mk @@ -0,0 +1,25 @@ +# +# +# \ | _ _| __| \ |\ \ /| | _ \ _ \ _ \ +# _ \ | | _| . | \ \ \ / __ | ( |( |__/ +# _/ _\____|___|___|_|\_| \_/\_/ _| _|\___/\___/_| +# +# +ifeq ($(TARGET), ALIENWHOOPF4) +F405_TARGETS += $(TARGET) # STM32F405RGT +else +ifeq ($(TARGET), ALIENWHOOPF7) +F7X2RE_TARGETS += $(TARGET) # STM32F722RET +else +# Nothing to do for generic ALIENWHOOP... an MCU arch should be specified +endif +endif + +FEATURES += VCP + +TARGET_SRC = \ + drivers/accgyro/accgyro_mpu6500.c \ + drivers/accgyro/accgyro_spi_mpu6500.c \ + drivers/barometer/barometer_bmp280.c \ + drivers/barometer/barometer_spi_bmp280.c \ + drivers/compass/compass_ak8963.c diff --git a/src/main/target/ANYFCF7/target.h b/src/main/target/ANYFCF7/target.h index 9a7567665..1ada7767c 100644 --- a/src/main/target/ANYFCF7/target.h +++ b/src/main/target/ANYFCF7/target.h @@ -44,13 +44,16 @@ #define USE_EXTI #define MAG -//#define USE_MAG_HMC5883 -//#define HMC5883_BUS I2C_DEVICE_EXT +#define USE_MAG_HMC5883 +#define MAG_I2C_INSTANCE (I2CDEV_2) + //#define MAG_HMC5883_ALIGN CW270_DEG_FLIP //#define MAG_HMC5883_ALIGN CW90_DEG #define BARO #define USE_BARO_MS5611 +#define USE_BARO_BMP280 +#define BARO_I2C_INSTANCE (I2CDEV_2) #define USABLE_TIMER_CHANNEL_COUNT 16 @@ -128,8 +131,9 @@ #define SDCARD_DMA_CHANNEL DMA_CHANNEL_4 #define USE_I2C -#define USE_I2C_DEVICE_4 -#define I2C_DEVICE (I2CDEV_4) +#define USE_I2C_DEVICE_2 // External I2C +#define USE_I2C_DEVICE_4 // Onboard I2C +#define I2C_DEVICE (I2CDEV_2) #define USE_ADC #define VBAT_ADC_PIN PC0 diff --git a/src/main/target/ANYFCF7/target.mk b/src/main/target/ANYFCF7/target.mk index bdc188d40..9069b243f 100644 --- a/src/main/target/ANYFCF7/target.mk +++ b/src/main/target/ANYFCF7/target.mk @@ -4,6 +4,8 @@ FEATURES += SDCARD VCP TARGET_SRC = \ drivers/accgyro/accgyro_spi_mpu6000.c \ drivers/barometer/barometer_ms5611.c \ + drivers/barometer/barometer_bmp280.c \ + drivers/compass/compass_hmc5883l.c \ drivers/light_ws2811strip.c \ drivers/light_ws2811strip_hal.c diff --git a/src/main/target/BETAFLIGHTF3/target.c b/src/main/target/BETAFLIGHTF3/target.c index 421d5297c..1bd73fffb 100755 --- a/src/main/target/BETAFLIGHTF3/target.c +++ b/src/main/target/BETAFLIGHTF3/target.c @@ -26,25 +26,22 @@ #include "drivers/dma.h" const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = { - DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, TIMER_INPUT_ENABLED), // PPM - DEF_TIM(TIM16,CH1, PA6, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM1 (1,4) - DEF_TIM(TIM8, CH1N,PA7, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED), // PWM2 (2,3) - DEF_TIM(TIM8, CH2, PB8, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM3 (2,5) - DEF_TIM(TIM17,CH1, PB9, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM4 (1,1) + DEF_TIM(TIM4, CH2, PB7, TIM_USE_PPM, TIMER_INPUT_ENABLED), // PPM DMA(1,4) -#ifdef BFF3_USE_HEXA_DSHOT - // For HEXA dshot - DEF_TIM(TIM1, CH2N,PB0, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED), // PWM5 (1,3) - DEF_TIM(TIM8, CH3N,PB1, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED), // PWM6 (2,1) -#else - // For softserial - DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED), // PWM5 (1,2) !LED - DEF_TIM(TIM3, CH4, PB1, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED), // PWM6 (1,3) -#endif + // Motors 1-4 + DEF_TIM(TIM16,CH1, PA6, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM1 DMA(1,6) + DEF_TIM(TIM8, CH1N,PA7, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED), // PWM2 DMA(2,3) + DEF_TIM(TIM8, CH2, PB8, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM3 DMA(2,5) + DEF_TIM(TIM17,CH1, PB9, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM4 DMA(1,7) + // Motors 5-6 or SoftSerial + DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM5 DMA(1,2) !LED + DEF_TIM(TIM3, CH4, PB1, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM6 DMA(1,3) + + // Motors 7-8 or UART2 DEF_TIM(TIM2, CH4, PA3, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM7/UART2_RX DEF_TIM(TIM2, CH3, PA2, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED), // PWM8/UART2_TX - // When using softserial config, LED will have DMA conflict with PB0 (SOFTSERIAL1_RX). - DEF_TIM(TIM1, CH1, PA8, TIM_USE_MOTOR | TIM_USE_LED, TIMER_OUTPUT_ENABLED), // LED (1,2) + // No LED for Hexa-Dshot; DMA conflict with Motor 5 (PB0); consider PPM if not used. + DEF_TIM(TIM1, CH1, PA8, TIM_USE_MOTOR | TIM_USE_LED, TIMER_OUTPUT_ENABLED), // LED DMA(1,2) }; diff --git a/src/main/target/OMNIBUSF4/DYSF4PRO.mk b/src/main/target/OMNIBUSF4/DYSF4PRO.mk new file mode 100644 index 000000000..290de85f1 --- /dev/null +++ b/src/main/target/OMNIBUSF4/DYSF4PRO.mk @@ -0,0 +1 @@ +#DYSF4PRO \ No newline at end of file diff --git a/src/main/target/OMNIBUSF4/target.h b/src/main/target/OMNIBUSF4/target.h index 8f328b51f..55162736d 100644 --- a/src/main/target/OMNIBUSF4/target.h +++ b/src/main/target/OMNIBUSF4/target.h @@ -19,12 +19,16 @@ #define TARGET_BOARD_IDENTIFIER "OBSD" #elif defined(LUXF4OSD) #define TARGET_BOARD_IDENTIFIER "LUX4" +#elif defined(DYSF4PRO) +#define TARGET_BOARD_IDENTIFIER "DYS4" #else #define TARGET_BOARD_IDENTIFIER "OBF4" #endif #if defined(LUXF4OSD) #define USBD_PRODUCT_STRING "LuxF4osd" +#elif defined(DYSF4PRO) +#define USBD_PRODUCT_STRING "DysF4Pro" #else #define USBD_PRODUCT_STRING "OmnibusF4" #endif diff --git a/src/main/target/REVO/target.h b/src/main/target/REVO/target.h index 6950cbd1b..6a776e993 100644 --- a/src/main/target/REVO/target.h +++ b/src/main/target/REVO/target.h @@ -190,11 +190,11 @@ #define UART3_RX_PIN PB11 #define UART3_TX_PIN PB10 -#if defined(REVOLT) +#if defined(REVOLT) || defined(REVO) #define USE_UART4 #define UART4_RX_PIN PA1 #define UART4_TX_PIN PA0 -#endif // REVOLT +#endif // REVOLT || REVO #define USE_UART6 #define UART6_RX_PIN PC7 @@ -203,7 +203,7 @@ #define USE_SOFTSERIAL1 #define USE_SOFTSERIAL2 -#if defined(REVOLT) +#if defined(REVOLT) || defined(REVO) #define SERIAL_PORT_COUNT 7 //VCP, USART1, USART3, UART4, USART6, SOFTSERIAL x 2 #else #define SERIAL_PORT_COUNT 6 //VCP, USART1, USART3, USART6, SOFTSERIAL x 2 diff --git a/src/main/target/YUPIF4/config.c b/src/main/target/YUPIF4/config.c index e680f323e..a72a10e1f 100644 --- a/src/main/target/YUPIF4/config.c +++ b/src/main/target/YUPIF4/config.c @@ -21,19 +21,39 @@ #include #ifdef TARGET_CONFIG +#include "blackbox/blackbox.h" + +#include "fc/config.h" #include "flight/pid.h" +#include "hardware_revision.h" + + // alternative defaults settings for YuPiF4 targets void targetConfiguration(void) { - pidProfilesMutable(0)->pid[PID_ROLL].P = 35; + /* Changes depending on versions */ + if (hardwareRevision == YUPIF4_RACE2) { + beeperDevConfigMutable()->ioTag = IO_TAG(BEEPER_OPT); + } else if (hardwareRevision == YUPIF4_MINI) { + beeperDevConfigMutable()->frequency = 0; + blackboxConfigMutable()->device = BLACKBOX_DEVICE_NONE; + adcConfigMutable()->current.enabled = 0; + } else if (hardwareRevision == YUPIF4_NAV) { + beeperDevConfigMutable()->ioTag = IO_TAG(BEEPER_OPT); + } else { + adcConfigMutable()->current.enabled = 0; + } + + /* Specific PID values for YupiF4 */ + pidProfilesMutable(0)->pid[PID_ROLL].P = 30; pidProfilesMutable(0)->pid[PID_ROLL].I = 45; - pidProfilesMutable(0)->pid[PID_ROLL].D = 30; - pidProfilesMutable(0)->pid[PID_PITCH].P = 40; + pidProfilesMutable(0)->pid[PID_ROLL].D = 20; + pidProfilesMutable(0)->pid[PID_PITCH].P = 30; pidProfilesMutable(0)->pid[PID_PITCH].I = 50; - pidProfilesMutable(0)->pid[PID_PITCH].D = 30; - pidProfilesMutable(0)->pid[PID_YAW].P = 50; + pidProfilesMutable(0)->pid[PID_PITCH].D = 20; + pidProfilesMutable(0)->pid[PID_YAW].P = 40; pidProfilesMutable(0)->pid[PID_YAW].I = 50; } #endif diff --git a/src/main/target/YUPIF4/hardware_revision.c b/src/main/target/YUPIF4/hardware_revision.c new file mode 100644 index 000000000..c14035520 --- /dev/null +++ b/src/main/target/YUPIF4/hardware_revision.c @@ -0,0 +1,70 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#include +#include +#include + +#include "platform.h" + +#include "build/build_config.h" + +#include "drivers/io.h" +#include "drivers/time.h" + +#include "hardware_revision.h" + +uint8_t hardwareRevision = UNKNOWN; + +void detectHardwareRevision(void) +{ + IO_t pin1 = IOGetByTag(IO_TAG(PC13)); + IOInit(pin1, OWNER_SYSTEM, 1); + IOConfigGPIO(pin1, IOCFG_IPU); + + IO_t pin2 = IOGetByTag(IO_TAG(PC14)); + IOInit(pin2, OWNER_SYSTEM, 1); + IOConfigGPIO(pin2, IOCFG_IPU); + + IO_t pin3 = IOGetByTag(IO_TAG(PC15)); + IOInit(pin3, OWNER_SYSTEM, 1); + IOConfigGPIO(pin3, IOCFG_IPU); + + // Check hardware revision + delayMicroseconds(10); // allow configuration to settle + + /* + Hardware pins : Pin1 = PC13 / Pin2 = PC14 / Pin3 = PC15 + no Hardware pins tied to ground => Race V1 + if Pin 1 is the only one tied to ground => Mini + if Pin 2 is the only one tied to ground => Race V2 + if Pin 3 is the only one tied to ground => Navigation + Other combinations available for potential evolutions + */ + if (!IORead(pin1)) { + hardwareRevision = YUPIF4_MINI; + } else if (!IORead(pin2)) { + hardwareRevision = YUPIF4_RACE2; + } else if (!IORead(pin3)) { + hardwareRevision = YUPIF4_NAV; + } else { + hardwareRevision = YUPIF4_RACE1; + } +} + +void updateHardwareRevision(void) { +} diff --git a/src/main/target/YUPIF4/hardware_revision.h b/src/main/target/YUPIF4/hardware_revision.h new file mode 100644 index 000000000..83d58c160 --- /dev/null +++ b/src/main/target/YUPIF4/hardware_revision.h @@ -0,0 +1,30 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ +#pragma once + +typedef enum yupif4HardwareRevision_t { + UNKNOWN = 0, + YUPIF4_RACE1, // Race V1 + YUPIF4_RACE2, // Race V2 + YUPIF4_MINI, // Mini + YUPIF4_NAV, // Navigation +} yupif4HardwareRevision_e; + +extern uint8_t hardwareRevision; + +void detectHardwareRevision(void); +void updateHardwareRevision(void); diff --git a/src/main/target/YUPIF4/target.c b/src/main/target/YUPIF4/target.c index 8f7f49277..77cf5aafc 100644 --- a/src/main/target/YUPIF4/target.c +++ b/src/main/target/YUPIF4/target.c @@ -25,13 +25,15 @@ const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = { - DEF_TIM(TIM8, CH3, PC8, TIM_USE_PPM, TIMER_INPUT_ENABLED, 0 ), // PPM IN - DEF_TIM(TIM5, CH1, PA0, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S1_OUT - DMA1_ST2 - DEF_TIM(TIM5, CH2, PA1, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S2_OUT - DMA1_ST4 - DEF_TIM(TIM2, CH3, PA2, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S3_OUT - DMA1_ST1 - DEF_TIM(TIM2, CH4, PA3, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 1 ), // S4_OUT - DMA1_ST6 - DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR | TIM_USE_LED, TIMER_OUTPUT_ENABLED, 0 ), // S5_OUT - DMA1_ST7 - DEF_TIM(TIM4, CH2, PB7, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S6_OUT - DMA1_ST2 - DEF_TIM(TIM3, CH4, PC9, TIM_USE_BEEPER, TIMER_OUTPUT_ENABLED, 0 ), // BEEPER PWM + DEF_TIM(TIM8, CH3, PC8, TIM_USE_PPM, TIMER_INPUT_ENABLED, 0 ), // PPM IN + DEF_TIM(TIM5, CH1, PA0, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S1_OUT - DMA1_ST2 + DEF_TIM(TIM5, CH2, PA1, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S2_OUT - DMA1_ST4 + DEF_TIM(TIM2, CH3, PA2, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S3_OUT - DMA1_ST1 + DEF_TIM(TIM2, CH4, PA3, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 1 ), // S4_OUT - DMA1_ST6 + DEF_TIM(TIM3, CH3, PB0, TIM_USE_MOTOR | TIM_USE_LED, TIMER_OUTPUT_ENABLED, 0 ), // S5_OUT - DMA1_ST7 + DEF_TIM(TIM4, CH2, PB7, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S6_OUT - DMA1_ST3 + DEF_TIM(TIM3, CH4, PB1, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED, 0 ), // S7_OUT + DEF_TIM(TIM3, CH4, PC9, TIM_USE_BEEPER, TIMER_OUTPUT_ENABLED, 0 ), // BEEPER PWM + DEF_TIM(TIM12, CH1, PB14, TIM_USE_BEEPER, TIMER_OUTPUT_ENABLED, 0 ), // BEEPER PWM OPT }; diff --git a/src/main/target/YUPIF4/target.h b/src/main/target/YUPIF4/target.h index e5a457aa8..59e47b5b8 100644 --- a/src/main/target/YUPIF4/target.h +++ b/src/main/target/YUPIF4/target.h @@ -21,12 +21,15 @@ #define USBD_PRODUCT_STRING "YupiF4" +#define USE_HARDWARE_REVISION_DETECTION + #define LED0_PIN PB6 #define LED1_PIN PB4 #define LED2_PIN PB5 #define BEEPER PC9 -#define BEEPER_PWM_HZ 2200 // Beeper PWM frequency in Hz +#define BEEPER_OPT PB14 +#define BEEPER_PWM_HZ 3150 // Beeper PWM frequency in Hz #define INVERTER_PIN_UART6 PB15 @@ -36,16 +39,16 @@ #define MPU_INT_EXTI PC4 //ICM 20689 -#define ICM20689_CS_PIN PA4 -#define ICM20689_SPI_INSTANCE SPI1 +#define ICM20689_CS_PIN PA4 +#define ICM20689_SPI_INSTANCE SPI1 #define ACC #define USE_ACC_SPI_ICM20689 -#define ACC_ICM20689_ALIGN CW90_DEG +#define ACC_ICM20689_ALIGN CW90_DEG #define GYRO #define USE_GYRO_SPI_ICM20689 -#define GYRO_ICM20689_ALIGN CW90_DEG +#define GYRO_ICM20689_ALIGN CW90_DEG // MPU 6500 #define MPU6500_CS_PIN PA4 @@ -78,6 +81,9 @@ #define UART6_TX_PIN PC6 #define USE_SOFTSERIAL1 +#define SOFTSERIAL1_RX_PIN PB0 // PWM5 +#define SOFTSERIAL1_TX_PIN PB1 // PWM7 + #define USE_SOFTSERIAL2 #define SERIAL_PORT_COUNT 6 // VCP, UART1, UART3, UART6, SOFTSERIAL x 2 @@ -103,7 +109,6 @@ #define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1 #define SDCARD_DMA_CHANNEL DMA_Channel_0 - // SPI Ports #define USE_SPI @@ -127,18 +132,18 @@ #define MAX7456_SPI_CLK (SPI_CLOCK_STANDARD*2) #define MAX7456_RESTORE_CLK (SPI_CLOCK_FAST) - // ADC inputs #define DEFAULT_VOLTAGE_METER_SOURCE VOLTAGE_METER_ADC #define USE_ADC -#define VBAT_ADC_PIN PC1 #define RSSI_ADC_GPIO_PIN PC0 +#define VBAT_ADC_PIN PC1 +#define CURRENT_METER_ADC_PIN PC2 // Default configuration -#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT #define DEFAULT_RX_FEATURE FEATURE_RX_SERIAL #define SERIALRX_PROVIDER SERIALRX_SBUS #define SERIALRX_UART SERIAL_PORT_USART6 +#define DEFAULT_FEATURES (FEATURE_OSD) // Target IO and timers #define USE_SERIAL_4WAY_BLHELI_INTERFACE @@ -148,5 +153,5 @@ #define TARGET_IO_PORTC 0xffff #define TARGET_IO_PORTD (BIT(2)) -#define USABLE_TIMER_CHANNEL_COUNT 8 -#define USED_TIMERS (TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(8)) +#define USABLE_TIMER_CHANNEL_COUNT 10 +#define USED_TIMERS (TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(8) | TIM_N(12)) diff --git a/src/test/Makefile b/src/test/Makefile index 1575e7236..106cdb5fb 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -52,6 +52,16 @@ blackbox_encoding_unittest_SRC := \ $(USER_DIR)/common/printf.c \ $(USER_DIR)/common/typeconversion.c +cli_unittest_SRC := \ + $(USER_DIR)/fc/cli.c \ + $(USER_DIR)/config/feature.c \ + $(USER_DIR)/config/parameter_group.c \ + $(USER_DIR)/common/typeconversion.c + +cli_unittest_DEFINES := \ + USE_CLI \ + SystemCoreClock=1000000 \ + OSD cms_unittest_SRC := \ $(USER_DIR)/cms/cms.c \ diff --git a/src/test/unit/cli_unittest.cc b/src/test/unit/cli_unittest.cc new file mode 100644 index 000000000..565023837 --- /dev/null +++ b/src/test/unit/cli_unittest.cc @@ -0,0 +1,267 @@ +/* + * This file is part of Cleanflight. + * + * Cleanflight is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Cleanflight is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Cleanflight. If not, see . + */ + +#include +#include +#include + +#include + +#include + +extern "C" { + #include "platform.h" + #include "target.h" + #include "fc/runtime_config.h" + #include "fc/fc_msp.h" + #include "config/parameter_group.h" + #include "config/feature.h" + #include "config/parameter_group_ids.h" + #include "sensors/battery.h" + #include "drivers/buf_writer.h" + #include "flight/mixer.h" + #include "flight/servos.h" + #include "flight/pid.h" + #include "io/ledstrip.h" + #include "io/serial.h" + #include "io/osd.h" + #include "fc/settings.h" + #include "rx/rx.h" + #include "io/beeper.h" + #include "fc/rc_adjustments.h" + #include "scheduler/scheduler.h" + #include "fc/runtime_config.h" + #include "build/version.h" + #include "fc/config.h" + #include "drivers/buf_writer.h" + #include "fc/cli.h" + + void cliSet(char *cmdline); + void cliGet(char *cmdline); + void *getValuePointer(const clivalue_t *value); + + const clivalue_t valueTable[] = { + { "array_unit_test", VAR_INT8 | MODE_ARRAY | MASTER_VALUE, .config.array.length = 3, PG_RESERVED_FOR_TESTING_1, 0 } + }; + const uint16_t valueTableEntryCount = ARRAYLEN(valueTable); + const lookupTableEntry_t lookupTables[] = {}; + + + PG_REGISTER(osdConfig_t, osdConfig, PG_OSD_CONFIG, 0); + PG_REGISTER(batteryConfig_t, batteryConfig, PG_BATTERY_CONFIG, 0); + PG_REGISTER(ledStripConfig_t, ledStripConfig, PG_LED_STRIP_CONFIG, 0); + PG_REGISTER(systemConfig_t, systemConfig, PG_SYSTEM_CONFIG, 0); + PG_REGISTER_ARRAY(adjustmentRange_t, MAX_ADJUSTMENT_RANGE_COUNT, adjustmentRanges, PG_ADJUSTMENT_RANGE_CONFIG, 0); + PG_REGISTER_ARRAY(modeActivationCondition_t, MAX_MODE_ACTIVATION_CONDITION_COUNT, modeActivationConditions, PG_MODE_ACTIVATION_PROFILE, 0); + PG_REGISTER(mixerConfig_t, mixerConfig, PG_MIXER_CONFIG, 0); + PG_REGISTER_ARRAY(motorMixer_t, MAX_SUPPORTED_MOTORS, customMotorMixer, PG_MOTOR_MIXER, 0); + PG_REGISTER_ARRAY(servoParam_t, MAX_SUPPORTED_SERVOS, servoParams, PG_SERVO_PARAMS, 0); + PG_REGISTER_ARRAY(servoMixer_t, MAX_SERVO_RULES, customServoMixers, PG_SERVO_MIXER, 0); + PG_REGISTER(featureConfig_t, featureConfig, PG_FEATURE_CONFIG, 0); + PG_REGISTER(beeperConfig_t, beeperConfig, PG_BEEPER_CONFIG, 0); + PG_REGISTER(rxConfig_t, rxConfig, PG_RX_CONFIG, 0); + PG_REGISTER(serialConfig_t, serialConfig, PG_SERIAL_CONFIG, 0); + PG_REGISTER_ARRAY(rxChannelRangeConfig_t, NON_AUX_CHANNEL_COUNT, rxChannelRangeConfigs, PG_RX_CHANNEL_RANGE_CONFIG, 0); + PG_REGISTER_ARRAY(rxFailsafeChannelConfig_t, MAX_SUPPORTED_RC_CHANNEL_COUNT, rxFailsafeChannelConfigs, PG_RX_FAILSAFE_CHANNEL_CONFIG, 0); + PG_REGISTER(pidConfig_t, pidConfig, PG_PID_CONFIG, 0); + + PG_REGISTER_WITH_RESET_FN(int8_t, unitTestData, PG_RESERVED_FOR_TESTING_1, 0); +} + +#include "unittest_macros.h" +#include "gtest/gtest.h" +TEST(CLIUnittest, TestCliSet) +{ + + cliSet((char *)"array_unit_test = 123, -3 , 1"); + + const clivalue_t cval = { + .name = "array_unit_test", + .type = MODE_ARRAY | MASTER_VALUE | VAR_INT8, + .pgn = PG_RESERVED_FOR_TESTING_1, + .offset = 0 + }; + + printf("\n===============================\n"); + int8_t *data = (int8_t *)getValuePointer(&cval); + for(int i=0; i<3; i++){ + printf("data[%d] = %d\n", i, data[i]); + } + printf("\n===============================\n"); + + + EXPECT_EQ(123, data[0]); + EXPECT_EQ( -3, data[1]); + EXPECT_EQ( 1, data[2]); + + + //cliGet((char *)"osd_item_vbat"); + //EXPECT_EQ(false, false); +} + +// STUBS +extern "C" { + +float motor_disarmed[MAX_SUPPORTED_MOTORS]; + +uint16_t batteryWarningVoltage; +uint8_t useHottAlarmSoundPeriod (void) { return 0; } +const uint32_t baudRates[] = {0, 9600, 19200, 38400, 57600, 115200, 230400, 250000, 400000}; // see baudRate_e + +uint32_t micros(void) {return 0;} + +int32_t getAmperage(void) { + return 100; +} + +uint16_t getBatteryVoltage(void) { + return 42; +} + +batteryState_e getBatteryState(void) { + return BATTERY_OK; +} + +uint8_t calculateBatteryPercentageRemaining(void) { + return 67; +} + +uint8_t getMotorCount() { + return 4; +} + + +void setPrintfSerialPort(struct serialPort_s) {} + +void tfp_printf(const char * expectedFormat, ...) { + va_list args; + + va_start(args, expectedFormat); + vprintf(expectedFormat, args); + va_end(args); +} + + +void tfp_format(void *, void (*) (void *, char), const char * expectedFormat, va_list va) { + vprintf(expectedFormat, va); +} + +static const box_t boxes[] = { { 0, "DUMMYBOX", 0 } }; +const box_t *findBoxByPermanentId(uint8_t) { return &boxes[0]; } +const box_t *findBoxByBoxId(boxId_e) { return &boxes[0]; } + +int8_t unitTestDataArray[3]; + +void pgResetFn_unitTestData(int8_t *ptr) { + ptr = &unitTestDataArray[0]; +} + +uint32_t getBeeperOffMask(void) { return 0; } +uint32_t getPreferredBeeperOffMask(void) { return 0; } + +void beeper(beeperMode_e) {} +void beeperSilence(void) {} +void beeperConfirmationBeeps(uint8_t) {} +void beeperWarningBeeps(uint8_t) {} +void beeperUpdate(timeUs_t) {} +uint32_t getArmingBeepTimeMicros(void) {return 0;} +beeperMode_e beeperModeForTableIndex(int) {return BEEPER_SILENCE;} +const char *beeperNameForTableIndex(int) {return NULL;} +int beeperTableEntryCount(void) {return 0;} +bool isBeeperOn(void) {return false;} +void beeperOffSetAll(uint8_t) {} +void setBeeperOffMask(uint32_t) {} +void setPreferredBeeperOffMask(uint32_t) {} + +void beeperOffSet(uint32_t) {} +void beeperOffClear(uint32_t) {} +void beeperOffClearAll(void) {} +bool parseColor(int, const char *) {return false; } +void resetEEPROM(void) {} +void bufWriterFlush(bufWriter_t *) {} +void mixerResetDisarmedMotors(void) {} +void gpsEnablePassthrough(struct serialPort_s *) {} +bool parseLedStripConfig(int, const char *){return false; } +const char rcChannelLetters[] = "AERT12345678abcdefgh"; + +void parseRcChannels(const char *, rxConfig_t *){} +void mixerLoadMix(int, motorMixer_t *) {} +bool setModeColor(ledModeIndex_e, int, int) { return false; } +float convertExternalToMotor(uint16_t ){ return 1.0; } +uint8_t getCurrentPidProfileIndex(void){ return 1; } +uint8_t getCurrentControlRateProfileIndex(void){ return 1; } +void changeControlRateProfile(uint8_t) {} +void resetAllRxChannelRangeConfigurations(rxChannelRangeConfig_t *) {} +void writeEEPROM() {} +serialPortConfig_t *serialFindPortConfiguration(serialPortIdentifier_e) {return NULL; } +baudRate_e lookupBaudRateIndex(uint32_t){return BAUD_9600; } +serialPortUsage_t *findSerialPortUsageByIdentifier(serialPortIdentifier_e){ return NULL; } +serialPort_t *openSerialPort(serialPortIdentifier_e, serialPortFunction_e, serialReceiveCallbackPtr, uint32_t, portMode_t, portOptions_t) { return NULL; } +void serialSetBaudRate(serialPort_t *, uint32_t) {} +void serialSetMode(serialPort_t *, portMode_t) {} +void serialPassthrough(serialPort_t *, serialPort_t *, serialConsumer *, serialConsumer *) {} +uint32_t millis(void) { return 0; } +uint8_t getBatteryCellCount(void) { return 1; } +void servoMixerLoadMix(int) {} +const char * getBatteryStateString(void){ return "_getBatteryStateString_"; } + +uint32_t stackTotalSize(void) { return 0x4000; } +uint32_t stackHighMem(void) { return 0x80000000; } +uint16_t getEEPROMConfigSize(void) { return 1024; } + +uint8_t __config_start = 0x00; +uint8_t __config_end = 0x10; +uint16_t averageSystemLoadPercent = 0; + +timeDelta_t getTaskDeltaTime(cfTaskId_e){ return 0; } +armingDisableFlags_e getArmingDisableFlags(void) { return ARMING_DISABLED_NO_GYRO; } + +const char *armingDisableFlagNames[]= { +"DUMMYDISABLEFLAGNAME" +}; + +void getTaskInfo(cfTaskId_e, cfTaskInfo_t *) {} +void getCheckFuncInfo(cfCheckFuncInfo_t *) {} + +const char * const targetName = "UNITTEST"; +const char* const buildDate = "Jan 01 2017"; +const char * const buildTime = "00:00:00"; +const char * const shortGitRevision = "MASTER"; + +uint32_t serialRxBytesWaiting(const serialPort_t *) {return 0;} +uint8_t serialRead(serialPort_t *){return 0;} + +void bufWriterAppend(bufWriter_t *, uint8_t ch){ printf("%c", ch); } +void serialWriteBufShim(void *, const uint8_t *, int) {} +bufWriter_t *bufWriterInit(uint8_t *, int, bufWrite_t, void *) {return NULL;} +void schedulerSetCalulateTaskStatistics(bool) {} +void setArmingDisabled(armingDisableFlags_e) {} + +void waitForSerialPortToFinishTransmitting(serialPort_t *) {} +void stopPwmAllMotors(void) {} +void systemResetToBootloader(void) {} +void resetConfigs(void) {} +void systemReset(void) {} + +void changePidProfile(uint8_t) {} +bool serialIsPortAvailable(serialPortIdentifier_e) { return false; } +void generateLedConfig(ledConfig_t *, char *, size_t) {} +bool isSerialTransmitBufferEmpty(const serialPort_t *) {return true; } +void serialWrite(serialPort_t *, uint8_t ch) { printf("%c", ch);} + + +}