commit 651cb6e6f2881c11b7192d475a804132f71dd117
Author: Felix Wittenfeld <fwittenf@techfak.uni-bielefeld.de>
Date:   Tue Mar 5 15:10:03 2019 +0100

    Extended unittest for AT42QT1050

diff --git a/periphery-lld/AMiRo-LLD b/periphery-lld/AMiRo-LLD
index b95be72..7df78c6 160000
--- a/periphery-lld/AMiRo-LLD
+++ b/periphery-lld/AMiRo-LLD
@@ -1 +1 @@
-Subproject commit b95be72b70314916909196ddea055642914f4c6d
+Subproject commit 7df78c60db679f32c180cc23776e5e449fc7fab5
diff --git a/unittests/periphery-lld/src/ut_alld_AT42QT1050_v1.c b/unittests/periphery-lld/src/ut_alld_AT42QT1050_v1.c
index 9d90e38..3037f47 100644
--- a/unittests/periphery-lld/src/ut_alld_AT42QT1050_v1.c
+++ b/unittests/periphery-lld/src/ut_alld_AT42QT1050_v1.c
@@ -20,7 +20,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include <ut_alld_AT42QT1050_v1.h>
 
 #if ((AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_AT42QT1050) && (AMIROLLD_CFG_AT42QT1050 == 1)) || defined(__DOXYGEN__)
-
 /******************************************************************************/
 /* LOCAL DEFINITIONS                                                          */
 /******************************************************************************/
@@ -43,114 +42,311 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /* LOCAL FUNCTIONS                                                            */
 /******************************************************************************/
 
