Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions components/kaos/autotest/src/autotest_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,8 @@ typedef struct {
uint8_t pos; /**< The place of that row in the run, from 1. */
bool step_fail; /**< A step of the row in flight was answered,
* and answered no. */
bool step_card; /**< The final station's own card refused the
* megabyte or did not give it back. */
bool step_timeout; /**< A step of it was never answered. */
bool step_absent; /**< The card's first step found no card. */
uint8_t tally[AUTOTEST_ROW_STATES]; /**< Rows ended so far, by state. */
Expand Down Expand Up @@ -781,7 +783,8 @@ static void row_close(Autotest *me, const krow_t *t, uint8_t state)
/**
* @brief How an owner's verdict reads, given what the row's steps said.
*
* An owner answers pass or fail. A fail with a step unanswered and none
* An owner answers pass or fail. A pass of the card row whose write or
* read-back failed at the final station is a fail. A fail with a step unanswered and none
* answered no was never judged (nobody pressed TOP): a timeout. A card row
* that found no card is skipped, where the row says an empty slot is no fault.
*
Expand All @@ -794,10 +797,14 @@ static uint8_t verdict_state(const Autotest *me, const krow_t *t, bool ok)
{
uint8_t state = AUTOTEST_ROW_FAIL;

if ( ok )
if ( ok && !me->step_card )
{
state = AUTOTEST_ROW_PASS;
}
else if ( ok )
{
/* The slot passed and the station's card did not: a failure there. */
}
else if ( me->step_absent && ((t->flags & KROW_F_SKIP_NO_CARD) != 0U) )
{
state = AUTOTEST_ROW_SKIPPED;
Expand Down Expand Up @@ -983,6 +990,7 @@ static void autotest_walk(Autotest *me)

me->pos += 1U;
me->step_fail = false;
me->step_card = false;
me->step_timeout = false;
me->step_absent = false;
if ( KROW_ASYNC == t->kind )
Expand Down Expand Up @@ -1087,6 +1095,7 @@ void Autotest_ctor(void)
me->row = NULL;
me->pos = 0U;
me->step_fail = false;
me->step_card = false;
me->step_timeout = false;
me->step_absent = false;
#if CONFIG_KODE_LOWPOWER
Expand Down Expand Up @@ -1286,6 +1295,16 @@ static void step_note(Autotest *me, QEvt const * const e)
{
me->step_absent = true;
}
/* At the final station the card is the station's own, a good one:
* a megabyte it will not take, or does not give back the same, is
* the slot's to answer for there. Anywhere else it stays what the
* owner says it is, a bad card in a good slot. */
if ( (AUTOTEST_CLIENT_TEST_DOT == me->client) && !t->ok
&& (SD_TEST_STEPS == t->total)
&& ((SD_TEST_WRITE == t->phase) || (SD_TEST_VERIFY == t->phase)) )
{
me->step_card = true;
}
break;
}
default:
Expand Down
38 changes: 38 additions & 0 deletions components/kaos/buttons/src/buttons_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ typedef struct {

/* The guided test, while one is running. */
bool test_on; /**< A run is in progress. */
uint8_t test_inject; /**< What the console's injections hold down, by
* the board's own button, for the run's judge. */
uint8_t test_origin; /**< Who asked for it: TEST_ORIGIN_AUTOTEST or a client. */
bool test_judged; /**< This step's press has been judged; waiting
* for everything to be released. */
Expand Down Expand Up @@ -335,6 +337,24 @@ bool buttons_inject(uint8_t id, bool pressed)
{
return false;
}
/* The test asks for the board's buttons, not for a thumb's: its judge
* hears an injection as it hears the pins, so a station with nobody at it
* (the bench's operator) can run the row. Only a running row has a judge
* to tell. A read of one byte the AO writes: a row that starts or ends
* under it costs one event at most. */
if ( l_buttons.test_on )
{
ButtonEvt *j = Q_NEW_X(ButtonEvt, 0U, BUTTONS_INJECT_SIG);
if ( NULL != j )
{
j->id = id; /* the board's own button, before the pad's turn */
j->pressed = pressed;
j->t_ms = khal_time_ms();
/* A refused post gives the event back to its pool: the row then
* hears nothing of this press, as of one nobody made. */
(void)QACTIVE_POST_X(AO_Buttons, &j->super, 1U, NULL);
}
}
ButtonEvt *e = Q_NEW_X(ButtonEvt, 0U, BUTTON_EVT_SIG);
if ( NULL == e )
{
Expand Down Expand Up @@ -388,6 +408,7 @@ void Buttons_ctor(void)
me->rot_pending = 0U;
s_rot = 0U; /* the pad as wired */
me->test_on = false;
me->test_inject = 0U;
me->test_origin = TEST_ORIGIN_AUTOTEST;
me->test_judged = false;
me->test_failed = false;
Expand Down Expand Up @@ -706,6 +727,7 @@ static void test_start(Buttons * const me, uint8_t origin)
return;
}
me->test_on = true;
me->test_inject = 0U;
me->test_failed = false;
me->test_gaveup = false;
me->test_wrong = 0U;
Expand Down Expand Up @@ -1063,6 +1085,22 @@ static QState Buttons_watching(Buttons * const me, QEvt const * const e)
status = Q_HANDLED();
break;
}
case BUTTONS_INJECT_SIG: {
ButtonEvt const * const j = Q_EVT_CAST(ButtonEvt);
uint8_t const bit = (uint8_t)(1U << j->id);

if ( j->pressed )
{
me->test_inject |= bit;
}
else
{
me->test_inject &= (uint8_t)~bit;
}
test_judge(me, (uint8_t)(me->stable | me->test_inject));
status = Q_HANDLED();
break;
}
case BUTTONS_PAD_IDLE_SIG: {
rot_settle(me);
status = Q_HANDLED();
Expand Down
8 changes: 8 additions & 0 deletions components/kaos/console/src/console_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ KAOS_WEAK void kaos_appmgr_start(void);
KAOS_WEAK void kaos_radio_start(void);
KAOS_WEAK void kaos_display_start(void);
KAOS_WEAK void kaos_net_start(void);
KAOS_WEAK void kaos_touch_start(void);
KAOS_WEAK void appdata_request(const char *project, QActive *who);
KAOS_WEAK kode_status_t appdata_rm_request(const char *project, QActive *who);
KAOS_WEAK kode_status_t appmgr_appdata_get_request(const char *project,
const char *url, bool install,
QActive *who);
KAOS_WEAK void touch_test_inject(int16_t x, int16_t y, bool pressed);
KAOS_WEAK const uint8_t *storage_buf(uint8_t idx);
KAOS_WEAK void storage_close_request(void);
KAOS_WEAK void storage_desc_request(const char *name, QActive *who);
Expand Down Expand Up @@ -2587,6 +2589,12 @@ static void h_touch(Console *me, const kcmd_t *c, const karg_val_t *v)
/* down/up only: logging every "move" would flood the log. */
if ( sent && (2U != v[2].u) )
{
/* The panel's owner is an app's choice: the injected sample went out
* above either way, and only a linked AO_Touch has a test to tell. */
if ( kaos_linked(&kaos_touch_start) )
{
touch_test_inject((int16_t)v[0].u, (int16_t)v[1].u, (1U != v[2].u));
}
KLOG_I(TAG, "console: injected touch x=%d y=%d state=%s",
(int)v[0].u, (int)v[1].u, A_TOUCH_STATES[v[2].u]);
}
Expand Down
12 changes: 12 additions & 0 deletions components/kaos/core/include/kaos.h
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,18 @@ void touch_field_request(QActive *who, uint8_t op, uint16_t field, int32_t value
*/
void touch_test_request(void);

/**
* @brief Tell the guided touch test about a finger the console injected.
*
* The test judges what the panel read, and an injected finger is not read
* from the panel: without this a station with nobody at it cannot run the row.
*
* @param x Where, in the panel's pixels.
* @param y Where.
* @param pressed true while the finger is down; false is its lift.
*/
void touch_test_inject(int16_t x, int16_t y, bool pressed);

/**
* @brief Subscribe @p who to TOUCH_EVT_SIG, AO_Touch's report of the finger.
*
Expand Down
39 changes: 34 additions & 5 deletions components/kaos/imu/src/imu_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -1894,14 +1894,43 @@ static void mag_row(Imu * const me)
return;
}

if ( kdrv_qmc5883p_self_test(st) == KODE_OK )
if ( kdrv_qmc5883p_self_test(st) != KODE_OK )
{
KLOG_N(TAG, "test mag: self-test shift %d %d %d mG (a reading, not "
"judged)", (int)st[0], (int)st[1], (int)st[2]);
KLOG_E(TAG, "test mag: FAIL - the self-test could not be run");
mag_row_publish(me, 2U, (uint8_t)MAG_TEST_ST, 0U, 0, 0, 0, 0);
mag_row_verdict(me, false, "the part identified itself and its "
"self-test would not run");
return;
}
else
{
KLOG_W(TAG, "test mag: the self-test could not be run");
/* The datasheet gives the procedure and no figure, so the floor is
* not a spec: it is far under what a board that works shows (about
* 1000 mG an axis) and over what an axis that does not move can. */
bool moved = true;

for ( size_t i = 0U; (size_t)KDRV_QMC5883P_AXES > i; ++i )
{
int32_t d = st[i];

if ( 0 > d )
{
d = -d;
}
if ( (int32_t)KDRV_QMC5883P_ST_MIN_MG > d )
{
moved = false;
}
}
KLOG_N(TAG, "test mag: self-test shift %d %d %d mG, at least %d an axis",
(int)st[0], (int)st[1], (int)st[2], (int)KDRV_QMC5883P_ST_MIN_MG);
if ( !moved )
{
KLOG_E(TAG, "test mag: FAIL - an axis did not move under the self-test");
mag_row_publish(me, 2U, (uint8_t)MAG_TEST_ST, 0U, st[0], st[1], st[2], 0);
mag_row_verdict(me, false, "an axis did not move under the self-test");
return;
}
mag_row_publish(me, 2U, (uint8_t)MAG_TEST_ST, (uint8_t)MAG_TF_PASS, st[0], st[1], st[2], 0);
}

if ( kdrv_qmc5883p_read(mg) != KODE_OK )
Expand Down
10 changes: 8 additions & 2 deletions components/kaos/test_dot/src/test_dot_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "kaos.h"
#include "kaos_claim.h"
#include "kaos_start.h"
#include "kbsp.h"
#include "kdrv_buttons.h"
#include "kdrv_wifi.h"
#include "khal_nvs.h"
Expand Down Expand Up @@ -1898,15 +1899,20 @@ _Static_assert(sizeof(TD_RADIO_TIME_WORST) <= KODE_FUNCTION_REC_MAX, "the longes

/**
* @brief Whether the C5's card passes: an ESP32-C5 running Kode's slave at this image's
* esp-hosted version, with its data lines up.
* esp-hosted version, on the bus the board is made for.
*
* Any width used to pass, and a link that had fallen back to one data line or to a slower
* clock (a data line that does not reach the C5) left the station as a good card. The
* production `c5` row has always asked for the board's own width and clock.
*
* @param e AO_Radio's answer to the radio check.
* @return true when the card, the chip, the slave, the version and the SDIO width all pass.
*/
static bool radio_card_ok(RadioProbeEvt const *e)
{
return e->card && (RADIO_PROBE_CHIP_C5 == e->chip) && e->kode && (e->fw[0] == e->host[0])
&& (e->fw[1] == e->host[1]) && (e->fw[2] == e->host[2]) && (0U < e->sdio_width);
&& (e->fw[1] == e->host[1]) && (e->fw[2] == e->host[2])
&& ((uint8_t)KBSP_C5_SDIO_WIDTH == e->sdio_width) && ((uint32_t)KBSP_C5_SDIO_KHZ == e->sdio_khz);
}

/**
Expand Down
45 changes: 45 additions & 0 deletions components/kaos/touch/src/touch_ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,28 @@ void touch_subscribe(QActive const *who)
QActive_subscribe(who, TOUCH_EVT_SIG);
}

void touch_test_inject(int16_t x, int16_t y, bool pressed)
{
TouchEvt *j = NULL;

/* Only a running test has a judge to tell. A read of one byte the AO
* writes: a test that starts or ends under it costs one event at most. */
if ( l_touch.test_on )
{
j = Q_NEW_X(TouchEvt, 0U, TOUCH_INJECT_SIG);
}
if ( NULL != j )
{
j->x = x;
j->y = y;
j->pressed = pressed;
j->t_ms = khal_time_ms();
j->stale = false;
/* A refused post gives the event back to its pool. */
(void)QACTIVE_POST_X(AO_Touch, &j->super, 1U, NULL);
}
}

void touch_test_request(void)
{
static const QEvt evt = QEVT_INITIALIZER(TOUCH_TEST_REQ_SIG);
Expand Down Expand Up @@ -1002,6 +1024,29 @@ static QState Touch_up(Touch * const me, QEvt const * const e)
status = Q_HANDLED();
break;
}
case TOUCH_INJECT_SIG: {
if ( me->test_on )
{
TouchEvt const * const j = Q_EVT_CAST(TouchEvt);

if ( j->pressed )
{
me->sum_x += (int32_t)j->x;
me->sum_y += (int32_t)j->y;
++me->n_samples;
}
else if ( 0U < me->n_samples )
{
test_judge(me); /* the injected tap lifted */
}
else
{
/* A lift with no press before it. */
}
}
status = Q_HANDLED();
break;
}
case TOUCH_TEST_TMO_SIG: {
if ( me->test_on )
{
Expand Down
4 changes: 4 additions & 0 deletions components/kdrv/motion/include/kdrv_qmc5883p.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ extern "C" {
/** @brief What the chip-id register reads on a QMC5883P. */
#define KDRV_QMC5883P_CHIP_ID 0x80U

/** @brief The least an axis must move under the self-test, mG. Not a datasheet
* figure (it gives none): boards that work show about 1000 an axis. */
#define KDRV_QMC5883P_ST_MIN_MG 150

/* ---- The calibration ----------------------------------------------------
* The part's own field and the board's are in every reading, so a raw one is
* no compass. The correction is a diagonal one: an offset per axis (hard
Expand Down
Loading