#include <cfg/compiler.h>
#include <cfg/debug.h>
+#include <cfg/macros.h>
+
#include <cpu/attr.h>
-int dac_write(int ch, void *buf, size_t len);
+#include CPU_HEADER(dac)
+
+struct DacContext;
+struct Dac;
+
+typedef int (*DacWriteFunc_t) (struct Dac *dac, unsigned channel, uint16_t sample);
+typedef void (*SetChannelMaskFunc_t) (struct Dac *dac, uint32_t mask);
+typedef void (*SetSamplingRate_t) (struct Dac *dac, uint32_t rate);
+typedef void (*DmaConversionBufFunc_t) (struct Dac *dac, void *buf, size_t len);
+typedef bool (*DmaConversionIsFinished_t) (struct Dac *dac);
+typedef void (*DmaStartStreamingFunc_t) (struct Dac *dac, void *buf, size_t len, size_t slice_len);
+typedef void (*DmaStopFunc_t) (struct Dac *dac);
+typedef void (*DmaCallbackFunc_t) (struct Dac *dac, void *_buf, size_t len);
+
+typedef struct DacContext
+{
+ DacWriteFunc_t write;
+ SetChannelMaskFunc_t setCh;
+ SetSamplingRate_t setSampleRate;
+ DmaConversionBufFunc_t conversion;
+ DmaConversionIsFinished_t isFinished;
+ DmaStartStreamingFunc_t start;
+ DmaStopFunc_t stop;
+ DmaCallbackFunc_t callback;
+ size_t slice_len;
+
+ DB(id_t _type);
+
+} DacContext;
+
+typedef struct Dac
+{
+ DacContext ctx;
+ struct DacHardware *hw;
+} Dac;
+
+INLINE int dac_write(Dac *dac, unsigned channel, uint16_t sample)
+{
+ ASSERT(dac->ctx.write);
+ return dac->ctx.write(dac, channel, sample);
+}
+
+INLINE void dac_setChannelMask(struct Dac *dac, uint32_t mask)
+{
+ ASSERT(dac->ctx.setCh);
+ dac->ctx.setCh(dac, mask);
+}
+
+INLINE void dac_setSamplingRate(Dac *dac, uint32_t rate)
+{
+ ASSERT(dac->ctx.setSampleRate);
+ dac->ctx.setSampleRate(dac, rate);
+}
-INLINE int dac_putHalfWord(int ch, uint16_t sample)
+/*
+ * Convert \param len samples stored into \param buf.
+ */
+INLINE void dac_dmaConversionBuffer(Dac *dac, void *buf, size_t len)
{
- return dac_write(ch, &sample, sizeof(uint16_t));
+ ASSERT(dac->ctx.conversion);
+ dac->ctx.conversion(dac, buf, len);
}
-INLINE int dac_putWord(int ch, uint32_t sample)
+/*
+ * Check if a dma transfer is finished.
+ *
+ * Useful for kernel-less applications.
+ */
+INLINE bool dac_dmaIsFinished(Dac *dac)
{
- return dac_write(ch, &sample, sizeof(uint32_t));
+ ASSERT(dac->ctx.isFinished);
+ return dac->ctx.isFinished(dac);
}
-void dac_init(void);
+/*
+ * \param slicelen Must be a divisor of len, ie. len % slicelen == 0.
+ */
+INLINE void dac_dmaStartStreaming(Dac *dac, void *buf, size_t len, size_t slice_len, DmaCallbackFunc_t callback)
+{
+ ASSERT(dac->ctx.start);
+ ASSERT(len % slice_len == 0);
+ ASSERT(callback);
+
+ dac->ctx.callback = callback;
+ dac->ctx.slice_len = slice_len;
+ dac->ctx.start(dac, buf, len, slice_len);
+}
+
+INLINE void dac_dmaStop(Dac *dac)
+{
+ ASSERT(dac->ctx.stop);
+ dac->ctx.stop(dac);
+}
+
+#define dac_bits() DAC_BITS
+
+void dac_init(Dac *dac);
/** \} */ //defgroup dac
#endif /* DRV_DAC_H */