http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.h ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.h b/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.h deleted file mode 100755 index 5d1cc61..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.h +++ /dev/null @@ -1,1406 +0,0 @@ -/** - * \file - * - * \brief SAM I2S - Inter-IC Sound Controller - * - * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ - -#ifndef I2S_H_INCLUDED -#define I2S_H_INCLUDED - -/** - * \defgroup asfdoc_sam0_i2s_group SAM Inter-IC Sound Controller (I2S) Driver - * - * This driver for Atmel® | SMART ARM®-based microcontrollers provides - * an interface for the configuration and management of the device's Inter-IC - * Sound Controller functionality. - * - * The following driver API modes are covered by this manual: - * - Polled APIs - * \if I2S_CALLBACK_MODE - * - Callback APIs - * \endif - * - * The following peripheral is used by this module: - * - I<SUP>2</SUP>S (Inter-IC Sound Controller) - * - * The following devices can use this module: - * - Atmel | SMART SAM D21 - * - Atmel | SMART SAM DA1 - * - * The outline of this documentation is as follows: - * - \ref asfdoc_sam0_i2s_prerequisites - * - \ref asfdoc_sam0_i2s_module_overview - * - \ref asfdoc_sam0_i2s_special_considerations - * - \ref asfdoc_sam0_i2s_extra_info - * - \ref asfdoc_sam0_i2s_examples - * - \ref asfdoc_sam0_i2s_api_overview - * - * \section asfdoc_sam0_i2s_prerequisites Prerequisites - * - * There are no prerequisites for this module. - * - * \section asfdoc_sam0_i2s_module_overview Module Overview - * - * The I2S provides bidirectional, synchronous, digital audio link with external - * audio devices through these signal pins: - * - Serial Data (SDm) - * - Frame Sync (FSn) - * - Serial Clock (SCKn) - * - Master Clock (MCKn) - * - * The I2S consists of 2 Clock Units and 2 Serializers, which can be separately - * configured and enabled, to provide varies functionalities as follow: - * - Communicate to Audio CODECs as Master or Slave, or provides clock and - * frame sync signals as Controller - * - Communicate to DAC or ADC through dedicated I2S serial interface - * - Communicate to multi-slot or multiple stereo DACs or ADCs, via - * Time Division Multiplexed (TDM) format - * - Reading mono or stereo MEMS microphones, using the Pulse Density - * Modulation (PDM) interface - * - * The I2S supports compact stereo data word, where left channel data bits are - * in lower half and right channel data bits are in upper half. It reduces the - * number of data words for stereo audio data and the DMA bandwidth. - * - * In master mode, the frame is configured by number of slots and slot size, and - * allows range covering 16fs to 1024fs MCK, to provide oversampling clock to an - * external audio CODEC or digital signal processor (DSP). - * - * A block diagram of the I2S can be seen in - * \ref asfdoc_sam0_i2s_module_block_diagram "the figure below". - * - * \anchor asfdoc_sam0_i2s_module_block_diagram - * \image html i2s_blocks.svg "I2S Block Diagram" - * - * This driver for I2S module provides an interface to: - * - Initialize and control I2S module - * - Configure and control the I2S Clock Unit and Serializer - * - Transmit/receive data through I2S Serializer - * - * \subsection asfdoc_sam0_i2s_module_overview_clocks Clocks - * - * To use I2S module, the I2S bus interface clock (clk_i2s) must be enabled via - * Power Manager. - * - * For each I2S Clock Unit, a generic clock (gclk_i2s_n) is connnected. When I2S - * works in master mode the generic clock is used. It should be prepared before - * clock unit is used. In master mode the input generic clock will be used as - * MCK for SCKn and FSn generation, in addition, the MCK could be devided and - * output to I2S MCKn pin, as oversampling clock to external audio device. - * - * The I2S Serializer uses clock and control signal from Clock Unit to handle - * transfer. Select different clock unit with different configurations allows - * the I2S to work as master or slave, to work on non-related clocks. - * - * When using the driver with ASF, enabling the register interface is normally - * done by the \c init function. - * The Generic Clock Controller (GCLK) source for the asynchronous domain is - * normally configured and set through the _configuration - * struct_ / _init_ function. - * If GCLK source != 0 is used, this source has to be configured and enabled - * through invoking the system_gclk driver function when needed, or modifying - * conf_clock.h to enable it at the beginning. - * - * \subsection asfdoc_sam0_i2s_module_overview_frame Audio Frame Generation - * - * Audio sample data for all channels are sent in frames, one frame can consist - * 1 - 8 slots where each slot can be configured to a size 8-bit, 16-bit, 24-bit, - * or 32-bit. The audio frame synch clock is generated by the I2S Clock unit in - * the master/controller mode. The frame rate (or frame sync frequency) is - * calculated as follows: - * - * FS = SCK / number_of_slots / number_of_bits_in_slot - * - * The serial clock (SCK) source is either an external source (slave mode) or - * generated by the I2S clock unit (controller or master mode) using the MCK as - * source. - * - * SCK = MCK / sck_div - * \note SCK generation division value is MCKDIV in register. - * - * MCK is either an external source or generated using the GCLK input from a - * generic clock generator. - * - * \subsection asfdoc_sam0_i2s_module_overview_mode Master, Controller, and Slave Modes - * - * The i2s module has three modes: master, controller, and slave. - * - * \subsubsection asfdoc_sam0_i2s_module_overview_mode_mst Master - * In master mode the module will control the data flow on the i2s bus and can - * be responsible for clock generation. The Serializers are enabled and will - * transmit/receive data. On a bus with only master and slave the SCK, and FS - * clock signal will be outputted on the SCK and FS pin on the master module. - * MCK can optionally be outputted on the MCK pin, if there is a controller - * module on the bus the SCK, FS, and optionally the MCK clock is sourced from - * the same pins. Serial data will be trancieved on the SD pin in both - * scenarios. - * - * \subsubsection asfdoc_sam0_i2s_module_overview_mode_ctl Controller - * In controller mode the module will generate the clock signals, but the - * Serializers are disabled and no data will be transmitted/received by the - * module in this mode. The clock signals is outputted on the SCK, FS and - * optionally the MCK pin. - * - * \subsubsection asfdoc_sam0_i2s_module_overview_mode_slv Slave - * In slave mode the module will use the SCK and FS clock source from the master - * or the controller which is received on the SCK and FS pin. The MCK can - * optionally be sourced externally on the MCK pin. The Serializers are enabled - * and will tranceive data on the SD pin. All data flow is controlled by the - * master. - * - * \subsubsection asfdoc_sam0_i2s_module_overview_mode_chg Switch Modes - * The mode switching between master, controller, and slave modes are actually - * done by modifying the source mode of I2S pins. - * The source mode of I2S pins are selected by writing corresponding bits in - * CLKCTRLn. - * Since source mode switching changes the direction of pin, the mode must be - * changed when the I2S Clock Unit is stopped. - * - * \subsection asfdoc_sam0_i2s_module_overview_data Data Stream Reception/Transmission - * - * The I2S module support several data stream formats: - * - I2S format - * - Time Division Multiplexed (TDM) format - * - Pulse Density Modulation (PDM) format (reception only) - * - * Basically the I2S module can send several words within each frame, it's more - * like TDM format. With adjust to the number of data words in a frame, the FS - * width, the FS to data bits delay, etc., the module is able to handle I2S - * compliant data stream. - * - * Also the Serializer can receive PDM format data stream, which allows the I2S - * module receive 1 PDM data on each SCK edge. - * - * \subsubsection asfdoc_sam0_i2s_module_overview_data_i2s I2S Stream Reception/Transmission - * - * For 2-channel I2S compliant data stream format the I2S module uses the FS - * line as word select (WS) signal and will send left channel data word on low - * WS level and right channel data word on high WS level as specified in the I2S - * standard. The supported word sizes are 8-, 16-, 18-, 20-, 24-, and 32- bit. - * - * Thus for I2S stream, the following settings should be applied to the module: - * - Data starting delay after FS transition : one SCK period - * - FS width : half of frame - * - Data bits adjust in word : left-adjusted - * - Bit transmitting order : MSB first - * - * Following is an example for I2S application connections and waveforms. See - * \ref asfdoc_sam0_i2s_module_i2s_example_diagram "the figure below". - * - * \anchor asfdoc_sam0_i2s_module_i2s_example_diagram - * \image html i2s_example.svg "I2S Example Diagram" - * - * \subsubsection asfdoc_sam0_i2s_module_overview_data_tdm TDM Stream Reception/Transmission - * In TDM format, the module sends several data words in each frame. For this - * data stream format most of the configurations could be adjusted: - * - Main Frame related settings are as follow: - * - Frame Sync (FS) options: - * - The active edge of the FS (or if FS is inverted before use) - * - The width of the FS - * - The delay between FS to first data bit - * - Data alignment in slot - * - The number of slots and slot size can be adjusted, it has been mentioned - * in \ref asfdoc_sam0_i2s_module_overview_frame - * - The data word size is controlled by Serializer, it can be chosen among - * 8, 16, 18, 20, 24, and 32 bits. - * - * The general TDM waveform generation is as follows: - * - * \anchor asfdoc_sam0_i2s_module_tdm_wave_diagram - * \image html tdm_wave.svg "TDM Waveform Generation" - * - * Some other settings could also be found to set up clock, data formatting and - * pin multiplexer(MUX). - * Refer to \ref i2s_clock_unit_config "Clock Unit Configurations" - * and \ref i2s_serializer_config "Serializer Configurations" for more - * details. - * - * Following is examples for different application use cases. - * - * See \ref asfdoc_sam0_i2s_module_tdm_timeslot_example_diagram "here" for - * the Time Slot Application connection and waveform example. - * - * \anchor asfdoc_sam0_i2s_module_tdm_timeslot_example_diagram - * \image html tdm_timeslot_example.svg "Codec Example Diagram" - * - * See \ref asfdoc_sam0_i2s_module_tdm_codec_example_diagram "here" for the - * Codec Application connection and waveform example. - * - * \anchor asfdoc_sam0_i2s_module_tdm_codec_example_diagram - * \image html tdm_codec_example.svg "Time Slot Example Diagram" - * - * \subsubsection asfdoc_sam0_i2s_module_overview_data_pdm PDM Reception - * The I2S Serializer integrates PDM reception feature, to use this feature, - * simply select PDM2 mode in Serializer configuration. In PDM2 mode, it assumes - * two microphones are input for stereo stream. The left microphone bits will - * be stored in lower half and right microphone bits in upper half of the data - * word, like in compact stereo format. - * - * See \ref asfdoc_sam0_i2s_module_pdm_example_diagram "following figure" for an - * example of PDM Microphones Application with both left and right channel - * microphone connected. - * - * \anchor asfdoc_sam0_i2s_module_pdm_example_diagram - * \image html pdm_example.svg "Time PDM2 Example Diagram" - * - * \subsubsection asfdoc_sam0_i2s_module_overview_data_fmt MONO and Compact Data - * The I2S Serializer can accept some pre-defined data format and generates - * the data stream in specified way. - * - * When transmitting data, the Serializer can work in MONO mode: assum input - * is single channel mono data on left channel and copy it to right channel - * automatically. - * - * Also the I2S Serializer can support compact stereo data word. The data word - * size of the Serializer can be set to \ref I2S_DATA_SIZE_16BIT_COMPACT - * "16-bit compact" or \ref I2S_DATA_SIZE_8BIT_COMPACT "8-bit compact", with - * these option I2S Serializer will compact left channel data and right channel - * data together, the left channel data will take lower bytes and right channel - * data take higher bytes. - * - * \subsection asfdoc_sam0_i2s_module_overview_loop Loop-back Mode - * The I2S can be configured to loop back the Transmitter to Receiver. In this - * mode Serializer's input will be connected to another Serializer's output - * internally. - * - * \subsection asfdoc_sam0_i2s_module_overview_sleep Sleep Modes - * The I2S will continue to operate in any sleep mode, where the selected source - * clocks are running. - * - * \section asfdoc_sam0_i2s_special_considerations Special Considerations - * - * There is no special considerations for I2S module. - * - * \section asfdoc_sam0_i2s_extra_info Extra Information - * - * For extra information see \ref asfdoc_sam0_i2s_extra. This includes: - * - \ref asfdoc_sam0_i2s_extra_acronyms - * - \ref asfdoc_sam0_i2s_extra_dependencies - * - \ref asfdoc_sam0_i2s_extra_errata - * - \ref asfdoc_sam0_i2s_extra_history - * - * \section asfdoc_sam0_i2s_examples Examples - * - * For a list of examples related to this driver, see - * \ref asfdoc_sam0_i2s_exqsg. - * - * - * \section asfdoc_sam0_i2s_api_overview API Overview - * @{ - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <compiler.h> -#include <system.h> - -#if I2S_CALLBACK_MODE == true -# include <system_interrupt.h> - -#if !defined(__DOXYGEN__) -extern struct i2s_module *_i2s_instances[I2S_INST_NUM]; -#endif - -/** Forward definition of the device instance */ -struct i2s_module; - -/** Type of the callback functions. */ -typedef void (*i2s_serializer_callback_t) - (struct i2s_module *const module); - -/** - * \brief I2S Serializer Callback enum - */ -enum i2s_serializer_callback { - /** Callback for buffer read/write finished */ - I2S_SERIALIZER_CALLBACK_BUFFER_DONE, - /** Callback for Serializer overrun/underrun */ - I2S_SERIALIZER_CALLBACK_OVER_UNDER_RUN, -# if !defined(__DOXYGEN__) - I2S_SERIALIZER_CALLBACK_N -# endif -}; - -#endif /* #if I2S_CALLBACK_MODE == true */ - -/** - * \name Module Status Flags - * - * I2S status flags, returned by \ref i2s_get_status() and cleared by - * \ref i2s_clear_status(). - * - * @{ - */ - -/** Module Serializer x (0~1) Transmit Underrun. */ -#define I2S_STATUS_TRANSMIT_UNDERRUN(x) (1u << ((x)+0)) -/** Module Serializer x (0~1) is ready to accept new data to be transmitted. */ -#define I2S_STATUS_TRANSMIT_READY(x) (1u << ((x)+2)) -/** Module Serializer x (0~1) Receive Overrun. */ -#define I2S_STATUS_RECEIVE_OVERRUN(x) (1u << ((x)+4)) -/** Module Serializer x (0~1) has received a new data. */ -#define I2S_STATUS_RECEIVE_READY(x) (1u << ((x)+6)) -/** Module is busy on synchronization. */ -#define I2S_STATUS_SYNC_BUSY (1u << 8) - -/** @} */ - -/** - * Master Clock (MCK) source selection. - */ -enum i2s_master_clock_source { - /** Master Clock (MCK) is from general clock */ - I2S_MASTER_CLOCK_SOURCE_GCLK, - /** Master Clock (MCK) is from MCK input pin */ - I2S_MASTER_CLOCK_SOURCE_MCKPIN -}; - -/** - * Serial Clock (SCK) source selection. - */ -enum i2s_serial_clock_source { - /** Serial Clock (SCK) is divided from Master Clock */ - I2S_SERIAL_CLOCK_SOURCE_MCKDIV, - /** Serial Clock (SCK) is input from SCK input pin */ - I2S_SERIAL_CLOCK_SOURCE_SCKPIN -}; - -/** - * Data delay from Frame Sync (FS). - */ -enum i2s_data_delay { - /** Left Justified (no delay) */ - I2S_DATA_DELAY_0, - /** I2S data delay (1-bit delay) */ - I2S_DATA_DELAY_1, - /** Left Justified (no delay) */ - I2S_DATA_DELAY_LEFT_JUSTIFIED = I2S_DATA_DELAY_0, - /** I2S data delay (1-bit delay) */ - I2S_DATA_DELAY_I2S = I2S_DATA_DELAY_1 -}; - -/** - * Frame Sync (FS) source. - */ -enum i2s_frame_sync_source { - /** Frame Sync (FS) is divided from I2S Serial Clock */ - I2S_FRAME_SYNC_SOURCE_SCKDIV, - /** Frame Sync (FS) is input from FS input pin */ - I2S_FRAME_SYNC_SOURCE_FSPIN -}; - -/** - * Frame Sync (FS) output pulse width. - */ -enum i2s_frame_sync_width { - /** Frame Sync (FS) Pulse is 1 Slot width */ - I2S_FRAME_SYNC_WIDTH_SLOT, - /** Frame Sync (FS) Pulse is half a Frame width */ - I2S_FRAME_SYNC_WIDTH_HALF_FRAME, - /** Frame Sync (FS) Pulse is 1 Bit width */ - I2S_FRAME_SYNC_WIDTH_BIT, - /** 1-bit wide Frame Sync (FS) per Data sample, only used when Data transfer - * is requested */ - I2S_FRAME_SYNC_WIDTH_BURST -}; - -/** - * Time Slot Size in number of I2S serial clocks (bits). - */ -enum i2s_slot_size { - /** 8-bit slot */ - I2S_SLOT_SIZE_8_BIT, - /** 16-bit slot */ - I2S_SLOT_SIZE_16_BIT, - /** 24-bit slot */ - I2S_SLOT_SIZE_24_BIT, - /** 32-bit slot */ - I2S_SLOT_SIZE_32_BIT -}; - -/** - * DMA channels usage for I2S. - */ -enum i2s_dma_usage { - /** Single DMA channel for all I2S channels */ - I2S_DMA_USE_SINGLE_CHANNEL_FOR_ALL, - /** One DMA channel per data channel */ - I2S_DMA_USE_ONE_CHANNEL_PER_DATA_CHANNEL -}; - -/** - * I2S data format, to extend mono data to 2 channels. - */ -enum i2s_data_format { - /** Normal mode, keep data to its right channel */ - I2S_DATA_FORMAT_STEREO, - /** Assume input is mono data for left channel, the data is duplicated to - * right channel */ - I2S_DATA_FORMAT_MONO -}; - -/** - * I2S data bit order. - */ -enum i2s_bit_order { - /** Transfer Data Most Significant Bit first (Default for I2S protocol) */ - I2S_BIT_ORDER_MSB_FIRST, - /** Transfer Data Least Significant Bit first */ - I2S_BIT_ORDER_LSB_FIRST -}; - -/** - * I2S data bit padding. - */ -enum i2s_bit_padding { - /** Padding with 0 */ - I2S_BIT_PADDING_0, - /** Padding with 1 */ - I2S_BIT_PADDING_1, - /** Padding with MSBit */ - I2S_BIT_PADDING_MSB, - /** Padding with LSBit */ - I2S_BIT_PADDING_LSB, -}; - -/** - * I2S data word adjust. - */ -enum i2s_data_adjust { - /** Data is right adjusted in word */ - I2S_DATA_ADJUST_RIGHT, - /** Data is left adjusted in word */ - I2S_DATA_ADJUST_LEFT -}; - -/** - * I2S data word size. - */ -enum i2s_data_size { - /** 32-bit */ - I2S_DATA_SIZE_32BIT, - /** 24-bit */ - I2S_DATA_SIZE_24BIT, - /** 20-bit */ - I2S_DATA_SIZE_20BIT, - /** 18-bit */ - I2S_DATA_SIZE_18BIT, - /** 16-bit */ - I2S_DATA_SIZE_16BIT, - /** 16-bit compact stereo */ - I2S_DATA_SIZE_16BIT_COMPACT, - /** 8-bit */ - I2S_DATA_SIZE_8BIT, - /** 8-bit compact stereo */ - I2S_DATA_SIZE_8BIT_COMPACT -}; - -/** - * I2S data slot adjust. - */ -enum i2s_slot_adjust { - /** Data is right adjusted in slot */ - I2S_SLOT_ADJUST_RIGHT, - /** Data is left adjusted in slot */ - I2S_SLOT_ADJUST_LEFT -}; - -/** - * I2S data padding. - */ -enum i2s_data_padding { - /** Padding 0 in case of under-run */ - I2S_DATA_PADDING_0, - /** Padding last data in case of under-run */ - I2S_DATA_PADDING_SAME_AS_LAST, - /** Padding last data in case of under-run - * (abbr. \c I2S_DATA_PADDING_SAME_AS_LAST) */ - I2S_DATA_PADDING_LAST = I2S_DATA_PADDING_SAME_AS_LAST, - /** Padding last data in case of under-run - * (abbr. \c I2S_DATA_PADDING_SAME_AS_LAST) */ - I2S_DATA_PADDING_SAME = I2S_DATA_PADDING_SAME_AS_LAST -}; - -/** - * I2S line default value when slot disabled. - */ -enum i2s_line_default_state { - /** Output default value is 0 */ - I2S_LINE_DEFAULT_0, - /** Output default value is 1 */ - I2S_LINE_DEFAULT_1, - /** Output default value is high impedance */ - I2S_LINE_DEFAULT_HIGH_IMPEDANCE = 3, - /** Output default value is high impedance - * (abbr. \c I2S_LINE_DEFAULT_HIGH_IMPEDANCE) */ - I2S_LINE_DEFAULT_HIZ = I2S_LINE_DEFAULT_HIGH_IMPEDANCE -}; - -/** - * I2S Serializer mode. - */ -enum i2s_serializer_mode { - /** Serializer is used to receive data */ - I2S_SERIALIZER_RECEIVE, - /** Serializer is used to transmit data */ - I2S_SERIALIZER_TRANSMIT, - /** Serializer is used to receive PDM data on each clock edge */ - I2S_SERIALIZER_PDM2 -}; - -/** - * I2S clock unit selection. - */ -enum i2s_clock_unit { - /** Clock Unit channel 0 */ - I2S_CLOCK_UNIT_0, - /** Clock Unit channel 1 */ - I2S_CLOCK_UNIT_1, - /** Number of Clock Unit channels */ - I2S_CLOCK_UNIT_N -}; - -/** - * I2S Serializer selection. - */ -enum i2s_serializer { - /** Serializer channel 0 */ - I2S_SERIALIZER_0, - /** Serializer channel 1 */ - I2S_SERIALIZER_1, - /** Number of Serializer channels */ - I2S_SERIALIZER_N -}; - - -/** - * Configure for I2S pin. - */ -struct i2s_pin_config { - /** GPIO index to access the pin */ - uint8_t gpio; - /** Pin function MUX */ - uint8_t mux; - /** Enable this pin for I2S module */ - bool enable; -}; - -/** - * Configure for I2S clock (SCK). - */ -struct i2s_clock_config { - /** Divide generic clock to master clock output (1~32, 0,1 means no div) */ - uint8_t mck_out_div; - /** Divide generic clock to serial clock (1~32, 0,1 means no div) */ - uint8_t sck_div; - /** Clock source selection */ - enum gclk_generator gclk_src; - /** Master clock source selection: generated or input from pin */ - enum i2s_master_clock_source mck_src; - /** Serial clock source selection: generated or input from pin */ - enum i2s_serial_clock_source sck_src; - /** Invert master clock output */ - bool mck_out_invert; - /** Invert serial clock output */ - bool sck_out_invert; - /** Generate MCK clock output */ - bool mck_out_enable; -}; - -/** - * Configure for I2S frame sync (FS). - */ -struct i2s_frame_sync_config { - /** Frame Sync (FS) generated or input from pin */ - enum i2s_frame_sync_source source; - /** Frame Sync (FS) width */ - enum i2s_frame_sync_width width; - /** Invert Frame Sync (FS) signal before use */ - bool invert_use; - /** Invert Frame Sync (FS) signal before output */ - bool invert_out; -}; - -/** - * Configure for I2S frame. - */ -struct i2s_frame_config { - /** Number of slots in a frame (1~8, 0,1 means minimum 1) */ - uint8_t number_slots; - /** Size of each slot in frame */ - enum i2s_slot_size slot_size; - /** Data delay from Frame Sync (FS) to first data bit */ - enum i2s_data_delay data_delay; - /** Frame sync (FS) */ - struct i2s_frame_sync_config frame_sync; -}; - -/** - * Configure for I2S clock unit. - */ -struct i2s_clock_unit_config { - /** Configure clock generation */ - struct i2s_clock_config clock; - /** Configure frame generation */ - struct i2s_frame_config frame; - - /** Configure master clock pin */ - struct i2s_pin_config mck_pin; - /** Configure serial clock pin */ - struct i2s_pin_config sck_pin; - /** Configure frame sync pin */ - struct i2s_pin_config fs_pin; -}; - -/** - * Configure for I2S Serializer. - */ -struct i2s_serializer_config { - /** Configure Serializer data pin */ - struct i2s_pin_config data_pin; - - /** Set to \c true to loop-back output to input pin for test */ - bool loop_back; - - /** Set to \c true to assumes mono input and duplicate it (left channel) to - * right channel */ - bool mono_mode; - - /** Disable data slot */ - bool disable_data_slot[8]; - - /** Set to \c true to transfer LSB first, \c false to transfer MSB first */ - bool transfer_lsb_first; - /** Data Word Formatting Adjust, - * set to \c true to adjust bits in word to left */ - bool data_adjust_left_in_word; - /** Data Slot Formatting Adjust, - * set to \c true to adjust words in slot to left */ - bool data_adjust_left_in_slot; - - /** Data Word Size */ - enum i2s_data_size data_size; - /** Data Formatting Bit Extension */ - enum i2s_bit_padding bit_padding; - /** Data padding when under-run */ - enum i2s_data_padding data_padding; - - /** DMA usage */ - enum i2s_dma_usage dma_usage; - - /** Clock unit selection */ - enum i2s_clock_unit clock_unit; - - /** Line default state where slot is disabled */ - enum i2s_line_default_state line_default_state; - - /** Serializer Mode */ - enum i2s_serializer_mode mode; -}; - -/** - * \brief I2S Serializer instance struct. - */ -struct i2s_serializer_module { - -#if I2S_CALLBACK_MODE == true - /** Callbacks list for Serializer */ - i2s_serializer_callback_t callback[I2S_SERIALIZER_CALLBACK_N]; - - /** Job buffer */ - void *job_buffer; - /** Requested data words to read/write */ - uint32_t requested_words; - /** Transferred data words for read/write */ - uint32_t transferred_words; - - /** Callback mask for registered callbacks */ - uint8_t registered_callback_mask; - /** Callback mask for enabled callbacks */ - uint8_t enabled_callback_mask; - - /** Status of the ongoing or last transfer job */ - enum status_code job_status; -#endif - - /** Serializer mode */ - enum i2s_serializer_mode mode; - /** Serializer data word size */ - enum i2s_data_size data_size; -}; - -/** - * \brief I2S Software Module instance struct. - */ -struct i2s_module { - /** Module HW register access base */ - I2s *hw; - - /** Module Serializer used */ - struct i2s_serializer_module serializer[2]; -}; - -/** - * \brief Determines if the hardware module(s) are currently synchronizing to the bus. - * - * Checks to see if the underlying hardware peripheral module(s) are currently - * synchronizing across multiple clock domains to the hardware bus, This - * function can be used to delay further operations on a module until such time - * that it is ready, to prevent blocking delays for synchronization in the - * user application. - * - * \param[in] module_inst Pointer to the software module instance struct - * - * \return Synchronization status of the underlying hardware module(s). - * - * \retval false If the module has completed synchronization - * \retval true If the module synchronization is ongoing - */ -static inline bool i2s_is_syncing( - const struct i2s_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - return (module_inst->hw->SYNCBUSY.reg > 0); -} - -/** - * \name Driver Initialization - * @{ - */ - -enum status_code i2s_init( - struct i2s_module *const module_inst, - I2s *hw); - -/** @} */ - -/** - * \name Enable/Disable/Reset - * @{ - */ - -/** - * \brief Enable the I2S module. - * - * Enables a I2S module that has been previously initialized. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void i2s_enable(const struct i2s_module *const module_inst) -{ - Assert(module_inst); - Assert(module_inst->hw); - - while (module_inst->hw->SYNCBUSY.reg & I2S_SYNCBUSY_ENABLE) { - /* Sync wait */ - } - module_inst->hw->CTRLA.reg |= I2S_SYNCBUSY_ENABLE; -} - -/** - * \brief Disables the I2S module. - * - * Disables a I2S module. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void i2s_disable(const struct i2s_module *const module_inst) -{ - Assert(module_inst); - Assert(module_inst->hw); - - while (module_inst->hw->SYNCBUSY.reg & I2S_SYNCBUSY_ENABLE) { - /* Sync wait */ - } - module_inst->hw->CTRLA.reg &= ~I2S_SYNCBUSY_ENABLE; -} - -/** - * \brief Resets the I2S module. - * - * Resets the I2S module, restoring all hardware module registers to their - * default values and disabling the module. The I2S module will not be - * accessible while the reset is being performed. - * - * \param[in] module_inst Pointer to the software module instance struct - */ -static inline void i2s_reset(const struct i2s_module *const module_inst) -{ - Assert(module_inst); - Assert(module_inst->hw); - - /* Disable the module if it is running */ - if (module_inst->hw->CTRLA.reg & I2S_CTRLA_ENABLE) { - i2s_disable(module_inst); - while (i2s_is_syncing(module_inst)) { - /* Sync wait */ - } - } - /* Reset the HW module */ - module_inst->hw->CTRLA.reg = I2S_CTRLA_SWRST; -} - -/** @} */ - -/** - * \name Clock Unit Initialization and Configuration - * @{ - */ - -/** - * \brief Initializes config with predefined default values for I2S clock unit. - * - * This function will initialize a given I2S Clock Unit configuration structure - * to a set of known default values. This function should be called on any new - * instance of the configuration structures before being modified by the user - * application. - * - * The default configuration is as follows: - * - The clock unit does not generate output clocks (MCK, SCK, and FS) - * - The pins (MCK, SCK, and FS) and MUX configurations are not set - * - * \param[out] config Pointer to a I2S module clock unit configuration struct - * to set - */ -static inline void i2s_clock_unit_get_config_defaults( - struct i2s_clock_unit_config *const config) -{ - Assert(config); - - config->clock.mck_out_enable = false; - config->clock.gclk_src = GCLK_GENERATOR_0; - - config->clock.mck_src = I2S_MASTER_CLOCK_SOURCE_GCLK; - config->clock.mck_out_div = 1; - config->clock.mck_out_invert = false; - - config->clock.sck_src = I2S_SERIAL_CLOCK_SOURCE_MCKDIV; - config->clock.sck_div = 1; - config->clock.sck_out_invert = false; - - config->frame.number_slots = 1; - config->frame.slot_size = I2S_SLOT_SIZE_32_BIT; - config->frame.data_delay = I2S_DATA_DELAY_I2S; - - config->frame.frame_sync.source = I2S_FRAME_SYNC_SOURCE_SCKDIV; - config->frame.frame_sync.width = I2S_FRAME_SYNC_WIDTH_HALF_FRAME; - config->frame.frame_sync.invert_use = false; - config->frame.frame_sync.invert_out = false; - - config->mck_pin.enable = false; - config->mck_pin.mux = 0; - config->mck_pin.gpio = 0; - - config->sck_pin.enable = false; - config->sck_pin.mux = 0; - config->sck_pin.gpio = 0; - - config->fs_pin.enable = false; - config->fs_pin.mux = 0; - config->fs_pin.gpio = 0; -} - -enum status_code i2s_clock_unit_set_config( - struct i2s_module *const module_inst, - const enum i2s_clock_unit clock_unit, - const struct i2s_clock_unit_config *config); - -/** @} */ - - -/** - * \name Clock Unit Enable/Disable - * @{ - */ - -/** - * \brief Enable the Specified Clock Unit of I2S module. - * - * Enables a Clock Unit in I2S module that has been previously initialized. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] clock_unit I2S Clock Unit to enable - */ -static inline void i2s_clock_unit_enable( - const struct i2s_module *const module_inst, - const enum i2s_clock_unit clock_unit) -{ - uint32_t cken_bit; - - Assert(module_inst); - Assert(module_inst->hw); - - cken_bit = I2S_CTRLA_CKEN0 << clock_unit; - - while (module_inst->hw->SYNCBUSY.reg & cken_bit) { - /* Sync wait */ - } - module_inst->hw->CTRLA.reg |= cken_bit; -} - -/** - * \brief Disable the Specified Clock Unit of I2S module. - * - * Disables a Clock Unit in I2S module that has been previously initialized. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] clock_unit I2S Clock Unit to disable - */ -static inline void i2s_clock_unit_disable( - const struct i2s_module *const module_inst, - const enum i2s_clock_unit clock_unit) -{ - uint32_t cken_bit; - - Assert(module_inst); - Assert(module_inst->hw); - - cken_bit = I2S_CTRLA_CKEN0 << clock_unit; - - while (module_inst->hw->SYNCBUSY.reg & cken_bit) { - /* Sync wait */ - } - module_inst->hw->CTRLA.reg &= ~cken_bit; -} - -/** @} */ - - -/** - * \name Serializer Initialization and Configuration - * @{ - */ - -/** - * \brief Initializes config with predefined default values for I2S Serializer. - * - * This function will initialize a given I2S Clock Unit configuration structure - * to a set of known default values. This function should be called on any new - * instance of the configuration structures before being modified by the user - * application. - * - * The default configuration is as follows: - * - Output data does not internally loopback to input line - * - Does not extend mono data (left channel) to right channel - * - None of the data slot is disabled - * - MSB of I2S data is transferred first - * - In data word data is adjusted right - * - In slot data word is adjusted left - * - The data size is 16-bit width - * - I2S will padd 0 to not defined bits - * - I2S will padd 0 to not defined words - * - I2S will use single DMA channel for all data channels - * - I2S will use clock unit 0 to serve as clock - * - The default data line state is 0, when there is no data - * - I2S will transmit data to output line - * - The data pin and MUX configuration are not set - * - * \param[out] config Pointer to a I2S module Serializer configuration struct - * to set - */ -static inline void i2s_serializer_get_config_defaults( - struct i2s_serializer_config *const config) -{ - config->loop_back = false; - - config->mono_mode = false; - - config->disable_data_slot[0] = false; - config->disable_data_slot[1] = false; - config->disable_data_slot[2] = false; - config->disable_data_slot[3] = false; - config->disable_data_slot[4] = false; - config->disable_data_slot[5] = false; - config->disable_data_slot[6] = false; - config->disable_data_slot[7] = false; - - config->transfer_lsb_first = false; - config->data_adjust_left_in_word = false; - config->data_adjust_left_in_slot = true; - - config->data_size = I2S_DATA_SIZE_16BIT; - - config->bit_padding = I2S_BIT_PADDING_0; - config->data_padding = I2S_DATA_PADDING_0; - - config->dma_usage = I2S_DMA_USE_SINGLE_CHANNEL_FOR_ALL; - - config->clock_unit = I2S_CLOCK_UNIT_0; - - config->line_default_state = I2S_LINE_DEFAULT_0; - - config->mode = I2S_SERIALIZER_TRANSMIT; - - config->data_pin.enable = false; - config->data_pin.gpio = 0; - config->data_pin.mux = 0; -} - -enum status_code i2s_serializer_set_config( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const struct i2s_serializer_config *config); -/** @} */ - -/** - * \name Serializer Enable/Disable - * @{ - */ - -/** - * \brief Enable the Specified Serializer of I2S module. - * - * Enables a Serializer in I2S module that has been previously initialized. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer I2S Serializer to enable - */ -static inline void i2s_serializer_enable( - const struct i2s_module *const module_inst, - const enum i2s_serializer serializer) -{ - uint32_t seren_bit; - - Assert(module_inst); - Assert(module_inst->hw); - - seren_bit = I2S_CTRLA_SEREN0 << serializer; - - while (module_inst->hw->SYNCBUSY.reg & seren_bit) { - /* Sync wait */ - } - module_inst->hw->CTRLA.reg |= seren_bit; -} - -/** - * \brief Disable the Specified Serializer of I2S module. - * - * Disables a Serializer in I2S module that has been previously initialized. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer I2S Serializer to disable - */ -static inline void i2s_serializer_disable( - const struct i2s_module *const module_inst, - const enum i2s_serializer serializer) -{ - uint32_t seren_bit; - - Assert(module_inst); - Assert(module_inst->hw); - - seren_bit = I2S_CTRLA_SEREN0 << serializer; - - while (module_inst->hw->SYNCBUSY.reg & seren_bit) { - /* Sync wait */ - } - module_inst->hw->CTRLA.reg &= ~seren_bit; -} -/** @} */ - -/** - * \name Status Management - * @{ - */ - -uint32_t i2s_get_status( - const struct i2s_module *const module_inst); - -void i2s_clear_status( - const struct i2s_module *const module_inst, - uint32_t status); - - -enum status_code i2s_enable_status_interrupt( - struct i2s_module *const module_inst, - uint32_t status); - -void i2s_disable_status_interrupt( - struct i2s_module *const module_inst, - uint32_t status); - -/** @}*/ - -/** - * \name Data Read/Write - * @{ - */ - -/** - * \brief Write a data word to the specified Serializer of I2S module - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The Serializer to write to - * \param[in] data The data to write - * - */ -static inline void i2s_serializer_write_wait( - const struct i2s_module *const module_inst, - enum i2s_serializer serializer, - uint32_t data) -{ - uint32_t sync_bit, ready_bit; - - Assert(module_inst); - Assert(module_inst->hw); - - ready_bit = I2S_INTFLAG_TXRDY0 << serializer; - while (!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait until ready to transmit */ - } - sync_bit = I2S_SYNCBUSY_DATA0 << serializer; - while (module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait sync */ - } - /* Write data */ - module_inst->hw->DATA[serializer].reg = data; - module_inst->hw->INTFLAG.reg = ready_bit; -} - -/** - * \brief Read a data word from the specified Serializer of I2S module - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The Serializer to read - */ -static inline uint32_t i2s_serializer_read_wait( - const struct i2s_module *const module_inst, - enum i2s_serializer serializer) -{ - uint32_t sync_bit, ready_bit; - uint32_t data; - - Assert(module_inst); - Assert(module_inst->hw); - - ready_bit = I2S_INTFLAG_RXRDY0 << serializer; - while (!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait until ready to transmit */ - } - sync_bit = I2S_SYNCBUSY_DATA0 << serializer; - while (module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait sync */ - } - /* Read data */ - data = module_inst->hw->DATA[serializer].reg; - module_inst->hw->INTFLAG.reg = ready_bit; - return data; -} - - -/** - * \brief Write buffer to the specified Serializer of I2S module - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The Serializer to write to - * \param[in] buffer The data buffer to write - * \param[in] size Number of data words to write - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The data was sent successfully - * \retval STATUS_INVALID_ARG An invalid buffer pointer was supplied - */ -enum status_code i2s_serializer_write_buffer_wait( - const struct i2s_module *const module_inst, - enum i2s_serializer serializer, - void *buffer, uint32_t size); - -/** - * \brief Read from the specified Serializer of I2S module to a buffer - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The Serializer to write to - * \param[in] buffer The buffer to fill read data - * \param[in] size Number of data words to read - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The data was sent successfully - * \retval STATUS_INVALID_ARG An invalid buffer pointer was supplied - */ -enum status_code i2s_serializer_read_buffer_wait( - const struct i2s_module *const module_inst, - enum i2s_serializer serializer, - void *buffer, uint32_t size); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -/** @} */ - - -/** - * \page asfdoc_sam0_i2s_extra Extra Information for I2S Driver - * - * \section asfdoc_sam0_i2s_extra_acronyms Acronyms - * Below is a table listing the acronyms used in this module, along with their - * intended meanings. - * - * <table> - * <tr> - * <th>Acronym</th> - * <th>Description</th> - * </tr> - * <tr> - * <td>I2S, IIS</td> - * <td>Inter-IC Sound Controller</td> - * </tr> - * <tr> - * <td>MCK</td> - * <td>Master Clock</td> - * </tr> - * <tr> - * <td>SCK</td> - * <td>Serial Clock</td> - * </tr> - * <tr> - * <td>FS</td> - * <td>Frame Sync</td> - * </tr> - * <tr> - * <td>SD</td> - * <td>Serial Data</td> - * </tr> - * <tr> - * <td>ADC</td> - * <td>Analog-to-Digital Converter</td> - * </tr> - * <tr> - * <td>DAC</td> - * <td>Digital-to-Analog Converter</td> - * </tr> - * <tr> - * <td>TDM</td> - * <td>Time Division Multiplexed</td> - * </tr> - * <tr> - * <td>PDM</td> - * <td>Pulse Density Modulation</td> - * </tr> - * <tr> - * <td>LSB</td> - * <td>Least Significant Bit</td> - * </tr> - * <tr> - * <td>MSB</td> - * <td>Most Significant Bit</td> - * </tr> - * <tr> - * <td>DSP</td> - * <td>Digital Signal Processor</td> - * </tr> - * </table> - * - * - * \section asfdoc_sam0_i2s_extra_dependencies Dependencies - * This driver has the following dependencies: - * - * - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver" - * - * - * \section asfdoc_sam0_i2s_extra_errata Errata - * There are no errata related to this driver. - * - * - * \section asfdoc_sam0_i2s_extra_history Module History - * An overview of the module history is presented in the table below, with - * details on the enhancements and fixes made to the module since its first - * release. The current version of this corresponds to the newest version in - * the table. - * - * <table> - * <tr> - * <th>Changelog</th> - * </tr> - * <tr> - * <td>Initial Release</td> - * </tr> - * </table> - */ - -/** - * \page asfdoc_sam0_i2s_exqsg Examples for I2S Driver - * - * This is a list of the available Quick Start guides (QSGs) and example - * applications for \ref asfdoc_sam0_i2s_group. QSGs are simple examples with - * step-by-step instructions to configure and use this driver in a selection of - * use cases. Note that QSGs can be compiled as a standalone application or be - * added to the user application. - * - * - \subpage asfdoc_sam0_i2s_basic_use_case - * \if I2S_CALLBACK_MODE - * - \subpage asfdoc_sam0_i2s_callback_use_case - * \endif - * - \subpage asfdoc_sam0_i2s_dma_use_case - * - * \page asfdoc_sam0_i2s_document_revision_history Document Revision History - * - * <table> - * <tr> - * <th>Doc. Rev.</th> - * <th>Date</th> - * <th>Comments</th> - * </tr> - * <tr> - * <td>42255B</td> - * <td>12/2015</td> - * <td>Added support for SAM DA1</td> - * </tr> - * <tr> - * <td>42255A</td> - * <td>01/2014</td> - * <td>Initial release</td> - * </tr> - * </table> - */ - -#endif /* #ifndef I2S_H_INCLUDED */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.c ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.c deleted file mode 100755 index e755420..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.c +++ /dev/null @@ -1,392 +0,0 @@ -/** - * \file - * - * \brief SAM I2S - Inter-IC Sound Controller - * - * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ - -#include "i2s_callback.h" - -struct i2s_module *_i2s_instances[I2S_INST_NUM]; - -static void _i2s_interrupt_handler(const uint8_t instance) -{ - struct i2s_module *module = _i2s_instances[instance]; - struct i2s_serializer_module *data_module; - - /* Get interrupt flags */ - uint32_t intflag = module->hw->INTFLAG.reg; - uint32_t inten = intflag & module->hw->INTENSET.reg; - uint32_t run_flags = (I2S_INTFLAG_TXUR0 | I2S_INTFLAG_RXOR0); - uint32_t ready_flags = (I2S_INTFLAG_TXRDY0 | I2S_INTFLAG_RXRDY0); - uint32_t call_mask; - uint8_t serializer; - - for (serializer = 0; serializer < 2; serializer ++) { - data_module = &module->serializer[serializer]; - call_mask = data_module->registered_callback_mask & - data_module->enabled_callback_mask; - - if (intflag & (run_flags | ready_flags)) { - /* Serializer Tx ready */ - if ((I2S_INTFLAG_TXRDY0 << serializer) & inten) { - - if (data_module->transferred_words < - data_module->requested_words) { - - /* Write data word */ - while (module->hw->SYNCBUSY.reg & - (I2S_SYNCBUSY_DATA0 << serializer)) { - /* Wait sync */ - } - switch(data_module->data_size) { - case I2S_DATA_SIZE_32BIT: - case I2S_DATA_SIZE_24BIT: - case I2S_DATA_SIZE_20BIT: - case I2S_DATA_SIZE_18BIT: - module->hw->DATA[serializer].reg = - ((uint32_t*)data_module->job_buffer) \ - [data_module->transferred_words]; - break; - case I2S_DATA_SIZE_16BIT: - case I2S_DATA_SIZE_16BIT_COMPACT: - module->hw->DATA[serializer].reg = - ((uint16_t*)data_module->job_buffer) \ - [data_module->transferred_words]; - break; - default: - module->hw->DATA[serializer].reg = - ((uint8_t*)data_module->job_buffer) \ - [data_module->transferred_words]; - } - /* Clear interrupt status */ - module->hw->INTFLAG.reg = I2S_INTFLAG_TXRDY0 << serializer; - - /* Count data */ - data_module->transferred_words ++; - } - - /* Check if the buffer is done */ - if (data_module->transferred_words >= - data_module->requested_words) { - /* It's done */ - data_module->job_status = STATUS_OK; - /* Disable interrupt */ - module->hw->INTENCLR.reg = - I2S_INTFLAG_TXRDY0 << serializer; - /* Invoke callback */ - if ((1 << I2S_SERIALIZER_CALLBACK_BUFFER_DONE) & - call_mask) { - (data_module->callback \ - [I2S_SERIALIZER_CALLBACK_BUFFER_DONE])(module); - } - } - return; - } - /* Serializer Rx ready */ - if ((I2S_INTFLAG_RXRDY0 << serializer) & inten) { - /* Read data word */ - switch(data_module->data_size) { - case I2S_DATA_SIZE_32BIT: - case I2S_DATA_SIZE_24BIT: - case I2S_DATA_SIZE_20BIT: - case I2S_DATA_SIZE_18BIT: - ((uint32_t*)data_module->job_buffer) \ - [data_module->transferred_words] = - module->hw->DATA[serializer].reg; - break; - case I2S_DATA_SIZE_16BIT: - case I2S_DATA_SIZE_16BIT_COMPACT: - ((uint16_t*)data_module->job_buffer) \ - [data_module->transferred_words] = - (uint16_t)module->hw->DATA[serializer].reg; - break; - default: - ((uint8_t*)data_module->job_buffer) \ - [data_module->transferred_words] = - (uint8_t)module->hw->DATA[serializer].reg; - - } - /* Clear interrupt status */ - module->hw->INTFLAG.reg = I2S_INTFLAG_RXRDY0 << serializer; - - /* Count data */ - data_module->transferred_words ++; - - /* Check if the buffer is done */ - if (data_module->transferred_words >= - data_module->requested_words) { - if (data_module->job_status == STATUS_BUSY) { - data_module->job_status = STATUS_OK; - /* Disable interrupt */ - module->hw->INTENCLR.reg = - I2S_INTFLAG_RXRDY0 << serializer; - /* Invoke callback */ - if ((1 << I2S_SERIALIZER_CALLBACK_BUFFER_DONE) & - call_mask) { - (data_module->callback \ - [I2S_SERIALIZER_CALLBACK_BUFFER_DONE])(module); - } - } - } - return; - } - /* Serializer Tx undrerun or Rx overrun */ - if (run_flags & inten) { - module->hw->INTFLAG.reg = I2S_INTFLAG_TXUR0 << serializer; - if ((1 << I2S_SERIALIZER_CALLBACK_OVER_UNDER_RUN) & - call_mask) { - (data_module->callback \ - [I2S_SERIALIZER_CALLBACK_OVER_UNDER_RUN])(module); - } - return; - } - } - run_flags <<= 1; - ready_flags <<= 1; - } - -} - -/** Interrupt handler for the I2S module */ -void I2S_Handler(void) -{ - _i2s_interrupt_handler(0); -} - -/** - * \brief Write buffer to the specified Serializer of I2S module - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The serializer to write to - * \param[in] buffer The data buffer to write - * \param[in] size Number of data words to write - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The data was sent successfully - * \retval STATUS_ERR_DENIED The serializer is not in transmit mode - * \retval STATUS_ERR_INVALID_ARG An invalid buffer pointer was supplied - */ -enum status_code i2s_serializer_write_buffer_job( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const void *buffer, - const uint32_t size) -{ - struct i2s_serializer_module *data_module; - - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - - data_module = &module_inst->serializer[serializer]; - - /* Serializer must in transmit mode */ - if (data_module->mode != I2S_SERIALIZER_TRANSMIT) { - return STATUS_ERR_DENIED; - } - - /* Buffer should be aligned */ - switch(data_module->data_size) { - case I2S_DATA_SIZE_32BIT: - case I2S_DATA_SIZE_24BIT: - case I2S_DATA_SIZE_20BIT: - case I2S_DATA_SIZE_18BIT: - if ((uint32_t)buffer & 0x3) { - return STATUS_ERR_INVALID_ARG; - } - break; - case I2S_DATA_SIZE_16BIT: - case I2S_DATA_SIZE_16BIT_COMPACT: - if ((uint32_t)buffer & 0x1) { - return STATUS_ERR_INVALID_ARG; - } - break; - default: - break; - } - - data_module = &module_inst->serializer[serializer]; - if (data_module->job_status == STATUS_BUSY) { - return STATUS_BUSY; - } - - data_module->job_status = STATUS_BUSY; - data_module->requested_words = size; - data_module->transferred_words = 0; - data_module->job_buffer = (void*)buffer; - - module_inst->hw->INTENSET.reg = (I2S_INTENSET_TXRDY0 << serializer); - - return STATUS_OK; -} - -/** - * \brief Read from the specified Serializer of I2S module to a buffer - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The serializer to write to - * \param[out] buffer The buffer to fill read data - * \param[in] size Number of data words to read - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The data was sent successfully - * \retval STATUS_ERR_DENIED The serializer is not in receive mode - * \retval STATUS_ERR_INVALID_ARG An invalid buffer pointer was supplied - */ -enum status_code i2s_serializer_read_buffer_job( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - void *buffer, - const uint32_t size) -{ - struct i2s_serializer_module *data_module; - - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - - data_module = &module_inst->serializer[serializer]; - - /* Serializer must in receive mode */ - if (data_module->mode == I2S_SERIALIZER_TRANSMIT) { - return STATUS_ERR_DENIED; - } - - /* Data buffer must be aligned */ - switch(data_module->data_size) { - case I2S_DATA_SIZE_32BIT: - case I2S_DATA_SIZE_24BIT: - case I2S_DATA_SIZE_20BIT: - case I2S_DATA_SIZE_18BIT: - if ((uint32_t)buffer & 0x3) { - return STATUS_ERR_INVALID_ARG; - } - break; - case I2S_DATA_SIZE_16BIT: - case I2S_DATA_SIZE_16BIT_COMPACT: - if ((uint32_t)buffer & 0x1) { - return STATUS_ERR_INVALID_ARG; - } - break; - default: - break; - } - - data_module = &module_inst->serializer[serializer]; - if (data_module->job_status == STATUS_BUSY) { - return STATUS_BUSY; - } - - data_module->job_status = STATUS_BUSY; - data_module->requested_words = size; - data_module->transferred_words = 0; - data_module->job_buffer = (void*)buffer; - - module_inst->hw->INTENCLR.reg = (I2S_INTENSET_RXRDY0 << serializer); - module_inst->hw->INTENSET.reg = (I2S_INTENSET_RXRDY0 << serializer); - - return STATUS_OK; -} - -/** - * \brief Aborts an ongoing job running on serializer - * - * Aborts an ongoing job. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The serializer which runs the job - * \param[in] job_type Type of job to abort - */ -void i2s_serializer_abort_job( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_job_type job_type) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - - if (job_type == I2S_JOB_WRITE_BUFFER) { - /* Disable interrupt */ - module_inst->hw->INTENCLR.reg = (I2S_INTENCLR_TXRDY0 << serializer); - /* Mark job as aborted */ - module_inst->serializer[serializer].job_status = STATUS_ABORTED; - } else if (job_type == I2S_JOB_READ_BUFFER) { - /* Disable interrupt */ - module_inst->hw->INTENCLR.reg = (I2S_INTENCLR_RXRDY0 << serializer); - /* Mark job as aborted */ - module_inst->serializer[serializer].job_status = STATUS_ABORTED; - } -} - -/** - * \brief Gets the status of a job running on serializer - * - * Gets the status of an ongoing or the last job. - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The serializer which runs the job - * \param[in] job_type Type of job to abort - * - * \return Status of the job. - */ -enum status_code i2s_serializer_get_job_status( - const struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_job_type job_type) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(serializer < I2S_SERIALIZER_N); - - if (job_type == I2S_JOB_WRITE_BUFFER || job_type == I2S_JOB_READ_BUFFER) { - return module_inst->serializer[serializer].job_status; - } else { - return STATUS_ERR_INVALID_ARG; - } -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.h ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.h b/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.h deleted file mode 100755 index 66b15e3..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s_callback.h +++ /dev/null @@ -1,234 +0,0 @@ -/** - * \file - * - * \brief SAM I2S - Inter-IC Sound Controller - * - * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ - -#ifndef I2S_CALLBACK_H_INCLUDED -#define I2S_CALLBACK_H_INCLUDED - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup asfdoc_sam0_i2s_group - * - * @{ - */ - -#include <i2s.h> - -/** - * Enum for the possible types of I2S asynchronous jobs that may be issued to - * the driver. - */ -enum i2s_job_type { - /** Asynchronous I2S write from a user provided buffer */ - I2S_JOB_WRITE_BUFFER, - /** Asynchronous I2S read into a user provided buffer */ - I2S_JOB_READ_BUFFER -}; - -/** - * \name Callback Management - * @{ - */ - -/** - * \brief Registers a callback for serializer - * - * Registers a callback function which is implemented by the user. - * - * \note The callback must be enabled by for the interrupt handler to call it - * when the condition for the callback is met. - * - * \param[in] module Pointer to ADC software instance struct - * \param[in] serializer The serializer that generates callback - * \param[in] callback_func Pointer to callback function - * \param[in] callback_type Callback type given by an enum - * - */ -static inline void i2s_serializer_register_callback( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const i2s_serializer_callback_t callback_func, - const enum i2s_serializer_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(serializer < I2S_SERIALIZER_N); - - module_inst->serializer[serializer].callback[callback_type] = callback_func; - module_inst->serializer[serializer].registered_callback_mask |= - (1u << callback_type); -} - -/** - * \brief Unregisters a callback for serializer - * - * Unregisters a callback function which is implemented by the user. - * - * \param[in] module Pointer to ADC software instance struct - * \param[in] serializer The serializer that generates callback - * \param[in] callback_type Callback type given by an enum - * - */ -static inline void i2s_serializer_unregister_callback( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_serializer_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(serializer < I2S_SERIALIZER_N); - - module_inst->serializer[serializer].callback[callback_type] = NULL; - module_inst->serializer[serializer].registered_callback_mask &= - ~(1u << callback_type); -} - -/** - * \brief Enables callback for serializer - * - * Enables the callback function registered by \ref - * i2s_serializer_register_callback. The callback function will be called from - * the interrupt handler when the conditions for the callback type are met. - * - * \param[in] module Pointer to ADC software instance struct - * \param[in] serializer The serializer that generates callback - * \param[in] callback_type Callback type given by an enum - * - */ -static inline void i2s_serializer_enable_callback( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_serializer_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - - module_inst->serializer[serializer].enabled_callback_mask |= - (1u << callback_type); - if (I2S_SERIALIZER_CALLBACK_OVER_UNDER_RUN != callback_type) { - return; - } - module_inst->hw->INTENSET.reg = - (module_inst->serializer[serializer].mode == I2S_SERIALIZER_TRANSMIT) ? - (I2S_INTFLAG_TXUR0 << serializer) : - (I2S_INTFLAG_RXOR0 << serializer); -} - -/** - * \brief Disables callback for Serializer - * - * Disables the callback function registered by the \ref - * i2s_serializer_register_callback. - * - * \param[in] module Pointer to ADC software instance struct - * \param[in] serializer The serializer that generates callback - * \param[in] callback_type Callback type given by an enum - * - */ -static inline void i2s_serializer_disable_callback( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_serializer_callback callback_type) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - - module_inst->serializer[serializer].enabled_callback_mask &= - ~(1u << callback_type); - if (I2S_SERIALIZER_CALLBACK_OVER_UNDER_RUN != callback_type) { - return; - } - module_inst->hw->INTENCLR.reg = - (module_inst->serializer[serializer].mode == I2S_SERIALIZER_TRANSMIT) ? - (I2S_INTFLAG_TXUR0 << serializer) : - (I2S_INTFLAG_RXOR0 << serializer); -} - -/** @} */ - -/** - * \name Job Management - * - * @{ - */ - -enum status_code i2s_serializer_write_buffer_job( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const void *buffer, - const uint32_t size); - -enum status_code i2s_serializer_read_buffer_job( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - void *buffer, - const uint32_t size); - -void i2s_serializer_abort_job( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_job_type job_type); - -enum status_code i2s_serializer_get_job_status( - const struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const enum i2s_job_type job_type); - -/** @} */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif /* #ifndef I2S_CALLBACK_H_INCLUDED */