diff --git a/make/source.mk b/make/source.mk index c17feaaab..5528bb326 100644 --- a/make/source.mk +++ b/make/source.mk @@ -21,6 +21,7 @@ COMMON_SRC = \ drivers/exti.c \ drivers/io.c \ drivers/light_led.c \ + drivers/mco.c \ drivers/pinio.c \ drivers/resource.c \ drivers/rcc.c \ diff --git a/src/main/drivers/mco.c b/src/main/drivers/mco.c new file mode 100644 index 000000000..33eb6674f --- /dev/null +++ b/src/main/drivers/mco.c @@ -0,0 +1,45 @@ +/* + * This file is part of Cleanflight and Betaflight. + * + * Cleanflight and Betaflight are free software. You can redistribute + * this software and/or modify this software 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 and Betaflight are distributed in the hope that they + * 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 this software. + * + * If not, see . + */ + +#include +#include +#include + +#include "platform.h" + +#ifdef USE_MCO + +#include "drivers/io.h" +#include "pg/mco.h" + +void mcoInit(const mcoConfig_t *mcoConfig) +{ + // Only configure MCO2 with PLLI2SCLK as source for now. + // Other MCO1 and other sources can easily be added. + // For all F4 and F7 varianets, MCO1 is on PA8 and MCO2 is on PC9. + + if (mcoConfig->enabled[1]) { + IO_t io = IOGetByTag(DEFIO_TAG_E(PC9)); + IOInit(io, OWNER_MCO, 2); + HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_PLLI2SCLK, RCC_MCODIV_4); + IOConfigGPIOAF(io, IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL), GPIO_AF0_MCO); + } +} +#endif diff --git a/src/main/drivers/mco.h b/src/main/drivers/mco.h new file mode 100644 index 000000000..a9a5b0692 --- /dev/null +++ b/src/main/drivers/mco.h @@ -0,0 +1,25 @@ +/* + * This file is part of Cleanflight and Betaflight. + * + * Cleanflight and Betaflight are free software. You can redistribute + * this software and/or modify this software 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 and Betaflight are distributed in the hope that they + * 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 this software. + * + * If not, see . + */ + +#pragma once + +#include "pg/mco.h" + +void mcoInit(const mcoConfig_t *mcoConfig); diff --git a/src/main/drivers/resource.c b/src/main/drivers/resource.c index c1bab637d..620e347de 100644 --- a/src/main/drivers/resource.c +++ b/src/main/drivers/resource.c @@ -76,4 +76,5 @@ const char * const ownerNames[OWNER_TOTAL_COUNT] = { "USB_MSC_PIN", "SPI_PREINIT_IPU", "SPI_PREINIT_OPU", + "MCO", }; diff --git a/src/main/drivers/resource.h b/src/main/drivers/resource.h index 54c66da9d..9d23789d6 100644 --- a/src/main/drivers/resource.h +++ b/src/main/drivers/resource.h @@ -76,6 +76,7 @@ typedef enum { OWNER_USB_MSC_PIN, OWNER_SPI_PREINIT_IPU, OWNER_SPI_PREINIT_OPU, + OWNER_MCO, OWNER_TOTAL_COUNT } resourceOwner_e; diff --git a/src/main/fc/init.c b/src/main/fc/init.c index 7bc5ab5f5..d49d2723c 100644 --- a/src/main/fc/init.c +++ b/src/main/fc/init.c @@ -56,6 +56,7 @@ #include "drivers/inverter.h" #include "drivers/io.h" #include "drivers/light_led.h" +#include "drivers/mco.h" #include "drivers/nvic.h" #include "drivers/pwm_esc_detect.h" #include "drivers/pwm_output.h" @@ -96,6 +97,7 @@ #include "pg/bus_i2c.h" #include "pg/bus_spi.h" #include "pg/flash.h" +#include "pg/mco.h" #include "pg/pinio.h" #include "pg/piniobox.h" #include "pg/pg.h" @@ -295,6 +297,12 @@ void init(void) } #endif + // Configure MCO output after config is stable + +#ifdef USE_MCO + mcoInit(mcoConfig()); +#endif + #if defined(USE_SPEKTRUM_BIND) if (featureIsEnabled(FEATURE_RX_SERIAL)) { switch (rxConfig()->serialrx_provider) { diff --git a/src/main/interface/cli.c b/src/main/interface/cli.c index 5cf455ca5..cf08ea1b4 100644 --- a/src/main/interface/cli.c +++ b/src/main/interface/cli.c @@ -128,6 +128,7 @@ extern uint8_t __config_end; #include "pg/bus_spi.h" #include "pg/gyrodev.h" #include "pg/max7456.h" +#include "pg/mco.h" #include "pg/pinio.h" #include "pg/pg.h" #include "pg/pg_ids.h" diff --git a/src/main/interface/settings.c b/src/main/interface/settings.c index 4d5d41d68..f26f0ad27 100644 --- a/src/main/interface/settings.c +++ b/src/main/interface/settings.c @@ -72,6 +72,7 @@ #include "pg/flash.h" #include "pg/gyrodev.h" #include "pg/max7456.h" +#include "pg/mco.h" #include "pg/pg.h" #include "pg/pg_ids.h" #include "pg/pinio.h" @@ -1190,6 +1191,9 @@ const clivalue_t valueTable[] = { { "gyro_2_i2c_address", VAR_UINT8 | MASTER_VALUE, .config.minmax = { 0, I2C_ADDR7_MAX }, PG_GYRO_DEVICE_CONFIG, PG_ARRAY_ELEMENT_OFFSET(gyroDeviceConfig_t, 1, i2cAddress) }, { "gyro_2_sensor_align", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_ALIGNMENT }, PG_GYRO_DEVICE_CONFIG, PG_ARRAY_ELEMENT_OFFSET(gyroDeviceConfig_t, 1, align) }, #endif +#ifdef USE_MCO + { "mco2_on_pc9", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_MCO_CONFIG, offsetof(mcoConfig_t, enabled[1]) }, +#endif }; const uint16_t valueTableEntryCount = ARRAYLEN(valueTable); diff --git a/src/main/pg/mco.c b/src/main/pg/mco.c new file mode 100644 index 000000000..e95f3e9b7 --- /dev/null +++ b/src/main/pg/mco.c @@ -0,0 +1,39 @@ +/* + * This file is part of Cleanflight and Betaflight. + * + * Cleanflight and Betaflight are free software. You can redistribute + * this software and/or modify this software 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 and Betaflight are distributed in the hope that they + * 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 this software. + * + * If not, see . + */ + +#include +#include + +#include "platform.h" + +#ifdef USE_MCO + +#include "drivers/io.h" +#include "pg/pg.h" +#include "pg/pg_ids.h" +#include "pg/mco.h" + +PG_REGISTER_WITH_RESET_TEMPLATE(mcoConfig_t, mcoConfig, PG_MCO_CONFIG, 0); + +PG_RESET_TEMPLATE(mcoConfig_t, mcoConfig, + .enabled[0] = 0, + .enabled[1] = 0, +); +#endif // USE_MCO diff --git a/src/main/pg/mco.h b/src/main/pg/mco.h new file mode 100644 index 000000000..d4fa86e3e --- /dev/null +++ b/src/main/pg/mco.h @@ -0,0 +1,33 @@ +/* + * This file is part of Cleanflight and Betaflight. + * + * Cleanflight and Betaflight are free software. You can redistribute + * this software and/or modify this software 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 and Betaflight are distributed in the hope that they + * 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 this software. + * + * If not, see . + */ + +#pragma once + +#include +#include + +#include "pg/pg.h" +#include "drivers/io_types.h" + +typedef struct mcoConfig_s { + uint8_t enabled[2]; +} mcoConfig_t; + +PG_DECLARE(mcoConfig_t, mcoConfig); diff --git a/src/main/pg/pg_ids.h b/src/main/pg/pg_ids.h index d17448229..7794f7464 100644 --- a/src/main/pg/pg_ids.h +++ b/src/main/pg/pg_ids.h @@ -135,7 +135,8 @@ #define PG_BOARD_CONFIG 538 #define PG_RCDEVICE_CONFIG 539 #define PG_GYRO_DEVICE_CONFIG 540 -#define PG_BETAFLIGHT_END 540 +#define PG_MCO_CONFIG 541 +#define PG_BETAFLIGHT_END 541 // OSD configuration (subject to change) diff --git a/src/main/target/common_pre.h b/src/main/target/common_pre.h index 49dd02938..7614f9c08 100644 --- a/src/main/target/common_pre.h +++ b/src/main/target/common_pre.h @@ -78,6 +78,7 @@ #define USE_ADC_INTERNAL #define USE_USB_CDC_HID #define USE_USB_MSC +#define USE_MCO #endif #if defined(STM32F4) || defined(STM32F7) diff --git a/src/main/target/system_stm32f7xx.c b/src/main/target/system_stm32f7xx.c index ef683a855..8c8d8900d 100644 --- a/src/main/target/system_stm32f7xx.c +++ b/src/main/target/system_stm32f7xx.c @@ -229,6 +229,19 @@ while (1); } + // Configure PLLI2S for 27MHz operation + // Actual output will be done by mcoInit in drivers/mco.c + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_PLLI2S; + PeriphClkInitStruct.PLLI2S.PLLI2SN = 216; + PeriphClkInitStruct.PLLI2S.PLLI2SR = 2; + PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2; + PeriphClkInitStruct.PLLI2SDivQ = 1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + while (1); + } + // Activating the timerprescalers while the APBx prescalers are 1/2/4 will connect the TIMxCLK to HCLK which has been configured to 216MHz __HAL_RCC_TIMCLKPRESCALER(RCC_TIMPRES_ACTIVATED);