DevCore: программная часть проекта DevBoy25.09.2018 10:02
//******************************************************************************
// @file InputDrv.h
// @author Nicolai Shlapunov
//
// @details DevCore: Input Driver Class, header
//
// @section LICENSE
//
// Software License Agreement (Modified BSD License)
//
// Copyright (c) 2016, Devtronic & Nicolai Shlapunov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the Devtronic nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
// 4. Redistribution and use of this software other than as permitted under
// this license is void and will automatically terminate your rights under
// this license.
//
// THIS SOFTWARE IS PROVIDED BY DEVTRONIC ''AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL DEVTRONIC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// @section SUPPORT
//
// Devtronic invests time and resources providing this open source code,
// please support Devtronic and open-source hardware/software by
// donations and/or purchasing products from Devtronic.
//
//******************************************************************************
#ifndef InputDrv_h
#define InputDrv_h
// *****************************************************************************
// *** Includes ************************************************************
// *****************************************************************************
#include "DevCfg.h"
#include "AppTask.h"
// *****************************************************************************
// * Input Driver Class. This class implement work with user input elements like
// * buttons and encoders.
class InputDrv : public AppTask
{
public:
// *************************************************************************
// *** Enum with all buttons *******************************************
// *************************************************************************
typedef enum
{
EXT_LEFT, // Left ext port
EXT_RIGHT, // Right ext port
EXT_MAX // Ext port count
} PortType;
// *************************************************************************
// *** Enum with all devices types *************************************
// *************************************************************************
typedef enum
{
EXT_DEV_NONE, // No device
EXT_DEV_BTN, // Buttons(cross)
EXT_DEV_ENC, // Encoder
EXT_DEV_JOY, // Joystick
EXT_DEV_MAX // Device types count
} ExtDeviceType;
// *************************************************************************
// *** Enum with all buttons *******************************************
// *************************************************************************
typedef enum
{
BTN_UP, // Up button
BTN_LEFT, // Left button
BTN_DOWN, // Down button
BTN_RIGHT, // Right button
BTN_MAX // Buttons count
} ButtonType;
// *************************************************************************
// *** Enum with all encoder buttons ***********************************
// *************************************************************************
typedef enum
{
ENC_BTN_ENT, // Press on the knob
ENC_BTN_BACK, // Small button
ENC_BTN_MAX // Buttons count
} EncButtonType;
// *************************************************************************
// *** Get Instance ****************************************************
// *************************************************************************
// * This class is singleton. For use this class you must call GetInstance()
// * to receive reference to Input Driver class
static InputDrv& GetInstance(void);
// *************************************************************************
// *** Init Input Driver Task ******************************************
// *************************************************************************
// * This function initialize Input Driver class. If htim provided, this
// * timer will be used instead FreeRTOS task.
virtual void InitTask(TIM_HandleTypeDef* htm, ADC_HandleTypeDef* had);
// *************************************************************************
// *** Input Driver Setup **********************************************
// *************************************************************************
virtual Result Setup();
// *************************************************************************
// *** Input Driver Loop ***********************************************
// *************************************************************************
// * If FreeRTOS task used, this function just call ProcessInput() with 1 ms
// * period. If FreeRTOS tick is 1 ms - this task must have highest priority
virtual Result Loop();
// *************************************************************************
// *** Process Input function ******************************************
// *************************************************************************
// * Main class function - must call periodically for process user input.
// * If timer used, this function must be called from interrupt handler.
void ProcessInput(void);
// *************************************************************************
// *** Process Encoders Input function *********************************
// *************************************************************************
void ProcessEncodersInput(void);
// *************************************************************************
// *** Get device type *************************************************
// *************************************************************************
ExtDeviceType GetDeviceType(PortType port);
// *************************************************************************
// *** Get button state ************************************************
// *************************************************************************
// Return button state: true - pressed, false - unpressed
bool GetButtonState(PortType port, ButtonType button);
// *************************************************************************
// *** Get button state ************************************************
// *************************************************************************
// Return button state change flag: true - changed, false - not changed
bool GetButtonState(PortType port, ButtonType button, bool& btn_state);
// *************************************************************************
// *** Get encoder counts from last call *******************************
// *************************************************************************
// * Return state of encoder. Class counts encoder clicks and stored inside.
// * This function substract from current encoder counter last_enc_val and
// * return it to user. Before return last_enc_val will be assigned to
// * current encoder counter.
int32_t GetEncoderState(PortType port, int32_t& last_enc_val);
// *************************************************************************
// *** Get button state ************************************************
// *************************************************************************
// Return button state: true - pressed, false - unpressed
bool GetEncoderButtonState(PortType port, EncButtonType button);
// *************************************************************************
// *** Get encoder button state ****************************************
// *************************************************************************
// Return button state: true - pressed, false - unpressed
bool GetEncoderButtonState(PortType port, EncButtonType button, bool& btn_state);
// *************************************************************************
// *** Get joystick counts from last call ******************************
// *************************************************************************
void GetJoystickState(PortType port, int32_t& x, int32_t& y);
// *************************************************************************
// *** SetJoystickCalibrationConsts ************************************
// *************************************************************************
// * Set calibration constants. Must be call for calibration joystick.
void SetJoystickCalibrationConsts(PortType port, int32_t x_mid,
int32_t x_kmin, int32_t x_kmax,
int32_t y_mid, int32_t y_kmin,
int32_t y_kmax);
// *************************************************************************
// *** Get joystick button state ***************************************
// *************************************************************************
// Return button state: true - pressed, false - unpressed
bool GetJoystickButtonState(PortType port);
// *************************************************************************
// *** Get joystick button state ***************************************
// *************************************************************************
// Return button state: true - pressed, false - unpressed
bool GetJoystickButtonState(PortType port, bool& btn_state);
private:
// How many cycles button must change state before state will be changed in
// result returned by GetButtonState() function. For reduce debouncing
const static uint32_t BUTTON_READ_DELAY = 4U;
// Coefficient for calibration
const static int32_t COEF = 100;
// ADC max value - 12 bit
const static int32_t ADC_MAX_VAL = 0xFFF;
// Joystich threshold
const static int32_t JOY_THRESHOLD = 1000;
// Ticks variable
uint32_t last_wake_ticks = 0U;
// *************************************************************************
// *** Structure to describe button ************************************
// *************************************************************************
typedef struct
{
bool btn_state; // Button state returned by GetButtonState() function
bool btn_state_tmp; // Temporary button state for reduce debouncing
uint8_t btn_state_cnt; // Counter for reduce debouncing
GPIO_TypeDef* button_port;// Button port
uint16_t button_pin; // Button pin
GPIO_PinState pin_state; // High/low on input treated as pressed
} ButtonProfile;
// *************************************************************************
// *** Structure to describe encoder ***********************************
// *************************************************************************
typedef struct
{
// Encoder rotation
int32_t enc_cnt; // Encoder counter
uint8_t enc_state; // Current state of encder clock & data pins
GPIO_TypeDef* enc_clk_port; // Encoder clock port
uint16_t enc_clk_pin; // Encoder clock pin
GPIO_TypeDef* enc_data_port;// Encoder data port
uint16_t enc_data_pin; // Encoder data pin
} EncoderProfile;
// *************************************************************************
// *** Structure to describe joysticks *********************************
// *************************************************************************
typedef struct
{
int32_t x_ch_val; // Joystick X axis value
uint32_t x_channel; // Joystick X axis ADC channel
GPIO_TypeDef* x_port; // Joystick X axis port
uint16_t x_pin; // Joystick X axis pin
int32_t bx; // Joystick X offset
int32_t kxmin; // Joystick X coefficient
int32_t kxmax; // Joystick X coefficient
bool x_inverted; // Joystick X inverted flag
int32_t y_ch_val; // Joystick Y axis value
uint32_t y_channel; // Joystick Y axis ADC channel
GPIO_TypeDef* y_port; // Joystick Y axis port
uint16_t y_pin; // Joystick Y axis pin
int32_t by; // Joystick Y offset
int32_t kymin; // Joystick Y coefficient
int32_t kymax; // Joystick Y coefficient
bool y_inverted; // Joystick Y inverted flag
} JoystickProfile;
// *************************************************************************
// *** Structure to describe encoders **********************************
// *************************************************************************
typedef struct
{
EncoderProfile enc;
ButtonProfile btn[ENC_BTN_MAX];
} DevEncoders;
// *************************************************************************
// *** Structure to describe encoders **********************************
// *************************************************************************
typedef struct
{
JoystickProfile joy;
ButtonProfile btn;
} DevJoysticks;
// *************************************************************************
// *** Structure to describe buttons ***********************************
// *************************************************************************
typedef struct
{
ButtonProfile button[BTN_MAX];
} DevButtons;
// *** Array describes types of connected devices ***********************
ExtDeviceType devices[EXT_MAX];
// *** Structures array for describe buttons inputs *********************
DevButtons buttons[EXT_MAX] =
{
// Left device
{{{false, false, 0, EXT_L1_GPIO_Port, EXT_L1_Pin, GPIO_PIN_RESET},
{false, false, 0, EXT_L2_GPIO_Port, EXT_L2_Pin, GPIO_PIN_RESET},
{false, false, 0, EXT_L3_GPIO_Port, EXT_L3_Pin, GPIO_PIN_RESET},
{false, false, 0, EXT_L4_GPIO_Port, EXT_L4_Pin, GPIO_PIN_RESET}}},
// Right device
{{{false, false, 0, EXT_R1_GPIO_Port, EXT_R1_Pin, GPIO_PIN_RESET},
{false, false, 0, EXT_R2_GPIO_Port, EXT_R2_Pin, GPIO_PIN_RESET},
{false, false, 0, EXT_R3_GPIO_Port, EXT_R3_Pin, GPIO_PIN_RESET},
{false, false, 0, EXT_R4_GPIO_Port, EXT_R4_Pin, GPIO_PIN_RESET}}}
};
// *** Structures array for describe encoders inputs ********************
DevEncoders encoders[EXT_MAX] =
{
// Left device
{{0, 0, EXT_L1_GPIO_Port, EXT_L1_Pin, EXT_L2_GPIO_Port, EXT_L2_Pin}, // Encoder
{{false, false, 0, EXT_L3_GPIO_Port, EXT_L3_Pin, GPIO_PIN_RESET}, // Button Enter
{false, false, 0, EXT_L4_GPIO_Port, EXT_L4_Pin, GPIO_PIN_SET}}}, // Button Back
// Right device
{{0, 0, EXT_R1_GPIO_Port, EXT_R1_Pin, EXT_R2_GPIO_Port, EXT_R2_Pin}, // Encoder
{{false, false, 0, EXT_R3_GPIO_Port, EXT_R3_Pin, GPIO_PIN_RESET}, // Button Enter
{false, false, 0, EXT_R4_GPIO_Port, EXT_R4_Pin, GPIO_PIN_SET}}} // Button Back
};
// *** Structures array for describe encoders inputs ********************
DevJoysticks joysticks[EXT_MAX] =
{
// Left device
{{0, ADC_CHANNEL_11, EXT_L2_GPIO_Port, EXT_L2_Pin, 0, COEF, COEF, false, // Joystick
0, ADC_CHANNEL_10, EXT_L1_GPIO_Port, EXT_L1_Pin, 0, COEF, COEF, true},
{false, false, 0, EXT_L3_GPIO_Port, EXT_L3_Pin, GPIO_PIN_RESET}}, // Button
// Right device
{{0, ADC_CHANNEL_13, EXT_R2_GPIO_Port, EXT_R2_Pin, 0, COEF, COEF, false, // Joystick
0, ADC_CHANNEL_12, EXT_R1_GPIO_Port, EXT_R1_Pin, 0, COEF, COEF, true},
{false, false, 0, EXT_R3_GPIO_Port, EXT_R3_Pin, GPIO_PIN_RESET}} // Button
};
// Handle to timer used for process encoders input
TIM_HandleTypeDef* htim = nullptr;
// Handle to timer used for process encoders input
ADC_HandleTypeDef* hadc = nullptr;
// *************************************************************************
// *** Process Button Input function ***********************************
// *************************************************************************
void ProcessButtonInput(ButtonProfile& button);
// *************************************************************************
// *** Process Encoder Input function **********************************
// *************************************************************************
void ProcessEncoderInput(EncoderProfile& encoder);
// *************************************************************************
// *** Process Joystick Input function *********************************
// *************************************************************************
void ProcessJoystickInput(JoystickProfile& joysticks, PortType port);
// *************************************************************************
// *** Emulate buttons using joystick function *************************
// *************************************************************************
void EmulateButtonsByJoystick(PortType port);
// *************************************************************************
// *** Emulate encoders using buttons function *************************
// *************************************************************************
void EmulateEncodersByButtons(PortType port);
// *************************************************************************
// *** Configure inputs devices types **********************************
// *************************************************************************
ExtDeviceType DetectDeviceType(PortType port);
// *************************************************************************
// *** Configure ADC ***************************************************
// *************************************************************************
void ConfigADC(ExtDeviceType dev_left, ExtDeviceType dev_right);
// *************************************************************************
// *** Configure inputs for read digital/analog data *******************
// *************************************************************************
void ConfigInputIO(bool is_digital, PortType port);
// *************************************************************************
// ** Private constructor. Only GetInstance() allow to access this class. **
// *************************************************************************
InputDrv() : AppTask(INPUT_DRV_TASK_STACK_SIZE, INPUT_DRV_TASK_PRIORITY,
"InputDrv") {};
};
#endif
© Habrahabr.ru