summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMyles Watson <mylesgw@chromium.org>2014-12-04 17:13:20 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2014-12-31 00:01:41 +0000
commita8ccffded0a447c5fe2ad0e4fe97b05bbc8a3be0 (patch)
tree9e6e2d14e364d87cccbedb66aa123396778f7a21
parentce9a8a2dad8945ce225ab1387bec0fdb261be482 (diff)
downloadchrome-ec-a8ccffded0a447c5fe2ad0e4fe97b05bbc8a3be0.tar.gz
nrf51: Add nRF51-specific code to keyboard_raw.c
Use the PORT event for keyboard inputs. Make a column mask for driving all outputs at once. BUG=chrome-os-partner:34477 BRANCH=none TEST=Used hadoken and the Ryu base keyboard to check that the keys are all functional, that the keyboard polls while keys are held, and that it waits for interrupts when the keys are released. Signed-off-by: Myles Watson <mylesgw@chromium.org> Change-Id: Ie1dd1ca17b21ed76b2d412bf25fe87e45c5ba757 Reviewed-on: https://chromium-review.googlesource.com/234394 Reviewed-by: Randall Spangler <rspangler@chromium.org> Tested-by: Myles Watson <mylesgw@chromium.org> Commit-Queue: Myles Watson <mylesgw@chromium.org>
-rw-r--r--chip/nrf51/build.mk1
-rw-r--r--chip/nrf51/keyboard_raw.c108
2 files changed, 28 insertions, 81 deletions
diff --git a/chip/nrf51/build.mk b/chip/nrf51/build.mk
index 6769049f06..ddfa46b078 100644
--- a/chip/nrf51/build.mk
+++ b/chip/nrf51/build.mk
@@ -15,3 +15,4 @@ chip-y+=jtag.o watchdog.o
chip-$(CONFIG_COMMON_TIMER)+=hwtimer.o clock.o
chip-$(CONFIG_I2C)+=i2c.o
+chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
diff --git a/chip/nrf51/keyboard_raw.c b/chip/nrf51/keyboard_raw.c
index 4ac7f2dcb2..6db9840499 100644
--- a/chip/nrf51/keyboard_raw.c
+++ b/chip/nrf51/keyboard_raw.c
@@ -1,8 +1,8 @@
-/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+/* 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.
*
- * Raw keyboard I/O layer for STM32
+ * Raw keyboard I/O layer for nRF51
*
* To make this code portable, we rely heavily on looping over the keyboard
* input and output entries in the board's gpio_list[]. Each set of inputs or
@@ -19,103 +19,50 @@
#include "task.h"
#include "util.h"
-/* Mask of external interrupts on input lines */
-static unsigned int irq_mask;
+/* Mask of output pins for driving. */
+static unsigned int col_mask;
-static const uint32_t kb_out_ports[] = { KB_OUT_PORT_LIST };
-
-static void set_irq_mask(void)
+void keyboard_raw_init(void)
{
int i;
- for (i = GPIO_KB_IN00; i < GPIO_KB_IN00 + KEYBOARD_ROWS; i++)
- irq_mask |= gpio_list[i].mask;
-}
+ /* Initialize col_mask */
+ col_mask = 0;
+ for (i = 0; i < KEYBOARD_COLS; i++)
+ col_mask |= gpio_list[GPIO_KB_OUT00 + i].mask;
-void keyboard_raw_init(void)
-{
- /* Determine EXTI_PR mask to use for the board */
- set_irq_mask();
-
- /* Ensure interrupts are disabled in EXTI_PR */
+ /* Ensure interrupts are disabled */
keyboard_raw_enable_interrupt(0);
}
void keyboard_raw_task_start(void)
{
- /* Enable interrupts for keyboard matrix inputs */
+ /*
+ * Enable the interrupt for keyboard matrix inputs.
+ * One is enough, since they are shared.
+ */
gpio_enable_interrupt(GPIO_KB_IN00);
- gpio_enable_interrupt(GPIO_KB_IN01);
- gpio_enable_interrupt(GPIO_KB_IN02);
- gpio_enable_interrupt(GPIO_KB_IN03);
- gpio_enable_interrupt(GPIO_KB_IN04);
- gpio_enable_interrupt(GPIO_KB_IN05);
- gpio_enable_interrupt(GPIO_KB_IN06);
- gpio_enable_interrupt(GPIO_KB_IN07);
}
test_mockable void keyboard_raw_drive_column(int out)
{
- int i, done = 0;
-
- for (i = 0; i < ARRAY_SIZE(kb_out_ports); i++) {
- uint32_t bsrr = 0;
- int j;
-
- for (j = GPIO_KB_OUT00; j <= GPIO_KB_OUT12; j++) {
- if (gpio_list[j].port != kb_out_ports[i])
- continue;
-
- if (out == KEYBOARD_COLUMN_ALL) {
- /* drive low (clear bit) */
- bsrr |= gpio_list[j].mask << 16;
- } else if (out == KEYBOARD_COLUMN_NONE) {
- /* put output in hi-Z state (set bit) */
- bsrr |= gpio_list[j].mask;
- } else if (j - GPIO_KB_OUT00 == out) {
- /*
- * Drive specified output low, others => hi-Z.
- *
- * To avoid conflict, tri-state all outputs
- * first, then assert specified output.
- */
- keyboard_raw_drive_column(KEYBOARD_COLUMN_NONE);
- bsrr |= gpio_list[j].mask << 16;
- done = 1;
- break;
- }
- }
-
- #ifdef CONFIG_KEYBOARD_COL2_INVERTED
- if (bsrr & (gpio_list[GPIO_KB_OUT02].mask << 16 |
- gpio_list[GPIO_KB_OUT02].mask))
- bsrr ^= (gpio_list[GPIO_KB_OUT02].mask << 16 |
- gpio_list[GPIO_KB_OUT02].mask);
- #endif
-
- if (bsrr)
- STM32_GPIO_BSRR(kb_out_ports[i]) = bsrr;
-
- if (done)
- break;
- }
+ /* tri-state all first */
+ NRF51_GPIO0_OUTSET = col_mask;
+
+ /* drive low for specified pin(s) */
+ if (out == KEYBOARD_COLUMN_ALL)
+ NRF51_GPIO0_OUTCLR = col_mask;
+ else if (out != KEYBOARD_COLUMN_NONE)
+ NRF51_GPIO0_OUTCLR = gpio_list[GPIO_KB_OUT00 + out].mask;
}
test_mockable int keyboard_raw_read_rows(void)
{
int i;
- unsigned int port, prev_port = 0;
int state = 0;
- uint16_t port_val = 0;
for (i = 0; i < KEYBOARD_ROWS; i++) {
- port = gpio_list[GPIO_KB_IN00 + i].port;
- if (port != prev_port) {
- port_val = STM32_GPIO_IDR(port);
- prev_port = port;
- }
-
- if (port_val & gpio_list[GPIO_KB_IN00 + i].mask)
+ if (NRF51_GPIO0_IN & gpio_list[GPIO_KB_IN00 + i].mask)
state |= 1 << i;
}
@@ -127,13 +74,12 @@ void keyboard_raw_enable_interrupt(int enable)
{
if (enable) {
/*
- * Assert all outputs would trigger un-wanted interrupts.
- * Clear them before enable interrupt.
+ * Clear the PORT event before enabling the interrupt.
*/
- STM32_EXTI_PR |= irq_mask;
- STM32_EXTI_IMR |= irq_mask; /* 1: unmask interrupt */
+ NRF51_GPIOTE_PORT = 0;
+ NRF51_GPIOTE_INTENSET = 1 << NRF51_GPIOTE_PORT_BIT;
} else {
- STM32_EXTI_IMR &= ~irq_mask; /* 0: mask interrupts */
+ NRF51_GPIOTE_INTENCLR = 1 << NRF51_GPIOTE_PORT_BIT;
}
}