samples: drivers: ps2: Add PS/2 driver sample app
This app illustrates a command sequence to enable PS/2 mouse Signed-off-by: Francisco Munoz <francisco.munoz.ruiz@intel.com>
This commit is contained in:
parent
20748fbb1b
commit
bf6791ee78
6 changed files with 239 additions and 0 deletions
8
samples/drivers/ps2/CMakeLists.txt
Normal file
8
samples/drivers/ps2/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.13.1)
|
||||
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
|
||||
project(espi)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
26
samples/drivers/ps2/README.rst
Normal file
26
samples/drivers/ps2/README.rst
Normal file
|
@ -0,0 +1,26 @@
|
|||
.. ps2-sample:
|
||||
|
||||
PS/2 Interface
|
||||
####################################
|
||||
|
||||
Overview
|
||||
********
|
||||
|
||||
This sample demonstrates how to use the :ref:`PS/2 API <ps2>`.
|
||||
Callbacks are registered that will write to the console indicating PS2 events.
|
||||
These events indicate mouse configuration responses and mouse interaction.
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
The sample can be built and executed on boards supporting PS/2.
|
||||
Please connect a PS/2 mouse in order to exercise the functionality.
|
||||
|
||||
Sample output
|
||||
=============
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
PS/2 test with mouse
|
||||
Note: You are expected to see several interrupts
|
||||
as you configure/move the mouse!
|
4
samples/drivers/ps2/prj.conf
Normal file
4
samples/drivers/ps2/prj.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
CONFIG_STDOUT_CONSOLE=y
|
||||
CONFIG_PRINTK=y
|
||||
CONFIG_PS2=y
|
||||
|
4
samples/drivers/ps2/prj_mec15xxevb_assy6853.conf
Normal file
4
samples/drivers/ps2/prj_mec15xxevb_assy6853.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
# PS2 + mec15xxevb_assy6853
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_PS2=y
|
12
samples/drivers/ps2/sample.yaml
Normal file
12
samples/drivers/ps2/sample.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
sample:
|
||||
name: PS2 driver sample
|
||||
tests:
|
||||
sample.driver.espi:
|
||||
tags: drivers
|
||||
harness: console
|
||||
harness_config:
|
||||
type: multi_line
|
||||
ordered: true
|
||||
regex:
|
||||
- "mb data(.*)"
|
||||
depends_on: ps2
|
185
samples/drivers/ps2/src/main.c
Normal file
185
samples/drivers/ps2/src/main.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr.h>
|
||||
#include <misc/printk.h>
|
||||
#include <ps2.h>
|
||||
#include <soc.h>
|
||||
#define LOG_LEVEL LOG_LEVEL_DBG
|
||||
#include <logging/log.h>
|
||||
#define LOG_MODULE_NAME main
|
||||
|
||||
LOG_MODULE_REGISTER();
|
||||
|
||||
#define TASK_STACK_SIZE 1024
|
||||
#define PRIORITY 7
|
||||
/*Minimum safe time invertal between regular PS/2 calls */
|
||||
#define MS_BETWEEN_REGULAR_CALLS 8
|
||||
/*Minimum safe time invertal between BAT/Reset PS/2 calls */
|
||||
#define MS_BETWEEN_RESET_CALLS 500
|
||||
|
||||
static void to_port_60_thread(void *dummy1, void *dummy2, void *dummy3);
|
||||
static void saturate_ps2(struct k_timer *timer);
|
||||
static bool host_blocked;
|
||||
|
||||
K_THREAD_DEFINE(aux_thread_id, TASK_STACK_SIZE, to_port_60_thread,
|
||||
NULL, NULL, NULL, PRIORITY, 0, K_NO_WAIT);
|
||||
K_SEM_DEFINE(p60_sem, 0, 1);
|
||||
K_MSGQ_DEFINE(aux_to_host_queue, sizeof(u8_t), 8, 4);
|
||||
|
||||
/* We use a timer to saturate the queue */
|
||||
K_TIMER_DEFINE(block_ps2_timer, saturate_ps2, NULL);
|
||||
|
||||
static struct device *ps2_0_dev;
|
||||
|
||||
static void saturate_ps2(struct k_timer *timer)
|
||||
{
|
||||
LOG_DBG("block host\n");
|
||||
host_blocked = true;
|
||||
ps2_disable_callback(ps2_0_dev);
|
||||
k_sleep(500);
|
||||
host_blocked = false;
|
||||
ps2_enable_callback(ps2_0_dev);
|
||||
}
|
||||
|
||||
static void mb_callback(struct device *dev, u8_t value)
|
||||
{
|
||||
if (k_msgq_put(&aux_to_host_queue, &value, K_NO_WAIT) != 0) {
|
||||
ps2_disable_callback(ps2_0_dev);
|
||||
}
|
||||
|
||||
if (!host_blocked) {
|
||||
k_sem_give(&p60_sem);
|
||||
}
|
||||
}
|
||||
|
||||
/* This data is sent to BIOS and eventually is consumed by the host OS */
|
||||
static void to_port_60_thread(void *dummy1, void *dummy2, void *dummy3)
|
||||
{
|
||||
u8_t data;
|
||||
|
||||
while (true) {
|
||||
k_sem_take(&p60_sem, K_FOREVER);
|
||||
while (!k_msgq_get(&aux_to_host_queue, &data, K_NO_WAIT)) {
|
||||
LOG_DBG("\nmb data :%02x\n", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Commands expected from BIOS and Windows */
|
||||
void initialize_mouse(void)
|
||||
{
|
||||
LOG_DBG("mouse->f4\n");
|
||||
ps2_write(ps2_0_dev, 0xf4);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Reset mouse->ff\n");
|
||||
ps2_write(ps2_0_dev, 0xff);
|
||||
k_sleep(MS_BETWEEN_RESET_CALLS);
|
||||
LOG_DBG("Reset mouse->ff\n");
|
||||
ps2_write(ps2_0_dev, 0xff);
|
||||
k_sleep(MS_BETWEEN_RESET_CALLS);
|
||||
LOG_DBG("Read ID mouse->f2\n");
|
||||
ps2_write(ps2_0_dev, 0xf2);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set resolution mouse->e8\n");
|
||||
ps2_write(ps2_0_dev, 0xe8);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("mouse->00\n");
|
||||
ps2_write(ps2_0_dev, 0x00);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set scaling 1:1 mouse->e6\n");
|
||||
ps2_write(ps2_0_dev, 0xe6);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set scaling 1:1 mouse->e6\n");
|
||||
ps2_write(ps2_0_dev, 0xe6);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set scaling 1:1 mouse->e6\n");
|
||||
ps2_write(ps2_0_dev, 0xe6);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("mouse->e9\n");
|
||||
ps2_write(ps2_0_dev, 0xe9);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set resolution mouse->e8\n");
|
||||
ps2_write(ps2_0_dev, 0xe8);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("8 Counts/mm mouse->0x03\n");
|
||||
ps2_write(ps2_0_dev, 0x03);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 200 ->0xc8\n");
|
||||
ps2_write(ps2_0_dev, 0xc8);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 100 ->0x64\n");
|
||||
ps2_write(ps2_0_dev, 0x64);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 80 ->0x50\n");
|
||||
ps2_write(ps2_0_dev, 0x50);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Read device type->0xf2\n");
|
||||
ps2_write(ps2_0_dev, 0xf2);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 200 ->0xc8\n");
|
||||
ps2_write(ps2_0_dev, 0xc8);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 200 ->0xc8\n");
|
||||
ps2_write(ps2_0_dev, 0xc8);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 80 ->0x50\n");
|
||||
ps2_write(ps2_0_dev, 0x50);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Read device type->0xf2\n");
|
||||
ps2_write(ps2_0_dev, 0xf2);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set sample rate mouse->0xF3\n");
|
||||
ps2_write(ps2_0_dev, 0xf3);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("decimal 100 ->0x64\n");
|
||||
ps2_write(ps2_0_dev, 0x64);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("Set resolution mouse->e8\n");
|
||||
ps2_write(ps2_0_dev, 0xe8);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("8 Counts/mm mouse->0x03\n");
|
||||
ps2_write(ps2_0_dev, 0x03);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
LOG_DBG("mouse->f4\n");
|
||||
ps2_write(ps2_0_dev, 0xf4);
|
||||
k_sleep(MS_BETWEEN_REGULAR_CALLS);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
printk("PS/2 test with mouse\n");
|
||||
/* Wait for the PS/2 BAT to finish */
|
||||
k_sleep(MS_BETWEEN_RESET_CALLS);
|
||||
|
||||
/* The ps2 blocks are generic, therefore, it is allowed to swap
|
||||
* keybaord and mouse as deired
|
||||
*/
|
||||
#ifdef CONFIG_PS2_XEC_0
|
||||
ps2_0_dev = device_get_binding(DT_PS2_XEC_0_LABEL);
|
||||
ps2_config(ps2_0_dev, mb_callback);
|
||||
/*Make sure there is a PS/2 device connected */
|
||||
initialize_mouse();
|
||||
#endif
|
||||
k_timer_start(&block_ps2_timer, K_SECONDS(2), K_SECONDS(1));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue