mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 01:50:53 +00:00
Keyborg: implement methods needed for touch wake
In order to wake the chips from STOP/SLEEP mode with a touch, we need to put the two chips in correct state before going into STOP/SLEEP mode. Also, when one of the chips wakes up, it needs to wake the other chip with GPIO interrupt. This CL implements the necessary methods and also adds a sample routine that put the chips in STOP mode and wait for a touch using the implemented methods. BUG=None TEST=Build and boot. Touch the panel and see the response in console. BRANCH=None Change-Id: Ia5f7df8b550ee2459bcae1840f8a2717c8d947ce Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/204482 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
6c8e451ff0
commit
94acd01e0c
@@ -5,6 +5,7 @@
|
||||
/* Keyborg board-specific configuration */
|
||||
|
||||
#include "common.h"
|
||||
#include "cpu.h"
|
||||
#include "debug.h"
|
||||
#include "master_slave.h"
|
||||
#include "registers.h"
|
||||
@@ -130,6 +131,27 @@ static const char *get_version(void)
|
||||
return version_data.version;
|
||||
}
|
||||
|
||||
static void low_power(void)
|
||||
{
|
||||
touch_scan_enable_interrupt();
|
||||
master_slave_enable_interrupt();
|
||||
|
||||
CPU_SCB_SYSCTRL |= 0x4;
|
||||
asm volatile("wfi");
|
||||
CPU_SCB_SYSCTRL &= ~0x4;
|
||||
|
||||
hardware_clock_init();
|
||||
|
||||
touch_scan_disable_interrupt();
|
||||
master_slave_disable_interrupt();
|
||||
master_slave_wake_other();
|
||||
|
||||
/* Wait for the other chip to wake */
|
||||
udelay(2 * MSEC);
|
||||
|
||||
master_slave_sync(5);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -151,6 +173,10 @@ int main(void)
|
||||
|
||||
master_slave_sync(100);
|
||||
|
||||
debug_printf("Touch to start...");
|
||||
low_power();
|
||||
debug_printf("\n");
|
||||
|
||||
while (1) {
|
||||
i++;
|
||||
task_wait_event(SECOND);
|
||||
|
||||
@@ -41,6 +41,9 @@ enum gpio_signal;
|
||||
/* Initialize all useful registers */
|
||||
void hardware_init(void);
|
||||
|
||||
/* Re-initialize clock */
|
||||
void hardware_clock_init(void);
|
||||
|
||||
/* On the master, reboot both chips. On the slave, reboot itself. */
|
||||
void system_reboot(void);
|
||||
|
||||
|
||||
@@ -9,4 +9,7 @@
|
||||
*/
|
||||
|
||||
ENABLE_IRQ(STM32_IRQ_EXTI0)
|
||||
ENABLE_IRQ(STM32_IRQ_EXTI1)
|
||||
ENABLE_IRQ(STM32_IRQ_EXTI2)
|
||||
ENABLE_IRQ(STM32_IRQ_EXTI3)
|
||||
ENABLE_IRQ(STM32_IRQ_TIM2)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "touch_scan.h"
|
||||
#include "util.h"
|
||||
|
||||
static void clock_init(void)
|
||||
void hardware_clock_init(void)
|
||||
{
|
||||
/* Turn on HSE */
|
||||
if (!(STM32_RCC_CR & (1 << 17))) {
|
||||
@@ -183,7 +183,7 @@ static void pmse_init(void)
|
||||
void hardware_init(void)
|
||||
{
|
||||
power_init();
|
||||
clock_init();
|
||||
hardware_clock_init();
|
||||
pins_init();
|
||||
timers_init();
|
||||
adc_init();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "debug.h"
|
||||
#include "master_slave.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -55,6 +56,55 @@ int master_slave_sync_impl(const char *filename, int line, int timeout_ms)
|
||||
return err;
|
||||
}
|
||||
|
||||
void master_slave_enable_interrupt(void)
|
||||
{
|
||||
if (is_master) {
|
||||
/* Interrupt on EXTI2 on port I */
|
||||
STM32_EXTI_RTSR |= 1 << 2;
|
||||
STM32_AFIO_EXTICR(0) = (STM32_AFIO_EXTICR(0) & ~0xf00) |
|
||||
(8 << 8);
|
||||
STM32_EXTI_IMR |= 1 << 2;
|
||||
task_clear_pending_irq(STM32_IRQ_EXTI2);
|
||||
task_enable_irq(STM32_IRQ_EXTI2);
|
||||
} else {
|
||||
/* Interrupt on EXTI1 on port I */
|
||||
STM32_EXTI_RTSR |= 1 << 1;
|
||||
STM32_AFIO_EXTICR(0) = (STM32_AFIO_EXTICR(0) & ~0xf0) |
|
||||
(8 << 4);
|
||||
STM32_EXTI_IMR |= 1 << 1;
|
||||
task_clear_pending_irq(STM32_IRQ_EXTI1);
|
||||
task_enable_irq(STM32_IRQ_EXTI1);
|
||||
}
|
||||
}
|
||||
|
||||
void master_slave_disable_interrupt(void)
|
||||
{
|
||||
if (is_master)
|
||||
task_disable_irq(STM32_IRQ_EXTI2);
|
||||
else
|
||||
task_disable_irq(STM32_IRQ_EXTI1);
|
||||
}
|
||||
|
||||
void master_slave_wake_other(void)
|
||||
{
|
||||
if (is_master) {
|
||||
STM32_GPIO_BSRR(GPIO_I) = SYNC1 << 0;
|
||||
udelay(MSEC);
|
||||
STM32_GPIO_BSRR(GPIO_I) = SYNC1 << 16;
|
||||
} else {
|
||||
STM32_GPIO_BSRR(GPIO_I) = SYNC2 << 0;
|
||||
udelay(MSEC);
|
||||
STM32_GPIO_BSRR(GPIO_I) = SYNC2 << 16;
|
||||
}
|
||||
}
|
||||
|
||||
void master_slave_interrupt(void)
|
||||
{
|
||||
STM32_EXTI_PR = STM32_EXTI_PR;
|
||||
}
|
||||
DECLARE_IRQ(STM32_IRQ_EXTI1, master_slave_interrupt, 1);
|
||||
DECLARE_IRQ(STM32_IRQ_EXTI2, master_slave_interrupt, 1);
|
||||
|
||||
static int master_handshake(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
@@ -28,6 +28,17 @@ int master_slave_is_master(void);
|
||||
master_slave_sync_impl(__FILE__, __LINE__, timeout_ms)
|
||||
int master_slave_sync_impl(const char *filename, int line, int timeout_ms);
|
||||
|
||||
/**
|
||||
* Enable/disable master-slave interrupt. Master-slave interrupt is
|
||||
* implemented using SYNC1/SYNC2 signal, so this is assuming the master
|
||||
* and the slave are in sync waiting for interrupt.
|
||||
*/
|
||||
void master_slave_enable_interrupt(void);
|
||||
void master_slave_disable_interrupt(void);
|
||||
|
||||
/* Interrupt the other chip with a 1-ms pulse. */
|
||||
void master_slave_wake_other(void);
|
||||
|
||||
/**
|
||||
* Identify this chip and shake hands with the other chip.
|
||||
*
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "cpu.h"
|
||||
#include "debug.h"
|
||||
#include "dma.h"
|
||||
#include "encode.h"
|
||||
@@ -15,6 +16,7 @@
|
||||
#include "master_slave.h"
|
||||
#include "registers.h"
|
||||
#include "spi_comm.h"
|
||||
#include "task.h"
|
||||
#include "timer.h"
|
||||
#include "touch_scan.h"
|
||||
#include "util.h"
|
||||
@@ -61,6 +63,8 @@ static void set_gpio(const struct ts_pin pin, enum pin_type type)
|
||||
} else if (type == PIN_PD) {
|
||||
mask |= 0x88888888 & mode;
|
||||
STM32_GPIO_BSRR(port) = pmask << 16;
|
||||
} else if (type == PIN_Z) {
|
||||
mask |= 0x44444444 & mode;
|
||||
} else if (type == PIN_ROW) {
|
||||
/* Nothing for PIN_ROW. Already analog input. */
|
||||
}
|
||||
@@ -73,7 +77,7 @@ void touch_scan_init(void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ROW_COUNT; ++i) {
|
||||
set_gpio(col_pins[i], PIN_ROW);
|
||||
set_gpio(row_pins[i], PIN_ROW);
|
||||
STM32_PMSE_PxPMR(row_pins[i].port_id) |= 1 << row_pins[i].pin;
|
||||
}
|
||||
for (i = 0; i < COL_COUNT; ++i)
|
||||
@@ -85,6 +89,47 @@ void touch_scan_init(void)
|
||||
mccr_list[i] = TS_PIN_TO_CR(col_pins[i]);
|
||||
}
|
||||
|
||||
void touch_scan_enable_interrupt(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Set ALLROW and ALLCOL */
|
||||
for (i = 0; i < ROW_COUNT; ++i)
|
||||
set_gpio(row_pins[i], PIN_Z);
|
||||
for (i = 0; i < COL_COUNT; ++i) {
|
||||
set_gpio(col_pins[i], PIN_COL);
|
||||
STM32_PMSE_PxPMR(col_pins[i].port_id) |= 1 << col_pins[i].pin;
|
||||
}
|
||||
STM32_PMSE_MCCR = (1 << 31) | (0 << 20);
|
||||
STM32_PMSE_MRCR = 1 << 31;
|
||||
|
||||
/* Enable external interrupt. EXTI3 on port E. Rising edge */
|
||||
STM32_EXTI_RTSR |= 1 << 3;
|
||||
STM32_AFIO_EXTICR(0) = (STM32_AFIO_EXTICR(0) & ~0xf000) | (4 << 12);
|
||||
STM32_EXTI_IMR |= 1 << 3;
|
||||
task_clear_pending_irq(STM32_IRQ_EXTI3);
|
||||
task_enable_irq(STM32_IRQ_EXTI3);
|
||||
}
|
||||
|
||||
void touch_scan_disable_interrupt(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ROW_COUNT; ++i)
|
||||
set_gpio(row_pins[i], PIN_ROW);
|
||||
for (i = 0; i < COL_COUNT; ++i) {
|
||||
set_gpio(col_pins[i], PIN_PD);
|
||||
STM32_PMSE_PxPMR(col_pins[i].port_id) &=
|
||||
~(1 << col_pins[i].pin);
|
||||
}
|
||||
}
|
||||
|
||||
void touch_scan_interrupt(void)
|
||||
{
|
||||
STM32_EXTI_PR = STM32_EXTI_PR;
|
||||
}
|
||||
DECLARE_IRQ(STM32_IRQ_EXTI3, touch_scan_interrupt, 1);
|
||||
|
||||
static void discharge(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -12,6 +12,7 @@ enum pin_type {
|
||||
PIN_ROW,
|
||||
PIN_COL,
|
||||
PIN_PD,
|
||||
PIN_Z,
|
||||
};
|
||||
|
||||
/* 8-bit window */
|
||||
@@ -55,10 +56,22 @@ extern const struct ts_pin col_pins[];
|
||||
#define ROW_COUNT 41
|
||||
#define COL_COUNT 60
|
||||
|
||||
/* Initialize touch scan module */
|
||||
void touch_scan_init(void);
|
||||
|
||||
/* Start scanning on the slave. This is called by SPI command handler. */
|
||||
void touch_scan_slave_start(void);
|
||||
|
||||
/**
|
||||
* Initiate full matrix scan on the master. This also sends SPI command
|
||||
* to the slave.
|
||||
*/
|
||||
int touch_scan_full_matrix(void);
|
||||
|
||||
/* Configure touch scan module to interrupt on touch. */
|
||||
void touch_scan_enable_interrupt(void);
|
||||
|
||||
/* Disable touch scan interrupt. */
|
||||
void touch_scan_disable_interrupt(void);
|
||||
|
||||
#endif /* __BOARD_KEYBORG_TOUCH_SCAN_H */
|
||||
|
||||
Reference in New Issue
Block a user