+void print_settings(apalExitStatus_t* status, BaseSequentialStream* stream, aos_unittest_t* ut) {
+    chprintf(stream, "settings...\n");
+
+    uint8_t test8;
+    at42qt1050_lld_register_t txbuf;
+    *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_LOWPOWERMODE, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    chprintf(stream, "\tmeasurement inverval %d ms\n", test8*8);
+
+    *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_MAXONDURATION, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    chprintf(stream, "\tMax on duration %d ms\n", test8*160);
+
+    *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_FINFOUTMAXCALGUARD, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    chprintf(stream, "\tFast In %d, Fast Out, %d MaxCal %d\n\tGuard channel ",
+             test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_FI,     //enter fast mode whenever an unfiltered signal value is detected
+             test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_FO,     //DI of 4 (global setting for all keys)
+             test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_MAXCAL);//recalibrate ALL KEYS after a Max On Duration timeout vs. individually
+
+    //guard channel (which gets priority filtering)
+    if((test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_GUARD) > AT42QT1050_LLD_NUM_KEYS-1)
+        chprintf(stream, "off");
+    else
+        chprintf(stream, " %d", test8 & AT42QT1050_LLD_FINFOUTMAXCALGUARD_GUARD);
+
+    chprintf(stream, "\n\n\tkey\tgroup\tintegr.\tdelay\tthresh.\tpulse\tscale\n");
+     for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
+         chprintf(stream, "\t%d\t", key);
+         txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_INTEGRATOR_AKS_0, key);
+         *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+         if(!((at42qt1050_lld_detectionintegratoraksreg_t)test8).aks)
+             chprintf(stream, "none\t");
+         else
+             chprintf(stream, "%d\t", ((at42qt1050_lld_detectionintegratoraksreg_t)test8).aks);
+
+         if(!((at42qt1050_lld_detectionintegratoraksreg_t)test8).detection_integrator)
+             chprintf(stream, "off", key);
+         else
+             chprintf(stream, "%d", ((at42qt1050_lld_detectionintegratoraksreg_t)test8).detection_integrator);
+
+         txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_CHARGESHAREDELAY_0, key);
+         *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+         chprintf(stream, "\t+%d", test8);
+
+         txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
+         *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+         chprintf(stream, "\t%d", test8);
+
+         txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_PULSE_SCALE_0, key);
+         *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &test8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+         chprintf(stream, "\t%d\t%d\n", key, ((at42qt1050_lld_pulsescalereg_t)test8).pulse, ((at42qt1050_lld_pulsescalereg_t)test8).scale);
+    }
+
+}
+
+void show_live(const uint8_t first_key, apalExitStatus_t* status,
+               BaseSequentialStream* stream, aos_unittest_t* ut) {
+
+    apalDbgAssert(first_key<5);
+
+    event_listener_t event_listener;
+    aos_timestamp_t tstart, tcurrent, tend;
+
+    uint8_t keyStatus, detectionStatus;
+    uint16_t signal, reference;
+    uint8_t threshold[AT42QT1050_LLD_NUM_KEYS];
+
+    chprintf(stream, "key, count, signal, ref, [threshold], \033[31mtouch\n\033[0m");
+
+    //get thresholds
+    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
+        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
+        *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &threshold[key], ((ut_at42qt1050data_t*)ut->data)->timeout);
+    }
+    chEvtRegister(((ut_at42qt1050data_t*)ut->data)->evtsource, &event_listener, INTERRUPT_EVENT_ID);
+    for(uint16_t i=0;; i++) {
+        aosSysGetUptime(&tstart);
+        //wait 1 second for a touch event
+        tend = tstart + (MICROSECONDS_PER_SECOND);
+
+        for (uint8_t key = first_key; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
+
+            //highlight touched key
+            *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_KEYSTATUS, &keyStatus, ((ut_at42qt1050data_t*)ut->data)->timeout);
+            if((key == 0 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY0)
+                    || (key == 1 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY1)
+                    || (key == 2 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY2)
+                    || (key == 3 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY3)
+                    || (key == 4 && keyStatus&AT42QT1050_LLD_KEYSTATUS_KEY4))
+                chprintf(stream, "\033[31m"); //red
+            else
+                chprintf(stream, "\033[0m"); //black
+
+            *status |= at42qt1050_lld_read_keyssignal(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, key, &signal, ((ut_at42qt1050data_t*)ut->data)->timeout);
+            *status |= at42qt1050_lld_read_referencedata(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, key, &reference, ((ut_at42qt1050data_t*)ut->data)->timeout);
+
+            const uint16_t dist = (signal<reference?0:signal-reference);
+            chprintf(stream, "\033[Kkey %d, %d\t0x%04X 0x%04X [", key, dist, reference, signal);
+            uint16_t stars=0;
+            for(; stars < dist; stars++) {
+                chprintf(stream, "0");
+                if(stars > 40) {           //max_stars = 40
+                    chprintf(stream, "+"); //more than max_stars
+                    break;
+                }
+            }
+            for(; stars < threshold[key]; stars++)
+                chprintf(stream, " ");
+            if(stars == threshold[key])
+                chprintf(stream, "]");
+            chprintf(stream, "\n\033[0m");
+        }
+
+        aosSysGetUptime(&tcurrent);
+//        const aos_timestamp_t ttimeout = MICROSECONDS_PER_SECOND - ((tcurrent - tstart) % MICROSECONDS_PER_SECOND);
+        const eventmask_t emask = chEvtWaitOneTimeout(EVENT_MASK(INTERRUPT_EVENT_ID), chTimeUS2I(tend));//ttimeout));
+        const eventflags_t eflags = chEvtGetAndClearFlags(&event_listener);
+        if (emask == EVENT_MASK(INTERRUPT_EVENT_ID) && eflags == ((ut_at42qt1050data_t*)ut->data)->evtflags) {
+            // interrupt detected
+            chprintf(stream, "interrupt ");
+        } // else: timeout
+
+        *status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_DETECTIONSTATUS, &detectionStatus, ((ut_at42qt1050data_t*)ut->data)->timeout);
+        if(detectionStatus & AT42QT1050_LLD_DETECTIONSTATUS_TOUCH)
+            chprintf(stream, "touch ");
+        if(detectionStatus & AT42QT1050_LLD_DETECTIONSTATUS_OVERFLOW)
+            chprintf(stream, "overflow ");
+        if(detectionStatus & AT42QT1050_LLD_DETECTIONSTATUS_CALIBRATE)
+            chprintf(stream, "calibrate");
+        chprintf(stream, "\033[K");
+
+        if(i>=30)
+            break;
+
+        chprintf(stream, "\033[%dF", 5-first_key); //cursor up
+    }
+    chEvtUnregister(((ut_at42qt1050data_t*)ut->data)->evtsource, &event_listener);
+}
+
 /******************************************************************************/
 /* EXPORTED FUNCTIONS                                                         */
 /******************************************************************************/
 
 aos_utresult_t utAlldAt42qt1050Func(BaseSequentialStream* stream, aos_unittest_t* ut)
 {
-  aosDbgCheck(ut->data != NULL && ((ut_at42qt1050data_t*)ut->data)->at42qt1050d != NULL);
-
-  // local variables
-  aos_utresult_t result = {0, 0};
-  uint32_t status;
-  uint8_t buffer8[4] = {0, 0};
-  uint16_t buffer16[5];
-  event_listener_t event_listener;
-  aos_timestamp_t tstart, tcurrent, tend;
-
-  chprintf(stream, "reset device...\n");
-  at42qt1050_lld_reset(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, ((ut_at42qt1050data_t*)ut->data)->timeout, true);
-
-  chprintf(stream, "read register...\n");
-  status = at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_CHIPID, &buffer8[0], ((ut_at42qt1050data_t*)ut->data)->timeout);
-  status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_FIRMWAREVERSION, &buffer8[1], ((ut_at42qt1050data_t*)ut->data)->timeout);
-  chprintf(stream, "\t\tchip ID: 0x%02X\n", buffer8[0]);
-  chprintf(stream, "\t\tfirmware version: %u.%u (0x%02X)\n", ((at42qt1050_lld_firmwarereg_t)buffer8[1]).major, ((at42qt1050_lld_firmwarereg_t)buffer8[1]).minor, buffer8[1]);
-  if (status == APAL_STATUS_SUCCESS && buffer8[0] == AT42QT1050_LLD_CHIPID) {
-    aosUtPassed(stream, &result);
-  } else {
-    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
-  }
-
-  chprintf(stream, "write register...\n");
-  buffer8[1] = (((uint8_t)(at42qt1050_lld_samples2pulse(4096) + 0.5f)) << 4) | ((uint8_t)(at42qt1050_lld_scaling2scale(1024) + 0.5f));
-  status = at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, &buffer8[0], ((ut_at42qt1050data_t*)ut->data)->timeout);
-  status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, buffer8[1] , ((ut_at42qt1050data_t*)ut->data)->timeout);
-  status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, &buffer8[2], ((ut_at42qt1050data_t*)ut->data)->timeout);
-  status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, buffer8[0] , ((ut_at42qt1050data_t*)ut->data)->timeout);
-  status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, &buffer8[3], ((ut_at42qt1050data_t*)ut->data)->timeout);
-  if (status == APAL_STATUS_SUCCESS &&
-      buffer8[3] == buffer8[0] &&
-      buffer8[2] == buffer8[1] &&
-      at42qt1050_lld_pulse2samples(((at42qt1050_lld_pulsescalereg_t)buffer8[2]).pulse) == 4096 &&
-      at42qt1050_lld_scale2scaling(((at42qt1050_lld_pulsescalereg_t)buffer8[2]).scale) == 1024) {
-    aosUtPassed(stream, &result);
-  } else {
-    aosUtFailedMsg(stream, &result, "0x%08X [0x%02X 0x%02X 0x%02X 0x%02X]\n", status, buffer8[0], buffer8[1], buffer8[2], buffer8[3]);
-  }
-
-  chprintf(stream, "read reference data...\n");
-  status = APAL_STATUS_OK;
-  for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
-    status |= at42qt1050_lld_read_referencedata(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, key, &buffer16[key], ((ut_at42qt1050data_t*)ut->data)->timeout);
-    chprintf(stream, "\t\tkey %u: 0x%04X\n", key, buffer16[key]);
-  }
-  if (status == APAL_STATUS_SUCCESS) {
-    aosUtPassed(stream, &result);
-  } else {
-    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
-  }
-
-  chprintf(stream, "read key signal for ten seconds...\n");
-  status = APAL_STATUS_OK;
-  chprintf(stream, "\t\t key 0  key 1  key 2  key 3  key 4\n");
-  for (uint8_t s = 0; s < 10; ++s) {
-    aosThdSSleep(1);
+    aosDbgCheck(ut->data != NULL && ((ut_at42qt1050data_t*)ut->data)->at42qt1050d != NULL);
+
+    // local variables
+    aos_utresult_t result = {0, 0};
+    apalExitStatus_t status;
+    uint8_t  test_8;
+    bool error;
+
+    chprintf(stream, "read register...\n");
+    error = false;
+    status = at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_CHIPID, &test_8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    chprintf(stream, "\t\tchip ID: 0x%02X\n", test_8);
+    if (test_8 != AT42QT1050_LLD_CHIPID)
+        error = true;
+    status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_FIRMWAREVERSION, &test_8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    chprintf(stream, "\t\tfirmware version: %u.%u (0x%02X)\n", ((at42qt1050_lld_firmwarereg_t)test_8).major, ((at42qt1050_lld_firmwarereg_t)test_8).minor, test_8);
+    if (status == APAL_STATUS_SUCCESS && !error) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    chprintf(stream, "write and readback threshold data...\n");
+    status = APAL_STATUS_OK;
+    const uint8_t threshold_test = 0x40;
+    error = false;
+    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
+        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
+        status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, threshold_test , ((ut_at42qt1050data_t*)ut->data)->timeout);
+        status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &test_8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+        if(test_8 != threshold_test)
+            error = true;
+    }
+    if (status == APAL_STATUS_SUCCESS  &&  !error) {
+        aosUtPassedMsg(stream, &result, "Set thresholds successfull to 0x%04X\n", threshold_test);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    chprintf(stream, "guarding...\nincrease charge_delay0\ndisable multitouch\n");
+
+    //channel 0 is to big to be charged in the default cycle
+    status = at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_CHARGESHAREDELAY_0, 128 , ((ut_at42qt1050data_t*)ut->data)->timeout);
+
+    //set all channel to group 1 -> only 1 simultaneous touch in group = single touch
+    at42qt1050_lld_detectionintegratoraksreg_t detectionintegrator;
+    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
+        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_INTEGRATOR_AKS_0, key);
+        detectionintegrator.aks = 1;                  //on touch per group-id simultaneous
+        detectionintegrator.detection_integrator = 4; //4 times > threshold => touchevent
+        status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, 0x11 , ((ut_at42qt1050data_t*)ut->data)->timeout);
+    }
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    chprintf(stream, "reset device...\n");
+    status = at42qt1050_lld_reset(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, ((ut_at42qt1050data_t*)ut->data)->timeout, true);
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    chprintf(stream, "read threshold data again...\n");
+    status = APAL_STATUS_OK;
+    const uint8_t threshold_default = 20;
+    error = false;
     for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
