touch interleaved sense mode, improved blinking in file writes via the api
This commit is contained in:
+29
-16
@@ -30,7 +30,7 @@ void UTOUCH_HandleIrq(void *arg)
|
||||
// assert_param((TSC->IOGCSR>>16) == priv->groups_phase[priv->next_phase]);
|
||||
|
||||
// Store captured data
|
||||
const uint32_t chmask = priv->channels_phase[priv->next_phase];
|
||||
const uint32_t chmask = TSC->IOCCR;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (chmask & (1<<i)) {
|
||||
priv->readouts[i] = (uint16_t) (TSC->IOGXCR[i >> 2] & 0x3FFF);
|
||||
@@ -38,11 +38,14 @@ void UTOUCH_HandleIrq(void *arg)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (!priv->cfg.interlaced) {
|
||||
// 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
|
||||
@@ -90,21 +93,31 @@ void UTOUCH_updateTick(Unit *unit)
|
||||
|
||||
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->all_channels_mask == 0) return;
|
||||
|
||||
if (priv->cfg.interlaced) {
|
||||
// Find the next non-zero bit, wrap around if needed
|
||||
while ((priv->all_channels_mask & (1<<priv->next_phase))==0) {
|
||||
priv->next_phase++;
|
||||
if (priv->next_phase == 32) {
|
||||
priv->next_phase = 0;
|
||||
priv->status = UTSC_STATUS_READY;
|
||||
}
|
||||
}
|
||||
TSC->IOGCSR = (uint32_t) (1 << (priv->next_phase >> 2)); // phase divided by 4
|
||||
TSC->IOCCR = (uint32_t) (1 << priv->next_phase);
|
||||
|
||||
// interlaced - float neighbouring electrodes
|
||||
TSC->CR |= TSC_CR_IODEF;
|
||||
// floaty (must be used for interlaced pads)
|
||||
// note: interlaced pads also need to be sampled individually
|
||||
} else {
|
||||
TSC->IOGCSR = priv->groups_phase[priv->next_phase];
|
||||
TSC->IOCCR = priv->channels_phase[priv->next_phase];
|
||||
|
||||
// separate - keep neighbouring electrodes at GND
|
||||
}
|
||||
|
||||
TSC->ICR = TSC_ICR_EOAIC | TSC_ICR_MCEIC;
|
||||
|
||||
// Go!
|
||||
priv->ongoing = true;
|
||||
TSC->CR |= TSC_CR_START;
|
||||
|
||||
+27
-12
@@ -75,6 +75,8 @@ error_t UTOUCH_init(Unit *unit)
|
||||
__HAL_RCC_TSC_FORCE_RESET();
|
||||
__HAL_RCC_TSC_RELEASE_RESET();
|
||||
|
||||
priv->all_channels_mask = 0;
|
||||
|
||||
for (int gi = 0; gi < 8; gi++) {
|
||||
const uint8_t cap = priv->cfg.group_scaps[gi];
|
||||
const uint8_t ch = priv->cfg.group_channels[gi];
|
||||
@@ -132,11 +134,16 @@ error_t UTOUCH_init(Unit *unit)
|
||||
else {
|
||||
dbg_touch("TSC ch @ %s", rsc_get_name(r));
|
||||
|
||||
// channels are configured individually when read.
|
||||
// we prepare bitmaps to use for the read groups (all can be read in at most 3 steps)
|
||||
priv->channels_phase[phasenum] |= bit; // this is used for the channel selection register
|
||||
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.
|
||||
phasenum++;
|
||||
if (priv->cfg.interlaced) {
|
||||
// interlaced - only update the mask beforehand
|
||||
priv->all_channels_mask |= bit;
|
||||
} else {
|
||||
// channels are configured individually when read.
|
||||
// we prepare bitmaps to use for the read groups (all can be read in at most 3 steps)
|
||||
priv->channels_phase[phasenum] |= bit; // this is used for the channel selection register
|
||||
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.
|
||||
phasenum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,7 +161,9 @@ error_t UTOUCH_init(Unit *unit)
|
||||
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);
|
||||
dbg_touch("CR = %08x, ht is %d, lt is %d", (int)TSC->CR,
|
||||
(int)priv->cfg.charge_time,
|
||||
(int)priv->cfg.drain_time);
|
||||
|
||||
// iofloat is used for discharging
|
||||
|
||||
@@ -162,16 +171,22 @@ error_t UTOUCH_init(Unit *unit)
|
||||
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]);
|
||||
if (!priv->cfg.interlaced) {
|
||||
dbg_touch("TSC phases:");
|
||||
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);
|
||||
|
||||
// starts in the tick callback
|
||||
|
||||
return E_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "unit_base.h"
|
||||
|
||||
#define TSC_DEBUG 1
|
||||
#define TSC_DEBUG 0
|
||||
|
||||
#if TSC_DEBUG
|
||||
#define dbg_touch(f,...) dbg(f,##__VA_ARGS__)
|
||||
|
||||
@@ -149,7 +149,7 @@ void UTOUCH_writeIni(Unit *unit, IniWriter *iw)
|
||||
iw_entry(iw, "ss-clock-prediv", "%d", (int)priv->cfg.ss_presc);
|
||||
|
||||
iw_cmt_newline(iw);
|
||||
iw_comment(iw, "Optimize for interlaced pads");
|
||||
iw_comment(iw, "Optimize for interlaced pads (individual sampling with others floating)");
|
||||
iw_entry(iw, "interlaced-pads", str_yn(priv->cfg.interlaced));
|
||||
|
||||
iw_cmt_newline(iw);
|
||||
|
||||
Reference in New Issue
Block a user