mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-07 16:11:43 +00:00
Cr50: Restore spstest command
I accidentally removed this when poking around with the SPS driver. This adds it back as a separate file. Enabling CONFIG_SPS_TEST will restore the "spstest" console command to use for low-level driver tests. Note that invoking it will replace any other registered SPS handler. BUG=chrome-os-partner:40969 BRANCH=none TEST=manual Connect the EC to the build host with an FTDI USB-to-SPI adapter. On the EC console, invoke spstest Build and run the external ftdi_dongle test: git clone sso://user/vbendeb/ftdi_dongle cd ftdi_dongle/src make ./examples/spiraw.py -l 10 -f 2000000 Change-Id: Ia6165e3be06d976c59c3e849349da0f7f5006f56 Signed-off-by: Bill Richardson <wfrichar@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/284943 Reviewed-by: Vadim Bendebury <vbendeb@google.com>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
693bf0e40b
commit
7070b42682
@@ -19,6 +19,7 @@ CPPFLAGS+= -DGC_REVISION="$(ver_str)"
|
||||
chip-y=clock.o gpio.o hwtimer.o jtag.o system.o uart.o
|
||||
chip-y+= pmu.o
|
||||
chip-$(CONFIG_SPI)+= sps.o
|
||||
chip-$(CONFIG_SPS_TEST)+=sps_test.o
|
||||
chip-$(CONFIG_HOSTCMD_SPI)+=sps_hc.o
|
||||
chip-$(CONFIG_WATCHDOG)+=watchdog.o
|
||||
|
||||
|
||||
18
chip/g/sps.c
18
chip/g/sps.c
@@ -41,6 +41,11 @@ static uint32_t fifo_count(uint32_t readptr, uint32_t writeptr)
|
||||
#define SPS_TX_FIFO_BASE_ADDR (GBASE(SPS) + 0x1000)
|
||||
#define SPS_RX_FIFO_BASE_ADDR (SPS_TX_FIFO_BASE_ADDR + SPS_FIFO_SIZE)
|
||||
|
||||
#ifdef CONFIG_SPS_TEST
|
||||
/* Statistics counters. Not always present, to save space & time. */
|
||||
uint32_t sps_tx_count, sps_rx_count, sps_tx_empty_count, sps_max_rx_batch;
|
||||
#endif
|
||||
|
||||
void sps_tx_status(uint8_t byte)
|
||||
{
|
||||
GREG32(SPS, DUMMY_WORD) = byte;
|
||||
@@ -54,6 +59,11 @@ int sps_transmit(uint8_t *data, size_t data_size)
|
||||
uint32_t fifo_room;
|
||||
int bytes_sent;
|
||||
|
||||
#ifdef CONFIG_SPS_TEST
|
||||
if (GREAD_FIELD(SPS, ISTATE, TXFIFO_EMPTY))
|
||||
sps_tx_empty_count++;
|
||||
#endif
|
||||
|
||||
wptr = GREG32(SPS, TXFIFO_WPTR);
|
||||
rptr = GREG32(SPS, TXFIFO_RPTR);
|
||||
fifo_room = SPS_FIFO_SIZE - fifo_count(rptr, wptr);
|
||||
@@ -113,6 +123,9 @@ int sps_transmit(uint8_t *data, size_t data_size)
|
||||
SPS_TX_FIFO_BASE_ADDR;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPS_TEST
|
||||
sps_tx_count += bytes_sent;
|
||||
#endif
|
||||
return bytes_sent;
|
||||
}
|
||||
|
||||
@@ -224,6 +237,11 @@ static void sps_rx_interrupt(int cs_enabled)
|
||||
if (sps_rx_handler)
|
||||
sps_rx_handler(received_data, data_size, cs_enabled);
|
||||
sps_advance_rx(data_size);
|
||||
#ifdef CONFIG_SPS_TEST
|
||||
sps_rx_count += data_size;
|
||||
if (data_size > sps_max_rx_batch)
|
||||
sps_max_rx_batch = data_size;
|
||||
#endif
|
||||
} while (data_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,4 +77,9 @@ void sps_register_rx_handler(enum spi_clock_mode m_spi,
|
||||
*/
|
||||
void sps_unregister_rx_handler(void);
|
||||
|
||||
|
||||
/* Statistics counters, present only with CONFIG_SPS_TEST. */
|
||||
extern uint32_t sps_tx_count, sps_rx_count,
|
||||
sps_tx_empty_count, sps_max_rx_batch;
|
||||
|
||||
#endif /* __CROS_EC_SPS_H */
|
||||
|
||||
172
chip/g/sps_test.c
Normal file
172
chip/g/sps_test.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/* Copyright 2015 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "console.h"
|
||||
#include "sps.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
/* Function to test SPS driver. It expects the host to send SPI frames of size
|
||||
* <size> (not exceeding 1100) of the following format:
|
||||
*
|
||||
* <size/256> <size%256> [<size> bytes of payload]
|
||||
*
|
||||
* Once the frame is received, it is sent back. The host can receive it and
|
||||
* compare with the original.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Receive callback implemets a simple state machine, it could be in one of
|
||||
* three states: not started, receiving frame, frame finished.
|
||||
*/
|
||||
|
||||
enum sps_test_rx_state {
|
||||
spstrx_not_started,
|
||||
spstrx_receiving,
|
||||
spstrx_finished
|
||||
};
|
||||
|
||||
static enum sps_test_rx_state rx_state;
|
||||
/* Storage for the received frame. Size chosen arbitrarily to match the
|
||||
* external test code. */
|
||||
static uint8_t test_frame[1100];
|
||||
|
||||
/*
|
||||
* To verify different alignment cases, the frame is saved in the buffer
|
||||
* starting with a certain offset (in range 0..3).
|
||||
*/
|
||||
static size_t frame_base;
|
||||
/*
|
||||
* This is the index of the next location where received data will be added
|
||||
* to. Points to the end of the received frame once it has been pulled in.
|
||||
*/
|
||||
static size_t frame_index;
|
||||
|
||||
static void sps_receive_callback(uint8_t *data, size_t data_size,
|
||||
int cs_enabled)
|
||||
{
|
||||
static size_t frame_size; /* Total size of the frame being received. */
|
||||
size_t to_go; /* Number of bytes still to receive. */
|
||||
|
||||
if (rx_state == spstrx_not_started) {
|
||||
if (data_size < 2)
|
||||
return; /* Something went wrong.*/
|
||||
|
||||
frame_size = data[0] * 256 + data[1] + 2;
|
||||
frame_base = (frame_base + 1) % 3;
|
||||
frame_index = frame_base;
|
||||
|
||||
if ((frame_index + frame_size) <= sizeof(test_frame))
|
||||
/* Enter 'receiving frame' state. */
|
||||
rx_state = spstrx_receiving;
|
||||
else
|
||||
/*
|
||||
* If we won't be able to receve this much, enter the
|
||||
* 'frame finished' state.
|
||||
*/
|
||||
rx_state = spstrx_finished;
|
||||
}
|
||||
|
||||
if (rx_state == spstrx_finished) {
|
||||
/*
|
||||
* If CS was deasserted, prepare to start receiving the next
|
||||
* frame.
|
||||
*/
|
||||
if (!cs_enabled)
|
||||
rx_state = spstrx_not_started;
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame_size > data_size)
|
||||
to_go = data_size;
|
||||
else
|
||||
to_go = frame_size;
|
||||
|
||||
memcpy(test_frame + frame_index, data, to_go);
|
||||
frame_index += to_go;
|
||||
frame_size -= to_go;
|
||||
|
||||
if (!frame_size)
|
||||
rx_state = spstrx_finished; /* Frame finished.*/
|
||||
}
|
||||
|
||||
static int command_sps(int argc, char **argv)
|
||||
{
|
||||
int count = 0;
|
||||
int target = 10; /* Expect 10 frames by default.*/
|
||||
char *e;
|
||||
|
||||
rx_state = spstrx_not_started;
|
||||
|
||||
sps_register_rx_handler(SPI_CLOCK_MODE0, SPS_GENERIC_MODE,
|
||||
sps_receive_callback);
|
||||
|
||||
if (argc > 1) {
|
||||
target = strtoi(argv[1], &e, 10);
|
||||
if (*e)
|
||||
return EC_ERROR_PARAM1;
|
||||
}
|
||||
|
||||
/* reset statistic counters */
|
||||
sps_rx_count = sps_tx_count = 0;
|
||||
sps_tx_empty_count = sps_max_rx_batch = 0;
|
||||
|
||||
while (count++ < target) {
|
||||
size_t transmitted;
|
||||
size_t to_go;
|
||||
size_t index;
|
||||
|
||||
/* Wait for a frame to be received.*/
|
||||
while (rx_state != spstrx_finished) {
|
||||
watchdog_reload();
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
/* Transmit the frame back to the host.*/
|
||||
index = frame_base;
|
||||
to_go = frame_index - frame_base;
|
||||
do {
|
||||
if ((index == frame_base) && (to_go > 8)) {
|
||||
/*
|
||||
* This is the first transmit attempt for this
|
||||
* frame. Send a little just to prime the
|
||||
* transmit FIFO.
|
||||
*/
|
||||
transmitted = sps_transmit(
|
||||
test_frame + index, 8);
|
||||
} else {
|
||||
transmitted = sps_transmit(
|
||||
test_frame + index, to_go);
|
||||
}
|
||||
index += transmitted;
|
||||
to_go -= transmitted;
|
||||
} while (to_go);
|
||||
|
||||
/*
|
||||
* Wait for receive state machine to transition out of 'frame
|
||||
* finised' state.
|
||||
*/
|
||||
while (rx_state == spstrx_finished) {
|
||||
watchdog_reload();
|
||||
usleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
sps_unregister_rx_handler();
|
||||
|
||||
ccprintf("Processed %d frames\n", count - 1);
|
||||
ccprintf("rx count %d, tx count %d, tx_empty %d, max rx batch %d\n",
|
||||
sps_rx_count, sps_tx_count,
|
||||
sps_tx_empty_count, sps_max_rx_batch);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
DECLARE_CONSOLE_COMMAND(spstest, command_sps,
|
||||
"<num of frames>",
|
||||
"Loop back frames (10 by default) back to the host",
|
||||
NULL);
|
||||
Reference in New Issue
Block a user