/*****************************************************************************
 * $Revision: 423 $
 * $Date: 2015-09-10 17:33:56 +0900#$
 *****************************************************************************/
/* __DISCLAIMER_START__                                                      */
/******************************************************************************
* (c)2017, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. All rights
* reserved.
*
* This software, including source code, documentation and related
* materials ( "Software" ), is owned by Cypress Semiconductor
* Corporation or one of its subsidiaries ( "Cypress" ) and is protected by
* and subject to worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ( "EULA" ).
*
* If no EULA applies, Cypress hereby grants you a personal, nonexclusive,
* non-transferable license to copy, modify, and compile the
* Software source code solely for use in connection with Cypress' s
* integrated circuit products. Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO
* WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING,
* BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. Cypress reserves the right to make
* changes to the Software without notice. Cypress does not assume any
* liability arising out of the application or use of the Software or any
* product or circuit described in the Software. Cypress does not
* authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ( "High Risk Product" ). By
* including Cypress' s product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
******************************************************************************/
/* __DISCLAIMER_END__                                                        */
/*****************************************************************************/
/** \file i2s.h
 **
 ** Basic I²S functions for writing a device.
 **
 ** History:
 ** - 2015-03-31  1.0   MAs  First version 
 *****************************************************************************/

#ifndef __I2S_H__
#define __I2S_H__

/*****************************************************************************/
/* Include files                                                             */
/*****************************************************************************/

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/*****************************************************************************/
/* Global pre-processor symbols/macros ('define')                            */
/*****************************************************************************/

//#define I2S_TIMEOUT_MS              10          ///< 10 ms timeout

/**
 *****************************************************************************
 ** \defgroup I2SGroup Inter IC Sound (I2S)
 **
 ** \brief This section describes the interface for the I2S Unit. (I2S)
 **
 **  This PDL library module provides some basic functions for interact with
 **  I2S module. The initialization function 'I2s_Init' handles only some 
 **  standard frame constructions with standard timings. A parameter set 
 **  ('stc_i2s_config_t*') defines a minimum of I2s configuration e.g. Timing, 
 **  clock souce, Master/Slave mode, sub frame construction parameters and 
 **  callback function definition. It supports enable/disable functions for 
 **  global I2s module as well as for dedicated I2s channels and for receiver
 **  and transmitter. I2s data can be sent by using the basic 'I2s_WriteData'
 **  function which can be used in combination with the I2s callback  function,
 **  but for an optimized performance it is also possible to activate the dma
 **  support for I2s.
 ** \note For a more in detail description of the I2S please consult the HW manual.
 *****************************************************************************/
//@{

/*****************************************************************************/
/* Global type definitions ('typedef')                                       */
/*****************************************************************************/
 /**
 *****************************************************************************
 ** \brief I2S access states
 *****************************************************************************/
typedef enum en_i2s_start_condition
{
    I2SRead,
    I2SWrite
} en_i2s_start_condition_t ;

/**
 *****************************************************************************
 ** \brief I2S sample rate setting
 ** This is the resulting frequency of WS signal which contains the data of
 ** all used frames. Usually a stereo signal with 2 frames.
 ** Note: For clear bit rate generation for those standard audio stream sample
 ** it is recommended to use an adequade external clock source
 ** 48KHz:            fext = 12,2880 MHz
 ** 22.05KHz/44.1KHz: fext = 11,2896 MHz
 *****************************************************************************/
typedef enum en_i2s_samplerate
{
    I2sSampleRate22K05Mono            = 0,    ///< Sample rate for 22.05KHz Mono
    I2sSampleRate44K1Mono             = 1,    ///< Sample rate for 44.1KHz Mono
    I2sSampleRate48KMono              = 2,    ///< Sample rate for 48KHz Mono
    I2sSampleRate22K05Stereo          = 3,    ///< Sample rate for 22.05KHz Stereo
    I2sSampleRate44K1Stereo           = 4,    ///< Sample rate for 44.1KHz Stereo
    I2sSampleRate48KStereo            = 5,    ///< Sample rate for 48KHz Stereo
} en_i2s_samplerate_t;

