kopia lustrzana https://github.com/OpenRTX/OpenRTX
106 wiersze
3.6 KiB
C
106 wiersze
3.6 KiB
C
/***************************************************************************
|
|
* Copyright (C) 2021 - 2023 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 <peripherals/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;
|
|
}
|