summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2014-05-14 17:06:00 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-05-18 02:41:39 +0000
commit4cb6971dafd7efb3476dfc45aad60c321b99cd84 (patch)
treeed51d3baa7de5ab171b43cd27ac2779f038bddde
parent09ad49c2bdd3bf125f8753bb7fd920d15af28750 (diff)
downloadchrome-ec-4cb6971dafd7efb3476dfc45aad60c321b99cd84.tar.gz
Keyborg: encode the scanned heat map to fit into RAM
A single frame of the scanned heat map is too big to fit into RAM. Let's encode it so that we can get the whole frame. BUG=None TEST=Touch on various places on the panel and see corresponding results. BRANCH=None Change-Id: I8c7c72d5d4a83ebc2018c0abd57075697c931bef Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/199940 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/keyborg/build.mk1
-rw-r--r--board/keyborg/encode.c114
-rw-r--r--board/keyborg/encode.h20
-rw-r--r--board/keyborg/touch_scan.c30
4 files changed, 143 insertions, 22 deletions
diff --git a/board/keyborg/build.mk b/board/keyborg/build.mk
index b31dafce38..cdd1a7ff84 100644
--- a/board/keyborg/build.mk
+++ b/board/keyborg/build.mk
@@ -10,4 +10,5 @@ CHIP_FAMILY:=stm32f
CHIP_VARIANT:=stm32ts60
board-y=board.o hardware.o runtime.o master_slave.o spi_comm.o touch_scan.o
+board-y+=encode.o
board-$(CONFIG_DEBUG_PRINTF)+=debug.o
diff --git a/board/keyborg/encode.c b/board/keyborg/encode.c
new file mode 100644
index 0000000000..266f67d3b3
--- /dev/null
+++ b/board/keyborg/encode.c
@@ -0,0 +1,114 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Touch data encoding/decoding */
+
+/*
+ * This removes the "whitespace" (i.e. cells below the threshold) and
+ * group the remaining active cells into "segments". By only storing
+ * the segments, we can fit a single frame in RAM in most cases.
+ */
+
+#include "common.h"
+#include "debug.h"
+#include "touch_scan.h"
+#include "util.h"
+
+#define BUF_SIZE 6000
+static uint8_t encoded[BUF_SIZE];
+static int encoded_size;
+
+void encode_reset(void)
+{
+ /* Just clear the encoded data */
+ encoded_size = 0;
+}
+
+void encode_add_column(const uint8_t *dptr)
+{
+ uint8_t *seg_count_ptr;
+ int p, p_start;
+ uint8_t *eptr = encoded + encoded_size, *e_seg_size;
+
+ seg_count_ptr = eptr;
+ eptr++;
+
+ *seg_count_ptr = 0;
+ p = 0;
+ while (p < ROW_COUNT * 2) {
+ if (dptr[p] < THRESHOLD) {
+ ++p;
+ continue;
+ }
+
+ /* Give up on overflow */
+ if (eptr + 2 >= encoded + BUF_SIZE)
+ return;
+
+ /* Save current position */
+ *(eptr++) = p;
+
+ /* Leave a byte for storing segment size */
+ e_seg_size = eptr;
+ eptr++;
+
+ /* Record segment starting point */
+ p_start = p;
+
+ /* Save the segment */
+ while (p < ROW_COUNT * 2 && dptr[p] >= THRESHOLD) {
+ if (eptr >= encoded + BUF_SIZE)
+ return;
+ *(eptr++) = dptr[p++];
+ }
+
+ /* Fill in the segment size now that we know it */
+ *e_seg_size = p - p_start;
+
+ (*seg_count_ptr)++;
+ }
+
+ /* Update encoded data size now that we're sure it fits */
+ encoded_size = eptr - encoded;
+}
+
+void encode_dump_matrix(void)
+{
+ uint8_t *dptr;
+ int row, col;
+ int seg_count;
+ int seg;
+ int seg_end;
+
+ debug_printf("Encoded size = %d\n", encoded_size);
+
+ dptr = encoded;
+ for (col = 0; col < COL_COUNT * 2; ++col) {
+ if (dptr >= encoded + encoded_size) {
+ for (row = 0; row < ROW_COUNT * 2; ++row)
+ debug_printf(" - ");
+ debug_printf("\n");
+ continue;
+ }
+ seg_count = *(dptr++);
+ row = 0;
+ for (seg = 0; seg < seg_count; ++seg) {
+ while (row < *dptr) {
+ debug_printf(" - ");
+ row++;
+ }
+ dptr++;
+ seg_end = *dptr + row;
+ dptr++;
+ for (; row < seg_end; ++row, ++dptr)
+ debug_printf("%3d ", *dptr);
+ }
+ while (row < ROW_COUNT * 2) {
+ debug_printf(" - ");
+ row++;
+ }
+ debug_printf("\n");
+ }
+}
diff --git a/board/keyborg/encode.h b/board/keyborg/encode.h
new file mode 100644
index 0000000000..b743c388d4
--- /dev/null
+++ b/board/keyborg/encode.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Touch data encoding/decoding */
+
+#ifndef __KEYBORG_ENCODE_H
+#define __KEYBORG_ENCODE_H
+
+/* Start encoding a new frame */
+void encode_reset(void);
+
+/* Encode a single column */
+void encode_add_column(const uint8_t *dptr);
+
+/* Decode and print the encoded frame to console */
+void encode_dump_matrix(void);
+
+#endif /* __KEYBORG_ENCODE_H */
diff --git a/board/keyborg/touch_scan.c b/board/keyborg/touch_scan.c
index 0728595c5a..9ea947eb43 100644
--- a/board/keyborg/touch_scan.c
+++ b/board/keyborg/touch_scan.c
@@ -9,6 +9,7 @@
#include "console.h"
#include "debug.h"
#include "dma.h"
+#include "encode.h"
#include "gpio.h"
#include "hooks.h"
#include "master_slave.h"
@@ -21,13 +22,7 @@
#define TS_PIN_TO_CR(p) ((((p).port_id + 1) << 16) | (1 << (p).pin))
#define TS_GPIO_TO_BASE(p) (0x40010800 + (p) * 0x400)
-/*
- * Storage for partial touch scan data. This will be smaller once
- * we figure out how to encode it.
- */
-static uint8_t touch_data[COL_COUNT + 10][ROW_COUNT * 2];
-
-static uint8_t buf[ROW_COUNT * 2];
+static uint8_t buf[2][ROW_COUNT * 2];
static uint32_t mccr_list[COL_COUNT];
static uint32_t mrcr_list[ROW_COUNT];
@@ -188,7 +183,7 @@ int touch_scan_full_matrix(void)
{
struct spi_comm_packet cmd;
const struct spi_comm_packet *resp;
- int col, row;
+ int col;
timestamp_t st = get_time();
uint8_t *dptr = NULL, *last_dptr = NULL;
@@ -198,6 +193,7 @@ int touch_scan_full_matrix(void)
if (spi_master_send_command(&cmd))
return EC_ERROR_UNKNOWN;
+ encode_reset();
for (col = 0; col < COL_COUNT * 2; ++col) {
if (col >= COL_COUNT) {
enable_col(col - COL_COUNT, 1);
@@ -208,10 +204,7 @@ int touch_scan_full_matrix(void)
return EC_ERROR_UNKNOWN;
last_dptr = dptr;
- if (col < COL_COUNT + 10)
- dptr = touch_data[col];
- else
- dptr = buf;
+ dptr = buf[col & 1];
scan_column(dptr + ROW_COUNT);
@@ -223,6 +216,7 @@ int touch_scan_full_matrix(void)
memcpy(last_dptr, resp->data, resp->size);
memset(last_dptr + resp->size, 0,
ROW_COUNT - resp->size);
+ encode_add_column(last_dptr);
}
if (master_slave_sync(20) != EC_SUCCESS)
@@ -243,20 +237,12 @@ int touch_scan_full_matrix(void)
return EC_ERROR_UNKNOWN;
memcpy(last_dptr, resp->data, resp->size);
memset(last_dptr + resp->size, 0, ROW_COUNT - resp->size);
+ encode_add_column(last_dptr);
master_slave_sync(20);
debug_printf("Sampling took %d us\n", get_time().val - st.val);
-
- for (row = 0; row < ROW_COUNT * 2; ++row) {
- for (col = 0; col < COL_COUNT + 10; ++col) {
- if (touch_data[col][row] < THRESHOLD)
- debug_printf(" - ");
- else
- debug_printf("%3d ", touch_data[col][row]);
- }
- debug_printf("\n");
- }
+ encode_dump_matrix();
return EC_SUCCESS;
}