1 /* -----------------------------------------------------------------------------
2  * Copyright (c) 2013-2014 ARM Ltd.
3  *
4  * This software is provided 'as-is', without any express or implied warranty.
5  * In no event will the authors be held liable for any damages arising from
6  * the use of this software. Permission is granted to anyone to use this
7  * software for any purpose, including commercial applications, and to alter
8  * it and redistribute it freely, subject to the following restrictions:
9  *
10  * 1. The origin of this software must not be misrepresented; you must not
11  *    claim that you wrote the original software. If you use this software in
12  *    a product, an acknowledgment in the product documentation would be
13  *    appreciated but is not required.
14  *
15  * 2. Altered source versions must be plainly marked as such, and must not be
16  *    misrepresented as being the original software.
17  *
18  * 3. This notice may not be removed or altered from any source distribution.
19  *
20  *
21  * $Date:        9. Dec 2014
22  * $Revision:    V1.00
23  *
24  * Project:      SAI (Serial Audio Interface) Driver definitions
25  * -------------------------------------------------------------------------- */
26 
27 /**
28 \defgroup sai_interface_gr SAI Interface
29 \brief   Driver API for Serial Audio Interface (%Driver_SAI.h)
30 \details
31 The <b>Serial Audio Interface</b> (SAI) implements a synchronous serial bus interface for connecting digital audio devices.
32 It is by far the most common mechanism used to transfer two channels of audio data between devices within a system. \b SAI
33 can transfer digital audio using various protocols:
34 - \ref Driver_SAI_I2S
35 - \ref Driver_SAI_MSB
36 - \ref Driver_SAI_LSB
37 - \ref Driver_SAI_PCM
38 - \ref Driver_SAI_AC97
39 - \ref Driver_SAI_User
40 
41 
42 <b>Block Diagram</b>
43 
44 <p>&nbsp;</p>
45 \image html SAI_Schematics.png "Simplified SAI Schematic"
46 <p>&nbsp;</p>
47 
48 
49 <b>SAI API</b>
50 
51 The following header files define the Application Programming Interface (API) for the SAI interface:
52   - \b %Driver_SAI.h : Driver API for Serial Audio Interface
53 
54 The driver implementation is a typical part of the
55 <a class="el" href="https://open-cmsis-pack.github.io/Open-CMSIS-Pack-Spec/main/html/index.html" target="_blank">Device Family Pack (DFP)</a> that supports the peripherals of the microcontroller family.
56 
57 
58 <b>Driver Functions</b>
59 
60 The driver functions are published in the access struct as explained in \ref DriverFunctions
61   - \ref ARM_DRIVER_SAI : access struct for SAI driver functions
62 
63 \section Driver_SAI_I2S I2S
64 <a href="https://en.wikipedia.org/wiki/I%C2%B2S" target="_blank">Integrated Interchip Sound</a> (\b I2S) is a serial bus
65 interface that connects digital audio devices together. It was introduced by Philips (now
66 <a href="https://www.nxp.com" target="_blank">NXP</a>) in the late 80's and last revised 1996. It uses pulse code modulation
67 to exchange the audio data between the devices. The following timing diagram explains the operation:
68 
69 \image html driver_sai_i2s.png
70 
71 I2S separates the clock (\b SCK) from the serial data (\b SD), resulting in a lower jitter. A complete audio data frame
72 consists of two slots, one for the left channel and one for the right. The slot size equals the data size.
73 The word select (\b WS) line lets the device know whether the left channel (WS is low) or the right channel (WS is high) is
74 currently being transmitted. WS has a 50% duty-cycle signal that has the same frequency as the sample frequency. It is an
75 early signal, meaning that the WS line changes one clock cycle before the actual data (SD) is transmitted (left or right).
76 The data on SD is always transmitted MSB first and can have a data size of 8 up to 32 bits.
77 
78 In terms of the CMSIS-Driver for SAI, the I2S protocol can be described as follows:
79 - Data Size: 8..32 (MSB first)
80 - Clock Polarity: Drive on falling edge, Capture on rising edge
81 - Frame Length: 2 * Data Size = 2 * Slot Size
82 - Frame Sync Width: Frame Length / 2
83 - Frame Sync Polarity: Active Low
84 - Frame Sync Early
85 - Slot Count: 2 (L R)
86 - Slot Size: Data Size
87 - Slot Offset: 0
88 
89 
90 \section Driver_SAI_MSB MSB Justified
91 \b MSB \b Justified is much like \ref Driver_SAI_I2S, with a few differences:
92 
93 \image html driver_sai_msb.png
94 
95 Unlike I2S, in MSB Justified the word select (\b WS) signals the left channel when it is active high and the right channel,
96 when it is active low. The signal changes when the first actual \b SD data is available. It might happen that a frame (left
97 or right) is not fully filled with data. In this case, all data after the LSB is forced to zero.
98 
99 In terms of the CMSIS-Driver for SAI, the MSB Justified protocol can be described as follows:
100 - Data Size: 8..32 (MSB first)
101 - Clock Polarity: Drive on falling edge, Capture on rising edge
102 - Frame Length: 2 * Slot Size
103 - Frame Sync Width: Frame Length / 2
104 - Frame Sync Polarity: Active High
105 - Slot Count: 2 (L R)
106 - Slot Size: Data Size or higher (16/32)
107 - Slot Offset: 0 (Zero padding after Data: Slot Size - Data Size)
108 
109 \section Driver_SAI_LSB LSB Justified
110 \b LSB \b Justified is much like \ref Driver_SAI_MSB, with the single difference that the padding 0's are sent before the
111 first actual data (MSB on \b SD):
112 
113 \image html driver_sai_lsb.png
114 
115 In terms of the CMSIS-Driver for SAI, the LSB Justified protocol can be described as follows:
116 - Data Size: 8..32 (MSB first)
117 - Clock Polarity: Drive on falling edge, Capture on rising edge
118 - Frame Length: 2*Slot Size
119 - Frame Sync Width: Frame Length / 2
120 - Frame Sync Polarity: Active High
121 - Slot Count: 2
122 - Slot Size: Data Size or higher (16/32)
123 - Slot Offset: Slot Size - Data Size (Zero padding before Data: Slot Size - Data Size)
124 
125 \section Driver_SAI_PCM PCM
126 <a href="https://en.wikipedia.org/wiki/Pulse-code_modulation" target="_blank">Pulse Code Modulation</a> (\b PCM) differs to
127 the previous protocols in a few ways:
128 
129 \image html driver_sai_pcm.png
130 
131 - Only one channel is transferred.
132 
133 - There are two types of synchronization modes available:
134   - In \b short \b frame sync mode, the falling edge of \b Frame \b Sync indicates the start of the serial data \b SD. \b Frame \b Sync is always
135     one clock cycle long.
136   - In \b long \b frame sync mode, the rising edge of \b Frame \b Sync indicates the start of the serial data \b SD. \b Frame \b Sync stays active
137     high for 13 clock cycles.
138 
139 In terms of the CMSIS-Driver for SAI, the PCM protocol can be described as follows:\n
140 \b PCM \b Short \b Frame
141 - Data Size: 8..32 (MSB first)
142 - Clock Polarity: Drive on falling edge, Capture on rising edge
143 - Frame Length: Slot Size
144 - Frame Sync Width: 1
145 - Frame Sync Polarity: Active High
146 - Frame Sync Early
147 - Slot Count: 1
148 - Slot Size: Data Size or higher (16/32)
149 - Slot Offset: 0
150 
151 \b PCM \b Long \b Frame
152 - Data Size: 16..32 (MSB first)
153 - Clock Polarity: Drive on falling edge, Capture on rising edge
154 - Frame Length: Slot Size
155 - Frame Sync Width: 13
156 - Frame Sync Polarity: Active High
157 - Slot Count: 1
158 - Slot Size: Data Size or higher (32)
159 - Slot Offset: 0
160 
161 \section Driver_SAI_AC97 AC'97
162 <a href="https://en.wikipedia.org/wiki/AC'97" target="_blank">Audio Codec '97</a> was developed by
163 <a href="https://www.intel.com" target="_blank">Intel</a>. It is composed of five wires: the clock (12.288 MHz), a sync
164 signal, a reset signal, and two data wires: sdata_out (contains the AC97 output) and sdata_in (contains the CODEC output).
165 For more information, consult the
166 <a href="https://inst.eecs.berkeley.edu/~cs150/Documents/ac97_r23.pdf" target="_blank">standard documentation</a>.
167 
168 \section Driver_SAI_User User Defined Protocol
169 Using the control structs of the CMSIS-Driver SAI, it is possible to create support for nearly all serial audio protocols
170 that are available today.
171 
172 \image html driver_sai_user.png
173 
174 The following properties can be configured for a user protocol:
175 - Data Size in bits (8..32)
176 - Data Bit Order: MSB first (default) or LSB first
177 - Clock Polarity:
178   - Driver on falling edge, Capture on rising edge (default)
179   - Driver on rising edge, Capture on falling edge
180 - Frame Length in bits
181 - Frame Sync Width in bits (default=1)
182 - Frame Sync Polarity: active high (default) or low
183 - Frame Sync Early: Sync signal one bit before the first bit of frame
184 - Slot Count: number of slots in frame (default=1)
185 - Slot Size: equal to data size (default) or 16 or 32-bit
186 - Slot Offset: offset of first data bit in slot (default=0)
187 
188 For more information, refer to \ref ARM_SAI_Control that explains the different configuration options in more detail.
189 
190 @{
191 */
192 
193 
194 /**
195 \struct     ARM_DRIVER_SAI
196 \details
197 The functions of the SAI driver are accessed by function pointers exposed by this structure.
198 Refer to \ref DriverFunctions for overview information.
199 
200 Each instance of an SAI interface provides such an access structure.
201 The instance is identified by a postfix number in the symbol name of the access structure, for example:
202  - \b Driver_SAI0 is the name of the access struct of the first instance (no. 0).
203  - \b Driver_SAI1 is the name of the access struct of the second instance (no. 1).
204 
205 A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_SAI<i>n</i>.
206 The default is \token{0}, which connects a middleware to the first instance of a driver.
207 *****************************************************************************************************************/
208 
209 /**
210 \struct     ARM_SAI_CAPABILITIES
211 \details
212 An SAI driver can be implemented with different capabilities (for example protocol support). The data fields of this
213 structure encode the capabilities implemented by this driver. If a certain hardware peripheral is not able to handle one
214 of the protocols directly (not advertised using ARM_SAI_CAPABILITIES), then it might be possible to implement it using
215 the \ref Driver_SAI_User (if supported).
216 
217 <b>Returned by:</b>
218   - \ref ARM_SAI_GetCapabilities
219 *****************************************************************************************************************/
220 
221 /**
222 \struct ARM_SAI_STATUS
223 \details
224 Structure with information about the status of the SAI. The data fields encode busy flags and error flags.
225 
226 <b>Returned by:</b>
227   - \ref ARM_SAI_GetStatus
228 *****************************************************************************************************************/
229 
230 /**
231 \typedef    ARM_SAI_SignalEvent_t
232 \details
233 Provides the typedef for the callback function \ref ARM_SAI_SignalEvent.
234 
235 <b>Parameter for:</b>
236   - \ref ARM_SAI_Initialize
237 *******************************************************************************************************************/
238 
239 
240 /****** SAI specific error codes *****/
241 /**
242 \defgroup sai_execution_status SAI Status Error Codes
243 \ingroup sai_interface_gr
244 \brief Negative values indicate errors (SAI has specific codes in addition to common \ref execution_status).
245 \details
246 The SAI driver has additional status error codes that are listed below.
247 \note
248 - In case multiple errors exist, only the first encountered error will be reported.
249 - errors ARM_SAI_ERROR_BIT_ORDER, ARM_SAI_ERROR_FRAME_SYNC_xxx, ARM_SAI_ERROR_SLOT_xxx will only be reported in \ref Driver_SAI_User mode.
250 - The SAI driver also returns the common \ref execution_status.
251 
252 @{
253 \def ARM_SAI_ERROR_SYNCHRONIZATION
254 The \b synchronization requested with the function \ref ARM_SAI_Control is not supported.
255 
256 \def ARM_SAI_ERROR_PROTOCOL
257 The \b protocol requested with the function \ref ARM_SAI_Control is not supported.
258 
259 \def ARM_SAI_ERROR_DATA_SIZE
260 The <b>data size</b> requested with the function \ref ARM_SAI_Control is not supported.
261 
262 \def ARM_SAI_ERROR_BIT_ORDER
263 The <b>bit order</b> requested with the function \ref ARM_SAI_Control is not supported.
264 
265 \def ARM_SAI_ERROR_MONO_MODE
266 The <b>mono mode</b> requested with the function \ref ARM_SAI_Control is not supported.
267 
268 \def ARM_SAI_ERROR_COMPANDING
269 The <b>companding</b> requested with the function \ref ARM_SAI_Control is not supported.
270 
271 \def ARM_SAI_ERROR_CLOCK_POLARITY
272 The <b>clock polarity</b> requested with the function \ref ARM_SAI_Control is not supported.
273 
274 \def ARM_SAI_ERROR_AUDIO_FREQ
275 The <b>audio frequency</b> requested with the function \ref ARM_SAI_Control is not supported.
276 
277 \def ARM_SAI_ERROR_MCLK_PIN
278 The <b>MCLK pin</b> setting requested with the function \ref ARM_SAI_Control is not supported.
279 
280 \def ARM_SAI_ERROR_MCLK_PRESCALER
281 The <b>MCLK prescaler</b> requested with the function \ref ARM_SAI_Control is not supported.
282 
283 \def ARM_SAI_ERROR_FRAME_LENGTH
284 The <b>frame length</b> requested with the function \ref ARM_SAI_Control is not supported.
285 
286 \def ARM_SAI_ERROR_FRAME_SYNC_WIDTH
287 The <b>frame sync width</b> requested with the function \ref ARM_SAI_Control is not supported.
288 
289 \def ARM_SAI_ERROR_FRAME_SYNC_POLARITY
290 The <b>frame sync polarity</b> requested with the function \ref ARM_SAI_Control is not supported.
291 
292 \def ARM_SAI_ERROR_FRAME_SYNC_EARLY
293 The <b>frame sync early</b> requested with the function \ref ARM_SAI_Control is not supported.
294 
295 \def ARM_SAI_ERROR_SLOT_COUNT
296 The <b>slot count</b> requested with the function \ref ARM_SAI_Control is not supported.
297 
298 \def ARM_SAI_ERROR_SLOT_SIZE
299 The <b>slot size</b> requested with the function \ref ARM_SAI_Control is not supported.
300 
301 \def ARM_SAI_ERROR_SLOT_OFFESET
302 The <b>slot offset</b> requested with the function \ref ARM_SAI_Control is not supported.
303 @}
304 */
305 
306 
307 /****** SAI Event *****/
308 /**
309 \defgroup SAI_events SAI Events
310 \ingroup sai_interface_gr
311 \brief The SAI driver generates call back events that are notified via the function \ref ARM_SAI_SignalEvent.
312 \details
313 This section provides the event values for the \ref ARM_SAI_SignalEvent callback function.
314 
315 The following call back notification events are generated:
316 @{
317 \def ARM_SAI_EVENT_SEND_COMPLETE
318 \def ARM_SAI_EVENT_RECEIVE_COMPLETE
319 \def ARM_SAI_EVENT_TX_UNDERFLOW
320 \def ARM_SAI_EVENT_RX_OVERFLOW
321 \def ARM_SAI_EVENT_FRAME_ERROR
322 @}
323 */
324 
325 
326 /**
327 \defgroup sai_control SAI Control Codes
328 \ingroup sai_interface_gr
329 \brief Many parameters of the SAI driver are configured using the \ref ARM_SAI_Control function.
330 \details
331 @{
332 The various SAI control codes define:
333   - \ref sai_configure_control specifies SAI configuration
334   - \ref sai_controls specifies SAI controls
335 
336 Refer to the \ref ARM_SAI_Control function for further details.
337 */
338 
339 
340 /**
341 \defgroup sai_configure_control SAI Configuration
342 \ingroup sai_control
343 \brief Specify Transmitter/Receiver configuration.
344 \details
345 @{
346 Configuration is specified by ORing \b ARM_SAI_CONFIGURE_<i>x</i> with the following parameters:
347  - \ref sai_mode_control
348  - \ref sai_sync_control
349  - \ref sai_protocol_control
350  - \ref sai_data_bits_control
351  - \ref sai_bit_order_control
352  - \ref sai_mono_control
353  - \ref sai_clock_pol_control
354  - \ref sai_companding_control
355  - \ref sai_mclk_pin_control
356 
357 Additional configuration specified by \em arg1:
358  - \ref sai_frame_control
359  - \ref sai_slot_control
360 
361 Additional configuration specified by \em arg2:
362  - <b>Audio Frequency</b> (Master only)
363  - \ref sai_mclk_pres_control
364 
365 \defgroup sai_mode_control SAI Mode
366 \ingroup sai_configure_control
367 \brief Defines Transmitter/Receiver mode.
368 \details
369 @{
370 \def ARM_SAI_MODE_MASTER
371 \def ARM_SAI_MODE_SLAVE
372 @}
373 
374 \defgroup sai_sync_control SAI Synchronization
375 \ingroup sai_configure_control
376 \brief Defines Transmitter/Receiver synchronization.
377 \details
378 @{
379 \def ARM_SAI_ASYNCHRONOUS
380 \def ARM_SAI_SYNCHRONOUS
381 @}
382 
383 \defgroup sai_protocol_control SAI Protocol
384 \ingroup sai_configure_control
385 \brief Defines Transmitter/Receiver protocol.
386 \details
387 @{
388 \def ARM_SAI_PROTOCOL_USER
389 \def ARM_SAI_PROTOCOL_I2S
390 \def ARM_SAI_PROTOCOL_MSB_JUSTIFIED
391 \def ARM_SAI_PROTOCOL_LSB_JUSTIFIED
392 \def ARM_SAI_PROTOCOL_PCM_SHORT
393 \def ARM_SAI_PROTOCOL_PCM_LONG
394 \def ARM_SAI_PROTOCOL_AC97
395 @}
396 
397 \defgroup sai_data_bits_control SAI Data Size
398 \ingroup sai_configure_control
399 \brief Defines data size in bits (per channel/slot).
400 \details
401 @{
402 \def ARM_SAI_DATA_SIZE(n)
403 @}
404 
405 \defgroup sai_bit_order_control SAI Bit Order
406 \ingroup sai_configure_control
407 \brief Defines the bit order.
408 \details
409 @{
410 \def ARM_SAI_MSB_FIRST
411 \def ARM_SAI_LSB_FIRST
412 @}
413 
414 \defgroup sai_mono_control SAI Mono Mode
415 \ingroup sai_configure_control
416 \brief Defines mono mode.
417 \details
418 @{
419 \def ARM_SAI_MONO_MODE
420 @}
421 
422 \defgroup sai_companding_control SAI Companding
423 \ingroup sai_configure_control
424 \brief Defines companding.
425 \details
426 @{
427 \def ARM_SAI_COMPANDING_NONE
428 \def ARM_SAI_COMPANDING_A_LAW
429 \def ARM_SAI_COMPANDING_U_LAW
430 @}
431 
432 \defgroup sai_clock_pol_control SAI Clock Polarity
433 \ingroup sai_configure_control
434 \brief Defines clock polarity.
435 \details
436 @{
437 \def ARM_SAI_CLOCK_POLARITY_0
438 \def ARM_SAI_CLOCK_POLARITY_1
439 @}
440 
441 \defgroup sai_frame_control SAI Frame
442 \ingroup sai_configure_control
443 \brief Defines frame.
444 \details
445 @{
446 \def ARM_SAI_FRAME_LENGTH(n)
447 \def ARM_SAI_FRAME_SYNC_WIDTH(n)
448 \def ARM_SAI_FRAME_SYNC_POLARITY_HIGH
449 \def ARM_SAI_FRAME_SYNC_POLARITY_LOW
450 \def ARM_SAI_FRAME_SYNC_EARLY
451 @}
452 
453 \defgroup sai_slot_control SAI Slot
454 \ingroup sai_configure_control
455 \brief Defines data slots.
456 \details
457 @{
458 \def ARM_SAI_SLOT_COUNT(n)
459 \def ARM_SAI_SLOT_SIZE_DEFAULT
460 \def ARM_SAI_SLOT_SIZE_16
461 \def ARM_SAI_SLOT_SIZE_32
462 \def ARM_SAI_SLOT_OFFSET(n)
463 @}
464 
465 \defgroup sai_mclk_pin_control SAI Master Clock Pin
466 \ingroup sai_configure_control
467 \brief Defines MCLK pin.
468 \details
469 @{
470 \def ARM_SAI_MCLK_PIN_INACTIVE
471 \def ARM_SAI_MCLK_PIN_OUTPUT
472 \def ARM_SAI_MCLK_PIN_INPUT
473 @}
474 
475 \defgroup sai_mclk_pres_control SAI Master Clock Prescaler
476 \ingroup sai_configure_control
477 \brief Defines MCLK prescaler.
478 \details
479 @{
480 \def ARM_SAI_MCLK_PRESCALER(n)
481 @}
482 
483 @}
484 */
485 
486 
487 /**
488 \defgroup sai_controls SAI Controls
489 \ingroup sai_control
490 \brief Specifies controls.
491 \details
492 @{
493 \def ARM_SAI_CONFIGURE_TX
494 \sa ARM_SAI_Control
495 \def ARM_SAI_CONFIGURE_RX
496 \sa ARM_SAI_Control
497 \def ARM_SAI_CONTROL_TX
498 \sa ARM_SAI_Control; ARM_SAI_Send
499 \def ARM_SAI_CONTROL_RX
500 \sa ARM_SAI_Control; ARM_SAI_Receive
501 \def ARM_SAI_MASK_SLOTS_TX
502 \sa ARM_SAI_Control; ARM_SAI_Send
503 \def ARM_SAI_MASK_SLOTS_RX
504 \sa ARM_SAI_Control; ARM_SAI_Receive
505 \def ARM_SAI_ABORT_SEND
506 \sa ARM_SAI_Control; ARM_SAI_Send
507 \def ARM_SAI_ABORT_RECEIVE
508 \sa ARM_SAI_Control; ARM_SAI_Receive
509 @}
510 */
511 
512 
513 /**
514 @}
515 */
516 // end group SAI_control
517 
518 
519 //
520 // Function documentation
521 //
522 
ARM_SAI_GetVersion(void)523 ARM_DRIVER_VERSION ARM_SAI_GetVersion (void)  {
524   return { 0, 0 };
525 }
526 /**
527 \fn ARM_DRIVER_VERSION ARM_SAI_GetVersion (void)
528 \details
529 The function \b ARM_SAI_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
530  - API version is the version of the CMSIS-Driver specification used to implement this driver.
531  - Driver version is source code version of the actual driver implementation.
532 
533 \b Example:
534 \code
535 extern ARM_DRIVER_SAI Driver_SAI0;
536 ARM_DRIVER_SAI *drv_info;
537 
538 void setup_sai (void)  {
539   ARM_DRIVER_VERSION  version;
540 
541   drv_info = &Driver_SAI0;
542   version = drv_info->GetVersion ();
543   if (version.api < 0x10A)  {      // requires at minimum API version 1.10 or higher
544     // error handling
545     return;
546   }
547 }
548 \endcode
549 *****************************************************************************************************************/
550 
ARM_SAI_GetCapabilities(void)551 ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void)  {
552   return {0};
553 }
554 /**
555 \details
556 \fn ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void)
557 The function \b  ARM_SAI_GetCapabilities retrieves information about the capabilities in this driver implementation.
558 The data fields of the struct \ref ARM_SAI_CAPABILITIES encode various capabilities, for example
559 supported protocols, or if a hardware is capable to create signal events using the \ref ARM_SAI_SignalEvent
560 callback function.
561 
562 \b Example:
563 \code
564 extern ARM_DRIVER_SAI Driver_SAI0;
565 ARM_DRIVER_SAI *drv_info;
566 
567 void read_capabilities (void)  {
568   ARM_SAI_CAPABILITIES drv_capabilities;
569 
570   drv_info = &Driver_SAI0;
571   drv_capabilities = drv_info->GetCapabilities ();
572   // interrogate capabilities
573 
574 }
575 \endcode
576 *****************************************************************************************************************/
577 
ARM_SAI_Initialize(ARM_SAI_SignalEvent_t cb_event)578 int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event)  {
579   return ARM_DRIVER_OK;
580 }
581 /**
582 \fn int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event)
583 \details
584 The function \b ARM_SAI_Initialize initializes the SAI interface. It is called when the middleware component starts
585 operation.
586 
587 The function performs the following operations:
588   - Initializes the required resources of the SAI interface.
589   - Registers the \ref ARM_SAI_SignalEvent callback function.
590 
591 The parameter \em cb_event is a pointer to the \ref ARM_SAI_SignalEvent callback function; use a NULL pointer
592 when no callback signals are required.
593 *****************************************************************************************************************/
594 
ARM_SAI_Uninitialize(void)595 int32_t ARM_SAI_Uninitialize (void)  {
596   return ARM_DRIVER_OK;
597 }
598 /**
599 \fn int32_t ARM_SAI_Uninitialize (void)
600 \details
601 The function \b ARM_SAI_Uninitialize de-initializes the resources of SAI interface.
602 
603 It is called when the middleware component stops operation and releases the software resources used by the interface.
604 *****************************************************************************************************************/
605 
ARM_SAI_PowerControl(ARM_POWER_STATE state)606 int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state)  {
607   return ARM_DRIVER_OK;
608 }
609 /**
610 \fn int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state)
611 \details
612 The function \b ARM_SAI_PowerControl allows you to control the power modes of the SAI interface.
613 
614 The parameter \em state sets the operation and can have the following values:
615   - \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
616                           Can be called multiple times. If the peripheral is already in this mode the function performs
617 						  no operation and returns with \ref ARM_DRIVER_OK.
618   - \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
619   - \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
620 
621 Refer to \ref CallSequence for more information.
622 *****************************************************************************************************************/
623 
ARM_SAI_Send(const void * data,uint32_t num)624 int32_t ARM_SAI_Send (const void *data, uint32_t num)  {
625   return ARM_DRIVER_OK;
626 }
627 /**
628 \fn int32_t ARM_SAI_Send (const void *data, uint32_t num)
629 \details
630 The function \b ARM_SAI_Send sends data to the SAI transmitter.
631 
632 The function parameters specify the buffer with \a data and the number \a num of items to send.
633 The item size is defined by the data type which depends on the configured number of data bits.
634 
635 Data type is:
636  - \em uint8_t when configured for \token{8} data bits
637  - \em uint16_t when configured for \token{9..16} data bits
638  - \em uint32_t when configured for \token{17..32} data bits
639 
640 Transmitter is enabled by calling \ref ARM_SAI_Control with \ref ARM_SAI_CONTROL_TX as the control parameter and \token{1} as
641 an argument. This starts the transmit engine which, generates a clock and frame sync signal in master mode and transmits the
642 data. In slave mode, clock and frame sync are generated by the external master. When mute is active, data is discarded and
643 zero values are transmitted.
644 
645 Calling the function <b>ARM_SAI_Send</b> only starts the send operation. The function is non-blocking and returns as soon as
646 the driver has started the operation (the driver typically configures DMA or the interrupt system for continuous transfer).
647 During the operation it is not allowed to call this function again. Also, the data buffer must stay allocated and the
648 contents of unsent data must not be modified. When the send operation is completed (requested number of items have been
649 sent), the event \ref ARM_SAI_EVENT_SEND_COMPLETE is generated. Progress of the send operation can be monitored by reading
650 the number of already sent items by calling the function \ref ARM_SAI_GetTxCount.
651 
652 The status of the transmitter can also be monitored by calling the function \ref ARM_SAI_GetStatus and checking the \em tx_busy flag,
653 which indicates if a transmission is still in progress.
654 
655 If the transmitter is enabled and data is to be sent but the send operation has not been started yet, then the event
656 \ref ARM_SAI_EVENT_TX_UNDERFLOW is generated.
657 
658 If an invalid synchronization frame is detected in slave mode, then the event \ref ARM_SAI_EVENT_FRAME_ERROR is generated (if
659 supported and reported by \em event_frame_error in \ref ARM_SAI_CAPABILITIES).
660 
661 The send operation can be aborted by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_ABORT_SEND.
662 *****************************************************************************************************************/
663 
ARM_SAI_Receive(void * data,uint32_t num)664 int32_t ARM_SAI_Receive (void *data, uint32_t num)  {
665   return ARM_DRIVER_OK;
666 }
667 /**
668 \fn int32_t ARM_SAI_Receive (void *data, uint32_t num)
669 \details
670 The function \b ARM_SAI_Receive is used to receive data from the SAI receiver. The function parameters specify the buffer for
671 \a data and the number \a num of items to receive. The item size is defined by the data type, which depends on the configured
672 number of data bits.
673 
674 Data type is:
675  - \em uint8_t when configured for \token{8} data bits
676  - \em uint16_t when configured for \token{9..16} data bits
677  - \em uint32_t when configured for \token{17..32} data bits
678 
679 The receiver is enabled by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_CONTROL_RX and the value \token{1}
680 for the parameter \em arg1. This starts the receive engine, which generates a clock and frame sync signal in master mode and receives
681 data. In slave mode, clock and frame sync are generated by the external master.
682 
683 Calling the function <b>ARM_SAI_Receive</b> only starts the receive operation. The function is non-blocking and returns as
684 soon as the driver has started the operation (the driver typically configures DMA or the interrupt system for continuous
685 transfer). During the operation, it is not allowed to call this function again. The data buffer must also stay allocated.
686 When receive operation is completed (the requested number of items have been received), the
687 \ref ARM_SAI_EVENT_RECEIVE_COMPLETE event is generated. Progress of the receive operation can also be monitored by reading
688 the number of items already received by calling the function \ref ARM_SAI_GetRxCount.
689 
690 The status of the receiver can also be monitored by calling the function \ref ARM_SAI_GetStatus and checking the \em rx_busy flag, which
691 indicates whether a reception is still in progress.
692 
693 When the receiver is enabled and data is received but the receive operation has not been started yet, then the event
694 \ref ARM_SAI_EVENT_RX_OVERFLOW is generated.
695 
696 If an invalid synchronization frame is detected in slave mode, then the event \ref ARM_SAI_EVENT_FRAME_ERROR is generated (if
697 supported and reported by \em event_frame_error in \ref ARM_SAI_CAPABILITIES).
698 
699 The receive operation can be aborted by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_ABORT_RECEIVE.
700 *****************************************************************************************************************/
701 
ARM_SAI_GetTxCount(void)702 uint32_t ARM_SAI_GetTxCount (void)  {
703   return 0;
704 }
705 /**
706 \fn uint32_t ARM_SAI_GetTxCount (void)
707 \details
708 The function \b ARM_SAI_GetTxCount returns the number of the currently transmitted data items during an \ref ARM_SAI_Send
709 operation.
710 *****************************************************************************************************************/
711 
ARM_SAI_GetRxCount(void)712 uint32_t ARM_SAI_GetRxCount (void)  {
713   return 0;
714 }
715 /**
716 \fn uint32_t ARM_SAI_GetRxCount (void)
717 \details
718 The function \b ARM_SAI_GetRxCount returns the number of the currently received data items during an \ref ARM_SAI_Receive
719 operation.
720 *****************************************************************************************************************/
721 
ARM_SAI_Control(uint32_t control,uint32_t arg1,uint32_t arg2)722 int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2)  {
723   return ARM_DRIVER_OK;
724 }
725 
726 /**
727 \fn int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2)
728 \details
729 The function \b ARM_SAI_Control controls the SAI interface and executes various operations.
730 
731 The parameter \em control specifies the operation. Values are listed in the table <a href="#sai_contrl_tab"><b>Parameter <i>control</i></b></a>.\n
732 The parameter \em arg1 provides,  depending on the operation,  additional information or sets values.
733 Refer to table <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>. \n
734 The parameter \em arg2 provides,  depending on the operation and/or \em arg1,  additional information or sets values.
735 
736 The driver provides a receiver/transmitter pair of signals.
737 In asynchronous operation mode, they operate completely independent from each other.
738 In synchronous operation mode, the synchronous channel uses the Clock (SCK) and Frame Sync (WS) signal from the asynchronous one
739 (control category <a href="#sai_sync"><b>Synchronization</b></a>).
740 
741 The clock polarity can be set for every protocol, regardless whether it is already predefined for I2S, MSB/LSB Jusitified
742 (control category <a href="#sai_clk_polarity"><b>Clock Polarity</b></a>).
743 
744 A master clock provides a faster clock from which the frame can be derived (usually 256 x faster than the normal frame clock).
745 You can use a master clock only in master mode. A slave will always have only one clock
746 (control category <a href="#master_clock"><b>Master Clock pin (MCLK)</b></a>).
747 
748 \anchor sai_contrl_tab
749 The table lists the operation values for \em control. Values from different categories can be ORed.
750 <table class="cmtable" summary="">
751 <tr><th> Parameter \em control              </th><th>                                       Bit </th><th>             Category      </th>
752     <th> Description                        </th></tr>
753 <tr><td> \ref ARM_SAI_CONFIGURE_TX          </td><td rowspan="8" style="text-align:right"> 0..7 </td><td rowspan="8"> Operation    </td>
754     <td> Configure transmitter. \em arg1 (see  <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>) and \em arg2 provide additional configuration.  </td></tr>
755 <tr><td> \ref ARM_SAI_CONFIGURE_RX          </td>
756     <td> Configure receiver. \em arg1 (see  <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>) and \em arg2 provide additional configuration.  </td></tr>
757 <tr><td> \ref ARM_SAI_CONTROL_TX                </td>
758     <td> Enable or disable transmitter and control mute;
759 	\em arg1.0 : \token{0=disable (default); 1=enable;} \em arg1.1 : \token{mute} (see \ref ARM_SAI_Send) </td></tr>
760 <tr><td> \ref ARM_SAI_CONTROL_RX            </td>
761     <td> Enable or disable receiver; \em arg1.0 : \token{0=disable (default); 1=enable} (see \ref ARM_SAI_Receive)  </td></tr>
762 <tr><td> \ref ARM_SAI_MASK_SLOTS_TX         </td>
763     <td> Mask transmitter slots; \em arg1 = \token{mask} (bit: 0=active, 1=inactive); all configured slots are active by default.  </td></tr>
764 <tr><td> \ref ARM_SAI_MASK_SLOTS_RX         </td>
765     <td> Mask receiver slots; \em arg1 = \token{mask} (bit: 0=active, 1=inactive); all configured slots are active by default.  </td></tr>
766 <tr><td> \ref ARM_SAI_ABORT_SEND            </td>
767     <td> Abort send operation (see \ref ARM_SAI_Send).  </td></tr>
768 <tr><td> \ref ARM_SAI_ABORT_RECEIVE         </td>
769     <td> Abort receive operation (see \ref ARM_SAI_Receive).  </td></tr>
770 <tr><td> \ref ARM_SAI_MODE_MASTER           </td><td rowspan="2" style="text-align:right"> 8    </td><td rowspan="2"> Mode             </td>
771     <td> Master mode. \em arg2 specifies the audio frequency in [Hz].  You can also set the <a href="#master_clock"><b>Master Clock pin</b></a>.</td></tr>
772 <tr><td> \ref ARM_SAI_MODE_SLAVE (default)  </td>
773     <td> Slave mode.  </td></tr>
774 <tr><td> \ref ARM_SAI_ASYNCHRONOUS (default)    \anchor sai_sync </td><td rowspan="2" style="text-align:right">  9  </td><td rowspan="2"> Synchronization </td>
775     <td> Asynchronous operation using own clock and sync signal.  </td></tr>
776 <tr><td> \ref ARM_SAI_SYNCHRONOUS               </td>
777     <td> Synchronous operation using clock and sync signal from other transmitter/receiver.  </td></tr>
778 <tr><td> \ref ARM_SAI_PROTOCOL_USER  (default)  </td><td rowspan="7" style="text-align:right"> 10..12 </td><td rowspan="7"> Protocol     </td>
779     <td> User defined                           </td></tr>
780 <tr><td> \ref ARM_SAI_PROTOCOL_I2S              </td>
781     <td> I2C                                    </td></tr>
782 <tr><td> \ref ARM_SAI_PROTOCOL_MSB_JUSTIFIED    </td>
783     <td> MSB (left) justified                   </td></tr>
784 <tr><td> \ref ARM_SAI_PROTOCOL_LSB_JUSTIFIED    </td>
785     <td> LSB (right) justified                  </td></tr>
786 <tr><td> \ref ARM_SAI_PROTOCOL_PCM_SHORT        </td>
787     <td> PCM with short frame                   </td></tr>
788 <tr><td> \ref ARM_SAI_PROTOCOL_PCM_LONG         </td>
789     <td> PCM with long frame                    </td></tr>
790 <tr><td> \ref ARM_SAI_PROTOCOL_AC97             </td>
791     <td> AC'97                                  </td></tr>
792 <tr><td> \ref ARM_SAI_DATA_SIZE(n)              </td><td style="text-align:right"> 13..17 </td><td> Data Size    </td>
793     <td> Data size in bits; the range for \em n is \token{8..32}. See also: <a href="#frame_slot_size"><b>Frame Slot Size</b></a>.    </td></tr>
794 <tr><td> \ref ARM_SAI_MSB_FIRST                 </td><td rowspan="2" style="text-align:right"> 18     </td><td rowspan="2"> Bit Order    </td>
795     <td> Data is transferred with MSB first.    </td></tr>
796 <tr><td> \ref ARM_SAI_LSB_FIRST                 </td>
797     <td> Data is transferred with LSB first (User protocol only, ignored otherwise).     </td></tr>
798 <tr><td> \ref ARM_SAI_MONO_MODE                 </td><td style="text-align:right"> 19     </td><td> Mono Mode</td>
799     <td> Only for I2S, MSB/LSB justified.
800 	     When using \ref Driver_SAI_I2S in mono mode, only data for a single channel is sent to and received from the driver.
801          Hardware will duplicate the data for the second channel on transmit and ignore the second channel on receive.    </td></tr>
802 <tr><td> \ref ARM_SAI_COMPANDING_NONE (default) </td><td rowspan="3" style="text-align:right"> 20..22 </td><td rowspan="3"> Companding    </td>
803     <td> No companding  </td></tr>
804 <tr><td> \ref ARM_SAI_COMPANDING_A_LAW          </td>
805     <td> A-Law companding (8-bit data)          </td></tr>
806 <tr><td> \ref ARM_SAI_COMPANDING_U_LAW          </td>
807     <td> u-Law companding (8-bit data)          </td></tr>
808 <tr><td> \ref ARM_SAI_CLOCK_POLARITY_0 &nbsp;(default)  \anchor sai_clk_polarity > </td><td rowspan="2" style="text-align:right">    23   </td><td rowspan="2"> Clock Polarity </td>
809     <td> Drive on falling edge, capture on rising  edge. </td></tr>
810 <tr><td> \ref ARM_SAI_CLOCK_POLARITY_1   &nbsp; \anchor master_clock </td>
811     <td> Drive on rising  edge, capture on falling edge. </td></tr>
812 <tr><td> \ref ARM_SAI_MCLK_PIN_INACTIVE &nbsp;(default)  </td><td rowspan="3" style="text-align:right"> 24..26 </td><td rowspan="3"> Master Clock pin (MCLK) </td>
813     <td> MCLK not used.                         </td></tr>
814 <tr><td> \ref ARM_SAI_MCLK_PIN_OUTPUT           </td>
815     <td> MCLK is output (Master mode only).     </td></tr>
816 <tr><td> \ref ARM_SAI_MCLK_PIN_INPUT            </td>
817     <td> MCLK is input (Master mode only).      </td></tr>
818 </table>
819 
820 \anchor sai_arg1_tab
821 The parameter \em arg1 provides frame-specific values depending on the \em control operation. Values from different categories can be ORed.
822 <table class="cmtable" summary="">
823 <tr><th nowrap> Parameter \em arg1       </th>
824     <th style="text-align:right">   Bit  </th>
825 	<th> Category                        </th>
826     <th> Description                     </th></tr>
827 <tr><td> \ref ARM_SAI_FRAME_LENGTH(n)    </td>
828     <td style="text-align:right">  0..9  </td>
829 	<td> Frame Length                    </td>
830     <td> Frame length in bits; the possible range for \em n is \token{8..1024}; default depends on protocol and data.    </td></tr>
831 <tr><td> \ref ARM_SAI_FRAME_SYNC_WIDTH(n)</td>
832     <td style="text-align:right"> 10..17 </td>
833 	<td> Frame Sync Width                </td>
834     <td> Frame Sync width in bits; the possible range for \em n is \token{1..256}; \token{default=1}; User protocol only, ignored otherwise.  </td></tr>
835 <tr><td> \ref ARM_SAI_FRAME_SYNC_POLARITY_HIGH   </td>
836     <td rowspan="2" style="text-align:right"> 18 </td>
837 	<td rowspan="2" style="white-spaces:nowrap"> Frame Sync Polarity  </td>
838     <td> Frame Sync is active high (default).    </td></tr>
839 <tr><td> \ref ARM_SAI_FRAME_SYNC_POLARITY_LOW    </td>
840     <td> Frame Sync is active low (User protocol only, ignored otherwise).   </td></tr>
841 <tr><td> \ref ARM_SAI_FRAME_SYNC_EARLY           </td>
842     <td style="text-align:right">  19  </td>
843 	<td> Frame Sync Early              </td>
844     <td> Frame Sync one bit before the first bit of the frame (User protocol only, ignored otherwise).                   </td></tr>
845 <tr><td> \ref ARM_SAI_SLOT_COUNT(n)              </td>
846     <td style="text-align:right"> 20..24         </td>
847 	<td> Frame Sync Count                        </td>
848     <td> Number of slots in frame; the possible range for \em n is \token{1..32}; default=\token{1};  User protocol only, ignored otherwise.  </td></tr>
849 <tr><td> \ref ARM_SAI_SLOT_SIZE_DEFAULT &nbsp; \anchor frame_slot_size  </td>
850     <td rowspan="3" style="text-align:right"> 25..26                </td>
851 	<td rowspan="3">  Frame Slot Size                               </td>
852     <td> Slot size is equal to data size (default).                 </td></tr>
853 <tr><td> \ref ARM_SAI_SLOT_SIZE_16                                  </td>
854     <td> Slot size is \token{16 bits} (User protocol only, ignored otherwise).     </td></tr>
855 <tr><td> \ref ARM_SAI_SLOT_SIZE_32                                  </td>
856     <td> Slot size is \token{32 bits} (User protocol only, ignored otherwise).     </td></tr>
857 <tr><td> \ref ARM_SAI_SLOT_OFFSET(n)     </td>
858     <td style="text-align:right"> 27..31 </td>
859 	<td> Frame Slot Offset               </td>
860     <td> Offset of first data bit in slot; The range for \em n is \token{0..31}; default=\token{0};  User protocol only, ignored otherwise.   </td></tr>
861 </table>
862 
863 
864 \anchor mckl_prescaler
865 Depending on the \em control operation, the parameter \em arg2 specifies the Master Clock (MCLK) prescaler and calculates the audio frequency automatically.
866 
867 Parameter \em arg2                       | MCLK Prescaler
868 :----------------------------------------|:--------------------------------------------
869 \ref ARM_SAI_MCLK_PRESCALER(n)           | MCLK prescaler; Audio frequency = MCLK/n; the range for \em n is \token{1..4096}; default=\token{1}.
870 
871 
872 \b Example
873 
874 \code
875 extern ARM_DRIVER_SAI Driver_SAI0;
876 
877 // configure Transmitter to Asynchronous Master: I2S Protocol, 16-bit data, 16kHz Audio frequency
878 status = Driver_SAI0.Control(ARM_SAI_CONFIGURE_TX |
879                              ARM_SAI_MODE_MASTER  |
880                              ARM_SAI_ASYNCHRONOUS |
881                              ARM_SAI_PROTOCOL_I2S |
882                              ARM_SAI_DATA_SIZE(16), 0, 16000);
883 
884 // configure Receiver to Asynchronous Master: I2S Protocol, 16-bit data, 16kHz Audio frequency
885 status = Driver_SAI0.Control(ARM_SAI_CONFIGURE_RX |
886                              ARM_SAI_MODE_MASTER  |
887                              ARM_SAI_ASYNCHRONOUS |
888                              ARM_SAI_PROTOCOL_I2S |
889                              ARM_SAI_DATA_SIZE(16), 0, 16000);
890 
891 // enable Transmitter
892 status = Driver_SAI0.Control(ARM_SAI_CONTROL_TX, 1, 0);
893 
894 // enable Receiver
895 status = Driver_SAI0.Control(ARM_SAI_CONTROL_RX, 1, 0);
896 \endcode
897 
898 *****************************************************************************************************************/
899 
ARM_SAI_GetStatus(void)900 ARM_SAI_STATUS ARM_SAI_GetStatus (void)  {
901   return { 0 };
902 }
903 /**
904 \fn ARM_SAI_STATUS ARM_SAI_GetStatus (void)
905 \details
906 The function \b ARM_SAI_GetStatus retrieves the current SAI interface status.
907 *****************************************************************************************************************/
908 
ARM_SAI_SignalEvent(uint32_t event)909 void ARM_SAI_SignalEvent (uint32_t event)  {
910   // function body
911 }
912 /**
913 \fn void ARM_SAI_SignalEvent (uint32_t event)
914 \details
915 The function \b ARM_SAI_SignalEvent is a callback function registered by the function \ref ARM_SAI_Initialize.
916 
917 The parameter \em event indicates one or more events that occurred during driver operation.
918 Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
919 
920 The following events can be generated:
921 
922 Parameter \em event                        | Bit | Description
923 ------------------------------------------ |:---:|:-----------
924 \ref ARM_SAI_EVENT_SEND_COMPLETE           |  0  | Occurs after call to \ref ARM_SAI_Send to indicate that all the data has been sent (or queued in transmit buffers). The driver is ready for the next call to \ref ARM_SAI_Send.
925 \ref ARM_SAI_EVENT_RECEIVE_COMPLETE        |  1  | Occurs after call to \ref ARM_SAI_Receive to indicate that all the data has been received. The driver is ready for the next call to \ref ARM_SAI_Receive.
926 \ref ARM_SAI_EVENT_TX_UNDERFLOW            |  2  | Occurs when data is to be sent but send operation has not been started. Data field \em tx_underflow = \token{1} of \ref ARM_SAI_STATUS.
927 \ref ARM_SAI_EVENT_RX_OVERFLOW             |  3  | Occurs when data is received but receive operation has not been started. Data field \em rx_underflow = \token{1} of \ref ARM_SAI_STATUS.
928 \ref ARM_SAI_EVENT_FRAME_ERROR             |  4  | Occurs in slave mode when invalid synchronization frame is detected. Data field \em  event_frame_error = \token{1} of \ref ARM_SAI_STATUS.
929 
930 *****************************************************************************************************************/
931 
932 /**
933 @}
934 */
935 // End SAI Interface
936