summaryrefslogtreecommitdiff
path: root/chip/stm32/dma.c
diff options
context:
space:
mode:
authorWei-Han Chen <stimim@google.com>2018-01-08 16:51:26 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-01-25 00:15:48 -0800
commit9a7e82bac8f8fbfa10e0e2a1f1ea33fb1d6b75cc (patch)
tree0834587dfa4a95ed38fed2974b470beaa862ca5b /chip/stm32/dma.c
parente68469b5242b9b95ea5de45c965825da35b7eaab (diff)
downloadchrome-ec-9a7e82bac8f8fbfa10e0e2a1f1ea33fb1d6b75cc.tar.gz
stm32: make half-duplex SPI works on STM32F0
According to RM0091, steps for using DMA for SPI peripheral should be: 1. enable DMA RX / TX 2. enable SPI 3. wait for DMA to complete 4. disable DMA RX / TX 5. disable SPI BUG=b:70482333 TEST=tested on reworked staff (half-duplex) TEST=tested elm (full-duplex) Change-Id: I095409195cd1e0379995f0bfa6605c2e1a0dfd3c Reviewed-on: https://chromium-review.googlesource.com/853715 Commit-Ready: Wei-Han Chen <stimim@chromium.org> Tested-by: Wei-Han Chen <stimim@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Diffstat (limited to 'chip/stm32/dma.c')
-rw-r--r--chip/stm32/dma.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/chip/stm32/dma.c b/chip/stm32/dma.c
index 9c08973098..26dfa0f823 100644
--- a/chip/stm32/dma.c
+++ b/chip/stm32/dma.c
@@ -104,13 +104,14 @@ void dma_disable_all(void)
* STM32_DMA_CCR_MINC | STM32_DMA_CCR_DIR for tx
* 0 for rx
*/
-static void prepare_channel(stm32_dma_chan_t *chan, unsigned count,
+static void prepare_channel(enum dma_channel channel, unsigned count,
void *periph, void *memory, unsigned flags)
{
+ stm32_dma_chan_t *chan = dma_get_channel(channel);
uint32_t ccr = STM32_DMA_CCR_PL_VERY_HIGH;
- if (chan->ccr & STM32_DMA_CCR_EN)
- chan->ccr &= ~STM32_DMA_CCR_EN;
+ dma_disable(channel);
+ dma_clear_isr(channel);
/* Following the order in Doc ID 15965 Rev 5 p194 */
chan->cpar = (uint32_t)periph;
@@ -133,13 +134,11 @@ void dma_go(stm32_dma_chan_t *chan)
void dma_prepare_tx(const struct dma_option *option, unsigned count,
const void *memory)
{
- stm32_dma_chan_t *chan = dma_get_channel(option->channel);
-
/*
* Cast away const for memory pointer; this is ok because we know
* we're preparing the channel for transmit.
*/
- prepare_channel(chan, count, option->periph, (void *)memory,
+ prepare_channel(option->channel, count, option->periph, (void *)memory,
STM32_DMA_CCR_MINC | STM32_DMA_CCR_DIR |
option->flags);
}
@@ -148,8 +147,7 @@ void dma_start_rx(const struct dma_option *option, unsigned count,
void *memory)
{
stm32_dma_chan_t *chan = dma_get_channel(option->channel);
-
- prepare_channel(chan, count, option->periph, memory,
+ prepare_channel(option->channel, count, option->periph, memory,
STM32_DMA_CCR_MINC | option->flags);
dma_go(chan);
}