/**
 *****************************************************************************
 ** \brief I2S frame construction settings
 ** The I2S data stream is generated by a frame which can be configured in 
 ** several modes: 1 subframe or 2 subframes. Each subframe can use up to 32
 ** channel. However, for stereo stream only 2 channels overall are necessary
 ** In addition here also the number of 
 *****************************************************************************/
typedef enum en_i2s_frameconstruction
{
    I2sSingleSubFrame                 = 0,    ///< One sub frame construction
    I2sDualSubFrame                   = 1,    ///< Two sub frame construction
} en_i2s_frameconstruction_t;

/**
 *****************************************************************************
 ** \brief I2scallback function prototypes.
 *****************************************************************************/
typedef void (*i2s_int_cb_func_ptr_t)(void);    
/**
 *****************************************************************************
 ** \brief I2S module internal data,
 **        storing internal information for each enabled I2S instance.
 *****************************************************************************/
typedef struct stc_i2s_intern_data
{
    i2s_int_cb_func_ptr_t     pfnInterruptCbFunction; ///< INT complete callback function
} stc_i2s_intern_data_t ;


/**
 *****************************************************************************
 ** \brief I2S channel list
 ** For en-(dis)abling dedicated I2s channels this list can be used.
 *****************************************************************************/
typedef enum en_i2s_channel
{
    I2sChannel0                       = 0x00000001,    ///< channel 0
    I2sChannel1                       = 0x00000002,    ///< channel 1
    I2sChannel2                       = 0x00000004,    ///< channel 2
    I2sChannel3                       = 0x00000008,    ///< channel 3
    I2sChannel4                       = 0x00000010,    ///< channel 4
    I2sChannel5                       = 0x00000020,    ///< channel 5
    I2sChannel6                       = 0x00000040,    ///< channel 6
    I2sChannel7                       = 0x00000080,    ///< channel 7
    I2sChannel8                       = 0x00000100,    ///< channel 8
    I2sChannel9                       = 0x00000200,    ///< channel 9
    I2sChannel10                      = 0x00000400,    ///< channel 10
    I2sChannel11                      = 0x00000800,    ///< channel 11
    I2sChannel12                      = 0x00001000,    ///< channel 12
    I2sChannel13                      = 0x00002000,    ///< channel 13
    I2sChannel14                      = 0x00004000,    ///< channel 14
    I2sChannel15                      = 0x00008000,    ///< channel 15
    I2sChannel16                      = 0x00010000,    ///< channel 16
    I2sChannel17                      = 0x00020000,    ///< channel 17
    I2sChannel18                      = 0x00040000,    ///< channel 18
    I2sChannel19                      = 0x00080000,    ///< channel 19
    I2sChannel20                      = 0x00100000,    ///< channel 20
    I2sChannel21                      = 0x00200000,    ///< channel 21
    I2sChannel22                      = 0x00400000,    ///< channel 22
    I2sChannel23                      = 0x00800000,    ///< channel 23
    I2sChannel24                      = 0x01000000,    ///< channel 24
    I2sChannel25                      = 0x02000000,    ///< channel 25
    I2sChannel26                      = 0x04000000,    ///< channel 26
    I2sChannel27                      = 0x08000000,    ///< channel 27
    I2sChannel28                      = 0x10000000,    ///< channel 28
    I2sChannel29                      = 0x20000000,    ///< channel 29
    I2sChannel30                      = 0x40000000,    ///< channel 30
    I2sChannel31                      = (int)0x80000000,    ///< channel 31 (enum problem)
} en_i2s_channel_t;

/**
 *****************************************************************************
 ** \brief Subframe construction parameters
 ** It is used to define the number of channels within one subframe, the channel
 ** length and the word length
 ** It is a part of 'stc_i2s_config' struct as 2 different subframes can be defined.
 *****************************************************************************/
typedef struct stc_subframe_config
{
    uint8_t                     u8SubframeNChNumber;                          ///< Sub Frame n Channel Numbers
    uint8_t                     u8SubframeNChLength;                          ///< Sub Frame n Channel Length
    uint8_t                     u8SubframeNWordLength;                       ///< Sub Frame n Word Length
} stc_subframe_config_t;

/**
 *****************************************************************************
 ** \brief DMA tranfer width
 **
 ** The configured transfer width automatically determines the address
 ** increment/decrement size (if enabled).
 *****************************************************************************/
