Files
OpenCellular/include/spi.h
Vadim Bendebury dbf027f2f7 cr50: add SPI Slave driver
The CR50 device will have to have two different drivers, for SPI slave
and master modes. This patch adds the slave driver which is called
SPS.

CR50 SPS controller uses 2KB buffer split evenly between receive and
transmit directions as two FIFOs. RX write and TX read pointers are
maintained by hardware, RX read and TX write pointers are maintained
by software.

The FIFO area allows only 32 bit writes from the CPU core, which
complicates the function placing TX data into the FIFO. There is no
limit to read access size.

Another complication is that the hardware pointers in the FIFO in fact
have 11 bits (instead of 10 required to address 1K), so the software
needs to use 10 bits when accessing the FIFO, but 11 bits when writing
the pointers into the registers.

Driver API provides three functions:

 - transmit a packet of a certain size, runs on the task context and can
   exit before the entire packet is transmitted.,

 - register a receive callback. The callback is running in interrupt
   context. Registering the callback (re)initializes the interface.

 - unregister receive callback.

A CLI command is added to help testing this driver. When invoked, it
installs the callback function to handle receive data. The data is
expected to be of the following format:

 <size/256> <size%256> [<size> bytes of payload]

where size should not exceed 1098 bytes.

Received frames are saved in a buffer and once received are
transmitted back to the host.

BRANCH=none
BUG=none

TEST=used the enhanced 'spiraw' utility which sends frames of random
     size in 10..1010 bytes, and then clocks the line to receive the
     same amount of bytes back, syncs up in the returning stream of
     bytes and compares received and transmitted data.

    # run 'sps 100' on the target
    $ src/examples/spiraw.py -l 100 -f 2000000
    FT232H Future Technology Devices International, Ltd initialized at 2000000 hertz
    $

     which is an indication of the successful loop back of 100 frames.
     The cli command on the target exits and reports the stats:

  > sps 100
  Processed 100 frames
  rx count 108532, tx count 51366, tx_empty count 100, max rx batch 11

Change-Id: I62956753eb09086b5fca7504f2241605c0afe613
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/269794
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
2015-05-07 23:39:06 +00:00

68 lines
1.7 KiB
C

/* 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.
*/
/* SPI interface for Chrome EC */
#ifndef __CROS_EC_SPI_H
#define __CROS_EC_SPI_H
/*
* SPI Clock polarity and phase mode (0 - 3)
* @code
* clk mode | POL PHA
* ---------+--------
* 0 | 0 0
* 1 | 0 1
* 2 | 1 0
* 3 | 1 1
* ---------+--------
* @endcode
*/
enum spi_clock_mode {
SPI_CLOCK_MODE0 = 0,
SPI_CLOCK_MODE1 = 1,
SPI_CLOCK_MODE2 = 2,
SPI_CLOCK_MODE3 = 3
};
/* Enable / disable the SPI port. When the port is disabled, all its I/O lines
* are high-Z so the EC won't interfere with other devices on the SPI bus. */
int spi_enable(int enable);
/* Issue a SPI transaction. Assumes SPI port has already been enabled.
* Transmits <txlen> bytes from <txdata>, throwing away the corresponding
* received data, then transmits <rxlen> dummy bytes, saving the received data
* in <rxdata>. */
int spi_transaction(const uint8_t *txdata, int txlen,
uint8_t *rxdata, int rxlen);
/* Similar to spi_transaction(), but hands over to DMA for reading response.
* Must call spi_transaction_flush() after this to make sure the response is
* received.
*/
int spi_transaction_async(const uint8_t *txdata, int txlen,
uint8_t *rxdata, int rxlen);
/* Wait for async response received */
int spi_transaction_flush(void);
#ifdef CONFIG_SPI
/**
* Called when the NSS level changes, signalling the start or end of a SPI
* transaction.
*
* @param signal GPIO signal that changed
*/
void spi_event(enum gpio_signal signal);
#else
static inline void spi_event(enum gpio_signal signal)
{
}
#endif
#endif /* __CROS_EC_SPI_H */