2 * Copyright (c) 2015-2016, Texas Instruments Incorporated
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 /*!*****************************************************************************
35 * @brief I2S driver interface
37 * The I2S header file should be included in an application as follows:
39 * #include <ti/drivers/I2S.h>
43 * The I2S driver facilitates the use of Inter-IC Sound (I2S), which is
44 * used to connect digital audio devices so that audio signals can be
45 * communicated between devices. The I2S driver simplifies reading and
46 * writing to any of the Multichannel Audio Serial Port (McASP) peripherals
47 * on the board with Receive and Transmit support. These include blocking,
48 * non-blocking, read and write characters on the McASP peripheral.
50 * The APIs in this driver serve as an interface to a typical RTOS
51 * application. Its purpose is to redirect the I2S APIs to specific
52 * driver implementations which are specified using a pointer to an
54 * The specific peripheral implementations are responsible
55 * for creating all the RTOS specific primitives to allow for thread-safe
60 * To use the I2S driver for reaading and writing data to the I2S peripheral,
61 * the application calls the following APIs:
62 * - I2S_init(): Initialize the I2S driver.
63 * - I2S_Params_init(): Initialize a #I2S_Params structure with default
64 * vaules. Then change the parameters from non-default values as
66 * - I2S_open(): Open an instance of the I2S driver, passing the
67 * initialized parameters, or NULL, and an index (described later).
68 * - If using callback mode, I2S_read() and I2S_write().
69 * - If using issue/reclaim mode, I2S_readIssue(), I2S_readReclaim(),
70 * I2S_writeIssue() and I2S_writeReclaim().
71 * - I2S_close(): De-initialize the I2S instance.
73 * ### I2S Driver Configuration #
75 * In order to use the I2S APIs, the application is required
76 * to provide device-specific I2S configuration in the Board.c file.
77 * The I2S driver interface defines a configuration data structure:
80 * typedef struct I2S_Config_ {
81 * // Pointer to driver-specific implementation of I2S functions
82 * I2S_FxnTable const *fxnTablePtr;
83 * void *object; // Driver specific data object
84 * void const *hwAttrs; // Driver specific hardware attributes
88 * The application must declare an array of I2S_Config elements, named
89 * I2S_config[]. Each element of I2S_config[] must be populated with
90 * pointers to a device specific I2S driver implementation's function
91 * table, driver object, and hardware attributes. The hardware attributes
92 * define properties such as the I2S peripheral's base address and pins.
93 * Each element in I2S_config[] corresponds to an I2S instance, and
94 * and none of the elements should have NULL pointers.
95 * There is no correlation between the index and the peripheral
96 * designation (such as I2S0 or I2S1). For example, it is possible
97 * to use I2S_config[0] for I2S1.
99 * Because I2S configuration is very device dependent, you will need to
100 * check the doxygen for the device specific I2S implementation. There you
101 * will find a description of the I2S hardware attributes. Please also
102 * refer to the board.c file of any of your examples to see the I2S
105 * ### Initializing the I2S Driver #
107 * I2S_init() must be called before any other I2S APIs. This function
108 * iterates through the elements of the I2S_config[] array, calling
109 * the element's device implementation I2S initialization function.
113 * The #I2S_Params structure is passed to the I2S_open() call. If NULL
114 * is passed for the parameters, I2S_open() uses default parameters.
115 * An #I2S_Params structure is initialized with default values by passing
116 * it to I2S_Params_init().
117 * Some of the I2S parameters are described below. To see brief descriptions
118 * of all the parameters, see #I2S_Params.
120 * #### I2S Operation Mode
121 * The I2S operation mode determines whether transmit and/or receive modes
122 * are enabled. The mode is specified with one of the following constants:
123 * - #I2S_OPMODE_TX_ONLY: Enable transmit only.
124 * - #I2S_OPMODE_RX_ONLY: Enable receive only.
125 * - #I2S_OPMODE_TX_RX_SYNC: Enable both receive and transmit.
128 * A separate data mode may be specified for read calls and write calls.
129 * The available modes are:
130 * - #I2S_MODE_CALLBACK: This mode is non-blocking. Calls to I2S_read() or
131 * I2S_write() return immediately. When the transfer is finished, the
132 * user configured callback function is called.
133 * - #I2S_MODE_ISSUERECLAIM: Call I2S_readIssue() and I2S_writeIssue() to
134 * queue buffers to the I2S. I2S_readReclaim() blocks until a buffer
135 * of data is available. I2S_writeReclaim() blocks until a buffer of
136 * data has been issued and the descriptor can be returned back to the
139 * ### Opening the I2S Driver #
140 * After initializing the I2S driver by calling I2S_init(), the application
141 * can open an I2S instance by calling I2S_open(). This function
142 * takes an index into the I2S_config[] array, and an I2S parameters data
143 * structure. The I2S instance is specified by the index of the I2S in
144 * I2S_config[]. Only one I2S index can be used at a time;
145 * calling I2S_open() a second time with the same index previosly
146 * passed to I2S_open() will result in an error. You can,
147 * though, re-use the index if the instance is closed via I2S_close().
149 * If NULL is passed for the I2S_Params structure to I2S_open(), default values
150 * are used. If the open call is successful, it returns a non-NULL value.
152 * Example opening an I2S driver instance:
157 * I2S_Params_init(¶ms);
158 * params.operationMode = I2S_MODE_TX_RX_SYNC;
159 * < Change other params as required >
161 * handle = I2S_open(Board_I2S0, ¶ms);
163 * // Error opening I2S, handle accordingly
168 * The following example calls I2S_writeIssue() to write to an I2S driver
169 * instance that has been opened. It first queues up two buffers of text.
170 * Within an infinite loop, it calls I2S_writeReclaim() to retrieve a
171 * buffer and then re-queues the buffer.
174 * const unsigned char hello[] = "Hello World\n";
175 * const unsigned char hello1[] = "Hello World1\n";
176 * I2S_BufDesc writeBuffer1;
177 * I2S_BufDesc writeBuffer2;
178 * I2S_BufDesc *pDesc = NULL;
180 * writeBuffer1.bufPtr = &hello;
181 * writeBuffer1.bufSize = sizeof(hello);
182 * writeBuffer2.bufPtr = &hello1;
183 * writeBuffer2.bufSize = sizeof(hello1);
185 * ret = I2S_writeIssue(handle, &writeBuffer1);
186 * ret = I2S_writeIssue(handle, &writeBuffer2);
189 * ret = I2S_writeReclaim(handle, &pDesc);
190 * pDesc->bufPtr = &hello;;
191 * pDesc->bufSize = sizeof(hello);
192 * ret = I2S_writeIssue(handle, pDesc);
198 * The following example calls I2S_readIssue() to queue a buffer for
199 * reading from an I2S driver instance. It first queues up two buffers of
200 * text. Within an infinite loop, it then calls I2S_readReclaim() to retrieve
201 * a full buffer of data.
204 * unsigned char rxBuffer[20];
205 * unsigned char rxBuffer1[20];
206 * I2S_BufDesc readBuffer1;
207 * I2S_BufDesc readBuffer2;
208 * I2S_BufDesc *pDesc = NULL;
210 * readBuffer1.bufPtr = &rxBuffer;
211 * readBuffer1.bufSize = 20;
212 * readBuffer2.bufPtr = &rxBuffer1;
213 * readBuffer2.bufSize = 20;
215 * ret = I2S_readIssue(handle, &readBuffer1);
216 * ret = I2S_readIssue(handle, &readBuffer2);
220 * ret = I2S_readReclaim(handle, &pDesc);
221 * pDesc->bufPtr = &rxBuffer;
222 * pDesc->bufSize = 20;
223 * ret = I2S_readIssue(handle, pDesc);
229 * The I2S driver interface module is joined (at link time) to an
230 * array of I2S_Config data structures named *I2S_config*.
231 * *I2S_config* is implemented in the application with each entry being an
232 * instance of a I2S peripheral. Each entry in *I2S_config* contains a:
233 * - (I2S_FxnTable *) to a set of functions that implement a I2S peripheral
234 * - (void *) data object that is associated with the I2S_FxnTable
235 * - (void *) hardware attributes that are associated to the I2S_FxnTable
237 *******************************************************************************
240 #ifndef ti_drivers_I2S__include
241 #define ti_drivers_I2S__include
250 #include <ti/drivers/utils/List.h>
253 * @defgroup I2S_CONTROL I2S_control command and status codes
254 * These I2S macros are reservations for I2S.h
259 * Common I2S_control command code reservation offset.
260 * I2S driver implementations should offset command codes with I2S_CMD_RESERVED
263 * Example implementation specific command codes:
265 * #define I2SXYZ_CMD_COMMAND0 I2S_CMD_RESERVED + 0
266 * #define I2SXYZ_CMD_COMMAND1 I2S_CMD_RESERVED + 1
269 #define I2S_CMD_RESERVED (32)
272 * Common I2S_control status code reservation offset.
273 * I2S driver implementations should offset status codes with
274 * I2S_STATUS_RESERVED growing negatively.
276 * Example implementation specific status codes:
278 * #define I2SXYZ_STATUS_ERROR0 I2S_STATUS_RESERVED - 0
279 * #define I2SXYZ_STATUS_ERROR1 I2S_STATUS_RESERVED - 1
280 * #define I2SXYZ_STATUS_ERROR2 I2S_STATUS_RESERVED - 2
283 #define I2S_STATUS_RESERVED (-32)
286 * @defgroup I2S_STATUS Status Codes
287 * I2S_STATUS_* macros are general status codes returned by I2S_control()
289 * @ingroup I2S_CONTROL
293 * @brief Successful status code returned by I2S_control().
295 * I2S_control() returns I2S_STATUS_SUCCESS if the control code was executed
298 #define I2S_STATUS_SUCCESS (0)
301 * @brief Generic error status code returned by I2S_control().
303 * I2S_control() returns I2S_STATUS_ERROR if the control code was not executed
306 #define I2S_STATUS_ERROR (-1)
309 * @brief An error status code returned by I2S_control() for undefined
312 * I2S_control() returns I2S_STATUS_UNDEFINEDCMD if the control code is not
313 * recognized by the driver implementation.
315 #define I2S_STATUS_UNDEFINEDCMD (-2)
319 * @defgroup I2S_CMD Command Codes
320 * I2S_CMD_* macros are general command codes for I2S_control(). Not all I2S
321 * driver implementations support these command codes.
323 * @ingroup I2S_CONTROL
326 /* Add I2S_CMD_<commands> here */
332 #define I2S_ERROR (I2S_STATUS_ERROR)
335 * @brief Wait forever define
337 #define I2S_WAIT_FOREVER (~(0U))
340 * @brief A handle that is returned from a I2S_open() call.
342 typedef struct I2S_Config_ *I2S_Handle;
345 * @brief I2S buffer descriptor for issue/reclaim mode.
347 typedef struct I2S_BufDesc_ {
349 /*! Used internally to link descriptors together */
352 /*! Pointer to the buffer */
355 /*! Size of the buffer (target MAUs). */
358 /*! Optional argument associated with the descriptor. */
363 * @brief The definition of a callback function used by the I2S driver
364 * when used in ::I2S_MODE_CALLBACK
366 * @param I2S_Handle I2S_Handle
368 * @param buf Pointer to read/write buffer
370 * @param count Number of elements read/written
372 typedef void (*I2S_Callback)(I2S_Handle handle, I2S_BufDesc *desc);
375 * @brief I2S mode settings
377 * This enum defines the read and write modes for the
380 typedef enum I2S_DataMode_ {
382 * Non-blocking and will return immediately. When the transfer by the intr
383 * is finished the configured callback function is called.
388 * Use I2S_readIssue, I2S_writeIssue calls to queue buffers to the
389 * I2S. I2S_readReclaim() blocks until a buffer of data is available.
390 * I2S_writeReclaim() blocks until a buffer of data has been written
391 * and the descriptor can be returned back to the caller.
393 I2S_MODE_ISSUERECLAIM
397 * @brief I2S mode settings
399 * This enumeration defines the mode for I2S operation.
401 typedef enum I2S_OpMode_ {
402 I2S_OPMODE_TX_ONLY, /*!< Only Transmit enabled */
403 I2S_OPMODE_RX_ONLY, /*!< Only Receive enabled */
404 I2S_OPMODE_TX_RX_SYNC /*!< Receive and Transmit are enabled in Sync */
408 * @brief I2S Serializer InActive state settings
410 * This enumeration defines the Serializer configuration
413 typedef enum I2S_SerInActiveConfig_ {
414 I2S_SERCONFIG_INACT_TRI_STATE, /*!< Inactive state to tristate */
415 I2S_SERCONFIG_INACT_LOW_LEVEL, /*!< Inactive state to low */
416 I2S_SERCONFIG_INACT_HIGH_LEVEL /*!< Inactive state to high */
417 } I2S_SerInActiveConfig;
420 * @brief I2S serial pin mode
422 * This enumeration defines the Serial pin configuration
424 typedef enum I2S_PinMode_ {
425 I2S_PINMODE_RX, /*!< Operate the pin in Rx mode */
426 I2S_PINMODE_TX, /*!< Operate the pin in Tx mode */
427 I2S_PINMODE_INACTIVE /*!< Pin in inactive mode */
431 * @brief Basic I2S Parameters
433 * I2S parameters are used to with the I2S_open() call. Default values for
434 * these parameters are set using I2S_Params_init().
436 * @sa I2S_Params_init()
438 typedef struct I2S_Params_ {
439 /*!< I2S operational mode */
440 I2S_OpMode operationMode;
442 /*!< I2S sampling frequency configuration in samples/second */
443 uint32_t samplingFrequency;
448 /*!< Bits per sample (Word length) */
449 uint8_t bitsPerSample;
451 /*!< Number of channels (slots per frame) */
454 /*!< Mode for all read calls */
455 I2S_DataMode readMode;
457 /*!< Pointer to read callback */
458 I2S_Callback readCallback;
460 /*!< Timeout for read semaphore */
461 uint32_t readTimeout;
463 /*!< Mode for all write calls */
464 I2S_DataMode writeMode;
466 /*!< Pointer to write callback */
467 I2S_Callback writeCallback;
469 /*!< Timeout for write semaphore */
470 uint32_t writeTimeout;
472 /*!< Pointer to device specific custom params */
477 * @brief A function pointer to a driver specific implementation of
480 typedef void (*I2S_CloseFxn) (I2S_Handle handle);
483 * @brief A function pointer to a driver specific implementation of
486 typedef int_fast16_t (*I2S_ControlFxn)(I2S_Handle handle,
491 * @brief A function pointer to a driver specific implementation of
494 typedef void (*I2S_InitFxn)(I2S_Handle handle);
497 * @brief A function pointer to a driver specific implementation of
500 typedef I2S_Handle (*I2S_OpenFxn)(I2S_Handle handle, I2S_Params *params);
503 * @brief A function pointer to a driver specific implementation of
506 typedef int_fast16_t (*I2S_IssueFxn)(I2S_Handle handle, I2S_BufDesc *desc);
509 * @brief A function pointer to a driver specific implementation of
512 typedef size_t (*I2S_ReclaimFxn)(I2S_Handle handle, I2S_BufDesc **desc);
515 * @brief The definition of a I2S function table that contains the
516 * required set of functions to control a specific I2S driver
519 typedef struct I2S_FxnTable_ {
520 /*! Function to close the specified peripheral */
521 I2S_CloseFxn closeFxn;
523 /*! Function to implementation specific control function */
524 I2S_ControlFxn controlFxn;
526 /*! Function to initialize the given data object */
529 /*! Function to open the specified peripheral */
532 /*! Function to queue a buffer for reading from the specified peripheral */
533 I2S_IssueFxn readIssueFxn;
535 /*! Function to retrieve a received buffer of data from the specified peripheral */
536 I2S_ReclaimFxn readReclaimFxn;
538 /*! Function to queue a buffer for writing from the specified peripheral */
539 I2S_IssueFxn writeIssueFxn;
541 /*! Function to retrieve a sent buffer of data from the specified peripheral */
542 I2S_ReclaimFxn writeReclaimFxn;
546 /*! @brief I2S Global configuration
548 * The I2S_Config structure contains a set of pointers used to characterize
549 * the I2S driver implementation.
551 * This structure needs to be defined before calling I2S_init() and it must
552 * not be changed thereafter.
556 typedef struct I2S_Config_ {
557 /*! Pointer to a table of a driver-specific implementation of I2S
559 I2S_FxnTable const *fxnTablePtr;
561 /*! Pointer to a driver specific data object */
564 /*! Pointer to a driver specific hardware attributes structure */
569 * @brief Function to close a given I2S peripheral specified by the I2S
572 * @pre I2S_open() had to be called first.
574 * @param handle A I2S_Handle returned from I2S_open
578 extern void I2S_close(I2S_Handle handle);
581 * @brief Function performs implementation specific features on a given
584 * Commands for I2S_control can originate from I2S.h or from
585 * implementation specific I2S*.h (_I2SCC32XX.h_, etc.. ) files.
586 * While commands from I2S.h are API portable across driver implementations,
587 * not all implementations may support all these commands.
588 * Conversely, commands from driver implementation specific I2S*.h files add
589 * unique driver capabilities but are not API portable across all I2S driver
592 * Commands supported by I2S.h follow a I2S_CMD_\<cmd\> naming
594 * Commands supported by I2S*.h follow a I2S*_CMD_\<cmd\> naming
596 * Each control command defines @b arg differently. The types of @b arg are
597 * documented with each command.
599 * See @ref I2S_CMD "I2S_control command codes" for command codes.
601 * See @ref I2S_STATUS "I2S_control return status codes" for status codes.
603 * @pre I2S_open() has to be called first.
605 * @param handle A I2S handle returned from I2S_open()
607 * @param cmd I2S.h or I2S*.h commands.
609 * @param arg An optional R/W (read/write) command argument
610 * accompanied with cmd
612 * @return Implementation specific return codes. Negative values indicate
613 * unsuccessful operations.
617 extern int_fast16_t I2S_control(I2S_Handle handle,
622 * @brief Function to initializes the I2S module
624 * @pre The I2S_config structure must exist and be persistent before this
625 * function can be called. This function must also be called before
626 * any other I2S driver APIs. This function call does not modify any
627 * peripheral registers.
629 extern void I2S_init(void);
632 * @brief Function to initialize a given I2S peripheral specified by the
633 * particular index value. The parameter specifies which mode the I2S
636 * @pre I2S controller has been initialized
638 * @param index Logical peripheral number for the I2S indexed into
639 * the I2S_config table
641 * @param params Pointer to an parameter block, if NULL it will use
642 * default values. All the fields in this structure are
645 * @return A I2S_Handle on success or a NULL on an error or if it has been
651 extern I2S_Handle I2S_open(uint_least8_t index, I2S_Params *params);
654 * @brief Function to initialize the I2S_Params struct to its defaults
656 * @param params An pointer to I2S_Params structure for
659 * Defaults values are:
661 * params.operationMode = #I2S_OPMODE_TX_RX_SYNC;
662 * params.samplingFrequency = 16000;
663 * params.slotLength = 16;
664 * params.bitsPerSample = 16;
665 * params.numChannels = 2;
666 * params.readMode = #I2S_MODE_ISSUERECLAIM;
667 * params.readCallback = NULL;
668 * params.readTimeout = #I2S_WAIT_FOREVER;
669 * params.writeMode = #I2S_MODE_ISSUERECLAIM;
670 * params.writeCallback = NULL;
671 * params.writeTimeout = #I2S_WAIT_FOREVER;
672 * params.customParams = NULL;
675 * @param params Parameter structure to initialize
677 extern void I2S_Params_init(I2S_Params *params);
680 * @brief Function to queue a buffer of data to the I2S in callback mode
683 * @param handle A I2S_Handle
685 * @param desc A pointer to a I2S_BufDesc object. The bufPtr
686 * and bufSize fields must be set to a buffer and the
687 * size of the buffer before passing to this function.
688 * @return Returns 0 if successful else would return
689 * I2S_STATUS_UNDEFINEDCMD on an error.
691 extern int_fast16_t I2S_read(I2S_Handle handle, I2S_BufDesc *desc);
695 * @brief Function to queue a buffer of data to the I2S in Issue/Reclaim
698 * @param handle A I2S_Handle
700 * @param desc A pointer to a I2S_BufDesc object. The bufPtr
701 * and bufSize fields must be set to a buffer and the
702 * size of the buffer before passing to this function.
703 * @return Returns 0 if successful else would return
704 * I2S_STATUS_UNDEFINEDCMD on an error.
707 extern int_fast16_t I2S_readIssue(I2S_Handle handle, I2S_BufDesc *desc);
710 * @brief Function to retrieve a full buffer of data read by the I2S.
712 * @param handle A I2S_Handle
714 * @param pDesc A pointer to a I2S_BufDesc pointer.
716 * @return Returns the number of bytes read from the I2S, or 0 on timeout.
718 extern size_t I2S_readReclaim(I2S_Handle handle, I2S_BufDesc **pDesc);
721 * @brief Function to queue a buffer of data to the I2S in
722 * callback mode for writing.
724 * @param handle A I2S_Handle
726 * @param desc A pointer to a I2S_BufDesc object. The bufPtr
727 * and bufSize fields must be set to a buffer and the
728 * size of the buffer before passing to this function.
729 * @return Returns 0 if successful else would return
730 * I2S_STATUS_UNDEFINEDCMD on an error.
732 extern int_fast16_t I2S_write(I2S_Handle handle, I2S_BufDesc *desc);
735 * @brief Function to queue a buffer of data to the I2S in
736 * Issue/Reclaim mode for writing.
738 * @param handle A I2S_Handle
740 * @param desc A pointer to a I2S_BufDesc object. The bufPtr
741 * and bufSize fields must be set to a buffer and the
742 * size of the buffer before passing to this function.
743 * @return Returns 0 if successful else would return
744 * I2S_STATUS_UNDEFINEDCMD on an error.
746 extern int_fast16_t I2S_writeIssue(I2S_Handle handle, I2S_BufDesc *desc);
749 * @brief Function to retrieve a buffer that the I2S has finished writing.
751 * @param handle A I2S_Handle
753 * @param pDesc A pointer to a I2S_BufDesc pointer.
755 * @return Returns the number of bytes that have been written to the I2S,
758 extern size_t I2S_writeReclaim(I2S_Handle handle, I2S_BufDesc **pDesc);
764 #endif /* ti_drivers_I2S__include */