1 /* -----------------------------------------------------------------------------
\r
2 * Copyright (c) 2013-2014 ARM Ltd.
\r
4 * This software is provided 'as-is', without any express or implied warranty.
\r
5 * In no event will the authors be held liable for any damages arising from
\r
6 * the use of this software. Permission is granted to anyone to use this
\r
7 * software for any purpose, including commercial applications, and to alter
\r
8 * it and redistribute it freely, subject to the following restrictions:
\r
10 * 1. The origin of this software must not be misrepresented; you must not
\r
11 * claim that you wrote the original software. If you use this software in
\r
12 * a product, an acknowledgment in the product documentation would be
\r
13 * appreciated but is not required.
\r
15 * 2. Altered source versions must be plainly marked as such, and must not be
\r
16 * misrepresented as being the original software.
\r
18 * 3. This notice may not be removed or altered from any source distribution.
\r
21 * $Date: 9. Dec 2014
\r
24 * Project: SAI (Serial Audio Interface) Driver definitions
\r
25 * -------------------------------------------------------------------------- */
\r
28 \defgroup sai_interface_gr SAI Interface
\r
29 \brief Driver API for Serial Audio Interface (%Driver_SAI.h)
\r
31 The <b>Serial Audio Interface</b> (SAI) implements a synchronous serial bus interface for connecting digital audio devices.
\r
32 It is by far the most common mechanism used to transfer two channels of audio data between devices within a system. \b SAI
\r
33 can transfer digital audio using various protocols:
\r
34 - \ref Driver_SAI_I2S
\r
35 - \ref Driver_SAI_MSB
\r
36 - \ref Driver_SAI_LSB
\r
37 - \ref Driver_SAI_PCM
\r
38 - \ref Driver_SAI_AC97
\r
39 - \ref Driver_SAI_User
\r
45 \image html SAI_Schematics.png "Simplified SAI Schematic"
\r
51 The following header files define the Application Programming Interface (API) for the SAI interface:
\r
52 - \b %Driver_SAI.h : Driver API for Serial Audio Interface
\r
54 The driver implementation is a typical part of the
\r
55 <a class="el" href="../../Pack/html/index.html" target="_blank">Device Family Pack (DFP)</a> that supports the peripherals of
\r
56 the microcontroller family.
\r
59 **Driver Functions**
\r
61 The driver functions are published in the access struct as explained in \ref DriverFunctions
\r
62 - \ref ARM_DRIVER_SAI : access struct for SAI driver functions
\r
64 \section Driver_SAI_I2S I2S
\r
65 <a href="https://en.wikipedia.org/wiki/I%C2%B2S" target="_blank">Integrated Interchip Sound</a> (\b I2S) is a serial bus
\r
66 interface that connects digital audio devices together. It was introduced by Philips (now
\r
67 <a href="http://www.nxp.com" target="_blank">NXP</a>) in the late 80's and last revised 1996. It uses pulse code modulation
\r
68 to exchange the audio data between the devices. The following timing diagram explains the operation:
\r
70 \image html driver_sai_i2s.png
\r
72 I2S separates the clock (\b SCK) from the serial data (\b SD), resulting in a lower jitter. A complete audio data frame
\r
73 consists of two slots, one for the left channel and one for the right. The slot size equals the data size.
\r
74 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
\r
75 currently being transmitted. WS has a 50% duty-cycle signal that has the same frequency as the sample frequency. It is an
\r
76 early signal, meaning that the WS line changes one clock cycle before the actual data (SD) is transmitted (left or right).
\r
77 The data on SD is always transmitted MSB first and can have a data size of 8 up to 32 bits.
\r
79 In terms of the CMSIS-Driver for SAI, the I2S protocol can be described as follows:
\r
80 - Data Size: 8..32 (MSB first)
\r
81 - Clock Polarity: Drive on falling edge, Capture on rising edge
\r
82 - Frame Length: 2 * Data Size = 2 * Slot Size
\r
83 - Frame Sync Width: Frame Length / 2
\r
84 - Frame Sync Polarity: Active Low
\r
86 - Slot Count: 2 (L R)
\r
87 - Slot Size: Data Size
\r
91 \section Driver_SAI_MSB MSB Justified
\r
92 \b MSB \b Justified is much like \ref Driver_SAI_I2S, with a few differences:
\r
94 \image html driver_sai_msb.png
\r
96 Unlike I2S, in MSB Justified the word select (\b WS) signals the left channel when it is active high and the right channel,
\r
97 when it is active low. The signal changes when the first actual \b SD data is available. It might happen that a frame (left
\r
98 or right) is not fully filled with data. In this case, all data after the LSB is forced to zero.
\r
100 In terms of the CMSIS-Driver for SAI, the MSB Justified protocol can be described as follows:
\r
101 - Data Size: 8..32 (MSB first)
\r
102 - Clock Polarity: Drive on falling edge, Capture on rising edge
\r
103 - Frame Length: 2 * Slot Size
\r
104 - Frame Sync Width: Frame Length / 2
\r
105 - Frame Sync Polarity: Active High
\r
106 - Slot Count: 2 (L R)
\r
107 - Slot Size: Data Size or higher (16/32)
\r
108 - Slot Offset: 0 (Zero padding after Data: Slot Size - Data Size)
\r
110 \section Driver_SAI_LSB LSB Justified
\r
111 \b LSB \b Justified is much like \ref Driver_SAI_MSB, with the single difference that the padding 0's are sent before the
\r
112 first actual data (MSB on \b SD):
\r
114 \image html driver_sai_lsb.png
\r
116 In terms of the CMSIS-Driver for SAI, the LSB Justified protocol can be described as follows:
\r
117 - Data Size: 8..32 (MSB first)
\r
118 - Clock Polarity: Drive on falling edge, Capture on rising edge
\r
119 - Frame Length: 2*Slot Size
\r
120 - Frame Sync Width: Frame Length / 2
\r
121 - Frame Sync Polarity: Active High
\r
123 - Slot Size: Data Size or higher (16/32)
\r
124 - Slot Offset: Slot Size - Data Size (Zero padding before Data: Slot Size - Data Size)
\r
126 \section Driver_SAI_PCM PCM
\r
127 <a href="https://en.wikipedia.org/wiki/Pulse-code_modulation" target="_blank">Pulse Code Modulation</a> (\b PCM) differs to
\r
128 the previous protocols in a few ways:
\r
130 \image html driver_sai_pcm.png
\r
132 - Only one channel is transferred.
\r
134 - There are two types of synchronization modes available:
\r
135 - 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
\r
136 one clock cycle long.
\r
137 - 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
\r
138 high for 13 clock cycles.
\r
140 In terms of the CMSIS-Driver for SAI, the PCM protocol can be described as follows:\n
\r
141 \b PCM \b Short \b Frame
\r
142 - Data Size: 8..32 (MSB first)
\r
143 - Clock Polarity: Drive on falling edge, Capture on rising edge
\r
144 - Frame Length: Slot Size
\r
145 - Frame Sync Width: 1
\r
146 - Frame Sync Polarity: Active High
\r
149 - Slot Size: Data Size or higher (16/32)
\r
152 \b PCM \b Long \b Frame
\r
153 - Data Size: 16..32 (MSB first)
\r
154 - Clock Polarity: Drive on falling edge, Capture on rising edge
\r
155 - Frame Length: Slot Size
\r
156 - Frame Sync Width: 13
\r
157 - Frame Sync Polarity: Active High
\r
159 - Slot Size: Data Size or higher (32)
\r
162 \section Driver_SAI_AC97 AC'97
\r
163 <a href="https://en.wikipedia.org/wiki/AC'97" target="_blank">Audio Codec '97</a> was developed by
\r
164 <a href="http://www.intel.com" target="_blank">Intel</a>. It is composed of five wires: the clock (12.288 MHz), a sync
\r
165 signal, a reset signal, and two data wires: sdata_out (contains the AC97 output) and sdata_in (contains the CODEC output).
\r
166 For more information, consult the
\r
167 <a href="http://download.intel.com/support/motherboards/desktop/sb/ac97_r23.pdf" target="_blank">standard documentation</a>.
\r
169 \section Driver_SAI_User User Defined Protocol
\r
170 Using the control structs of the CMSIS-Driver SAI, it is possible to create support for nearly all serial audio protocols
\r
171 that are available today.
\r
173 \image html driver_sai_user.png
\r
175 The following properties can be configured for a user protocol:
\r
176 - Data Size in bits (8..32)
\r
177 - Data Bit Order: MSB first (default) or LSB first
\r
179 - Driver on falling edge, Capture on rising edge (default)
\r
180 - Driver on rising edge, Capture on falling edge
\r
181 - Frame Length in bits
\r
182 - Frame Sync Width in bits (default=1)
\r
183 - Frame Sync Polarity: active high (default) or low
\r
184 - Frame Sync Early: Sync signal one bit before the first bit of frame
\r
185 - Slot Count: number of slots in frame (default=1)
\r
186 - Slot Size: equal to data size (default) or 16 or 32-bit
\r
187 - Slot Offset: offset of first data bit in slot (default=0)
\r
189 For more information, refer to \ref ARM_SAI_Control that explains the different configuration options in more detail.
\r
196 \struct ARM_DRIVER_SAI
\r
198 The functions of the SAI driver are accessed by function pointers exposed by this structure.
\r
199 Refer to \ref DriverFunctions for overview information.
\r
201 Each instance of an SAI interface provides such an access structure.
\r
202 The instance is identified by a postfix number in the symbol name of the access structure, for example:
\r
203 - \b Driver_SAI0 is the name of the access struct of the first instance (no. 0).
\r
204 - \b Driver_SAI1 is the name of the access struct of the second instance (no. 1).
\r
206 A middleware configuration setting allows connecting the middleware to a specific driver instance \b %Driver_SAI<i>n</i>.
\r
207 The default is \token{0}, which connects a middleware to the first instance of a driver.
\r
208 *****************************************************************************************************************/
\r
211 \struct ARM_SAI_CAPABILITIES
\r
213 An SAI driver can be implemented with different capabilities (for example protocol support). The data fields of this
\r
214 structure encode the capabilities implemented by this driver. If a certain hardware peripheral is not able to handle one
\r
215 of the protocols directly (not advertised using ARM_SAI_CAPABILITIES), then it might be possible to implement it using
\r
216 the \ref Driver_SAI_User (if supported).
\r
218 <b>Returned by:</b>
\r
219 - \ref ARM_SAI_GetCapabilities
\r
220 *****************************************************************************************************************/
\r
223 \struct ARM_SAI_STATUS
\r
225 Structure with information about the status of the SAI. The data fields encode busy flags and error flags.
\r
227 <b>Returned by:</b>
\r
228 - \ref ARM_SAI_GetStatus
\r
229 *****************************************************************************************************************/
\r
232 \typedef ARM_SAI_SignalEvent_t
\r
234 Provides the typedef for the callback function \ref ARM_SAI_SignalEvent.
\r
236 <b>Parameter for:</b>
\r
237 - \ref ARM_SAI_Initialize
\r
238 *******************************************************************************************************************/
\r
241 /****** SAI specific error codes *****/
\r
243 \defgroup sai_execution_status Status Error Codes
\r
244 \ingroup common_drv_gr
\r
245 \brief Negative values indicate errors (SAI has specific codes in addition to common \ref execution_status).
\r
247 The SAI driver has additional status error codes that are listed below.
\r
249 - In case multiple errors exist, only the first encountered error will be reported.
\r
250 - 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.
\r
251 - The SAI driver also returns the common \ref execution_status.
\r
254 \def ARM_SAI_ERROR_SYNCHRONIZATION
\r
255 The \b synchronization requested with the function \ref ARM_SAI_Control is not supported.
\r
257 \def ARM_SAI_ERROR_PROTOCOL
\r
258 The \b protocol requested with the function \ref ARM_SAI_Control is not supported.
\r
260 \def ARM_SAI_ERROR_DATA_SIZE
\r
261 The <b>data size</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
263 \def ARM_SAI_ERROR_BIT_ORDER
\r
264 The <b>bit order</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
266 \def ARM_SAI_ERROR_MONO_MODE
\r
267 The <b>mono mode</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
269 \def ARM_SAI_ERROR_COMPANDING
\r
270 The <b>companding</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
272 \def ARM_SAI_ERROR_CLOCK_POLARITY
\r
273 The <b>clock polarity</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
275 \def ARM_SAI_ERROR_AUDIO_FREQ
\r
276 The <b>audio frequency</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
278 \def ARM_SAI_ERROR_MCLK_PIN
\r
279 The <b>MCLK pin</b> setting requested with the function \ref ARM_SAI_Control is not supported.
\r
281 \def ARM_SAI_ERROR_MCLK_PRESCALER
\r
282 The <b>MCLK prescaler</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
284 \def ARM_SAI_ERROR_FRAME_LENGHT
\r
285 The <b>frame length</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
287 \def ARM_SAI_ERROR_FRAME_SYNC_WIDTH
\r
288 The <b>frame sync width</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
290 \def ARM_SAI_ERROR_FRAME_SYNC_POLARITY
\r
291 The <b>frame sync polarity</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
293 \def ARM_SAI_ERROR_FRAME_SYNC_EARLY
\r
294 The <b>frame sync early</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
296 \def ARM_SAI_ERROR_SLOT_COUNT
\r
297 The <b>slot count</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
299 \def ARM_SAI_ERROR_SLOT_SIZE
\r
300 The <b>slot size</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
302 \def ARM_SAI_ERROR_SLOT_OFFESET
\r
303 The <b>slot offset</b> requested with the function \ref ARM_SAI_Control is not supported.
\r
308 /****** SAI Event *****/
\r
310 \defgroup SAI_events SAI Events
\r
311 \ingroup sai_interface_gr
\r
312 \brief The SAI driver generates call back events that are notified via the function \ref ARM_SAI_SignalEvent.
\r
314 This section provides the event values for the \ref ARM_SAI_SignalEvent callback function.
\r
316 The following call back notification events are generated:
\r
318 \def ARM_SAI_EVENT_SEND_COMPLETE
\r
319 \def ARM_SAI_EVENT_RECEIVE_COMPLETE
\r
320 \def ARM_SAI_EVENT_TX_UNDERFLOW
\r
321 \def ARM_SAI_EVENT_RX_OVERFLOW
\r
322 \def ARM_SAI_EVENT_FRAME_ERROR
\r
328 \defgroup sai_control SAI Control Codes
\r
329 \ingroup sai_interface_gr
\r
330 \brief Many parameters of the SAI driver are configured using the \ref ARM_SAI_Control function.
\r
333 The various SAI control codes define:
\r
334 - \ref sai_configure_control specifies SAI configuration
\r
335 - \ref sai_controls specifies SAI controls
\r
337 Refer to the \ref ARM_SAI_Control function for further details.
\r
342 \defgroup sai_configure_control SAI Configuration
\r
343 \ingroup sai_control
\r
344 \brief Specify Transmitter/Receiver configuration.
\r
347 Configuration is specified by ORing \b ARM_SAI_CONFIGURE_<i>x</i> with the following parameters:
\r
348 - \ref sai_mode_control
\r
349 - \ref sai_sync_control
\r
350 - \ref sai_protocol_control
\r
351 - \ref sai_data_bits_control
\r
352 - \ref sai_bit_order_control
\r
353 - \ref sai_mono_control
\r
354 - \ref sai_clock_pol_control
\r
355 - \ref sai_companding_control
\r
356 - \ref sai_mclk_pin_control
\r
358 Additional configuration specified by \em arg1:
\r
359 - \ref sai_frame_control
\r
360 - \ref sai_slot_control
\r
362 Additional configuration specified by \em arg2:
\r
363 - <b>Audio Frequency</b> (Master only)
\r
364 - \ref sai_mclk_pres_control
\r
366 \defgroup sai_mode_control SAI Mode
\r
367 \ingroup sai_configure_control
\r
368 \brief Defines Transmitter/Receiver mode.
\r
371 \def ARM_SAI_MODE_MASTER
\r
372 \def ARM_SAI_MODE_SLAVE
\r
375 \defgroup sai_sync_control SAI Synchronization
\r
376 \ingroup sai_configure_control
\r
377 \brief Defines Transmitter/Receiver synchronization.
\r
380 \def ARM_SAI_ASYNCHRONOUS
\r
381 \def ARM_SAI_SYNCHRONOUS
\r
384 \defgroup sai_protocol_control SAI Protocol
\r
385 \ingroup sai_configure_control
\r
386 \brief Defines Transmitter/Receiver protocol.
\r
389 \def ARM_SAI_PROTOCOL_USER
\r
390 \def ARM_SAI_PROTOCOL_I2S
\r
391 \def ARM_SAI_PROTOCOL_MSB_JUSTIFIED
\r
392 \def ARM_SAI_PROTOCOL_LSB_JUSTIFIED
\r
393 \def ARM_SAI_PROTOCOL_PCM_SHORT
\r
394 \def ARM_SAI_PROTOCOL_PCM_LONG
\r
395 \def ARM_SAI_PROTOCOL_AC97
\r
398 \defgroup sai_data_bits_control SAI Data Size
\r
399 \ingroup sai_configure_control
\r
400 \brief Defines data size in bits (per channel/slot).
\r
403 \def ARM_SAI_DATA_SIZE(n)
\r
406 \defgroup sai_bit_order_control SAI Bit Order
\r
407 \ingroup sai_configure_control
\r
408 \brief Defines the bit order.
\r
411 \def ARM_SAI_MSB_FIRST
\r
412 \def ARM_SAI_LSB_FIRST
\r
415 \defgroup sai_mono_control SAI Mono Mode
\r
416 \ingroup sai_configure_control
\r
417 \brief Defines mono mode.
\r
420 \def ARM_SAI_MONO_MODE
\r
423 \defgroup sai_companding_control SAI Companding
\r
424 \ingroup sai_configure_control
\r
425 \brief Defines companding.
\r
428 \def ARM_SAI_COMPANDING_NONE
\r
429 \def ARM_SAI_COMPANDING_A_LAW
\r
430 \def ARM_SAI_COMPANDING_U_LAW
\r
433 \defgroup sai_clock_pol_control SAI Clock Polarity
\r
434 \ingroup sai_configure_control
\r
435 \brief Defines clock polarity.
\r
438 \def ARM_SAI_CLOCK_POLARITY_0
\r
439 \def ARM_SAI_CLOCK_POLARITY_1
\r
442 \defgroup sai_frame_control SAI Frame
\r
443 \ingroup sai_configure_control
\r
444 \brief Defines frame.
\r
447 \def ARM_SAI_FRAME_LENGTH(n)
\r
448 \def ARM_SAI_FRAME_SYNC_WIDTH(n)
\r
449 \def ARM_SAI_FRAME_SYNC_POLARITY_HIGH
\r
450 \def ARM_SAI_FRAME_SYNC_POLARITY_LOW
\r
451 \def ARM_SAI_FRAME_SYNC_EARLY
\r
454 \defgroup sai_slot_control SAI Slot
\r
455 \ingroup sai_configure_control
\r
456 \brief Defines data slots.
\r
459 \def ARM_SAI_SLOT_COUNT(n)
\r
460 \def ARM_SAI_SLOT_SIZE_DEFAULT
\r
461 \def ARM_SAI_SLOT_SIZE_16
\r
462 \def ARM_SAI_SLOT_SIZE_32
\r
463 \def ARM_SAI_SLOT_OFFSET(n)
\r
466 \defgroup sai_mclk_pin_control SAI Master Clock Pin
\r
467 \ingroup sai_configure_control
\r
468 \brief Defines MCLK pin.
\r
471 \def ARM_SAI_MCLK_PIN_INACTIVE
\r
472 \def ARM_SAI_MCLK_PIN_OUTPUT
\r
473 \def ARM_SAI_MCLK_PIN_INPUT
\r
476 \defgroup sai_mclk_pres_control SAI Master Clock Prescaler
\r
477 \ingroup sai_configure_control
\r
478 \brief Defines MCLK prescaler.
\r
481 \def ARM_SAI_MCLK_PRESCALER(n)
\r
489 \defgroup sai_controls SAI Controls
\r
490 \ingroup sai_control
\r
491 \brief Specifies controls.
\r
494 \def ARM_SAI_CONFIGURE_TX
\r
495 \sa ARM_SAI_Control
\r
496 \def ARM_SAI_CONFIGURE_RX
\r
497 \sa ARM_SAI_Control
\r
498 \def ARM_SAI_CONTROL_TX
\r
499 \sa ARM_SAI_Control; ARM_SAI_Send
\r
500 \def ARM_SAI_CONTROL_RX
\r
501 \sa ARM_SAI_Control; ARM_SAI_Receive
\r
502 \def ARM_SAI_MASK_SLOTS_TX
\r
503 \sa ARM_SAI_Control; ARM_SAI_Send
\r
504 \def ARM_SAI_MASK_SLOTS_RX
\r
505 \sa ARM_SAI_Control; ARM_SAI_Receive
\r
506 \def ARM_SAI_ABORT_SEND
\r
507 \sa ARM_SAI_Control; ARM_SAI_Send
\r
508 \def ARM_SAI_ABORT_RECEIVE
\r
509 \sa ARM_SAI_Control; ARM_SAI_Receive
\r
517 // end group SAI_control
\r
521 // Function documentation
\r
524 ARM_DRIVER_VERSION ARM_SAI_GetVersion (void) {
\r
528 \fn ARM_DRIVER_VERSION ARM_SAI_GetVersion (void)
\r
530 The function \b ARM_SAI_GetVersion returns version information of the driver implementation in \ref ARM_DRIVER_VERSION
\r
531 - API version is the version of the CMSIS-Driver specification used to implement this driver.
\r
532 - Driver version is source code version of the actual driver implementation.
\r
536 extern ARM_DRIVER_SAI Driver_SAI0;
\r
537 ARM_DRIVER_SAI *drv_info;
\r
539 void setup_sai (void) {
\r
540 ARM_DRIVER_VERSION version;
\r
542 drv_info = &Driver_SAI0;
\r
543 version = drv_info->GetVersion ();
\r
544 if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
\r
550 *****************************************************************************************************************/
\r
552 ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void) {
\r
557 \fn ARM_SAI_CAPABILITIES ARM_SAI_GetCapabilities (void)
\r
558 The function \b ARM_SAI_GetCapabilities retrieves information about the capabilities in this driver implementation.
\r
559 The data fields of the struct \ref ARM_SAI_CAPABILITIES encode various capabilities, for example
\r
560 supported protocols, or if a hardware is capable to create signal events using the \ref ARM_SAI_SignalEvent
\r
565 extern ARM_DRIVER_SAI Driver_SAI0;
\r
566 ARM_DRIVER_SAI *drv_info;
\r
568 void read_capabilities (void) {
\r
569 ARM_SAI_CAPABILITIES drv_capabilities;
\r
571 drv_info = &Driver_SAI0;
\r
572 drv_capabilities = drv_info->GetCapabilities ();
\r
573 // interrogate capabilities
\r
577 *****************************************************************************************************************/
\r
579 int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event) {
\r
580 return ARM_DRIVER_OK;
\r
583 \fn int32_t ARM_SAI_Initialize (ARM_SAI_SignalEvent_t cb_event)
\r
585 The function \b ARM_SAI_Initialize initializes the SAI interface. It is called when the middleware component starts
\r
588 The function performs the following operations:
\r
589 - Initializes the required resources of the SAI interface.
\r
590 - Registers the \ref ARM_SAI_SignalEvent callback function.
\r
592 The parameter \em cb_event is a pointer to the \ref ARM_SAI_SignalEvent callback function; use a NULL pointer
\r
593 when no callback signals are required.
\r
594 *****************************************************************************************************************/
\r
596 int32_t ARM_SAI_Uninitialize (void) {
\r
597 return ARM_DRIVER_OK;
\r
600 \fn int32_t ARM_SAI_Uninitialize (void)
\r
602 The function \b ARM_SAI_Uninitialize de-initializes the resources of SAI interface.
\r
604 It is called when the middleware component stops operation and releases the software resources used by the interface.
\r
605 *****************************************************************************************************************/
\r
607 int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state) {
\r
608 return ARM_DRIVER_OK;
\r
611 \fn int32_t ARM_SAI_PowerControl (ARM_POWER_STATE state)
\r
613 The function \b ARM_SAI_PowerControl allows you to control the power modes of the SAI interface.
\r
615 The parameter \em state sets the operation and can have the following values:
\r
616 - \ref ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA.
\r
617 Can be called multiple times. If the peripheral is already in this mode the function performs
\r
618 no operation and returns with \ref ARM_DRIVER_OK.
\r
619 - \ref ARM_POWER_LOW : may use power saving. Returns \ref ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
\r
620 - \ref ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
\r
622 Refer to \ref CallSequence for more information.
\r
623 *****************************************************************************************************************/
\r
625 int32_t ARM_SAI_Send (const void *data, uint32_t num) {
\r
626 return ARM_DRIVER_OK;
\r
629 \fn int32_t ARM_SAI_Send (const void *data, uint32_t num)
\r
631 The function \b ARM_SAI_Send sends data to the SAI transmitter.
\r
633 The function parameters specify the buffer with \a data and the number \a num of items to send.
\r
634 The item size is defined by the data type which depends on the configured number of data bits.
\r
637 - \em uint8_t when configured for \token{8} data bits
\r
638 - \em uint16_t when configured for \token{9..16} data bits
\r
639 - \em uint32_t when configured for \token{17..32} data bits
\r
641 Transmitter is enabled by calling \ref ARM_SAI_Control with \ref ARM_SAI_CONTROL_TX as the control parameter and \token{1} as
\r
642 an argument. This starts the transmit engine which, generates a clock and frame sync signal in master mode and transmits the
\r
643 data. In slave mode, clock and frame sync are generated by the external master. When mute is active, data is discarded and
\r
644 zero values are transmitted.
\r
646 Calling the function <b>ARM_SAI_Send</b> only starts the send operation. The function is non-blocking and returns as soon as
\r
647 the driver has started the operation (the driver typically configures DMA or the interrupt system for continuous transfer).
\r
648 During the operation it is not allowed to call this function again. Also, the data buffer must stay allocated and the
\r
649 contents of unsent data must not be modified. When the send operation is completed (requested number of items have been
\r
650 sent), the event \ref ARM_SAI_EVENT_SEND_COMPLETE is generated. Progress of the send operation can be monitored by reading
\r
651 the number of already sent items by calling the function \ref ARM_SAI_GetTxCount.
\r
653 The status of the transmitter can also be monitored by calling the function \ref ARM_SAI_GetStatus and checking the \em tx_busy flag,
\r
654 which indicates if a transmission is still in progress.
\r
656 If the transmitter is enabled and data is to be sent but the send operation has not been started yet, then the event
\r
657 \ref ARM_SAI_EVENT_TX_UNDERFLOW is generated.
\r
659 If an invalid synchronization frame is detected in slave mode, then the event \ref ARM_SAI_EVENT_FRAME_ERROR is generated (if
\r
660 supported and reported by \em event_frame_error in \ref ARM_SAI_CAPABILITIES).
\r
662 The send operation can be aborted by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_ABORT_SEND.
\r
663 *****************************************************************************************************************/
\r
665 int32_t ARM_SAI_Receive (void *data, uint32_t num) {
\r
666 return ARM_DRIVER_OK;
\r
669 \fn int32_t ARM_SAI_Receive (void *data, uint32_t num)
\r
671 The function \b ARM_SAI_Receive is used to receive data from the SAI receiver. The function parameters specify the buffer for
\r
672 \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
\r
673 number of data bits.
\r
676 - \em uint8_t when configured for \token{8} data bits
\r
677 - \em uint16_t when configured for \token{9..16} data bits
\r
678 - \em uint32_t when configured for \token{17..32} data bits
\r
680 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}
\r
681 for the parameter \em arg1. This starts the receive engine, which generates a clock and frame sync signal in master mode and receives
\r
682 data. In slave mode, clock and frame sync are generated by the external master.
\r
684 Calling the function <b>ARM_SAI_Receive</b> only starts the receive operation. The function is non-blocking and returns as
\r
685 soon as the driver has started the operation (the driver typically configures DMA or the interrupt system for continuous
\r
686 transfer). During the operation, it is not allowed to call this function again. The data buffer must also stay allocated.
\r
687 When receive operation is completed (the requested number of items have been received), the
\r
688 \ref ARM_SAI_EVENT_RECEIVE_COMPLETE event is generated. Progress of the receive operation can also be monitored by reading
\r
689 the number of items already received by calling the function \ref ARM_SAI_GetRxCount.
\r
691 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
\r
692 indicates whether a reception is still in progress.
\r
694 When the receiver is enabled and data is received but the receive operation has not been started yet, then the event
\r
695 \ref ARM_SAI_EVENT_RX_OVERFLOW is generated.
\r
697 If an invalid synchronization frame is detected in slave mode, then the event \ref ARM_SAI_EVENT_FRAME_ERROR is generated (if
\r
698 supported and reported by \em event_frame_error in \ref ARM_SAI_CAPABILITIES).
\r
700 The receive operation can be aborted by calling the function \ref ARM_SAI_Control with the control parameter \ref ARM_SAI_ABORT_RECEIVE.
\r
701 *****************************************************************************************************************/
\r
703 uint32_t ARM_SAI_GetTxCount (void) {
\r
707 \fn uint32_t ARM_SAI_GetTxCount (void)
\r
709 The function \b ARM_SAI_GetTxCount returns the number of the currently transmitted data items during an \ref ARM_SAI_Send
\r
711 *****************************************************************************************************************/
\r
713 uint32_t ARM_SAI_GetRxCount (void) {
\r
717 \fn uint32_t ARM_SAI_GetRxCount (void)
\r
719 The function \b ARM_SAI_GetRxCount returns the number of the currently received data items during an \ref ARM_SAI_Receive
\r
721 *****************************************************************************************************************/
\r
723 int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2) {
\r
724 return ARM_DRIVER_OK;
\r
728 \fn int32_t ARM_SAI_Control (uint32_t control, uint32_t arg1, uint32_t arg2)
\r
730 The function \b ARM_SAI_Control controls the SAI interface and executes various operations.
\r
732 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
\r
733 The parameter \em arg1 provides, depending on the operation, additional information or sets values.
\r
734 Refer to table <a href="#sai_arg1_tab"><b>Parameter <i>arg1</i></b></a>. \n
\r
735 The parameter \em arg2 provides, depending on the operation and/or \em arg1, additional information or sets values.
\r
737 The driver provides a receiver/transmitter pair of signals.
\r
738 In asynchronous operation mode, they operate completely independent from each other.
\r
739 In synchronous operation mode, the synchronous channel uses the Clock (SCK) and Frame Sync (WS) signal from the asynchronous one
\r
740 (control category <a href="#sai_sync"><b>Synchronization</b></a>).
\r
742 The clock polarity can be set for every protocol, regardless whether it is already predefined for I2S, MSB/LSB Jusitified
\r
743 (control category <a href="#sai_clk_polarity"><b>Clock Polarity</b></a>).
\r
745 A master clock provides a faster clock from which the frame can be derived (usually 256 x faster than the normal frame clock).
\r
746 You can use a master clock only in master mode. A slave will always have only one clock
\r
747 (control category <a href="#master_clock"><b>Master Clock pin (MCLK)</b></a>).
\r
749 \anchor sai_contrl_tab
\r
750 The table lists the operation values for \em control. Values from different categories can be ORed.
\r
751 <table class="cmtable" summary="">
\r
752 <tr><th> Parameter \em control </th><th> Bit </th><th> Category </th>
\r
753 <th> Description </th></tr>
\r
754 <tr><td> \ref ARM_SAI_CONFIGURE_TX </td><td rowspan="9" style="text-align:right"> 0..7 </td><td rowspan="9"> Operation </td>
\r
755 <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>
\r
756 <tr><td> \ref ARM_SAI_CONFIGURE_TX </td>
\r
757 <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>
\r
758 <tr><td> \ref ARM_SAI_CONFIGURE_RX </td>
\r
759 <td> Configure transmitter. \em arg1 and \em arg2 provide additional configuration. </td></tr>
\r
760 <tr><td> \ref ARM_SAI_CONTROL_TX </td>
\r
761 <td> Enable or disable transmitter and control mute;
\r
762 \em arg1.0 : \token{0=disable (default); 1=enable;} \em arg1.1 : \token{mute} (see \ref ARM_SAI_Send) </td></tr>
\r
763 <tr><td> \ref ARM_SAI_CONTROL_RX </td>
\r
764 <td> Enable or disable receiver; \em arg1.0 : \token{0=disable (default); 1=enable} (see \ref ARM_SAI_Receive) </td></tr>
\r
765 <tr><td> \ref ARM_SAI_MASK_SLOTS_TX </td>
\r
766 <td> Mask transmitter slots; \em arg1 = \token{mask} (bit: 0=active, 1=inactive); all configured slots are active by default. </td></tr>
\r
767 <tr><td> \ref ARM_SAI_MASK_SLOTS_RX </td>
\r
768 <td> Mask receiver slots; \em arg1 = \token{mask} (bit: 0=active, 1=inactive); all configured slots are active by default. </td></tr>
\r
769 <tr><td> \ref ARM_SAI_ABORT_SEND </td>
\r
770 <td> Abort send operation (see \ref ARM_SAI_Send). </td></tr>
\r
771 <tr><td> \ref ARM_SAI_ABORT_RECEIVE </td>
\r
772 <td> Abort receive operation (see \ref ARM_SAI_Receive). </td></tr>
\r
773 <tr><td> \ref ARM_SAI_MODE_MASTER </td><td rowspan="2" style="text-align:right"> 8 </td><td rowspan="2"> Mode </td>
\r
774 <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>
\r
775 <tr><td> \ref ARM_SAI_MODE_SLAVE (default) </td>
\r
776 <td> Slave mode. </td></tr>
\r
777 <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>
\r
778 <td> Asynchronous operation using own clock and sync signal. </td></tr>
\r
779 <tr><td> \ref ARM_SAI_SYNCHRONOUS </td>
\r
780 <td> Synchronous operation using clock and sync signal from other transmitter/receiver. </td></tr>
\r
781 <tr><td> \ref ARM_SAI_PROTOCOL_USER (default) </td><td rowspan="7" style="text-align:right"> 10..12 </td><td rowspan="7"> Protocol </td>
\r
782 <td> User defined </td></tr>
\r
783 <tr><td> \ref ARM_SAI_PROTOCOL_I2S </td>
\r
784 <td> I2C </td></tr>
\r
785 <tr><td> \ref ARM_SAI_PROTOCOL_MSB_JUSTIFIED </td>
\r
786 <td> MSB (left) justified </td></tr>
\r
787 <tr><td> \ref ARM_SAI_PROTOCOL_LSB_JUSTIFIED </td>
\r
788 <td> LSB (right) justified </td></tr>
\r
789 <tr><td> \ref ARM_SAI_PROTOCOL_PCM_SHORT </td>
\r
790 <td> PCM with short frame </td></tr>
\r
791 <tr><td> \ref ARM_SAI_PROTOCOL_PCM_LONG </td>
\r
792 <td> PCM with long frame </td></tr>
\r
793 <tr><td> \ref ARM_SAI_PROTOCOL_AC97 </td>
\r
794 <td> AC'97 </td></tr>
\r
795 <tr><td> \ref ARM_SAI_DATA_SIZE(n) </td><td style="text-align:right"> 13..17 </td><td> Data Size </td>
\r
796 <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>
\r
797 <tr><td> \ref ARM_SAI_MSB_FIRST </td><td rowspan="2" style="text-align:right"> 18 </td><td rowspan="2"> Bit Order </td>
\r
798 <td> Data is transferred with MSB first. </td></tr>
\r
799 <tr><td> \ref ARM_SAI_LSB_FIRST </td>
\r
800 <td> Data is transferred with LSB first (User protocol only, ignored otherwise). </td></tr>
\r
801 <tr><td> \ref ARM_SAI_MONO_MODE </td><td style="text-align:right"> 19 </td><td> Mono Mode</td>
\r
802 <td> Only for I2S, MSB/LSB justified.
\r
803 When using \ref Driver_SAI_I2S in mono mode, only data for a single channel is sent to and received from the driver.
\r
804 Hardware will duplicate the data for the second channel on transmit and ignore the second channel on receive. </td></tr>
\r
805 <tr><td> \ref ARM_SAI_COMPANDING_NONE (default) </td><td rowspan="3" style="text-align:right"> 20..22 </td><td rowspan="3"> Companding </td>
\r
806 <td> No companding </td></tr>
\r
807 <tr><td> \ref ARM_SAI_COMPANDING_A_LAW </td>
\r
808 <td> A-Law companding (8-bit data) </td></tr>
\r
809 <tr><td> \ref ARM_SAI_COMPANDING_U_LAW </td>
\r
810 <td> u-Law companding (8-bit data) </td></tr>
\r
811 <tr><td> \ref ARM_SAI_CLOCK_POLARITY_0 (default) \anchor sai_clk_polarity > </td><td rowspan="2" style="text-align:right"> 23 </td><td rowspan="2"> Clock Polarity </td>
\r
812 <td> Drive on falling edge, capture on rising edge. </td></tr>
\r
813 <tr><td> \ref ARM_SAI_CLOCK_POLARITY_1 \anchor master_clock </td>
\r
814 <td> Drive on rising edge, capture on falling edge. </td></tr>
\r
815 <tr><td> \ref ARM_SAI_MCLK_PIN_INACTIVE (default) </td><td rowspan="3" style="text-align:right"> 24..26 </td><td rowspan="3"> Master Clock pin (MCLK) </td>
\r
816 <td> MCLK not used. </td></tr>
\r
817 <tr><td> \ref ARM_SAI_MCLK_PIN_OUTPUT </td>
\r
818 <td> MCLK is output (Master mode only). </td></tr>
\r
819 <tr><td> \ref ARM_SAI_MCLK_PIN_INPUT </td>
\r
820 <td> MCLK is input (Master mode only). </td></tr>
\r
823 \anchor sai_arg1_tab
\r
824 The parameter \em arg1 provides frame-specific values depending on the \em control operation. Values from different categories can be ORed.
\r
825 <table class="cmtable" summary="">
\r
826 <tr><th nowrap> Parameter \em arg1 </th>
\r
827 <th style="text-align:right"> Bit </th>
\r
828 <th> Category </th>
\r
829 <th> Description </th></tr>
\r
830 <tr><td> \ref ARM_SAI_FRAME_LENGTH(n) </td>
\r
831 <td style="text-align:right"> 0..9 </td>
\r
832 <td> Frame Length </td>
\r
833 <td> Frame length in bits; the possible range for \em n is \token{8..1024}; default depends on protocol and data. </td></tr>
\r
834 <tr><td> \ref ARM_SAI_FRAME_SYNC_WIDTH(n)</td>
\r
835 <td style="text-align:right"> 10..17 </td>
\r
836 <td> Frame Sync Width </td>
\r
837 <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>
\r
838 <tr><td> \ref ARM_SAI_FRAME_SYNC_POLARITY_HIGH </td>
\r
839 <td rowspan="2" style="text-align:right"> 18 </td>
\r
840 <td rowspan="2" style="white-spaces:nowrap"> Frame Sync Polarity </td>
\r
841 <td> Frame Sync is active high (default). </td></tr>
\r
842 <tr><td> \ref ARM_SAI_FRAME_SYNC_POLARITY_LOW </td>
\r
843 <td> Frame Sync is active low (User protocol only, ignored otherwise). </td></tr>
\r
844 <tr><td> \ref ARM_SAI_FRAME_SYNC_EARLY </td>
\r
845 <td style="text-align:right"> 19 </td>
\r
846 <td> Frame Sync Early </td>
\r
847 <td> Frame Sync one bit before the first bit of the frame (User protocol only, ignored otherwise). </td></tr>
\r
848 <tr><td> \ref ARM_SAI_SLOT_COUNT(n) </td>
\r
849 <td style="text-align:right"> 20..24 </td>
\r
850 <td> Frame Sync Count </td>
\r
851 <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>
\r
852 <tr><td> \ref ARM_SAI_SLOT_SIZE_DEFAULT \anchor frame_slot_size </td>
\r
853 <td rowspan="3" style="text-align:right"> 25..26 </td>
\r
854 <td rowspan="3"> Frame Slot Size </td>
\r
855 <td> Slot size is equal to data size (default). </td></tr>
\r
856 <tr><td> \ref ARM_SAI_SLOT_SIZE_16 </td>
\r
857 <td> Slot size is \token{16 bits} (User protocol only, ignored otherwise). </td></tr>
\r
858 <tr><td> \ref ARM_SAI_SLOT_SIZE_32 </td>
\r
859 <td> Slot size is \token{32 bits} (User protocol only, ignored otherwise). </td></tr>
\r
860 <tr><td> \ref ARM_SAI_SLOT_OFFSET(n) </td>
\r
861 <td style="text-align:right"> 27..31 </td>
\r
862 <td> Frame Slot Offset </td>
\r
863 <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>
\r
867 \anchor mckl_prescaler
\r
868 Depending on the \em control operation, the parameter \em arg2 specifies the Master Clock (MCLK) prescaler and calculates the audio frequency automatically.
\r
870 Parameter \em arg2 | MCLK Prescaler
\r
871 :----------------------------------------|:--------------------------------------------
\r
872 \ref ARM_SAI_MCLK_PRESCALER(n) | MCLK prescaler; Audio frequency = MCLK/n; the range for \em n is \token{1..4096}; default=\token{1}.
\r
878 extern ARM_DRIVER_SAI Driver_SAI0;
\r
880 // configure Transmitter to Asynchronous Master: I2S Protocol, 16-bit data, 16kHz Audio frequency
\r
881 status = Driver_SAI0.Control(ARM_SAI_CONFIGURE_TX |
\r
882 ARM_SAI_MODE_MASTER |
\r
883 ARM_SAI_ASYNCHRONOUS |
\r
884 ARM_SAI_PROTOCOL_I2S |
\r
885 ARM_SAI_DATA_SIZE(16), 0, 16000);
\r
887 // configure Receiver to Asynchronous Master: I2S Protocol, 16-bit data, 16kHz Audio frequency
\r
888 status = Driver_SAI0.Control(ARM_SAI_CONFIGURE_RX |
\r
889 ARM_SAI_MODE_MASTER |
\r
890 ARM_SAI_ASYNCHRONOUS |
\r
891 ARM_SAI_PROTOCOL_I2S |
\r
892 ARM_SAI_DATA_SIZE(16), 0, 16000);
\r
894 // enable Transmitter
\r
895 status = Driver_SAI0.Control(ARM_SAI_CONTROL_TX, 1, 0);
\r
898 status = Driver_SAI0.Control(ARM_SAI_CONTROL_RX, 1, 0);
\r
901 *****************************************************************************************************************/
\r
903 ARM_SAI_STATUS ARM_SAI_GetStatus (void) {
\r
907 \fn ARM_SAI_STATUS ARM_SAI_GetStatus (void)
\r
909 The function \b ARM_SAI_GetStatus retrieves the current SAI interface status.
\r
910 *****************************************************************************************************************/
\r
912 void ARM_SAI_SignalEvent (uint32_t event) {
\r
916 \fn void ARM_SAI_SignalEvent (uint32_t event)
\r
918 The function \b ARM_SAI_SignalEvent is a callback function registered by the function \ref ARM_SAI_Initialize.
\r
920 The parameter \em event indicates one or more events that occurred during driver operation.
\r
921 Each event is encoded in a separate bit and therefore it is possible to signal multiple events within the same call.
\r
923 The following events can be generated:
\r
925 Parameter \em event | Bit | Description
\r
926 ------------------------------------------ |:---:|:-----------
\r
927 \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.
\r
928 \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.
\r
929 \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.
\r
930 \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.
\r
931 \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.
\r
933 *****************************************************************************************************************/
\r
938 // End SAI Interface
\r