typedef enum en_i2s_frame_construction
{
  I2sOneFrameConstruction = 0x0, ///< 
  I2sTwoFrameConstruction = 0x1 ///< 
} en_i2s_frame_construction_t;

 /**
 *****************************************************************************
 ** \brief General I2S configuration parameters
 ** It is used to define the parameters for I2S. This parameter set is handed over 
 ** to 'I2s_Init'. 
 ** \note only applicated relevant parameters are used here to define some standard
 ** configurations which are sensible for most Audio Codecs
 *****************************************************************************/
typedef struct stc_i2s_config
{
    uint8_t                     u8SampleRate;                     ///< Sample rate for data stream
    boolean_t                   bExternalClock;                   ///< Clock source
    boolean_t                   bMasterMode;                      ///< Master mode
    en_i2s_frame_construction_t eFrameConstuction;                ///< Sub Frame Contruction; 1 or 2 sub frame construction
    uint8_t                     u8OneWordOrTwoHalfWordConstruct;  ///< Word Construction; 32bit FIFO word as 1 word or 2 16bits halfwords
    uint8_t                     u8BitExtendByZeroOrSign;          ///< Bit Extension
    uint8_t                     u8OutputModeOfFrameSignal;        ///< Output mode; burst or free-runnning mode
    uint8_t                     u8ShiftingOrder;                  ///< Shifting Order; MSB or LSB first
    uint8_t                     u8SamplingPoint;                  ///< Sampling Point; center or end of reception data
    uint8_t                     u8ClockPolarity;                  ///< Clock polarity; driving and sampling time
    uint8_t                     u8FrameSyncPhase;                 ///< Frame Sync Phase
    uint8_t                     u8FrameSyncPulseWidth;            ///< Frame Sync Pulse Width; Pulse width of WS is 1bit or 1 channel long
    uint8_t                     u8FrameSyncPolarity;              ///< Frame Sync Polarity; Polarity of WS
    stc_subframe_config_t       stc_SubFrameConfig0;              ///< Sub Frame 0 config
    stc_subframe_config_t       stc_SubFrameConfig1;              ///< Sub Frame 1 config
    func_ptr_t                  pfnCallback;                      ///< Callback for I2S interrupts. It enables also the FIFO interrupt    
} stc_i2s_config_t;

/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source)           */
/*****************************************************************************/


/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source)             */
/*****************************************************************************/

extern en_result_t I2s_Init(volatile stc_i2sn_t* pstcI2s,
                            const stc_i2s_config_t* pstcConfig) ;

extern en_result_t I2s_DeInit(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_Start(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_WriteData(volatile stc_i2sn_t* pstcI2s,
                                 uint32_t i2sdata) ;

extern en_result_t I2s_ConfigureI2sSoundPlayViaDma(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_EnableReceiver(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_DisableReceiver(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_EnableTransmitter(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_DisableTransmitter(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_EnableSubframe0Channel(volatile stc_i2sn_t* pstcI2s,
                                              en_i2s_channel_t channel) ;

extern en_result_t I2s_DisableSubframe0Channel(volatile stc_i2sn_t* pstcI2s,
                                               en_i2s_channel_t channel) ;

extern en_result_t I2s_EnableSubframe1Channel(volatile stc_i2sn_t* pstcI2s,
                                              en_i2s_channel_t channel) ;

extern en_result_t I2s_DisableSubframe1Channel(volatile stc_i2sn_t* pstcI2s,
                                               en_i2s_channel_t channel) ;

extern en_result_t I2s_EnableDma(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_DisableDma(volatile stc_i2sn_t* pstcI2s) ;

extern en_result_t I2s_WaitForEmptyTxFifoSpace(volatile stc_i2sn_t* pstcI2s) ;

// For interupts
extern en_result_t I2s_EnableOrDisableTxInterupt(volatile stc_i2sn_t* pstcI2s,
                                                boolean_t bMaskEmptyFifo);

#ifdef __cplusplus
}
#endif

#endif /* __I2S_H__ */
/*****************************************************************************/
/* EOF (not truncated)                                                       */
/*****************************************************************************/
