kopia lustrzana https://github.com/OpenRTX/OpenRTX
Created low-level driver for management of channel selector knobs with quadrature encoder
rodzic
26eb381ca2
commit
944a597d33
|
@ -34,6 +34,7 @@ openrtx_inc = ['openrtx/include',
|
|||
'platform/drivers/tones',
|
||||
'platform/drivers/baseband',
|
||||
'platform/drivers/backlight',
|
||||
'platform/drivers/chSelector',
|
||||
'openrtx/include/fonts/adafruit']
|
||||
|
||||
# Add to sources either the main executable or a platform test
|
||||
|
@ -218,6 +219,7 @@ mduv3x0_src = src + mdx_src + stm32f405_src + ['platform/drivers/NVM/nvmem_MDUV3
|
|||
'platform/targets/MD-UV3x0/platform.c',
|
||||
'platform/drivers/keyboard/keyboard_MD3x.c',
|
||||
'platform/drivers/display/HX8353_MD3x.cpp',
|
||||
'platform/drivers/chSelector/chSelector_UV3x0.c',
|
||||
'platform/drivers/baseband/radio_UV3x0.c',
|
||||
'platform/drivers/baseband/AT1846S_UV3x0.c',
|
||||
'platform/drivers/baseband/HR_C6000_UV3x0.c',
|
||||
|
@ -232,6 +234,7 @@ mduv3x0_def = def + stm32f405_def + {'PLATFORM_MDUV3x0': '', 'timegm': 'mktime'}
|
|||
md9600_src = src + mdx_src + stm32f405_src + ['platform/targets/MD-9600/platform.c',
|
||||
'platform/drivers/display/ST7567_MD9600.c',
|
||||
'platform/drivers/keyboard/keyboard_MD9600.c',
|
||||
'platform/drivers/chSelector/chSelector_MD9600.c',
|
||||
'platform/drivers/baseband/radio_MD9600.c',
|
||||
'platform/drivers/NVM/nvmem_MD9600.c',
|
||||
'platform/drivers/NVM/spiFlash_MD9600.c']
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2021 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Caleb Jamison *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program 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. *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CH_SELECTOR_H
|
||||
#define CH_SELECTOR_H
|
||||
|
||||
/**
|
||||
* Low-level driver for correct handling of channel selector knobs connected to
|
||||
* a quadrature encoder.
|
||||
* This header file only provides the API for driver initialisation and shutdown,
|
||||
* while the readout of current encoder position is provided by target-specific
|
||||
* sources by implementating platform_getChSelector().
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise channel selector driver.
|
||||
*/
|
||||
void chSelector_init();
|
||||
|
||||
/**
|
||||
* Terminate channel selector driver.
|
||||
*/
|
||||
void chSelector_terminate();
|
||||
|
||||
#endif /* CH_SELECTOR_H */
|
|
@ -0,0 +1,105 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2021 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program 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. *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <interfaces/platform.h>
|
||||
#include <interfaces/gpio.h>
|
||||
#include <hwconfig.h>
|
||||
#include <qdec.h>
|
||||
#include "chSelector.h"
|
||||
|
||||
static uint8_t last_state = 0; /* State storage */
|
||||
static int8_t knob_pos = 0; /* Knob position */
|
||||
|
||||
|
||||
/* Name of interrupt handler is mangled for C++ compatibility */
|
||||
void _Z20EXTI15_10_IRQHandlerv()
|
||||
{
|
||||
if(EXTI->PR & (EXTI_PR_PR10 | EXTI_PR_PR11))
|
||||
{
|
||||
/* Clear interrupt flags */
|
||||
EXTI->PR = EXTI_PR_PR10 | EXTI_PR_PR11;
|
||||
|
||||
/* Read curent pin state */
|
||||
uint8_t pin_state = (gpio_readPin(CH_SELECTOR_1) << 1)
|
||||
| gpio_readPin(CH_SELECTOR_0);
|
||||
|
||||
/* Look up next state */
|
||||
uint8_t next_state = HALF_STEP_STATE_TRANSITIONS[last_state][pin_state];
|
||||
|
||||
/* update state for next call */
|
||||
last_state = next_state & QDECODER_STATE_BITMASK;
|
||||
|
||||
/* Mask out events to switch on */
|
||||
uint8_t event = next_state & QDECODER_EVENT_BITMASK;
|
||||
|
||||
/* Update knob_pos variable */
|
||||
switch(event)
|
||||
{
|
||||
case QDECODER_EVENT_CW:
|
||||
knob_pos++;
|
||||
break;
|
||||
case QDECODER_EVENT_CCW:
|
||||
knob_pos--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void chSelector_init()
|
||||
{
|
||||
gpio_setMode(CH_SELECTOR_0, INPUT_PULL_UP);
|
||||
gpio_setMode(CH_SELECTOR_1, INPUT_PULL_UP);
|
||||
|
||||
/*
|
||||
* Configure GPIO interrupts: encoder signal is on PB10 and PB11
|
||||
*/
|
||||
EXTI->IMR |= EXTI_IMR_MR10 | EXTI_IMR_MR11;
|
||||
EXTI->RTSR |= EXTI_RTSR_TR10 | EXTI_RTSR_TR11;
|
||||
EXTI->FTSR |= EXTI_FTSR_TR10 | EXTI_FTSR_TR11;
|
||||
|
||||
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI10_PB
|
||||
| SYSCFG_EXTICR3_EXTI11_PB;
|
||||
|
||||
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
|
||||
NVIC_SetPriority(EXTI15_10_IRQn, 15);
|
||||
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
||||
}
|
||||
|
||||
void chSelector_terminate()
|
||||
{
|
||||
EXTI->IMR &= ~(EXTI_IMR_MR10 | EXTI_IMR_MR11);
|
||||
NVIC_DisableIRQ(EXTI15_10_IRQn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is defined in platform.h
|
||||
*/
|
||||
int8_t platform_getChSelector()
|
||||
{
|
||||
/*
|
||||
* The knob_pos variable is set in the EXTI15_10 interrupt handler
|
||||
* this is safe because interrupt nesting is not allowed.
|
||||
*/
|
||||
return knob_pos;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2021 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN *
|
||||
* Frederik Saraci IU2NRO *
|
||||
* Silvano Seva IU2KWO *
|
||||
* *
|
||||
* This program 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. *
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <interfaces/platform.h>
|
||||
#include <interfaces/gpio.h>
|
||||
#include <hwconfig.h>
|
||||
#include <qdec.h>
|
||||
#include "chSelector.h"
|
||||
|
||||
static uint8_t last_state = 0; /* State storage */
|
||||
static int8_t knob_pos = 0; /* Knob position */
|
||||
|
||||
|
||||
/* Name of interrupt handler is mangled for C++ compatibility */
|
||||
void _Z20EXTI15_10_IRQHandlerv()
|
||||
{
|
||||
if(EXTI->PR & (EXTI_PR_PR11 | EXTI_PR_PR14))
|
||||
{
|
||||
/* Clear interrupt flags */
|
||||
EXTI->PR = EXTI_PR_PR11 | EXTI_PR_PR14;
|
||||
|
||||
/* Read curent pin state */
|
||||
uint8_t pin_state = (gpio_readPin(CH_SELECTOR_1) << 1)
|
||||
| gpio_readPin(CH_SELECTOR_0);
|
||||
|
||||
/* Look up next state */
|
||||
uint8_t next_state = HALF_STEP_STATE_TRANSITIONS[last_state][pin_state];
|
||||
|
||||
/* update state for next call */
|
||||
last_state = next_state & QDECODER_STATE_BITMASK;
|
||||
|
||||
/* Mask out events to switch on */
|
||||
uint8_t event = next_state & QDECODER_EVENT_BITMASK;
|
||||
|
||||
/* Update knob_pos variable */
|
||||
switch(event)
|
||||
{
|
||||
case QDECODER_EVENT_CW:
|
||||
knob_pos++;
|
||||
break;
|
||||
case QDECODER_EVENT_CCW:
|
||||
knob_pos--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void chSelector_init()
|
||||
{
|
||||
gpio_setMode(CH_SELECTOR_0, INPUT_PULL_UP);
|
||||
gpio_setMode(CH_SELECTOR_1, INPUT_PULL_UP);
|
||||
|
||||
/*
|
||||
* Configure GPIO interrupts: encoder signal is on PB11 and PE14
|
||||
*/
|
||||
EXTI->IMR |= EXTI_IMR_MR11 | EXTI_IMR_MR14;
|
||||
EXTI->RTSR |= EXTI_RTSR_TR11 | EXTI_RTSR_TR14;
|
||||
EXTI->FTSR |= EXTI_FTSR_TR11 | EXTI_FTSR_TR14;
|
||||
|
||||
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI11_PB;
|
||||
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI14_PE;
|
||||
|
||||
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
|
||||
NVIC_SetPriority(EXTI15_10_IRQn, 15);
|
||||
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
||||
}
|
||||
|
||||
void chSelector_terminate()
|
||||
{
|
||||
EXTI->IMR &= ~(EXTI_IMR_MR1 | EXTI_IMR_MR14);
|
||||
NVIC_DisableIRQ(EXTI15_10_IRQn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function is defined in platform.h
|
||||
*/
|
||||
int8_t platform_getChSelector()
|
||||
{
|
||||
/*
|
||||
* The knob_pos variable is set in the EXTI15_10 interrupt handler
|
||||
* this is safe because interrupt nesting is not allowed.
|
||||
*/
|
||||
return knob_pos;
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
#include <toneGenerator_MDx.h>
|
||||
#include <interfaces/rtc.h>
|
||||
#include <SPI2.h>
|
||||
#include <chSelector.h>
|
||||
|
||||
hwInfo_t hwInfo;
|
||||
|
||||
|
@ -76,6 +77,7 @@ void platform_init()
|
|||
toneGen_init(); /* Initialise tone generator */
|
||||
rtc_init(); /* Initialise RTC */
|
||||
backlight_init(); /* Initialise backlight driver */
|
||||
chSelector_init(); /* Initialise channel selector handler */
|
||||
}
|
||||
|
||||
void platform_terminate()
|
||||
|
@ -87,6 +89,7 @@ void platform_terminate()
|
|||
adc1_terminate();
|
||||
toneGen_terminate();
|
||||
rtc_terminate();
|
||||
chSelector_terminate();
|
||||
|
||||
/* Finally, remove power supply */
|
||||
gpio_clearPin(PWR_SW);
|
||||
|
@ -112,15 +115,6 @@ float platform_getVolumeLevel()
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
int8_t platform_getChSelector()
|
||||
{
|
||||
static const uint8_t rsPositions[] = { 1, 4, 2, 3};
|
||||
int pos = gpio_readPin(CH_SELECTOR_0)
|
||||
| (gpio_readPin(CH_SELECTOR_1) << 1);
|
||||
|
||||
return rsPositions[pos];
|
||||
}
|
||||
|
||||
bool platform_getPttStatus()
|
||||
{
|
||||
/* PTT line has a pullup resistor with PTT switch closing to ground */
|
||||
|
@ -160,6 +154,12 @@ const hwInfo_t *platform_getHwInfo()
|
|||
return &hwInfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: implementation of this API function is provided in
|
||||
* platform/drivers/chSelector/chSelector_MD9600.c
|
||||
*/
|
||||
// int8_t platform_getChSelector()
|
||||
|
||||
/*
|
||||
* NOTE: implementation of this API function is provided in
|
||||
* platform/drivers/backlight/backlight_MDx.c
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <calibInfo_MDx.h>
|
||||
#include <interfaces/nvmem.h>
|
||||
#include <interfaces/rtc.h>
|
||||
#include <qdec.h>
|
||||
#include <chSelector.h>
|
||||
|
||||
#ifdef ENABLE_BKLIGHT_DIMMING
|
||||
#include <backlight.h>
|
||||
|
@ -33,43 +33,6 @@
|
|||
|
||||
mduv3x0Calib_t calibration;
|
||||
hwInfo_t hwInfo;
|
||||
static int8_t knob_pos = 0;
|
||||
|
||||
/*
|
||||
* Note that this interrupt handler currently assumes only the encoder will
|
||||
* ever cause this interrupt to fire
|
||||
*/
|
||||
void _Z20EXTI15_10_IRQHandlerv()
|
||||
{
|
||||
/* State storage */
|
||||
static uint8_t last_state = 0;
|
||||
|
||||
/* Read curent pin state */
|
||||
uint8_t pin_state = gpio_readPin(CH_SELECTOR_1)<<1 | gpio_readPin(CH_SELECTOR_0);
|
||||
/* Look up next state */
|
||||
uint8_t next_state = HALF_STEP_STATE_TRANSITIONS[last_state][pin_state];
|
||||
/* update state for next call */
|
||||
last_state = next_state & QDECODER_STATE_BITMASK;
|
||||
|
||||
/* Mask out events to switch on */
|
||||
uint8_t event = next_state & QDECODER_EVENT_BITMASK;
|
||||
|
||||
/* Update file global knob_pos variable */
|
||||
switch (event)
|
||||
{
|
||||
case QDECODER_EVENT_CW:
|
||||
knob_pos++;
|
||||
break;
|
||||
case QDECODER_EVENT_CCW:
|
||||
knob_pos--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear pin change flags */
|
||||
EXTI->PR = EXTI_PR_PR11 | EXTI_PR_PR14;
|
||||
}
|
||||
|
||||
void platform_init()
|
||||
{
|
||||
|
@ -77,20 +40,6 @@ void platform_init()
|
|||
gpio_setMode(GREEN_LED, OUTPUT);
|
||||
gpio_setMode(RED_LED, OUTPUT);
|
||||
|
||||
gpio_setMode(CH_SELECTOR_0, INPUT_PULL_UP);
|
||||
gpio_setMode(CH_SELECTOR_1, INPUT_PULL_UP);
|
||||
|
||||
EXTI->IMR |= EXTI_IMR_MR11 | EXTI_IMR_MR14;
|
||||
EXTI->RTSR |= EXTI_RTSR_TR11 | EXTI_RTSR_TR14;
|
||||
EXTI->FTSR |= EXTI_FTSR_TR11 | EXTI_FTSR_TR14;
|
||||
|
||||
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR3_EXTI11_PB;
|
||||
SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI14_PE;
|
||||
|
||||
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
|
||||
NVIC_SetPriority(EXTI15_10_IRQn, 15);
|
||||
NVIC_EnableIRQ(EXTI15_10_IRQn);
|
||||
|
||||
gpio_setMode(PTT_SW, INPUT_PULL_UP);
|
||||
|
||||
gpio_setMode(PWR_SW, OUTPUT);
|
||||
|
@ -108,6 +57,7 @@ void platform_init()
|
|||
nvm_readCalibData(&calibration); /* Load calibration data */
|
||||
nvm_loadHwInfo(&hwInfo); /* Load hardware information data */
|
||||
rtc_init(); /* Initialise RTC */
|
||||
chSelector_init(); /* Initialise channel selector handler */
|
||||
|
||||
#ifdef ENABLE_BKLIGHT_DIMMING
|
||||
backlight_init(); /* Initialise backlight driver */
|
||||
|
@ -134,6 +84,7 @@ void platform_terminate()
|
|||
adc1_terminate();
|
||||
nvm_terminate();
|
||||
rtc_terminate();
|
||||
chSelector_terminate();
|
||||
|
||||
/* Finally, remove power supply */
|
||||
gpio_clearPin(PWR_SW);
|
||||
|
@ -159,15 +110,6 @@ float platform_getVolumeLevel()
|
|||
return adc1_getMeasurement(ADC_VOL_CH);
|
||||
}
|
||||
|
||||
int8_t platform_getChSelector()
|
||||
{
|
||||
/*
|
||||
* The knob_pos variable is set in the EXTI15_10 interrupt handler
|
||||
* this is safe because interrupt nesting is not allowed.
|
||||
*/
|
||||
return knob_pos;
|
||||
}
|
||||
|
||||
bool platform_getPttStatus()
|
||||
{
|
||||
/* PTT line has a pullup resistor with PTT switch closing to ground */
|
||||
|
@ -229,6 +171,12 @@ const hwInfo_t *platform_getHwInfo()
|
|||
return &hwInfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: implementation of this API function is provided in
|
||||
* platform/drivers/chSelector/chSelector_MDUV3x0.c
|
||||
*/
|
||||
// int8_t platform_getChSelector()
|
||||
|
||||
/*
|
||||
* NOTE: when backligth dimming is enabled, the implementation of this API
|
||||
* function is provided in platform/drivers/backlight/backlight_MDx.c to avoid
|
||||
|
|
Ładowanie…
Reference in New Issue