improvements + added a toggle for interlaced, not yet fully implemented
This commit is contained in:
@@ -96,7 +96,7 @@ GEX_CDEFS = $(GEX_CDEFS_BASE) \
|
|||||||
-DUSE_STACK_MONITOR=1 \
|
-DUSE_STACK_MONITOR=1 \
|
||||||
-DUSE_DEBUG_UART=1 \
|
-DUSE_DEBUG_UART=1 \
|
||||||
-DDEBUG_MALLOC=0 \
|
-DDEBUG_MALLOC=0 \
|
||||||
-DDEBUG_RSC=1
|
-DDEBUG_RSC=0
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ static struct callbacks_ {
|
|||||||
struct cbslot tim16;
|
struct cbslot tim16;
|
||||||
|
|
||||||
struct cbslot adc1;
|
struct cbslot adc1;
|
||||||
|
struct cbslot tsc;
|
||||||
|
|
||||||
// XXX add more callbacks here when needed
|
// XXX add more callbacks here when needed
|
||||||
} callbacks;
|
} callbacks;
|
||||||
@@ -92,7 +93,8 @@ void irqd_init(void)
|
|||||||
HAL_NVIC_SetPriority(EXTI2_3_IRQn, 2, 0);
|
HAL_NVIC_SetPriority(EXTI2_3_IRQn, 2, 0);
|
||||||
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
|
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);
|
||||||
|
|
||||||
// NVIC_EnableIRQ(TSC_IRQn); /*!< Touch Sensing Controller Interrupts */
|
NVIC_EnableIRQ(TSC_IRQn); /*!< Touch Sensing Controller Interrupts */
|
||||||
|
HAL_NVIC_SetPriority(TSC_IRQn, 2, 0);
|
||||||
|
|
||||||
NVIC_EnableIRQ(DMA1_Channel1_IRQn); /*!< DMA1 Channel 1 Interrupt */
|
NVIC_EnableIRQ(DMA1_Channel1_IRQn); /*!< DMA1 Channel 1 Interrupt */
|
||||||
NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); /*!< DMA1 Channel 2 and Channel 3 Interrupt */
|
NVIC_EnableIRQ(DMA1_Channel2_3_IRQn); /*!< DMA1 Channel 2 and Channel 3 Interrupt */
|
||||||
@@ -178,6 +180,8 @@ static struct cbslot *get_slot_for_periph(void *periph)
|
|||||||
else if (periph == TIM16) slot = &callbacks.tim16;
|
else if (periph == TIM16) slot = &callbacks.tim16;
|
||||||
// 17 - used by timebase
|
// 17 - used by timebase
|
||||||
|
|
||||||
|
else if (periph == TSC) slot = &callbacks.tsc;
|
||||||
|
|
||||||
else if (periph == ADC1) slot = &callbacks.adc1;
|
else if (periph == ADC1) slot = &callbacks.adc1;
|
||||||
|
|
||||||
else if (periph >= EXTIS[0] && periph <= EXTIS[15]) {
|
else if (periph >= EXTIS[0] && periph <= EXTIS[15]) {
|
||||||
@@ -352,6 +356,11 @@ void ADC1_COMP_IRQHandler(void)
|
|||||||
CALL_IRQ_HANDLER(callbacks.adc1);
|
CALL_IRQ_HANDLER(callbacks.adc1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TSC_IRQHandler(void)
|
||||||
|
{
|
||||||
|
CALL_IRQ_HANDLER(callbacks.tsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// other ISRs...
|
// other ISRs...
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
//
|
||||||
|
// Created by MightyPork on 2018/02/25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
#include "unit_base.h"
|
||||||
|
#include "unit_touch.h"
|
||||||
|
|
||||||
|
#define TOUCH_INTERNAL
|
||||||
|
|
||||||
|
#include "_touch_internal.h"
|
||||||
|
|
||||||
|
#define DIS_TIME 1
|
||||||
|
|
||||||
|
static void startNextPhase(struct priv *priv);
|
||||||
|
|
||||||
|
void UTOUCH_HandleIrq(void *arg)
|
||||||
|
{
|
||||||
|
Unit *unit = arg;
|
||||||
|
struct priv *priv = unit->data;
|
||||||
|
|
||||||
|
if (TSC->ISR & TSC_ISR_MCEF) {
|
||||||
|
priv->status = UTSC_STATUS_FAIL;
|
||||||
|
dbg_touch("TSC Failure.");
|
||||||
|
TSC->ICR = TSC_ICR_EOAIC | TSC_ICR_MCEIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSC->ISR & TSC_ISR_EOAF) {
|
||||||
|
TSC->ICR = TSC_ICR_EOAIC;
|
||||||
|
// assert_param((TSC->IOGCSR>>16) == priv->groups_phase[priv->next_phase]);
|
||||||
|
|
||||||
|
// Store captured data
|
||||||
|
const uint32_t chmask = priv->channels_phase[priv->next_phase];
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
if (chmask & (1<<i)) {
|
||||||
|
priv->readouts[i] = (uint16_t) (TSC->IOGXCR[i >> 2] & 0x3FFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->next_phase++;
|
||||||
|
// check if we've run out of existing or populated groups
|
||||||
|
if (priv->next_phase == 3 || priv->groups_phase[priv->next_phase] == 0) {
|
||||||
|
priv->next_phase = 0;
|
||||||
|
priv->status = UTSC_STATUS_READY;
|
||||||
|
// we'll stay in READY after the first loop until an error occurs or it's re-inited
|
||||||
|
}
|
||||||
|
|
||||||
|
TSC->CR &= ~TSC_CR_IODEF; // pull low - discharge
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->ongoing = false;
|
||||||
|
priv->discharge_delay = DIS_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TSC_DEBUG
|
||||||
|
static volatile uint32_t xcnt=0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void UTOUCH_updateTick(Unit *unit)
|
||||||
|
{
|
||||||
|
#if TSC_DEBUG
|
||||||
|
xcnt++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct priv *priv = unit->data;
|
||||||
|
|
||||||
|
if (priv->ongoing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->discharge_delay > 0) {
|
||||||
|
priv->discharge_delay--;
|
||||||
|
} else {
|
||||||
|
startNextPhase(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if TSC_DEBUG
|
||||||
|
if(xcnt >= 250) {
|
||||||
|
xcnt=0;
|
||||||
|
PRINTF("> ");
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
if (priv->all_channels_mask & (1<<i)) {
|
||||||
|
PRINTF("%d ", (int)priv->readouts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PRINTF("\r\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void startNextPhase(struct priv *priv)
|
||||||
|
{
|
||||||
|
if (priv->next_phase == 0 && priv->groups_phase[0] == 0) {
|
||||||
|
// no groups are configured
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSC->IOGCSR = priv->groups_phase[priv->next_phase];
|
||||||
|
TSC->IOCCR = priv->channels_phase[priv->next_phase];
|
||||||
|
TSC->ICR = TSC_ICR_EOAIC | TSC_ICR_MCEIC;
|
||||||
|
|
||||||
|
if (priv->cfg.interlaced) {
|
||||||
|
TSC->CR |= TSC_CR_IODEF;
|
||||||
|
// floaty (must be used for interlaced pads)
|
||||||
|
// note: interlaced pads also need to be sampled individually
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go!
|
||||||
|
priv->ongoing = true;
|
||||||
|
TSC->CR |= TSC_CR_START;
|
||||||
|
}
|
||||||
+92
-15
@@ -2,11 +2,11 @@
|
|||||||
// Created by MightyPork on 2018/02/03.
|
// Created by MightyPork on 2018/02/03.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <stm32f072xb.h>
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "unit_base.h"
|
#include "unit_base.h"
|
||||||
|
|
||||||
#define TOUCH_INTERNAL
|
#define TOUCH_INTERNAL
|
||||||
|
|
||||||
#include "_touch_internal.h"
|
#include "_touch_internal.h"
|
||||||
|
|
||||||
/** Allocate data structure and set defaults */
|
/** Allocate data structure and set defaults */
|
||||||
@@ -33,10 +33,47 @@ error_t UTOUCH_init(Unit *unit)
|
|||||||
bool suc = true;
|
bool suc = true;
|
||||||
struct priv *priv = unit->data;
|
struct priv *priv = unit->data;
|
||||||
|
|
||||||
|
unit->tick_interval = 1; // sample every 1 ms
|
||||||
|
|
||||||
TRY(rsc_claim(unit, R_TSC));
|
TRY(rsc_claim(unit, R_TSC));
|
||||||
|
|
||||||
|
// simple bound checks, just clamp without error
|
||||||
|
if (priv->cfg.charge_time > 16) priv->cfg.charge_time = 16;
|
||||||
|
if (priv->cfg.charge_time < 1) priv->cfg.charge_time = 1;
|
||||||
|
|
||||||
|
if (priv->cfg.drain_time > 16) priv->cfg.drain_time = 16;
|
||||||
|
if (priv->cfg.drain_time < 1) priv->cfg.drain_time = 1;
|
||||||
|
|
||||||
|
if (priv->cfg.spread_deviation > 128) priv->cfg.drain_time = 128;
|
||||||
|
|
||||||
|
if (priv->cfg.ss_presc > 2) priv->cfg.ss_presc = 2;
|
||||||
|
if (priv->cfg.ss_presc < 1) priv->cfg.ss_presc = 1;
|
||||||
|
|
||||||
|
if (priv->cfg.sense_timeout > 7) priv->cfg.sense_timeout = 7;
|
||||||
|
if (priv->cfg.sense_timeout < 1) priv->cfg.sense_timeout = 1;
|
||||||
|
|
||||||
|
uint8_t tmppgpresc = priv->cfg.pg_presc;
|
||||||
|
if (tmppgpresc == 0) return E_BAD_CONFIG;
|
||||||
|
uint8_t pgpresc_reg = 0;
|
||||||
|
while ((tmppgpresc & 1) == 0 && tmppgpresc != 0) {
|
||||||
|
pgpresc_reg++;
|
||||||
|
tmppgpresc >>= 1;
|
||||||
|
}
|
||||||
|
if (tmppgpresc != 1 || pgpresc_reg > 7) {
|
||||||
|
dbg("Bad pgpresc");
|
||||||
|
return E_BAD_CONFIG; // TODO better reporting
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pgpresc_reg==0 && priv->cfg.drain_time<=2) || (pgpresc_reg==1 && priv->cfg.drain_time==0)) {
|
||||||
|
dbg("Illegal PGPSC vs CTPL");
|
||||||
|
return E_BAD_CONFIG;
|
||||||
|
}
|
||||||
|
|
||||||
// enable clock
|
// enable clock
|
||||||
hw_periph_clock_enable(TSC);
|
hw_periph_clock_enable(TSC);
|
||||||
|
// reset
|
||||||
|
__HAL_RCC_TSC_FORCE_RESET();
|
||||||
|
__HAL_RCC_TSC_RELEASE_RESET();
|
||||||
|
|
||||||
for (int gi = 0; gi < 8; gi++) {
|
for (int gi = 0; gi < 8; gi++) {
|
||||||
const uint8_t cap = priv->cfg.group_scaps[gi];
|
const uint8_t cap = priv->cfg.group_scaps[gi];
|
||||||
@@ -62,42 +99,80 @@ error_t UTOUCH_init(Unit *unit)
|
|||||||
return E_BAD_CONFIG;
|
return E_BAD_CONFIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
int chnum = 0;
|
// This is a loop through the pins in a group gi
|
||||||
|
int phasenum = 0;
|
||||||
for (int pi = 0; pi < 4; pi++) {
|
for (int pi = 0; pi < 4; pi++) {
|
||||||
// pin numbers are 1-based in the config
|
// pin numbers are 1-based in the config
|
||||||
const bool iscap = 0 != (cap & (2 << pi));
|
const bool iscap = 0 != (cap & (2 << pi));
|
||||||
const bool isch = 0 != (ch & (2 << pi));
|
const bool isch = 0 != (ch & (2 << pi));
|
||||||
|
|
||||||
if (iscap || isch) {
|
if (!iscap && !isch) continue;
|
||||||
|
|
||||||
Resource r = utouch_group_rscs[gi][pi];
|
Resource r = utouch_group_rscs[gi][pi];
|
||||||
TRY(rsc_claim(unit, r));
|
TRY(rsc_claim(unit, r));
|
||||||
|
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint32_t ll;
|
||||||
|
assert_param(hw_pinrsc2ll(r, &port, &ll));
|
||||||
|
LL_GPIO_SetPinOutputType(port, ll, isch ? LL_GPIO_OUTPUT_PUSHPULL : LL_GPIO_OUTPUT_OPENDRAIN);
|
||||||
|
|
||||||
// 7 and 8 (1-based) use AF1, else AF3
|
// 7 and 8 (1-based) use AF1, else AF3
|
||||||
TRY(hw_configure_gpiorsc_af(r, gi >= 6 ? LL_GPIO_AF_1 : LL_GPIO_AF_3));
|
TRY(hw_configure_gpiorsc_af(r, gi >= 6 ? LL_GPIO_AF_1 : LL_GPIO_AF_3));
|
||||||
|
|
||||||
if (iscap) dbg_touch("TSC *cap @ %s", rsc_get_name(r));
|
uint32_t bit = (uint32_t) (1 << (gi * 4 + pi));
|
||||||
else dbg_touch("TSC -ch @ %s", rsc_get_name(r));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sampling cap
|
|
||||||
if (iscap) {
|
if (iscap) {
|
||||||
TSC->IOSCR |= (cap>>1) << (gi*4);
|
dbg_touch("TSC cap @ %s", rsc_get_name(r));
|
||||||
|
// Sampling cap
|
||||||
|
TSC->IOSCR |= bit;
|
||||||
|
|
||||||
|
// Disable pin hysteresis (causes noise)
|
||||||
|
TSC->IOHCR ^= bit;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
dbg_touch("TSC ch @ %s", rsc_get_name(r));
|
||||||
|
|
||||||
// channels are configured individually when read.
|
// channels are configured individually when read.
|
||||||
// we prepare bitmaps to use for the read groups (all can be read in at most 3 steps)
|
// we prepare bitmaps to use for the read groups (all can be read in at most 3 steps)
|
||||||
if (isch) {
|
priv->channels_phase[phasenum] |= bit; // this is used for the channel selection register
|
||||||
priv->channels_phase[chnum] |= 1 << (gi*4+pi);
|
priv->groups_phase[phasenum] |= 1 << gi; // this will be used for the group enable register, if all 0, this and any following phases are unused.
|
||||||
priv->pgen_phase[chnum] |= 1 << gi;
|
phasenum++;
|
||||||
chnum++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_touch("TSC phases:");
|
// common TSC config
|
||||||
for (int i = 0; i < 3; i++) {
|
TSC->CR =
|
||||||
dbg_touch(" %d: ch %08"PRIx32", g %02"PRIx32, i+1, priv->channels_phase[i], (uint32_t)priv->pgen_phase[i]);
|
((priv->cfg.charge_time - 1) << TSC_CR_CTPH_Pos) |
|
||||||
|
((priv->cfg.drain_time - 1) << TSC_CR_CTPL_Pos) |
|
||||||
|
((priv->cfg.ss_presc - 1) << TSC_CR_SSPSC_Pos) |
|
||||||
|
(pgpresc_reg << TSC_CR_PGPSC_Pos) |
|
||||||
|
((priv->cfg.sense_timeout - 1) << TSC_CR_MCV_Pos) |
|
||||||
|
TSC_CR_TSCE;
|
||||||
|
|
||||||
|
if (priv->cfg.spread_deviation > 0) {
|
||||||
|
TSC->CR |= ((priv->cfg.spread_deviation - 1) << TSC_CR_SSD_Pos) | TSC_CR_SSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbg_touch("CR = %08x, ht is %d, lt is %d", TSC->CR, priv->cfg.charge_time, priv->cfg.drain_time);
|
||||||
|
|
||||||
|
// iofloat is used for discharging
|
||||||
|
|
||||||
|
// Enable the interrupts
|
||||||
|
TSC->IER = TSC_IER_EOAIE | TSC_IER_MCEIE;
|
||||||
|
irqd_attach(TSC, UTOUCH_HandleIrq, unit);
|
||||||
|
|
||||||
|
dbg_touch("TSC phases:");
|
||||||
|
priv->all_channels_mask = 0;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
priv->all_channels_mask |= priv->channels_phase[i];
|
||||||
|
dbg_touch(" %d: ch %08"PRIx32", g %02"PRIx32, i + 1, priv->channels_phase[i], (uint32_t) priv->groups_phase[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->status = UTSC_STATUS_BUSY; // first loop ...
|
||||||
|
priv->next_phase = 0;
|
||||||
|
UTOUCH_updateTick(unit);
|
||||||
|
|
||||||
return E_SUCCESS;
|
return E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +188,8 @@ void UTOUCH_deInit(Unit *unit)
|
|||||||
// clear all registers to their default values
|
// clear all registers to their default values
|
||||||
__HAL_RCC_TSC_FORCE_RESET();
|
__HAL_RCC_TSC_FORCE_RESET();
|
||||||
__HAL_RCC_TSC_RELEASE_RESET();
|
__HAL_RCC_TSC_RELEASE_RESET();
|
||||||
|
|
||||||
|
irqd_detach(TSC, UTOUCH_HandleIrq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release all resources, deinit pins
|
// Release all resources, deinit pins
|
||||||
|
|||||||
@@ -11,14 +11,20 @@
|
|||||||
|
|
||||||
#include "unit_base.h"
|
#include "unit_base.h"
|
||||||
|
|
||||||
#define TSC_DEBUG 0
|
#define TSC_DEBUG 1
|
||||||
|
|
||||||
#if TSC_DEBUG
|
#if TSC_DEBUG
|
||||||
#define dbg_touch(...) dbg(...)
|
#define dbg_touch(f,...) dbg(f,##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define dbg_touch(...) do{}while(0)
|
#define dbg_touch(f,...) do{}while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum utsc_status {
|
||||||
|
UTSC_STATUS_BUSY = 0,
|
||||||
|
UTSC_STATUS_READY = 1,
|
||||||
|
UTSC_STATUS_FAIL = 2
|
||||||
|
};
|
||||||
|
|
||||||
/** Private data structure */
|
/** Private data structure */
|
||||||
struct priv {
|
struct priv {
|
||||||
// settings
|
// settings
|
||||||
@@ -32,12 +38,18 @@ struct priv {
|
|||||||
// the schmitts must be disabled on all used channels, restored to 0xFFFF on deinit
|
// the schmitts must be disabled on all used channels, restored to 0xFFFF on deinit
|
||||||
uint8_t group_scaps[8];
|
uint8_t group_scaps[8];
|
||||||
uint8_t group_channels[8];
|
uint8_t group_channels[8];
|
||||||
|
bool interlaced;
|
||||||
} cfg;
|
} cfg;
|
||||||
|
|
||||||
uint8_t next_phase;
|
uint8_t next_phase;
|
||||||
|
uint8_t discharge_delay;
|
||||||
uint32_t channels_phase[3];
|
uint32_t channels_phase[3];
|
||||||
uint8_t pgen_phase[3];
|
uint8_t groups_phase[3];
|
||||||
uint16_t readouts[32];
|
uint16_t readouts[32];
|
||||||
|
uint32_t all_channels_mask;
|
||||||
|
bool ongoing;
|
||||||
|
|
||||||
|
enum utsc_status status;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *utouch_group_labels[8];
|
extern const char *utouch_group_labels[8];
|
||||||
@@ -68,4 +80,8 @@ error_t UTOUCH_init(Unit *unit);
|
|||||||
/** Tear down the unit */
|
/** Tear down the unit */
|
||||||
void UTOUCH_deInit(Unit *unit);
|
void UTOUCH_deInit(Unit *unit);
|
||||||
|
|
||||||
|
void UTOUCH_updateTick(Unit *unit);
|
||||||
|
|
||||||
|
void UTOUCH_HandleIrq(void *arg);
|
||||||
|
|
||||||
#endif //GEX_F072_TOUCH_INTERNAL_H
|
#endif //GEX_F072_TOUCH_INTERNAL_H
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ void UTOUCH_loadBinary(Unit *unit, PayloadParser *pp)
|
|||||||
priv->cfg.sense_timeout = pp_u8(pp);
|
priv->cfg.sense_timeout = pp_u8(pp);
|
||||||
pp_buf(pp, priv->cfg.group_scaps, 8);
|
pp_buf(pp, priv->cfg.group_scaps, 8);
|
||||||
pp_buf(pp, priv->cfg.group_channels, 8);
|
pp_buf(pp, priv->cfg.group_channels, 8);
|
||||||
|
|
||||||
|
if (version >= 1) {
|
||||||
|
priv->cfg.interlaced = pp_bool(pp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Write to a binary buffer for storing in Flash */
|
/** Write to a binary buffer for storing in Flash */
|
||||||
@@ -53,7 +57,7 @@ void UTOUCH_writeBinary(Unit *unit, PayloadBuilder *pb)
|
|||||||
{
|
{
|
||||||
struct priv *priv = unit->data;
|
struct priv *priv = unit->data;
|
||||||
|
|
||||||
pb_u8(pb, 0); // version
|
pb_u8(pb, 1); // version
|
||||||
|
|
||||||
pb_u8(pb, priv->cfg.charge_time);
|
pb_u8(pb, priv->cfg.charge_time);
|
||||||
pb_u8(pb, priv->cfg.drain_time);
|
pb_u8(pb, priv->cfg.drain_time);
|
||||||
@@ -63,6 +67,7 @@ void UTOUCH_writeBinary(Unit *unit, PayloadBuilder *pb)
|
|||||||
pb_u8(pb, priv->cfg.sense_timeout);
|
pb_u8(pb, priv->cfg.sense_timeout);
|
||||||
pb_buf(pb, priv->cfg.group_scaps, 8);
|
pb_buf(pb, priv->cfg.group_scaps, 8);
|
||||||
pb_buf(pb, priv->cfg.group_channels, 8);
|
pb_buf(pb, priv->cfg.group_channels, 8);
|
||||||
|
pb_bool(pb, priv->cfg.interlaced);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@@ -91,6 +96,9 @@ error_t UTOUCH_loadIni(Unit *unit, const char *key, const char *value)
|
|||||||
else if (streq(key, "sense-timeout")) {
|
else if (streq(key, "sense-timeout")) {
|
||||||
priv->cfg.sense_timeout = cfg_u8_parse(value, &suc);
|
priv->cfg.sense_timeout = cfg_u8_parse(value, &suc);
|
||||||
}
|
}
|
||||||
|
else if (streq(key, "interlaced-pads")) {
|
||||||
|
priv->cfg.interlaced = cfg_bool_parse(value, &suc);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
volatile char namebuf[10]; // must be volatile or gcc optimizes out the second compare and fucks it up
|
volatile char namebuf[10]; // must be volatile or gcc optimizes out the second compare and fucks it up
|
||||||
|
|
||||||
@@ -126,17 +134,23 @@ void UTOUCH_writeIni(Unit *unit, IniWriter *iw)
|
|||||||
iw_cmt_newline(iw);
|
iw_cmt_newline(iw);
|
||||||
|
|
||||||
iw_comment(iw, "Pulse generator clock prescaller (1,2,4,...,128)");
|
iw_comment(iw, "Pulse generator clock prescaller (1,2,4,...,128)");
|
||||||
iw_entry(iw, "pg-clock-prediv", "%d", (int)priv->cfg.ss_presc);
|
iw_entry(iw, "pg-clock-prediv", "%d", (int)priv->cfg.pg_presc);
|
||||||
iw_comment(iw, "Sense pad charging time (1-16)");
|
iw_comment(iw, "Sense pad charging time (1-16)");
|
||||||
iw_entry(iw, "charge-time", "%d", (int)priv->cfg.charge_time);
|
iw_entry(iw, "charge-time", "%d", (int)priv->cfg.charge_time);
|
||||||
iw_comment(iw, "Charge transfer time (1-16)");
|
iw_comment(iw, "Charge transfer time (1-16)");
|
||||||
iw_entry(iw, "drain-time", "%d", (int)priv->cfg.drain_time);
|
iw_entry(iw, "drain-time", "%d", (int)priv->cfg.drain_time);
|
||||||
|
iw_comment(iw, "Measurement timeout (1-7)");
|
||||||
|
iw_entry(iw, "sense-timeout", "%d", (int)priv->cfg.sense_timeout);
|
||||||
|
|
||||||
|
iw_cmt_newline(iw);
|
||||||
iw_comment(iw, "Spread spectrum max deviation (0-128,0=off)");
|
iw_comment(iw, "Spread spectrum max deviation (0-128,0=off)");
|
||||||
iw_entry(iw, "ss-deviation", "%d", (int)priv->cfg.spread_deviation);
|
iw_entry(iw, "ss-deviation", "%d", (int)priv->cfg.spread_deviation);
|
||||||
iw_comment(iw, "Spreading clock prescaller (1,2)");
|
iw_comment(iw, "Spreading clock prescaller (1,2)");
|
||||||
iw_entry(iw, "ss-clock-prediv", "%d", (int)priv->cfg.ss_presc);
|
iw_entry(iw, "ss-clock-prediv", "%d", (int)priv->cfg.ss_presc);
|
||||||
iw_comment(iw, "Measurement timeout (1-7)");
|
|
||||||
iw_entry(iw, "sense-timeout", "%d", (int)priv->cfg.sense_timeout);
|
iw_cmt_newline(iw);
|
||||||
|
iw_comment(iw, "Optimize for interlaced pads");
|
||||||
|
iw_entry(iw, "interlaced-pads", str_yn(priv->cfg.interlaced));
|
||||||
|
|
||||||
iw_cmt_newline(iw);
|
iw_cmt_newline(iw);
|
||||||
iw_comment(iw, "Each used group must have 1 sampling capacitor and 1-3 channels.");
|
iw_comment(iw, "Each used group must have 1 sampling capacitor and 1-3 channels.");
|
||||||
|
|||||||
+16
-13
@@ -11,13 +11,28 @@
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
enum TouchCmd_ {
|
enum TouchCmd_ {
|
||||||
DUMMY=0
|
CMD_READ=0
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Handle a request message */
|
/** Handle a request message */
|
||||||
static error_t UTOUCH_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp)
|
static error_t UTOUCH_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, PayloadParser *pp)
|
||||||
{
|
{
|
||||||
|
struct priv* priv = unit->data;
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
|
case CMD_READ:
|
||||||
|
if (priv->status == UTSC_STATUS_BUSY) return E_BUSY;
|
||||||
|
if (priv->status == UTSC_STATUS_FAIL) return E_HW_TIMEOUT;
|
||||||
|
|
||||||
|
PayloadBuilder pb = pb_start(unit_tmp512, UNIT_TMP_LEN, NULL);
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
if (priv->all_channels_mask & (1<<i)) {
|
||||||
|
pb_u16(&pb, priv->readouts[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
com_respond_pb(frame_id, MSG_SUCCESS, &pb);
|
||||||
|
return E_SUCCESS;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return E_UNKNOWN_COMMAND;
|
return E_UNKNOWN_COMMAND;
|
||||||
}
|
}
|
||||||
@@ -25,18 +40,6 @@ static error_t UTOUCH_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command,
|
|||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle update-tick (if configured in init)
|
|
||||||
*
|
|
||||||
* @param unit
|
|
||||||
*/
|
|
||||||
static void UTOUCH_updateTick(Unit *unit)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** Unit template */
|
/** Unit template */
|
||||||
const UnitDriver UNIT_TOUCH = {
|
const UnitDriver UNIT_TOUCH = {
|
||||||
.name = "TOUCH",
|
.name = "TOUCH",
|
||||||
|
|||||||
Reference in New Issue
Block a user