basic button handler routines added, hard buttons tested
touch sensors were also preliminary tested but not all have been analyzed yet.
This commit is contained in:
parent
180aa589ee
commit
fe169b64f6
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#define TOUCH_DEFAULT_CHARGE 0x4c
|
#define TOUCH_DEFAULT_CHARGE 0x4c
|
||||||
#define TOUCH_DEFAULT_THRESH 0x800
|
#define TOUCH_DEFAULT_THRESH 0x800
|
||||||
|
#define TOUCH_HYSTERESIS 66
|
||||||
|
|
||||||
|
|
||||||
typedef struct AdcChan {
|
typedef struct AdcChan {
|
||||||
@ -35,6 +36,8 @@ typedef struct AdcChan {
|
|||||||
static uint8_t adc_idx = 0;
|
static uint8_t adc_idx = 0;
|
||||||
static AdcChan adc_chan[ADC_CHANNELS] = {0};
|
static AdcChan adc_chan[ADC_CHANNELS] = {0};
|
||||||
|
|
||||||
|
static uint32_t touch_status = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void adc_init()
|
void adc_init()
|
||||||
@ -57,6 +60,7 @@ void adc_init()
|
|||||||
adc_chan[1].thresh = 3580;
|
adc_chan[1].thresh = 3580;
|
||||||
|
|
||||||
adc_chan[2].chan = ADC_Channel_2;
|
adc_chan[2].chan = ADC_Channel_2;
|
||||||
|
adc_chan[2].timing = 0x6f;
|
||||||
adc_chan[2].thresh = 3380;
|
adc_chan[2].thresh = 3380;
|
||||||
|
|
||||||
adc_chan[3].chan = ADC_Channel_3;
|
adc_chan[3].chan = ADC_Channel_3;
|
||||||
@ -108,16 +112,10 @@ void adc_init()
|
|||||||
|
|
||||||
int8_t adc_get_tkey(uint8_t key_idx)
|
int8_t adc_get_tkey(uint8_t key_idx)
|
||||||
{
|
{
|
||||||
if (key_idx > ADC_CHANNELS)
|
return (touch_status & (1 << key_idx) ? 1 : 0);
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (adc_chan[key_idx].avg < adc_chan[key_idx].thresh) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute((section(".ramfunc")))
|
||||||
void adc_next()
|
void adc_next()
|
||||||
{
|
{
|
||||||
AdcChan *chan;
|
AdcChan *chan;
|
||||||
@ -205,6 +203,16 @@ void adc_isr()
|
|||||||
v += chan->rawval[i];
|
v += chan->rawval[i];
|
||||||
}
|
}
|
||||||
chan->avg = v >> ashift;
|
chan->avg = v >> ashift;
|
||||||
|
|
||||||
|
// calculate if touched if measuring a touch sensor
|
||||||
|
if (amax == 4) {
|
||||||
|
if (chan->avg <= chan->thresh) {
|
||||||
|
touch_status |= (1 << adc_idx);
|
||||||
|
}
|
||||||
|
if (chan->avg > (chan->thresh + TOUCH_HYSTERESIS)) {
|
||||||
|
touch_status &= ~(1 << adc_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,8 @@
|
|||||||
#include "led/matrix.h"
|
#include "led/matrix.h"
|
||||||
#include "led/ledprog.h"
|
#include "led/ledprog.h"
|
||||||
|
|
||||||
|
#include "ui/btn.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*@Note
|
*@Note
|
||||||
***Only PA0--PA15 and PC16--PC17 support input pull-down.
|
***Only PA0--PA15 and PC16--PC17 support input pull-down.
|
||||||
@ -39,13 +41,13 @@ volatile uint8_t lp_render = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void clk_init()
|
inline void clk_init()
|
||||||
{
|
{
|
||||||
SystemCoreClockUpdate();
|
SystemCoreClockUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void periphclk_init()
|
static inline void periphclk_init()
|
||||||
{
|
{
|
||||||
// needed for GPIO, remap, ADC, SPI
|
// needed for GPIO, remap, ADC, SPI
|
||||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
|
||||||
@ -59,7 +61,7 @@ void periphclk_init()
|
|||||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_USBPD, ENABLE);
|
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_USBPD, ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpio_init()
|
static inline void gpio_init()
|
||||||
{
|
{
|
||||||
GPIO_InitTypeDef gpio = {0};
|
GPIO_InitTypeDef gpio = {0};
|
||||||
|
|
||||||
@ -90,7 +92,7 @@ void gpio_init()
|
|||||||
gpio.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_12;
|
gpio.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_12;
|
||||||
GPIO_Init(GPIOB, &gpio);
|
GPIO_Init(GPIOB, &gpio);
|
||||||
|
|
||||||
// PC10 USB DP (btn2), PC11 USB DM (unused)
|
// PC16 USB DM (unused), PC17 USB DP (btn2)
|
||||||
gpio.GPIO_Mode = GPIO_Mode_IPD;
|
gpio.GPIO_Mode = GPIO_Mode_IPD;
|
||||||
gpio.GPIO_Pin = GPIO_Pin_16 | GPIO_Pin_17;
|
gpio.GPIO_Pin = GPIO_Pin_16 | GPIO_Pin_17;
|
||||||
GPIO_Init(GPIOC, &gpio);
|
GPIO_Init(GPIOC, &gpio);
|
||||||
@ -105,7 +107,7 @@ void gpio_init()
|
|||||||
// todo later
|
// todo later
|
||||||
}
|
}
|
||||||
|
|
||||||
void awu_init()
|
static inline void awu_init()
|
||||||
{
|
{
|
||||||
NVIC_InitTypeDef nvic;
|
NVIC_InitTypeDef nvic;
|
||||||
EXTI_InitTypeDef exti = {0};
|
EXTI_InitTypeDef exti = {0};
|
||||||
@ -174,12 +176,13 @@ int main(void)
|
|||||||
|
|
||||||
// stay a while
|
// stay a while
|
||||||
// __WFI();
|
// __WFI();
|
||||||
PWR_EnterSTANDBYMode();
|
// PWR_EnterSTANDBYMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AWU_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
void AWU_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||||
|
|
||||||
void AWU_IRQHandler(void)
|
void AWU_IRQHandler(void)
|
||||||
{
|
{
|
||||||
// clear interrupt flag
|
// clear interrupt flag
|
||||||
@ -204,5 +207,6 @@ void AWU_IRQHandler(void)
|
|||||||
// handle ADC
|
// handle ADC
|
||||||
adc_next();
|
adc_next();
|
||||||
|
|
||||||
// handle buttons
|
// handle buttons and touch sensors
|
||||||
|
btn_process();
|
||||||
}
|
}
|
||||||
@ -3,4 +3,99 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ch32x035_conf.h"
|
#include "ch32x035_conf.h"
|
||||||
|
#include "btn.h"
|
||||||
|
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BtnSub btn[BTN_COUNT];
|
||||||
|
|
||||||
|
uint16_t btn_pushed;
|
||||||
|
uint16_t btn_held;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void btn_push_cb(uint8_t idx)
|
||||||
|
{
|
||||||
|
if (!(btn_pushed & (1 << idx))) {
|
||||||
|
btn_pushed |= (1 << idx);
|
||||||
|
if (btn[idx].cb_push) btn[idx].cb_push(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void btn_hold_cb(uint8_t idx)
|
||||||
|
{
|
||||||
|
btn_held |= (1 << idx);
|
||||||
|
if (btn[idx].cb_hold) btn[idx].cb_hold(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btn_release_cb(uint8_t idx)
|
||||||
|
{
|
||||||
|
btn_pushed &= ~(1 << idx);
|
||||||
|
btn_held &= ~(1 << idx);
|
||||||
|
if (btn[idx].cb_release) btn[idx].cb_release(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void btn_process()
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
uint32_t x;
|
||||||
|
uint16_t btn_state[4] = {0};
|
||||||
|
|
||||||
|
// fill button bitfield
|
||||||
|
for (i = 0; i < BTN_COUNT; i++) {
|
||||||
|
if (i == 0) {
|
||||||
|
// GPIOC pulldown button
|
||||||
|
x = GPIOC->INDR & (1 << 10); // PC10 (or PC17)
|
||||||
|
} else if (i < 3) {
|
||||||
|
// GPIOB pullup buttons
|
||||||
|
x = !(GPIOB->INDR & (1 << (i + 10))); // PB11, PB12
|
||||||
|
} else {
|
||||||
|
// touch sensors
|
||||||
|
x = adc_get_tkey(i - 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// is pushed?
|
||||||
|
if (x) {
|
||||||
|
if (btn[i].hold != 0xffff)
|
||||||
|
btn[i].hold++;
|
||||||
|
|
||||||
|
if (btn[i].hold == DEBOUNCE) {
|
||||||
|
btn_state[1] |= (1 << (i + 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// is held?
|
||||||
|
if (btn[i].hold == HOLD_COUNTS) {
|
||||||
|
btn_state[2] |= (1 << (i + 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
// is repeated?
|
||||||
|
if (btn[i].repeat && (btn[i].hold == (HOLD_COUNTS + btn[i].repeat))) {
|
||||||
|
btn_state[2] |= (1 << (i + 3));
|
||||||
|
btn[i].hold = HOLD_COUNTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is released?
|
||||||
|
if (!x) {
|
||||||
|
if (btn[i].hold) {
|
||||||
|
btn[i].hold = 0;
|
||||||
|
btn_state[3] |= (1 << (i + 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// process callbacks for new events
|
||||||
|
for (i = 0; i < BTN_COUNT; i++) {
|
||||||
|
if (btn_state[1] & (1 << i)) {
|
||||||
|
btn_push_cb(i);
|
||||||
|
}
|
||||||
|
if (btn_state[2] & (1 << i)) {
|
||||||
|
btn_hold_cb(i);
|
||||||
|
}
|
||||||
|
if (btn_state[3] & (1 << i)) {
|
||||||
|
btn_release_cb(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
43
firmware/app/ui/btn.h
Normal file
43
firmware/app/ui/btn.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* btn.h
|
||||||
|
*
|
||||||
|
* Created on: Oct 13, 2024
|
||||||
|
* Author: true
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef USER_UI_BTN_H_
|
||||||
|
#define USER_UI_BTN_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define HB_COUNT 3 // total hard buttons in system
|
||||||
|
#define TS_COUNT 7 // total touch sensors in system
|
||||||
|
#define BTN_COUNT (HB_COUNT + TS_COUNT) // total buttons in system
|
||||||
|
|
||||||
|
#define DEBOUNCE 12
|
||||||
|
#define HOLD_COUNTS 600 // how long until a push-and-hold is detected
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BtnSub {
|
||||||
|
uint16_t hold; // initial hold
|
||||||
|
uint16_t repeat; // repeated hold
|
||||||
|
void (*cb_push)(uint8_t);
|
||||||
|
void (*cb_hold)(uint8_t);
|
||||||
|
void (*cb_release)(uint8_t);
|
||||||
|
} BtnSub;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern BtnSub btn[BTN_COUNT];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void btn_process();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* USER_UI_BTN_H_ */
|
||||||
@ -23,6 +23,12 @@ SECTIONS
|
|||||||
_einit = .;
|
_einit = .;
|
||||||
} >FLASH AT>FLASH
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
|
.ramfunclalign :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
PROVIDE(_ramfunc_lma = .);
|
||||||
|
} >FLASH AT>FLASH
|
||||||
|
|
||||||
.vector :
|
.vector :
|
||||||
{
|
{
|
||||||
*(.vector);
|
*(.vector);
|
||||||
@ -132,6 +138,9 @@ SECTIONS
|
|||||||
*(.srodata.cst2)
|
*(.srodata.cst2)
|
||||||
*(.srodata .srodata.*)
|
*(.srodata .srodata.*)
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
|
*(.ramfunc)
|
||||||
|
*(.ramfunc*)
|
||||||
|
. = ALIGN(4);
|
||||||
PROVIDE( _edata = .);
|
PROVIDE( _edata = .);
|
||||||
} >RAM AT>FLASH
|
} >RAM AT>FLASH
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user