175 lines
4.2 KiB
C++
175 lines
4.2 KiB
C++
/*
|
|
* 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"
|
|
|
|
#if !defined(BOOT)
|
|
#include "hal/adc_driver.h"
|
|
#endif
|
|
|
|
#define BOOTLOADER_KEYS 0x42
|
|
|
|
/* The output bit-order has to be:
|
|
0 LHL STD (Left equals down)
|
|
1 LHR STU
|
|
2 LVD THD
|
|
3 LVU THU
|
|
*/
|
|
|
|
enum PhysicalTrims
|
|
{
|
|
STD = 0,
|
|
STU,
|
|
THD = 2,
|
|
THU,
|
|
/* TR2L = 4,
|
|
TR2R,
|
|
TR2D = 8,
|
|
TR2U,*/
|
|
};
|
|
|
|
void keysInit()
|
|
{
|
|
#if defined(BOOT)
|
|
LL_GPIO_InitTypeDef pinInit;
|
|
LL_GPIO_StructInit(&pinInit);
|
|
|
|
pinInit.Pin = ADC_GPIO_PIN_EXT1;
|
|
pinInit.Mode = LL_GPIO_MODE_ANALOG;
|
|
pinInit.Pull = LL_GPIO_PULL_NO;
|
|
stm32_gpio_enable_clock(ADC_GPIO_EXT1);
|
|
LL_GPIO_Init(ADC_GPIO_EXT1, &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_EXT1);
|
|
LL_ADC_SetChannelSamplingTime(ADC_MAIN, ADC_CHANNEL_EXT1, 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_EXIT;
|
|
else if (value < 512)
|
|
result |= 1 << KEY_ENTER;
|
|
#else
|
|
uint16_t value = getAnalogValue(4);
|
|
if (value >= 3584)
|
|
result |= 1 << KEY_EXIT;
|
|
else if (value < 512)
|
|
result |= 1 << KEY_ENTER;
|
|
#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;
|
|
#else
|
|
uint16_t tr1Val = getAnalogValue(6);
|
|
uint16_t tr2Val = getAnalogValue(7);
|
|
if (tr1Val < 500) // Physical TR1 Left
|
|
// result |= 1 << TR1L;
|
|
;
|
|
else if (tr1Val < 1500) // Physical TR1 Up
|
|
result |= 1 << STD;
|
|
else if (tr1Val < 2500) // Physical TR1 Right
|
|
// result |= 1 << TR1R;
|
|
;
|
|
else if (tr1Val < 3500) // Physical TR1 Down
|
|
result |= 1 << STU;
|
|
if (tr2Val < 500) // Physical TR2 Left
|
|
// result |= 1 << TR2L;
|
|
;
|
|
else if (tr2Val < 1500) // Physical TR2 Up
|
|
result |= 1 << THD;
|
|
else if (tr2Val < 2500) // Physical TR2 Right
|
|
// result |= 1 << TR2R;
|
|
;
|
|
else if (tr2Val < 3500) // Physical TR2 Down
|
|
result |= 1 << THU;
|
|
#endif
|
|
|
|
return result;
|
|
} |