diff options
author | Vic Yang <victoryang@chromium.org> | 2014-05-14 17:06:00 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-05-18 02:41:39 +0000 |
commit | 4cb6971dafd7efb3476dfc45aad60c321b99cd84 (patch) | |
tree | ed51d3baa7de5ab171b43cd27ac2779f038bddde | |
parent | 09ad49c2bdd3bf125f8753bb7fd920d15af28750 (diff) | |
download | chrome-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.mk | 1 | ||||
-rw-r--r-- | board/keyborg/encode.c | 114 | ||||
-rw-r--r-- | board/keyborg/encode.h | 20 | ||||
-rw-r--r-- | board/keyborg/touch_scan.c | 30 |
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; } |