-      status |= at42qt1050_lld_read_keyssignal(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, key, &buffer16[key], ((ut_at42qt1050data_t*)ut->data)->timeout);
-    }
-    chprintf(stream, "\t\t0x%04X 0x%04X 0x%04X 0x%04X 0x%04X\n", buffer16[0], buffer16[1], buffer16[2], buffer16[3], buffer16[4]);
-  }
-  if (status == APAL_STATUS_SUCCESS) {
-    aosUtPassed(stream, &result);
-  } else {
-    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
-  }
-
-  chprintf(stream, "test interrupts...\n");
-  status = AOS_OK;
-  chEvtRegister(((ut_at42qt1050data_t*)ut->data)->evtsource, &event_listener, INTERRUPT_EVENT_ID);
-  aosSysGetUptime(&tstart);
-  tend = tstart + (30 * MICROSECONDS_PER_SECOND);
-  do {
-    aosSysGetUptime(&tcurrent);
-    const aos_timestamp_t ttimeout = MICROSECONDS_PER_SECOND - ((tcurrent - tstart) % MICROSECONDS_PER_SECOND);
-    const eventmask_t emask = chEvtWaitOneTimeout(EVENT_MASK(INTERRUPT_EVENT_ID), chTimeUS2I(ttimeout));
-    const eventflags_t eflags = chEvtGetAndClearFlags(&event_listener);
-    if (emask == EVENT_MASK(INTERRUPT_EVENT_ID) && eflags == ((ut_at42qt1050data_t*)ut->data)->evtflags) {
-      // interrupt detected
-      chprintf(stream, "\t\tinterrupt detected\n");
-    } // else: timeout
-    status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_KEYSTATUS, &buffer8[0], ((ut_at42qt1050data_t*)ut->data)->timeout);
-    chprintf(stream, "\t\tkey status: %u %u %u %u %u\n",
-             (((buffer8[0] & AT42QT1050_LLD_KEYSTATUS_KEY0) == 0) ? 0 : 1),
-             (((buffer8[0] & AT42QT1050_LLD_KEYSTATUS_KEY1) == 0) ? 0 : 1),
-             (((buffer8[0] & AT42QT1050_LLD_KEYSTATUS_KEY2) == 0) ? 0 : 1),
-             (((buffer8[0] & AT42QT1050_LLD_KEYSTATUS_KEY3) == 0) ? 0 : 1),
-             (((buffer8[0] & AT42QT1050_LLD_KEYSTATUS_KEY4) == 0) ? 0 : 1));
-    aosSysGetUptime(&tcurrent);
-  } while (tcurrent < tend);
-  chEvtUnregister(((ut_at42qt1050data_t*)ut->data)->evtsource, &event_listener);
-  if (status == APAL_STATUS_SUCCESS) {
-    aosUtPassed(stream, &result);
-  } else {
-    aosUtFailedMsg(stream, &result, "0x%08X\n", status);
-  }
-
-  aosUtInfoMsg(stream,"driver object memory footprint: %u bytes\n", sizeof(AT42QT1050Driver));
-
-  return result;
+        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
+        status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, &test_8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+        if(test_8 != threshold_default)
+            error = true;
+    }
+
+    if (status == APAL_STATUS_SUCCESS && !error) {
+        aosUtPassedMsg(stream, &result, "threshold 0x%04X = default\n", threshold_default);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    chprintf(stream, "demo of default configuration:\n");
+    status = APAL_STATUS_OK;
+    show_live(0, &status, stream, ut);
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    status = APAL_STATUS_OK;
+    chprintf(stream, "write configuration...\npuls + scale + threshold 16\n");
+    at42qt1050_lld_pulsescalereg_t pulse_scale;
+    //values stored as exponent of 2
+    pulse_scale.pulse = 0; // accumulate #pulses -> increase resolution & time to acquire
+    pulse_scale.scale = 0; // scale = average factor n: NewAvg = (NewData/n) + [OldAvg*(n-1/n)] -> decrease noise
+    status  = at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_0, pulse_scale.raw , ((ut_at42qt1050data_t*)ut->data)->timeout);
+    status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_3, 0x00u , ((ut_at42qt1050data_t*)ut->data)->timeout);
+    pulse_scale.pulse = 4;
+    status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_1, pulse_scale.raw , ((ut_at42qt1050data_t*)ut->data)->timeout);
+    status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_2, pulse_scale.raw , ((ut_at42qt1050data_t*)ut->data)->timeout);
+    status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_PULSE_SCALE_4, pulse_scale.raw , ((ut_at42qt1050data_t*)ut->data)->timeout);
+
+    for (uint8_t key = 0; key < AT42QT1050_LLD_NUM_KEYS; ++key) {
+        const at42qt1050_lld_register_t txbuf = at42qt1050_lld_addr_calc(AT42QT1050_LLD_REG_NEGATIVETHRESHOLD_0, key);
+        status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, txbuf, 16, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    }
+    chprintf(stream, "disable guard key\n");
+    status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_INTEGRATOR_AKS_0, 0 , ((ut_at42qt1050data_t*)ut->data)->timeout); //disable key
+    status |= at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_FINFOUTMAXCALGUARD, 8 , ((ut_at42qt1050data_t*)ut->data)->timeout); //disable feature
+
+    chprintf(stream, "calibrate...\n");
+    status = at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_RESET_CALIBRATE, AT42QT1050_LLD_RESETCALIBRATE_CALIBRATE, ((ut_at42qt1050data_t*)ut->data)->timeout);
+
+
+
+    //wait for calibration to complete
+    error = true;
+    for(uint8_t i=0; i<0xFF; i++) {
+        usleep(10);
+        status |= at42qt1050_lld_read_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_DETECTIONSTATUS, &test_8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+        if(!(test_8 & AT42QT1050_LLD_DETECTIONSTATUS_CALIBRATE)) {
+            error = false;
+            break;
+        }
+    }
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+    chprintf(stream, "demo of custom configuration:\n");
+    status = APAL_STATUS_OK;
+    show_live(1, &status, stream, ut);
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    status = APAL_STATUS_OK;
+    print_settings(&status, stream, ut);
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    chprintf(stream, "shutdown touch\n");
+    test_8 = 0; //Power down
+    status = at42qt1050_lld_write_reg(((ut_at42qt1050data_t*)ut->data)->at42qt1050d, AT42QT1050_LLD_REG_LOWPOWERMODE, &test_8, ((ut_at42qt1050data_t*)ut->data)->timeout);
+    if (status == APAL_STATUS_SUCCESS) {
+        aosUtPassed(stream, &result);
+    } else {
+        aosUtFailedMsg(stream, &result, "0x%08X\n", status);
+    }
+
+    aosUtInfoMsg(stream,"driver object memory footprint: %u bytes\n", sizeof(AT42QT1050Driver));
+
+    return result;
 }
 
-#endif /* (AMIROOS_CFG_TESTS_ENABLE == true) && defined(AMIROLLD_CFG_AT42QT1050) && (AMIROLLD_CFG_AT42QT1050 == 1) */
+#endif
