diff --git a/radio/src/targets/pl18/CMakeLists.txt b/radio/src/targets/pl18/CMakeLists.txt index 162e1d741..84db218e8 100644 --- a/radio/src/targets/pl18/CMakeLists.txt +++ b/radio/src/targets/pl18/CMakeLists.txt @@ -43,16 +43,19 @@ if(PCBREV STREQUAL NB4P) set(FLAVOUR nb4p) add_definitions(-DRADIO_NB4P) set(ROTARY_ENCODER YES) + set(KEY_DRIVER nb4p_key_driver.cpp) elseif(PCBREV STREQUAL PL18EV) set(FLAVOUR pl18ev) add_definitions(-DRADIO_PL18EV -DUSE_HATS_AS_KEYS) set(WIRELESS_CHARGER YES) set(FLYSKY_GIMBAL ON) + set(KEY_DRIVER key_driver.cpp) else() set(FLAVOUR pl18) add_definitions(-DRADIO_PL18 -DUSE_HATS_AS_KEYS) set(WIRELESS_CHARGER YES) set(FLYSKY_GIMBAL ON) + set(KEY_DRIVER key_driver.cpp) # Defines internal modules for PL18 via UART7 set(INTERNAL_MODULES MULTI CACHE STRING "Internal modules") @@ -107,7 +110,7 @@ set(TARGET_SRC_DIR targets/${TARGET_DIR}) set(BOARD_COMMON_SRC ${TARGET_SRC_DIR}/board.cpp ${TARGET_SRC_DIR}/led_driver.cpp - ${TARGET_SRC_DIR}/key_driver.cpp + ${TARGET_SRC_DIR}/${KEY_DRIVER} ${TARGET_SRC_DIR}/haptic_driver.cpp ${TARGET_SRC_DIR}/backlight_driver.cpp ${TARGET_SRC_DIR}/${LCD_DRIVER} diff --git a/radio/src/targets/pl18/board.cpp b/radio/src/targets/pl18/board.cpp index 4aa518931..68997c63c 100644 --- a/radio/src/targets/pl18/board.cpp +++ b/radio/src/targets/pl18/board.cpp @@ -100,6 +100,13 @@ void boardBLEarlyInit() gpio_init(UCHARGER_GPIO, GPIO_IN, GPIO_PIN_SPEED_LOW); } +#if defined(RADIO_NB4P) +void boardBLPreJump() +{ + LL_ADC_Disable(ADC_MAIN); +} +#endif + void boardInit() { #if defined(SEMIHOSTING) diff --git a/radio/src/targets/pl18/hal.h b/radio/src/targets/pl18/hal.h index 660272fb4..8548475ab 100644 --- a/radio/src/targets/pl18/hal.h +++ b/radio/src/targets/pl18/hal.h @@ -313,6 +313,7 @@ #define ADC_CHANNEL_STICK_TH LL_ADC_CHANNEL_3 // ADC123_IN3 -> ADC1_IN3 #define ADC_CHANNEL_STICK_ST LL_ADC_CHANNEL_2 // ADC123_IN2 -> ADC1_IN2 #define ADC_GPIO_PIN_SWA LL_GPIO_PIN_1 //PC.01 + #define ADC_GPIO_SWB GPIOC #define ADC_GPIO_PIN_SWB LL_GPIO_PIN_0 //PC.00 #define ADC_CHANNEL_SWA LL_ADC_CHANNEL_11 // ADC123_IN11 -> ADC1_IN11 #define ADC_CHANNEL_SWB LL_ADC_CHANNEL_10 // ADC123_IN10 -> ADC1_IN10 diff --git a/radio/src/targets/pl18/key_driver.cpp b/radio/src/targets/pl18/key_driver.cpp index fefd7783d..89f399136 100644 --- a/radio/src/targets/pl18/key_driver.cpp +++ b/radio/src/targets/pl18/key_driver.cpp @@ -28,8 +28,6 @@ #include "delays_driver.h" #include "keys.h" -#if !defined(RADIO_NB4P) - /* The output bit-order has to be: 0 LHL TR7L (Left equals down) 1 LHR TR7R @@ -220,5 +218,3 @@ uint32_t readTrims() return result; } - -#endif diff --git a/radio/src/targets/pl18/nb4p_key_driver.cpp b/radio/src/targets/pl18/nb4p_key_driver.cpp new file mode 100644 index 000000000..5d41e93f8 --- /dev/null +++ b/radio/src/targets/pl18/nb4p_key_driver.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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. + */ + +#include "hal/key_driver.h" + +#include "stm32_hal_ll.h" +#include "stm32_gpio_driver.h" + +#include "hal.h" +#include "delays_driver.h" +#include "keys.h" + +#define BOOTLOADER_KEYS 0x42 + +void keysInit() +{ +#if defined(BOOT) + LL_GPIO_InitTypeDef pinInit; + LL_GPIO_StructInit(&pinInit); + + pinInit.Pin = ADC_GPIO_PIN_SWB; + pinInit.Mode = LL_GPIO_MODE_ANALOG; + pinInit.Pull = LL_GPIO_PULL_NO; + stm32_gpio_enable_clock(ADC_GPIO_SWB); + LL_GPIO_Init(ADC_GPIO_SWB, &pinInit); + + // Init ADC clock + uint32_t adc_idx = (((uint32_t) ADC_MAIN) - ADC1_BASE) / 0x100UL; + uint32_t adc_msk = RCC_APB2ENR_ADC1EN << adc_idx; + LL_APB2_GRP1_EnableClock(adc_msk); + + // Init common to all ADCs + LL_ADC_CommonInitTypeDef commonInit; + LL_ADC_CommonStructInit(&commonInit); + + commonInit.CommonClock = LL_ADC_CLOCK_SYNC_PCLK_DIV4; + LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC_MAIN), &commonInit); + + // ADC must be disabled for the functions used here + LL_ADC_Disable(ADC_MAIN); + + LL_ADC_InitTypeDef adcInit; + LL_ADC_StructInit(&adcInit); + adcInit.SequencersScanMode = LL_ADC_SEQ_SCAN_DISABLE; + adcInit.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + adcInit.Resolution = LL_ADC_RESOLUTION_12B; + LL_ADC_Init(ADC_MAIN, &adcInit); + + LL_ADC_REG_InitTypeDef adcRegInit; + LL_ADC_REG_StructInit(&adcRegInit); + adcRegInit.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + adcRegInit.ContinuousMode = LL_ADC_REG_CONV_SINGLE; + LL_ADC_REG_Init(ADC_MAIN, &adcRegInit); + + // Enable ADC + LL_ADC_Enable(ADC_MAIN); +#endif +} + +#if defined(BOOT) +uint16_t _adcRead() +{ + // Configure ADC channel + LL_ADC_REG_SetSequencerRanks(ADC_MAIN, LL_ADC_REG_RANK_1, ADC_CHANNEL_SWB); + LL_ADC_SetChannelSamplingTime(ADC_MAIN, ADC_CHANNEL_SWB, LL_ADC_SAMPLINGTIME_3CYCLES); + + // Start ADC conversion + LL_ADC_REG_StartConversionSWStart(ADC_MAIN); + + // Wait until ADC conversion is complete + uint32_t timeout = 0; + while (!LL_ADC_IsActiveFlag_EOCS(ADC_MAIN)); + + // Read ADC converted value + return LL_ADC_REG_ReadConversionData12(ADC_MAIN); +} +#endif + +uint32_t readKeys() +{ + uint32_t result = 0; + +#if defined(BOOT) + uint16_t value = _adcRead(); + if (value >= 3584) + result |= 1 << KEY_ENTER; + else if (value < 512) + result |= 1 << KEY_EXIT; +#endif + + return result; +} + +uint32_t readTrims() +{ + uint32_t result = 0; + +#if defined(BOOT) + uint16_t value = _adcRead(); + if (value >= 1536 && value < 2560) + result = BOOTLOADER_KEYS; +#endif + return result; +} \ No newline at end of file