X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;ds=inline;f=bertos%2Fdrv%2Fi2s.h;h=73768c3131581898d8c2c330424e241a24b9f52d;hb=a5cc64b8fb7daebbb65b96034757c4daee115649;hp=c3cfef50c06e6987412c27ed691f506662c6c7d2;hpb=f296d81300aac2c5e0afb30aa3e14659853a4eda;p=bertos.git
diff --git a/bertos/drv/i2s.h b/bertos/drv/i2s.h
index c3cfef50..73768c31 100644
--- a/bertos/drv/i2s.h
+++ b/bertos/drv/i2s.h
@@ -1,22 +1,188 @@
-#ifndef I2S_H
-#define I2S_H
+/**
+ * \file
+ *
+ *
+ * \defgroup i2s Generic I2S driver
+ * \ingroup drivers
+ * \{
+ * \brief
+ *
+ * Configuration file: cfg_i2s.h
+ *
+ * \author Daniele Basile
+ *
+ * $WIZ$ module_name = "i2s"
+ * $WIZ$ module_configuration = "bertos/cfg/cfg_i2s.h"
+ * $WIZ$ module_supports = "not all"
+ */
+
+
+#ifndef DRV_I2S_H
+#define DRV_I2S_H
+
+#warning This API is ALPHA! we could change it..
#include
+#include
+#include
+
+#include
+
+#include CPU_HEADER(i2s)
+
+struct I2sContext;
+struct I2s;
+
+typedef int (*i2s_write_t) (struct I2s *i2s, uint32_t sample);
+typedef uint32_t (*i2s_read_t) (struct I2s *i2s);
+typedef void (*i2s_dma_tx_buf_t) (struct I2s *i2s, void *buf, size_t len);
+typedef void (*i2s_dma_rx_buf_t) (struct I2s *i2s, void *buf, size_t len);
+typedef bool (*i2s_dma_tx_is_finished_t) (struct I2s *i2s);
+typedef bool (*i2s_dma_rx_is_finished_t) (struct I2s *i2s);
+typedef void (*i2s_dma_callback_t) (struct I2s *i2s, void *_buf, size_t len);
+typedef void (*i2s_dma_start_streaming_t) (struct I2s *i2s, void *buf, size_t len, size_t slice_len);
+typedef void (*i2s_dma_wait_t) (struct I2s *i2s);
+typedef void (*i2s_dma_stop_t) (struct I2s *i2s);
+
+typedef struct I2sContext
+{
+ i2s_write_t write;
+ i2s_dma_tx_buf_t tx_buf;
+ i2s_dma_tx_is_finished_t tx_isFinish;
+ i2s_dma_callback_t tx_callback;
+ i2s_dma_start_streaming_t tx_start;
+ i2s_dma_wait_t tx_wait;
+ i2s_dma_stop_t tx_stop;
+ size_t tx_slice_len;
+
+ i2s_read_t read;
+ i2s_dma_rx_buf_t rx_buf;
+ i2s_dma_rx_is_finished_t rx_isFinish;
+ i2s_dma_callback_t rx_callback;
+ i2s_dma_start_streaming_t rx_start;
+ i2s_dma_wait_t rx_wait;
+ i2s_dma_stop_t rx_stop;
+ size_t rx_slice_len;
+
+ DB(id_t _type);
+
+} I2sContext;
+
+typedef struct I2s
+{
+ I2sContext ctx;
+ struct I2sHardware *hw;
+} I2s;
+
+INLINE int i2s_write(I2s *i2s, uint32_t sample)
+{
+ ASSERT(i2s->ctx.write);
+ return i2s->ctx.write(i2s, sample);
+}
+
+
+INLINE uint32_t i2s_read(I2s *i2s)
+{
+ ASSERT(i2s->ctx.read);
+ return i2s->ctx.read(i2s);
+}
+
+/*
+ * Check if a dma transfer is finished.
+ *
+ * Useful for kernel-less applications.
+ */
+INLINE bool i2s_dmaTxIsFinished(I2s *i2s)
+{
+ ASSERT(i2s->ctx.tx_isFinish);
+ return i2s->ctx.tx_isFinish(i2s);
+}
+
+INLINE bool i2s_dmaRxIsFinished(I2s *i2s)
+{
+ ASSERT(i2s->ctx.rx_isFinish);
+ return i2s->ctx.rx_isFinish(i2s);
+}
+
+INLINE void i2s_dmaTxBuffer(I2s *i2s, void *buf, size_t len)
+{
+ ASSERT(i2s->ctx.tx_buf);
+ i2s->ctx.tx_buf(i2s, buf, len);
+}
+
+INLINE void i2s_dmaRxBuffer(I2s *i2s, void *buf, size_t len)
+{
+ ASSERT(i2s->ctx.rx_buf);
+ i2s->ctx.rx_buf(i2s, buf, len);
+}
+
+
+INLINE void i2s_dmaStartTxStreaming(I2s *i2s, void *buf, size_t len, size_t slice_len, i2s_dma_callback_t callback)
+{
+ ASSERT(i2s->ctx.tx_start);
+ ASSERT(len % slice_len == 0);
+ ASSERT(callback);
+
+ i2s->ctx.rx_callback = callback;
+ i2s->ctx.rx_slice_len = slice_len;
+ i2s->ctx.tx_start(i2s, buf, len, slice_len);
+}
+
+INLINE void i2s_dmaTxStop(I2s *i2s)
+{
+ ASSERT(i2s->ctx.tx_stop);
+ i2s->ctx.tx_stop(i2s);
+}
+
+
+INLINE void i2s_dmaStartRxStreaming(I2s *i2s, void *buf, size_t len, size_t slice_len, i2s_dma_callback_t callback)
+{
+ ASSERT(i2s->ctx.rx_start);
+ ASSERT(len % slice_len == 0);
+ ASSERT(callback);
-#define CONFIG_PLAY_BUF_LEN 64
-#define I2S_FIRST_BUF 1
-#define I2S_SECOND_BUF 2
+ i2s->ctx.rx_callback = callback;
+ i2s->ctx.rx_slice_len = slice_len;
+ i2s->ctx.rx_start(i2s, buf, len, slice_len);
+}
-void i2s_init(void);
-/* Low level call that returns one of the two buffers or NULL if none is available */
-uint8_t *i2s_getBuffer(unsigned buf_num);
-/* Returns a buffer that will be played after the current one. Blocking call */
-uint8_t *i2s_getFreeBuffer(void);
+INLINE void i2s_dmaRxStop(I2s *i2s)
+{
+ ASSERT(i2s->ctx.rx_stop);
+ i2s->ctx.rx_stop(i2s);
+}
-/* Starts playing from I2S_FIRST_BUFFER. You must have filled both buffers before calling this
- * function. Does nothing if already playing. */
-bool i2s_start(void);
+void i2s_init(I2s *i2s, int channel);
-#endif /* I2S_H */
+/** \} */ //defgroup i2s
+#endif /* DRV_I2S_H */