summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2014-06-13 16:03:21 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-06-15 11:53:25 +0000
commit21aa3f7a48b0e573e662ad57b181494cf8beb57f (patch)
tree69ebc217687fd506ca6f77cd6964427f491854a9
parentefd3a8925eecce4559d8c81175258d5974140db6 (diff)
downloadchrome-ec-21aa3f7a48b0e573e662ad57b181494cf8beb57f.tar.gz
Keyborg: improve async slave response
Currently the master and the slave must synchronize before starting slave response. This is to make sure the previous slave response is done and the slave is ready for the next response. By enabling interrupt on the master side to capture slave ready event, we can get rid of the extra sync's. This saves about 1300 us per frame. BUG=None TEST=Build and boot. Measure time. Examine heat map. BRANCH=None Change-Id: I3c319d8a3636f1f6ae905d7021433c3ba220c9b0 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/203789 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/keyborg/spi_comm.c32
-rw-r--r--board/keyborg/touch_scan.c6
2 files changed, 28 insertions, 10 deletions
diff --git a/board/keyborg/spi_comm.c b/board/keyborg/spi_comm.c
index 5099e80faf..0b5c55358c 100644
--- a/board/keyborg/spi_comm.c
+++ b/board/keyborg/spi_comm.c
@@ -46,6 +46,22 @@ static inline int wait_for_signal(uint32_t port, uint32_t mask,
return EC_ERROR_TIMEOUT;
}
+static volatile uint8_t slave_ready = 1;
+
+static inline int wait_for_slave_ready(int timeout_us)
+{
+ uint32_t start = get_time().le.lo;
+
+ while ((get_time().le.lo - start) < timeout_us) {
+ if (slave_ready) {
+ slave_ready = 0; /* Clear for the next event */
+ return EC_SUCCESS;
+ }
+ }
+
+ return EC_ERROR_TIMEOUT;
+}
+
/*****************************************************************************/
/* Master */
@@ -85,6 +101,12 @@ void spi_master_init(void)
/* Set MSTR and SPE */
spi->cr1 |= STM32_SPI_CR1_MSTR | STM32_SPI_CR1_SPE;
+
+ /* Enable interrupt on PA0 (GPIO_SPI_NSS) */
+ STM32_AFIO_EXTICR(0) &= ~0xF;
+ STM32_EXTI_IMR |= (1 << 0);
+ task_clear_pending_irq(STM32_IRQ_EXTI0);
+ task_enable_irq(STM32_IRQ_EXTI0);
}
static int spi_master_read_write_byte(uint8_t *in_buf, uint8_t *out_buf, int sz)
@@ -140,7 +162,7 @@ int spi_master_send_command(struct spi_comm_packet *cmd)
int spi_master_wait_response_async(void)
{
- master_slave_sync(40);
+ wait_for_slave_ready(100 * MSEC);
if (wait_for_signal(GPIO_A, 1 << 0, 1, 40 * MSEC))
goto err_wait_resp_async;
@@ -331,9 +353,6 @@ int spi_slave_send_response_async(struct spi_comm_packet *resp)
if (out_msg != (uint8_t *)resp)
memcpy(out_msg, resp, size);
- if (master_slave_sync(100) != EC_SUCCESS)
- return EC_ERROR_UNKNOWN;
-
#ifdef CONFIG_KEYBORG_SPI_FULL_PACKET
dma_clear_isr(STM32_DMAC_SPI1_TX);
dma_prepare_tx(&dma_tx_option, SPI_PACKET_MAX_SIZE, out_msg);
@@ -411,6 +430,11 @@ static void spi_nss_interrupt(void)
const struct spi_comm_packet *cmd =
(const struct spi_comm_packet *)in_msg;
+ if (master_slave_is_master()) {
+ slave_ready = 1;
+ return;
+ }
+
if (spi->sr & STM32_SPI_SR_RXNE)
in_msg[0] = spi->dr;
diff --git a/board/keyborg/touch_scan.c b/board/keyborg/touch_scan.c
index 21505bd0bf..83e58f219c 100644
--- a/board/keyborg/touch_scan.c
+++ b/board/keyborg/touch_scan.c
@@ -264,9 +264,6 @@ void touch_scan_slave_start(void)
if (spi_slave_send_response_flush() != EC_SUCCESS)
goto slave_err;
- if (master_slave_sync(40) != EC_SUCCESS)
- goto slave_err;
-
/* Start sending the response for the current column */
if (spi_slave_send_response_async(resp) != EC_SUCCESS)
goto slave_err;
@@ -336,9 +333,6 @@ int touch_scan_full_matrix(void)
encode_add_column(last_dptr);
}
- if (master_slave_sync(40) != EC_SUCCESS)
- goto master_err;
-
/* Start receiving data for the current column */
if (spi_master_wait_response_async() != EC_SUCCESS)
goto master_err;