mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 01:21:49 +00:00
Merge "Use common host command processing for Daisy I2C"
This commit is contained in:
@@ -17,6 +17,9 @@
|
||||
/* support programming on-chip flash */
|
||||
#define CONFIG_FLASH
|
||||
|
||||
/* use I2C for host communication */
|
||||
#define CONFIG_I2C
|
||||
|
||||
/* By default, enable all console messages except keyboard */
|
||||
#define CC_DEFAULT (CC_ALL & ~CC_MASK(CC_KEYSCAN))
|
||||
|
||||
|
||||
@@ -18,5 +18,4 @@
|
||||
TASK(KEYSCAN, keyboard_scan_task, NULL) \
|
||||
TASK(GAIAPOWER, gaia_power_task, NULL) \
|
||||
TASK(CONSOLE, console_task, NULL) \
|
||||
TASK(SPI_WORK, spi_work_task, NULL) \
|
||||
TASK(I2C2_WORK, i2c2_work_task, NULL)
|
||||
TASK(HOSTCMD, host_command_task, NULL)
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
/* Use USART1 as console serial port */
|
||||
#define CONFIG_CONSOLE_UART 1
|
||||
|
||||
/* use I2C for host communication */
|
||||
#define CONFIG_I2C
|
||||
|
||||
#define USB_CHARGE_PORT_COUNT 0
|
||||
|
||||
/* EC drives 13 outputs to keyboard matrix */
|
||||
|
||||
@@ -18,5 +18,4 @@
|
||||
TASK(KEYSCAN, keyboard_scan_task, NULL) \
|
||||
TASK(GAIAPOWER, gaia_power_task, NULL) \
|
||||
TASK(CONSOLE, console_task, NULL) \
|
||||
TASK(SPI_WORK, spi_work_task, NULL) \
|
||||
TASK(I2C2_WORK, i2c2_work_task, NULL)
|
||||
TASK(HOSTCMD, host_command_task, NULL)
|
||||
|
||||
@@ -11,8 +11,8 @@ CORE:=cortex-m
|
||||
|
||||
chip-y=dma.o gpio.o hwtimer.o system.o uart.o
|
||||
chip-y+=jtag-$(CHIP_VARIANT).o clock-$(CHIP_VARIANT).o gpio-$(CHIP_VARIANT).o
|
||||
chip-$(CONFIG_TASK_SPI_WORK)+=spi.o
|
||||
chip-$(CONFIG_TASK_I2C2_WORK)+=i2c.o
|
||||
chip-$(CONFIG_SPI)+=spi.o
|
||||
chip-$(CONFIG_I2C)+=i2c.o
|
||||
chip-$(CONFIG_TASK_WATCHDOG)+=watchdog.o
|
||||
chip-$(CONFIG_TASK_KEYSCAN)+=keyboard_scan.o
|
||||
chip-$(CONFIG_FLASH)+=flash-$(CHIP_VARIANT).o
|
||||
|
||||
178
chip/stm32/i2c.c
178
chip/stm32/i2c.c
@@ -6,12 +6,14 @@
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "ec_commands.h"
|
||||
#include "gpio.h"
|
||||
#include "hooks.h"
|
||||
#include "host_command.h"
|
||||
#include "i2c.h"
|
||||
#include "message.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Console output macros */
|
||||
#define CPUTS(outstr) cputs(CC_I2C, outstr)
|
||||
@@ -30,35 +32,15 @@
|
||||
#define I2C1 STM32_I2C1_PORT
|
||||
#define I2C2 STM32_I2C2_PORT
|
||||
|
||||
static task_id_t task_waiting_on_port[NUM_PORTS];
|
||||
static struct mutex port_mutex[NUM_PORTS];
|
||||
|
||||
static uint16_t i2c_sr1[NUM_PORTS];
|
||||
|
||||
/* per-transaction counters */
|
||||
static unsigned int tx_byte_count;
|
||||
static unsigned int rx_byte_count;
|
||||
/* buffer for host commands (including error code and checksum) */
|
||||
static uint8_t host_buffer[EC_PARAM_SIZE + 2];
|
||||
|
||||
/*
|
||||
* i2c_xmit_mode determines what EC sends when AP initiates a
|
||||
* read transaction. If AP has not set a transmit mode, then
|
||||
* default to NOP.
|
||||
*/
|
||||
static enum message_cmd_t i2c_xmit_mode[NUM_PORTS] = { CMDC_NOP, CMDC_NOP };
|
||||
/* current position in host buffer for reception */
|
||||
static int rx_index;
|
||||
|
||||
/*
|
||||
* Our output buffers. These must be large enough for our largest message,
|
||||
* including protocol overhead.
|
||||
*/
|
||||
static uint8_t out_msg[32];
|
||||
|
||||
|
||||
static void wait_rx(int port)
|
||||
{
|
||||
/* TODO: Add timeouts and error checking for safety */
|
||||
while (!(STM32_I2C_SR1(port) & (1 << 6)))
|
||||
;
|
||||
}
|
||||
|
||||
static void wait_tx(int port)
|
||||
{
|
||||
@@ -67,71 +49,59 @@ static void wait_tx(int port)
|
||||
;
|
||||
}
|
||||
|
||||
static int i2c_read_raw(int port, void *buf, int len)
|
||||
{
|
||||
int i;
|
||||
uint8_t *data = buf;
|
||||
|
||||
mutex_lock(&port_mutex[port]);
|
||||
rx_byte_count = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
wait_rx(port);
|
||||
data[i] = STM32_I2C_DR(port);
|
||||
rx_byte_count++;
|
||||
}
|
||||
mutex_unlock(&port_mutex[port]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int i2c_write_raw(int port, void *buf, int len)
|
||||
{
|
||||
int i;
|
||||
uint8_t *data = buf;
|
||||
|
||||
mutex_lock(&port_mutex[port]);
|
||||
tx_byte_count = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
tx_byte_count++;
|
||||
STM32_I2C_DR(port) = data[i];
|
||||
wait_tx(port);
|
||||
}
|
||||
mutex_unlock(&port_mutex[port]);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void i2c2_work_task(void)
|
||||
static void _send_result(int slot, int result, int size)
|
||||
{
|
||||
int msg_len;
|
||||
uint16_t tmp16;
|
||||
task_waiting_on_port[1] = task_get_current();
|
||||
int i;
|
||||
int len = 1;
|
||||
uint8_t sum = 0;
|
||||
|
||||
while (1) {
|
||||
task_wait_event(-1);
|
||||
tmp16 = i2c_sr1[I2C2];
|
||||
if (tmp16 & (1 << 6)) {
|
||||
/* RxNE; AP issued write command */
|
||||
i2c_read_raw(I2C2, &i2c_xmit_mode[I2C2], 1);
|
||||
#ifdef CONFIG_DEBUG
|
||||
CPRINTF("%s: i2c2_xmit_mode: %02x\n",
|
||||
__func__, i2c_xmit_mode[I2C2]);
|
||||
#endif
|
||||
} else if (tmp16 & (1 << 7)) {
|
||||
/* RxE; AP is waiting for EC response */
|
||||
msg_len = message_process_cmd(i2c_xmit_mode[I2C2],
|
||||
out_msg, sizeof(out_msg));
|
||||
if (msg_len > 0) {
|
||||
i2c_write_raw(I2C2, out_msg, msg_len);
|
||||
} else {
|
||||
CPRINTF("%s: unexpected mode %u\n",
|
||||
__func__, i2c_xmit_mode[I2C2]);
|
||||
}
|
||||
|
||||
/* reset EC mode to NOP after transfer is finished */
|
||||
i2c_xmit_mode[I2C2] = CMDC_NOP;
|
||||
}
|
||||
ASSERT(slot == 0);
|
||||
/* record the error code */
|
||||
host_buffer[0] = result;
|
||||
if (size) {
|
||||
/* compute checksum */
|
||||
for (i = 1; i <= size; i++)
|
||||
sum += host_buffer[i];
|
||||
host_buffer[size + 1] = sum;
|
||||
len = size + 2;
|
||||
}
|
||||
|
||||
/* send the answer to the AP */
|
||||
i2c_write_raw(I2C2, host_buffer, len);
|
||||
}
|
||||
|
||||
void host_send_result(int slot, int result)
|
||||
{
|
||||
_send_result(slot, result, 0);
|
||||
}
|
||||
|
||||
void host_send_response(int slot, const uint8_t *data, int size)
|
||||
{
|
||||
uint8_t *out = host_get_buffer(slot);
|
||||
|
||||
if (data != out)
|
||||
memcpy(out, data, size);
|
||||
|
||||
_send_result(slot, EC_RES_SUCCESS, size);
|
||||
}
|
||||
|
||||
uint8_t *host_get_buffer(int slot)
|
||||
{
|
||||
ASSERT(slot == 0);
|
||||
return host_buffer + 1 /* skip room for error code */;
|
||||
}
|
||||
|
||||
static void i2c_event_handler(int port)
|
||||
@@ -146,32 +116,35 @@ static void i2c_event_handler(int port)
|
||||
/* cleared by reading SR1 followed by reading SR2 */
|
||||
STM32_I2C_SR1(port);
|
||||
STM32_I2C_SR2(port);
|
||||
#ifdef CONFIG_DEBUG
|
||||
CPRINTF("%s: ADDR\n", __func__);
|
||||
#endif
|
||||
} else if (i2c_sr1[port] & (1 << 2)) {
|
||||
;
|
||||
#ifdef CONFIG_DEBUG
|
||||
CPRINTF("%s: BTF\n", __func__);
|
||||
#endif
|
||||
} else if (i2c_sr1[port] & (1 << 4)) {
|
||||
/* clear STOPF bit by reading SR1 and then writing CR1 */
|
||||
STM32_I2C_SR1(port);
|
||||
STM32_I2C_CR1(port) = STM32_I2C_CR1(port);
|
||||
#ifdef CONFIG_DEBUG
|
||||
CPRINTF("%s: STOPF\n", __func__);
|
||||
#endif
|
||||
} else {
|
||||
;
|
||||
#ifdef CONFIG_DEBUG
|
||||
CPRINTF("%s: unknown event\n", __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* RxNE or TxE, wake the worker task */
|
||||
if (i2c_sr1[port] & ((1 << 6) | (1 << 7))) {
|
||||
if (port == I2C2)
|
||||
task_wake(TASK_ID_I2C2_WORK);
|
||||
/* RxNE event */
|
||||
if (i2c_sr1[port] & (1 << 6)) {
|
||||
if (port == I2C2) { /* AP issued write command */
|
||||
if (rx_index >= sizeof(host_buffer) - 1) {
|
||||
rx_index = 0;
|
||||
CPRINTF("I2C message too large\n");
|
||||
}
|
||||
host_buffer[rx_index++] = STM32_I2C_DR(I2C2);
|
||||
}
|
||||
}
|
||||
/* TxE event */
|
||||
if (i2c_sr1[port] & (1 << 7)) {
|
||||
if (port == I2C2) { /* AP is waiting for EC response */
|
||||
if (rx_index) {
|
||||
/* we have an available command : execute it */
|
||||
host_command_received(0, host_buffer[0]);
|
||||
/* reset host buffer after end of transfer */
|
||||
rx_index = 0;
|
||||
} else {
|
||||
/* spurious read : return dummy value */
|
||||
STM32_I2C_DR(port) = 0xec;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void i2c2_event_interrupt(void) { i2c_event_handler(I2C2); }
|
||||
@@ -185,13 +158,12 @@ static void i2c_error_handler(int port)
|
||||
if (i2c_sr1[port] & 1 << 10) {
|
||||
/* ACK failed (NACK); expected when AP reads final byte.
|
||||
* Software must clear AF bit. */
|
||||
CPRINTF("%s: AF detected\n", __func__);
|
||||
}
|
||||
CPRINTF("%s: tx byte count: %u, rx_byte_count: %u\n",
|
||||
__func__, tx_byte_count, rx_byte_count);
|
||||
CPRINTF("%s: I2C_SR1(%s): 0x%04x\n", __func__, port, i2c_sr1[port]);
|
||||
CPRINTF("%s: I2C_SR2(%s): 0x%04x\n",
|
||||
} else {
|
||||
CPRINTF("%s: I2C_SR1(%s): 0x%04x\n",
|
||||
__func__, port, i2c_sr1[port]);
|
||||
CPRINTF("%s: I2C_SR2(%s): 0x%04x\n",
|
||||
__func__, port, STM32_I2C_SR2(port));
|
||||
}
|
||||
#endif
|
||||
|
||||
STM32_I2C_SR1(port) &= ~0xdf00;
|
||||
@@ -201,8 +173,6 @@ DECLARE_IRQ(STM32_IRQ_I2C2_ER, i2c2_error_interrupt, 2);
|
||||
|
||||
static int i2c_init2(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* enable I2C2 clock */
|
||||
STM32_RCC_APB1ENR |= 1 << 22;
|
||||
|
||||
@@ -220,10 +190,6 @@ static int i2c_init2(void)
|
||||
/* clear status */
|
||||
STM32_I2C_SR1(I2C2) = 0;
|
||||
|
||||
/* No tasks are waiting on ports */
|
||||
for (i = 0; i < NUM_PORTS; i++)
|
||||
task_waiting_on_port[i] = TASK_ID_INVALID;
|
||||
|
||||
/* enable event and error interrupts */
|
||||
task_enable_irq(STM32_IRQ_I2C2_EV);
|
||||
task_enable_irq(STM32_IRQ_I2C2_ER);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "board.h"
|
||||
#include "console.h"
|
||||
#include "gpio.h"
|
||||
#include "host_command.h"
|
||||
#include "keyboard.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "registers.h"
|
||||
@@ -40,9 +41,6 @@ enum COL_INDEX {
|
||||
/* The keyboard state from the last read */
|
||||
static uint8_t raw_state[KB_OUTPUTS];
|
||||
|
||||
/* The keyboard state we will return when requested */
|
||||
static uint8_t saved_state[KB_OUTPUTS];
|
||||
|
||||
/* Mask with 1 bits only for keys that actually exist */
|
||||
static const uint8_t *actual_key_mask;
|
||||
|
||||
@@ -386,9 +384,23 @@ int keyboard_scan_recovery_pressed(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keyboard_get_scan(uint8_t **buffp, int max_bytes)
|
||||
static int keyboard_get_scan(uint8_t *data, int *resp_size)
|
||||
{
|
||||
kb_fifo_remove(saved_state);
|
||||
*buffp = saved_state;
|
||||
return KB_OUTPUTS;
|
||||
kb_fifo_remove(data);
|
||||
*resp_size = KB_OUTPUTS;
|
||||
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_MKBP_STATE, keyboard_get_scan);
|
||||
|
||||
static int keyboard_get_info(uint8_t *data, int *resp_size)
|
||||
{
|
||||
struct ec_response_mkbp_info *r = (struct ec_response_mkbp_info *)data;
|
||||
|
||||
r->rows = 8;
|
||||
r->cols = KB_OUTPUTS;
|
||||
|
||||
*resp_size = sizeof(struct ec_response_mkbp_info);
|
||||
return EC_RES_SUCCESS;
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_MKBP_INFO, keyboard_get_info);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Common files build
|
||||
#
|
||||
|
||||
common-y=main.o message.o util.o console.o uart_buffering.o
|
||||
common-y=main.o util.o console.o uart_buffering.o
|
||||
common-y+=memory_commands.o shared_mem.o system_common.o hooks.o
|
||||
common-y+=gpio_commands.o version.o
|
||||
common-$(CONFIG_BATTERY_ATL706486)+=battery_atl706486.o
|
||||
|
||||
@@ -106,6 +106,7 @@ static int host_command_read_test(uint8_t *data, int *resp_size)
|
||||
DECLARE_HOST_COMMAND(EC_CMD_READ_TEST, host_command_read_test);
|
||||
|
||||
|
||||
#ifdef CONFIG_LPC
|
||||
/* ACPI query event handler. Note that the returned value is NOT actually
|
||||
* an EC_RES enum; it's 0 if no event was pending, or the 1-based
|
||||
* index of the lowest bit which was set. */
|
||||
@@ -126,6 +127,7 @@ static int host_command_acpi_query_event(uint8_t *data, int *resp_size)
|
||||
}
|
||||
DECLARE_HOST_COMMAND(EC_CMD_ACPI_QUERY_EVENT,
|
||||
host_command_acpi_query_event);
|
||||
#endif
|
||||
|
||||
|
||||
/* Finds a command by command number. Returns the command structure, or NULL if
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* This handles incoming commands and provides responses.
|
||||
*
|
||||
* Copyright (c) 2012 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.
|
||||
*
|
||||
* EC <--> AP message handling.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "message.h"
|
||||
#include "keyboard_scan.h"
|
||||
#include "util.h"
|
||||
|
||||
/* EC ID */
|
||||
/* (TODO(dhendrix): Define this in board-specific code */
|
||||
static const char ec_id[] = "Google Chrome EC";
|
||||
|
||||
/* Protocol version (least significant byte in lowest byte position) */
|
||||
static const uint8_t proto_ver[] = { 1, 0, 0, 0 };
|
||||
|
||||
/**
|
||||
* Get the response to a given command
|
||||
*
|
||||
* @param cmd Command byte to respond to
|
||||
* @param buffp Buffer to use for data, or it can be updated to
|
||||
* point to a new buffer
|
||||
* @param max_len Number of bytes free at *buffp for the response.
|
||||
* If the supplied buffer is used, this size must not
|
||||
* be exceeded.
|
||||
* @return number of bytes in response (which is in *buffp), or -1 on error
|
||||
*/
|
||||
static int message_get_response(int cmd, uint8_t **buffp, int max_len)
|
||||
{
|
||||
/*
|
||||
* Invalid commands are ignored, just returning a stream of 0xff
|
||||
* bytes.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case CMDC_PROTO_VER:
|
||||
*buffp = (uint8_t *)proto_ver;
|
||||
return sizeof(proto_ver);
|
||||
case CMDC_NOP:
|
||||
return 0;
|
||||
case CMDC_ID:
|
||||
*buffp = (char *)ec_id;
|
||||
return sizeof(ec_id) - 1;
|
||||
#ifdef CONFIG_TASK_KEYSCAN
|
||||
case CMDC_KEY_STATE:
|
||||
return keyboard_get_scan(buffp, max_len);
|
||||
#endif
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int message_process_cmd(int cmd, uint8_t *out_msg, int max_len)
|
||||
{
|
||||
uint8_t *msg;
|
||||
int msg_len;
|
||||
int need_copy;
|
||||
int sum = 0;
|
||||
int i;
|
||||
|
||||
msg = out_msg;
|
||||
msg_len = message_get_response(cmd, &msg, max_len - MSG_PROTO_BYTES);
|
||||
if (msg_len < 0)
|
||||
return msg_len;
|
||||
|
||||
/*
|
||||
* We add MSG_PROTO_BYTES bytes of overhead: truncate the reply
|
||||
* if needed.
|
||||
*/
|
||||
if (msg_len + MSG_PROTO_BYTES > max_len)
|
||||
msg_len = max_len - MSG_PROTO_BYTES;
|
||||
ASSERT(msg_len >= 0 && msg_len < 0xffff);
|
||||
need_copy = msg != out_msg;
|
||||
ASSERT(!need_copy ||
|
||||
msg + msg_len < out_msg ||
|
||||
msg > out_msg + sizeof(out_msg));
|
||||
|
||||
for (i = 0; i < msg_len; i++) {
|
||||
if (need_copy)
|
||||
out_msg[i] = msg[i];
|
||||
sum += msg[i];
|
||||
}
|
||||
out_msg[i] = sum;
|
||||
|
||||
return msg_len + MSG_PROTO_BYTES;
|
||||
}
|
||||
@@ -8,6 +8,25 @@
|
||||
#ifndef __CROS_EC_COMMANDS_H
|
||||
#define __CROS_EC_COMMANDS_H
|
||||
|
||||
/* Protocol overview
|
||||
*
|
||||
* request: CMD [ P0 P1 P2 ... Pn S ]
|
||||
* response: ERR [ P0 P1 P2 ... Pn S ]
|
||||
*
|
||||
* where the bytes are defined as follow :
|
||||
* - CMD is the command code. (defined by EC_CMD_ constants)
|
||||
* - ERR is the error code. (defined by EC_RES_ constants)
|
||||
* - Px is the optional payload.
|
||||
* it is not sent if the error code is not success.
|
||||
* (defined by ec_params_ and ec_response_ structures)
|
||||
* - S is the checksum which is the sum of all payload bytes.
|
||||
*
|
||||
* On LPC, CMD and ERR are sent/received at EC_LPC_ADDR_KERNEL|USER_CMD
|
||||
* and the payloads are sent/received at EC_LPC_ADDR_KERNEL|USER_PARAM.
|
||||
* On I2C, all bytes are sent serially in the same message.
|
||||
*/
|
||||
|
||||
|
||||
/* During the development stage, the LPC bus has high error bit rate.
|
||||
* Using checksum can detect the error and trigger re-transmit.
|
||||
* FIXME: remove this after mass production.
|
||||
|
||||
@@ -16,21 +16,6 @@ int keyboard_scan_init(void);
|
||||
/* Returns non-zero if recovery key was pressed at boot. */
|
||||
int keyboard_scan_recovery_pressed(void);
|
||||
|
||||
/**
|
||||
* Get the scan data from the keyboard.
|
||||
*
|
||||
* This returns the results of the last keyboard scan, by pointing the
|
||||
* supplied buffer to it, and returning the number of bytes available.
|
||||
*
|
||||
* The supplied buffer can be used directly if required, but in that case
|
||||
* the number of bytes available is limited to 'max_bytes'.
|
||||
*
|
||||
* @param buffp Pointer to buffer to contain data
|
||||
* @param max_bytes Maximum number of bytes available in *buffp
|
||||
* @return number of bytes available, or -1 for error
|
||||
*/
|
||||
int keyboard_get_scan(uint8_t **buffp, int max_bytes);
|
||||
|
||||
/* clear any saved keyboard state (empty FIFO, etc) */
|
||||
void keyboard_clear_state(void);
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/* Copyright (c) 2012 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.
|
||||
*/
|
||||
|
||||
#ifndef __MESSAGE_IF_H
|
||||
#define __MESSAGE_IF_H
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* Command interface between EC and AP */
|
||||
|
||||
enum {
|
||||
MSG_TRAILER_BYTES = 1,
|
||||
MSG_PROTO_BYTES = MSG_TRAILER_BYTES,
|
||||
};
|
||||
|
||||
/* The command codes that we understand */
|
||||
enum message_cmd_t {
|
||||
/* EC control/status messages */
|
||||
CMDC_PROTO_VER = 0x00, /* Protocol version */
|
||||
CMDC_NOP, /* No operation / ping */
|
||||
CMDC_ID, /* Read EC ID */
|
||||
|
||||
/* Functional messages */
|
||||
CMDC_KEY_STATE = 0x20, /* Read key state */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Process a command received and return the response
|
||||
*
|
||||
* There is no time to compute a reply. The data should be ready
|
||||
* immediately. This function can be called in interrupt context.
|
||||
*
|
||||
* The format of a reply is a sequence of bytes:
|
||||
*
|
||||
* <msg bytes> <sum>
|
||||
*
|
||||
* The checksum is calculated as the sum of all message bytes
|
||||
*
|
||||
* @param cmd Command to process (CMD_...)
|
||||
* @param buff Pointer to buffer to store reponse
|
||||
* @param max_len Maximum length of buffer
|
||||
* @return number of bytes in reply, 0 if none, -1 for unknown command
|
||||
*/
|
||||
int message_process_cmd(int cmd, uint8_t *buff, int max_len);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user