Add wait dma transfer functions.
[bertos.git] / bertos / drv / i2s.h
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2011 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \defgroup i2s Generic I2S driver
34  * \ingroup drivers
35  * \{
36  * \brief
37  *
38  * <b>Configuration file</b>: cfg_i2s.h
39  *
40  * \author Daniele Basile <asterix@develer.com>
41  *
42  * $WIZ$ module_name = "i2s"
43  * $WIZ$ module_configuration = "bertos/cfg/cfg_i2s.h"
44  * $WIZ$ module_supports = "not all"
45  */
46
47
48 #ifndef DRV_I2S_H
49 #define DRV_I2S_H
50
51 #warning This API is ALPHA! we could change it..
52
53 #include <cfg/compiler.h>
54 #include <cfg/debug.h>
55 #include <cfg/macros.h>
56
57 #include <cpu/attr.h>
58
59 #include CPU_HEADER(i2s)
60
61 struct I2sContext;
62 struct I2s;
63
64 typedef int (*i2s_write_t) (struct I2s *i2s, uint32_t sample);
65 typedef uint32_t (*i2s_read_t) (struct I2s *i2s);
66 typedef void (*i2s_dma_tx_buf_t) (struct I2s *i2s, void *buf, size_t len);
67 typedef void (*i2s_dma_rx_buf_t) (struct I2s *i2s, void *buf, size_t len);
68 typedef bool (*i2s_dma_tx_is_finished_t) (struct I2s *i2s);
69 typedef bool (*i2s_dma_rx_is_finished_t) (struct I2s *i2s);
70 typedef void (*i2s_dma_callback_t) (struct I2s *i2s, void *_buf, size_t len);
71 typedef void (*i2s_dma_start_streaming_t) (struct I2s *i2s, void *buf, size_t len, size_t slice_len);
72 typedef void (*i2s_dma_wait_t) (struct I2s *i2s);
73 typedef void (*i2s_dma_stop_t) (struct I2s *i2s);
74
75 typedef struct I2sContext
76 {
77         i2s_write_t                write;
78         i2s_dma_tx_buf_t           tx_buf;
79         i2s_dma_tx_is_finished_t   tx_isFinish;
80         i2s_dma_callback_t         tx_callback;
81         i2s_dma_start_streaming_t  tx_start;
82         i2s_dma_wait_t             tx_wait;
83         i2s_dma_stop_t             tx_stop;
84         size_t tx_slice_len;
85
86         i2s_read_t                 read;
87         i2s_dma_rx_buf_t           rx_buf;
88         i2s_dma_rx_is_finished_t   rx_isFinish;
89         i2s_dma_callback_t         rx_callback;
90         i2s_dma_start_streaming_t  rx_start;
91         i2s_dma_wait_t             rx_wait;
92         i2s_dma_stop_t             rx_stop;
93         size_t rx_slice_len;
94
95         DB(id_t _type);
96
97 } I2sContext;
98
99 typedef struct I2s
100 {
101         I2sContext ctx;
102         struct I2sHardware *hw;
103 } I2s;
104
105 INLINE int i2s_write(I2s *i2s, uint32_t sample)
106 {
107         ASSERT(i2s->ctx.write);
108         return i2s->ctx.write(i2s, sample);
109 }
110
111
112 INLINE uint32_t i2s_read(I2s *i2s)
113 {
114         ASSERT(i2s->ctx.read);
115         return i2s->ctx.read(i2s);
116 }
117
118 /*
119  * Check if a dma transfer is finished.
120  *
121  * Useful for kernel-less applications.
122  */
123 INLINE bool i2s_dmaTxIsFinished(I2s *i2s)
124 {
125         ASSERT(i2s->ctx.tx_isFinish);
126         return i2s->ctx.tx_isFinish(i2s);
127 }
128
129 INLINE bool i2s_dmaRxIsFinished(I2s *i2s)
130 {
131         ASSERT(i2s->ctx.rx_isFinish);
132         return i2s->ctx.rx_isFinish(i2s);
133 }
134
135 INLINE void i2s_dmaTxBuffer(I2s *i2s, void *buf, size_t len)
136 {
137         ASSERT(i2s->ctx.tx_buf);
138         i2s->ctx.tx_buf(i2s, buf, len);
139 }
140
141 INLINE void i2s_dmaRxBuffer(I2s *i2s, void *buf, size_t len)
142 {
143         ASSERT(i2s->ctx.rx_buf);
144         i2s->ctx.rx_buf(i2s, buf, len);
145 }
146
147
148 INLINE void i2s_dmaTxWait(I2s *i2s)
149 {
150         ASSERT(i2s->ctx.tx_wait);
151         i2s->ctx.tx_wait(i2s);
152 }
153
154
155 INLINE void i2s_dmaStartTxStreaming(I2s *i2s, void *buf, size_t len, size_t slice_len, i2s_dma_callback_t callback)
156 {
157         ASSERT(i2s->ctx.tx_start);
158         ASSERT(len % slice_len == 0);
159         ASSERT(callback);
160
161         i2s->ctx.tx_callback = callback;
162         i2s->ctx.tx_slice_len = slice_len;
163         i2s->ctx.tx_start(i2s, buf, len, slice_len);
164 }
165
166 INLINE void i2s_dmaTxStop(I2s *i2s)
167 {
168         ASSERT(i2s->ctx.tx_stop);
169         i2s->ctx.tx_stop(i2s);
170 }
171
172 INLINE void i2s_dmaStartRxStreaming(I2s *i2s, void *buf, size_t len, size_t slice_len, i2s_dma_callback_t callback)
173 {
174         ASSERT(i2s->ctx.rx_start);
175         ASSERT(len % slice_len == 0);
176         ASSERT(callback);
177
178         i2s->ctx.rx_callback = callback;
179         i2s->ctx.rx_slice_len = slice_len;
180         i2s->ctx.rx_start(i2s, buf, len, slice_len);
181 }
182
183 INLINE void i2s_dmaRxStop(I2s *i2s)
184 {
185         ASSERT(i2s->ctx.rx_stop);
186         i2s->ctx.rx_stop(i2s);
187 }
188
189 void i2s_init(I2s *i2s, int channel);
190
191 /** \} */ //defgroup i2s
192 #endif /* DRV_I2S_H */