summaryrefslogtreecommitdiff
path: root/include/dma.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/dma.h')
-rw-r--r--include/dma.h137
1 files changed, 59 insertions, 78 deletions
diff --git a/include/dma.h b/include/dma.h
index c784558612..eeefc45654 100644
--- a/include/dma.h
+++ b/include/dma.h
@@ -11,37 +11,43 @@
#include "common.h"
/*
- * Available DMA channels, numbered from 0
+ * Available DMA channels, numbered from 0.
*
* Note: The STM datasheet tends to number things from 1. We should ask
* the European elevator engineers to talk to MCU engineer counterparts
* about this. This means that if the datasheet refers to channel n,
- * you need to use n-1 in the code.
- */
-enum {
- DMAC_ADC,
- DMAC_SPI1_RX,
- DMAC_SPI1_TX,
- DMAC_SPI2_RX,
- DMAC_SPI2_TX,
-
- /*
- * The same channels are used for i2c2 and spi, you can't use them at
- * the same time or it will cause dma to not work
- */
- DMAC_I2C2_TX = 3,
- DMAC_I2C2_RX = 4,
- DMAC_I2C1_TX = 5,
- DMAC_I2C1_RX = 6,
-
- /* DMA1 has 7 channels, DMA2 has 5 */
- DMA1_NUM_CHANNELS = 7,
- DMA2_NUM_CHANNELS = 5,
- DMA_NUM_CHANNELS = DMA1_NUM_CHANNELS + DMA2_NUM_CHANNELS,
+ * you need to use DMAC_CHn (=n-1) in the code.
+ *
+ * Also note that channels are overloaded; obviously you can only use one
+ * function on each channel at a time.
+ */
+enum dma_channel {
+ /* Channel numbers */
+ DMAC_CH1 = 0,
+ DMAC_CH2 = 1,
+ DMAC_CH3 = 2,
+ DMAC_CH4 = 3,
+ DMAC_CH5 = 4,
+ DMAC_CH6 = 5,
+ DMAC_CH7 = 6,
+
+ /* Channel functions */
+ DMAC_ADC = DMAC_CH1,
+ DMAC_SPI1_RX = DMAC_CH2,
+ DMAC_SPI1_TX = DMAC_CH3,
+ DMAC_I2C2_TX = DMAC_CH4,
+ DMAC_I2C2_RX = DMAC_CH5,
+ DMAC_USART1_TX = DMAC_CH4,
+ DMAC_USART1_RX = DMAC_CH5,
+ DMAC_I2C1_TX = DMAC_CH6,
+ DMAC_I2C1_RX = DMAC_CH7,
+
+ /* Only DMA1 (with 7 channels) is present on STM32F100 and STM32L151x */
+ DMA_NUM_CHANNELS = 7,
};
-/* A single channel of the DMA controller */
-struct dma_channel {
+/* Registers for a single channel of the DMA controller */
+struct dma_channel_regs {
uint32_t ccr; /* Control */
uint32_t cndtr; /* Number of data to transfer */
uint32_t cpar; /* Peripheral address */
@@ -49,16 +55,12 @@ struct dma_channel {
uint32_t reserved;
};
-/* Registers for the DMA controller */
-struct dma_ctlr {
- uint32_t isr;
- uint32_t ifcr;
- struct dma_channel chan[DMA_NUM_CHANNELS];
-};
+/* Always use dma_channel_t so volatile keyword is included! */
+typedef volatile struct dma_channel_regs dma_channel_t;
/* DMA channel options */
struct dma_option {
- unsigned channel; /* DMA channel */
+ enum dma_channel channel; /* DMA channel */
void *periph; /* Pointer to peripheral data register */
unsigned flags; /* DMA flags for the control register. Normally
used to select memory size. */
@@ -93,28 +95,13 @@ enum {
#define DMA_POLLING_INTERVAL_US 100 /* us */
#define DMA_TRANSFER_TIMEOUT_US (100 * MSEC) /* us */
-/*
- * Certain DMA channels must be used for certain peripherals and transfer
- * directions. We provide an easy way for drivers to select the correct
- * channel.
- */
-
-/**
- * @param spi SPI port to request: STM32_SPI1_PORT or STM32_SPI2_PORT
- * @return DMA channel to use for rx / tx on that port
- */
-#define DMA_CHANNEL_FOR_SPI_RX(spi) \
- ((spi) == STM32_SPI1_PORT ? DMAC_SPI1_RX : DMAC_SPI2_RX)
-#define DMA_CHANNEL_FOR_SPI_TX(spi) \
- ((spi) == STM32_SPI1_PORT ? DMAC_SPI1_TX : DMAC_SPI2_TX)
-
/**
* Get a pointer to a DMA channel.
*
- * @param channel Channel number to read (DMAC_...)
+ * @param channel Channel to read
* @return pointer to DMA channel registers
*/
-struct dma_channel *dma_get_channel(int channel);
+dma_channel_t *dma_get_channel(enum dma_channel channel);
/**
* Prepare a DMA transfer to transmit data from memory to a peripheral
@@ -137,17 +124,17 @@ void dma_prepare_tx(const struct dma_option *option, unsigned count,
* @param count Number of bytes to transfer
* @param memory Pointer to memory address
*/
-int dma_start_rx(const struct dma_option *option, unsigned count,
- const void *memory);
+void dma_start_rx(const struct dma_option *option, unsigned count,
+ void *memory);
/**
* Stop a DMA transfer on a channel
*
* Disable the DMA channel and immediate stop all transfers on it.
*
- * @param channel Channel number to stop (DMAC_...)
+ * @param channel Channel to stop
*/
-void dma_disable(unsigned channel);
+void dma_disable(enum dma_channel channel);
/**
* Get the number of bytes available to read, or number of bytes written
@@ -155,75 +142,69 @@ void dma_disable(unsigned channel);
* Since the DMA controller counts downwards, if we know the starting value
* we can work out how many bytes have been completed so far.
*
- * @param chan DMA channel to check (use dma_get_channel())
+ * @param chan DMA channel to check, from dma_get_channel()
* @param orig_count Original number of bytes requested on channel
* @return number of bytes completed on a channel, or 0 if this channel is
* not enabled
*/
-int dma_bytes_done(struct dma_channel *chan, int orig_count);
+int dma_bytes_done(dma_channel_t *chan, int orig_count);
/**
* Start a previously-prepared dma channel
*
- * @param chan Channel to start (returned from dma_prepare...())
+ * @param chan Channel to start, from dma_get_channel()
*/
-void dma_go(struct dma_channel *chan);
+void dma_go(dma_channel_t *chan);
+#ifdef CONFIG_DMA_HELP
/**
* Testing: Print out the data transferred by a channel
*
- * @param channel Channel number to read (DMAC_...)
+ * @param channel Channel to read
* @param buff Start of DMA buffer
*/
-void dma_check(int channel, char *buff);
+void dma_check(enum dma_channel channel, char *buf);
/**
* Dump out imformation about a dma channel
*
- * @param channel Channel number to read (DMAC_...)
+ * @param channel Channel to read
*/
-void dma_dump(unsigned channel);
+void dma_dump(enum dma_channel channel);
/**
* Testing: Test that DMA works correctly for memory to memory transfers
*/
void dma_test(void);
+#endif /* CONFIG_DMA_HELP */
/**
* Clear the DMA interrupt/event flags for a given channel
*
- * @param channel Which channel's isr to clear (DMAC_...)
+ * @param channel Which channel's isr to clear
*/
-void dma_clear_isr(int channel);
+void dma_clear_isr(enum dma_channel channel);
/**
* Enable "Transfer Complete" interrupt for a DMA channel
*
- * @param channel Which channel's interrupts to change (DMAC_...)
+ * @param channel Which channel's interrupts to change
*/
-void dma_enable_tc_interrupt(int channel);
+void dma_enable_tc_interrupt(enum dma_channel channel);
/**
* Disable "Transfer Complete" interrupt for a DMA channel
*
- * @param channel Which channel's interrupts to change (DMAC_...)
- */
-void dma_disable_tc_interrupt(int channel);
-
-/**
- * Get a pointer to the DMA peripheral controller that owns the channel
- *
- * @param channel Channel number to get the controller for (DMAC_...)
- * @return pointer to DMA channel registers
+ * @param channel Which channel's interrupts to change
*/
-struct dma_ctlr *dma_get_ctlr(int channel);
+void dma_disable_tc_interrupt(enum dma_channel channel);
/**
* Wait for the DMA transfer to complete by polling the transfer complete flag
*
- * @param channelĀ» Channel number to wait on (DMAC_...)
- * @return -1 for timeout, 0 for sucess
+ * @param channel Channel number to wait on
+ * @return EC_ERROR_TIMEOUT for timeout, EC_SUCCESS for success
*/
-int dma_wait(int channel);
+int dma_wait(enum dma_channel channel);
#endif