1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-12-10 21:24:12 +01:00
Arduino/hardware/arduino/sam/system/libsam/include/ssc.h
2012-12-19 15:20:14 +01:00

211 lines
8.3 KiB
C

/**
* \file
*
* \brief Synchronous Serial Controller (SSC) driver for SAM.
*
* Copyright (c) 2011-2012 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
*
*/
#ifndef SSC_H_INCLUDED
#define SSC_H_INCLUDED
#include "../chip.h"
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
//! Receive stop selection.
#define SSC_RX_STOP_COMPARE_0 0
#define SSC_RX_STOP_COMPARE_0_1 1
//! Compare register ID.
#define COMPARE_ID0 0
#define COMPARE_ID1 1
//! SSC module default timeout. */
#define SSC_DEFAULT_TIMEOUT 10000
//! \brief SSC driver return codes.
enum ssc_return_code {
SSC_RC_OK = 0, //!< OK
SSC_RC_YES = 0, //!< Yes
SSC_RC_NO = 1, //!< No
SSC_RC_ERROR = 1, //!< General error
SSC_RC_INVALID = 0xFFFFFFFF //!< Parameter invalid
};
//! Data frame structure.
typedef struct {
//! Data bits length per transfer, should be 0 to 31.
uint32_t ul_datlen;
//! Bit sequence LSBF or MSBF.
//! For receiver configuration, SSC_RFMR_MSBF or 0.
//! For transmitter configuration, SSC_TFMR_MSBF or 0.
uint32_t ul_msbf;
//! Data number per frame, should be 0 to 15.
uint32_t ul_datnb;
//! Frame Sync. length should be 0 to 15.
uint32_t ul_fslen;
//! Frame Sync. length extension field, should be 0 to 15.
uint32_t ul_fslen_ext;
//! Frame Sync. output selection.
//! For receiver configuration, one of SSC_RFMR_FSOS_NONE, SSC_RFMR_FSOS_NEGATIVE, SSC_RFMR_FSOS_POSITIVE,
//! SSC_RFMR_FSOS_LOW, SSC_RFMR_FSOS_HIGH or SSC_RFMR_FSOS_TOGGLING.
//! For transmitter configuration, one of SSC_TFMR_FSOS_NONE, SSC_TFMR_FSOS_NEGATIVE, SSC_TFMR_FSOS_POSITIVE
//! SSC_TFMR_FSOS_LOW, SSC_TFMR_FSOS_HIGH, SSC_TFMR_FSOS_TOGGLING,
uint32_t ul_fsos;
//! Frame Sync. edge detection.
//! For receiver configuration, SSC_RFMR_FSEDGE_POSITIVE or SSC_RFMR_FSEDGE_NEGATIVE.
//! For transmitter configuration, SSC_TFMR_FSEDGE_POSITIVE or SSC_TFMR_FSEDGE_NEGATIVE.
uint32_t ul_fsedge;
} data_frame_opt_t;
//! Clock mode structure.
typedef struct {
//! Communication clock selection.
//! For receiver configuration, one of SSC_RCMR_CKS_MCK, SSC_RCMR_CKS_TK or SSC_RCMR_CKS_RK.
//! For transmitter configuration, one of SSC_TCMR_CKS_MCK, SSC_TCMR_CKS_TK or SSC_TCMR_CKS_RK.
uint32_t ul_cks;
//! Communication clock output mode selection.
//! For receiver configuration, one of SSC_RCMR_CKO_NONE, SSC_RCMR_CKO_CONTINUOUS or SSC_RCMR_CKO_TRANSFER.
//! For transmitter configuration, one of SSC_TCMR_CKO_NONE, SSC_TCMR_CKO_CONTINUOUS or SSC_TCMR_CKO_TRANSFER.
uint32_t ul_cko;
//! Communication clock inversion.
//! For receiver configuration, SSC_RCMR_CKI or 0.
//! For transmitter configuration, SSC_TCMR_CKI or 0.
uint32_t ul_cki;
//! Communication clock gating selection.
//! For receiver configuration, one of SSC_RCMR_CKG_NONE, SSC_RCMR_CKG_CONTINUOUS and SSC_RCMR_CKG_TRANSFER.
//! For transmitter configuration, one of SSC_TCMR_CKG_NONE, SSC_TCMR_CKG_CONTINUOUS and SSC_TCMR_CKG_TRANSFER.
uint32_t ul_ckg;
//! Period divider selection, should be 0 to 255.
uint32_t ul_period;
//! Communication start delay, should be 0 to 255.
uint32_t ul_sttdly;
//! Communication start selection.
//! For receiver configuration, one of SSC_RCMR_START_CONTINUOUS, SSC_RCMR_START_TRANSMIT, SSC_RCMR_START_RF_LOW,
//! SSC_RCMR_START_RF_HIGH, SSC_RCMR_START_RF_FALLING, SSC_RCMR_START_RF_RISING, SSC_RCMR_START_RF_LEVEL,
//! SSC_RCMR_START_RF_EDGE or SSC_RCMR_START_CMP_0.
//! For transmitter configuration, one of SSC_TCMR_START_CONTINUOUS, SSC_TCMR_START_TRANSMIT, SSC_TCMR_START_RF_LOW,
//! SSC_TCMR_START_RF_HIGH, SSC_TCMR_START_RF_FALLING, SSC_TCMR_START_RF_RISING, SSC_TCMR_START_RF_LEVEL,
//! SSC_TCMR_START_RF_EDGE or SSC_TCMR_START_CMP_0.
uint32_t ul_start_sel;
} clock_opt_t;
//! SSC working role in I2S mode.
#define SSC_I2S_MASTER_OUT (1 << 0) //! Working mode for transmitter as master.
#define SSC_I2S_MASTER_IN (1 << 1) //! Working mode for receiver as master.
#define SSC_I2S_SLAVE_OUT (1 << 2) //! Working mode for transmitter as slave.
#define SSC_I2S_SLAVE_IN (1 << 3) //! Working mode for receiver as slave.
//! Bit for SSC Audio channel left.
#define SSC_AUDIO_CH_LEFT (1 << 0)
//! Bit for SSC Audio channel right.
#define SSC_AUDIO_CH_RIGHT (1 << 1)
//! SSC Audio Channel modes.
enum {
//! Mono, left channel enabled.
SSC_AUDIO_MONO_LEFT = (SSC_AUDIO_CH_LEFT),
//! Mono, right channel enabled.
SSC_AUDIO_MONO_RIGHT = (SSC_AUDIO_CH_RIGHT),
//! Stereo, two channels.
SSC_AUDIO_STERO = (SSC_AUDIO_CH_LEFT | SSC_AUDIO_CH_RIGHT)
};
uint32_t ssc_set_clock_divider(Ssc *p_ssc, uint32_t ul_bitclock, uint32_t ul_mck);
void ssc_i2s_set_transmitter(Ssc *p_ssc, uint32_t ul_mode,
uint32_t ul_cks, uint32_t ul_ch_mode, uint32_t ul_datlen);
void ssc_i2s_set_receiver(Ssc *p_ssc, uint32_t ul_mode,
uint32_t ul_cks, uint32_t ul_ch_mode, uint32_t ul_datlen);
void ssc_reset(Ssc *p_ssc);
void ssc_enable_rx(Ssc *p_ssc);
void ssc_disable_rx(Ssc *p_ssc);
void ssc_enable_tx(Ssc *p_ssc);
void ssc_disable_tx(Ssc *p_ssc);
void ssc_set_normal_mode(Ssc *p_ssc);
void ssc_set_loop_mode(Ssc *p_ssc);
void ssc_set_rx_stop_selection(Ssc *p_ssc, uint32_t ul_sel);
void ssc_set_td_default_level(Ssc *p_ssc, uint32_t ul_level);
void ssc_enable_tx_frame_sync_data(Ssc *p_ssc);
void ssc_disable_tx_frame_sync_data(Ssc *p_ssc);
void ssc_set_receiver(Ssc *p_ssc, clock_opt_t *p_rx_clk_opt, data_frame_opt_t *p_rx_data_frame);
void ssc_set_transmitter(Ssc *p_ssc, clock_opt_t *p_tx_clk_opt, data_frame_opt_t *p_tx_data_frame);
void ssc_set_rx_compare(Ssc *p_ssc, uint32_t ul_id, uint32_t ul_value);
uint32_t ssc_get_rx_compare(Ssc *p_ssc, uint32_t ul_id);
void ssc_enable_interrupt(Ssc *p_ssc, uint32_t ul_sources);
void ssc_disable_interrupt(Ssc *p_ssc, uint32_t ul_sources);
uint32_t ssc_get_interrupt_mask(Ssc *p_ssc);
uint32_t ssc_get_status(Ssc *p_ssc);
uint32_t ssc_is_tx_ready(Ssc *p_ssc);
uint32_t ssc_is_tx_empty(Ssc *p_ssc);
uint32_t ssc_is_rx_ready(Ssc *p_ssc);
uint32_t ssc_is_tx_enabled(Ssc *p_ssc);
uint32_t ssc_is_rx_enabled(Ssc *p_ssc);
#if (defined _SAM3S_) || (defined _SAM4S_)
uint32_t ssc_is_rx_buf_end(Ssc *p_ssc);
uint32_t ssc_is_tx_buf_end(Ssc *p_ssc);
uint32_t ssc_is_rx_buf_full(Ssc *p_ssc);
uint32_t ssc_is_tx_buf_empty(Ssc *p_ssc);
Pdc *ssc_get_pdc_base(Ssc *p_ssc);
#endif
uint32_t ssc_write(Ssc *p_ssc, uint32_t ul_frame);
uint32_t ssc_read(Ssc *p_ssc, uint32_t *ul_data);
void ssc_write_sync_data(Ssc *p_ssc, uint32_t ul_frame);
uint32_t ssc_read_sync_data(Ssc *p_ssc);
#if ((defined _SAM3XA_) || (defined _SAM3U_))
void *ssc_get_tx_access(Ssc *p_ssc);
void *ssc_get_rx_access(Ssc *p_ssc);
#endif
void ssc_set_writeprotect(Ssc *p_ssc, uint32_t ul_enable);
uint32_t ssc_get_writeprotect_status(Ssc *p_ssc);
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
#endif /* SSC_H_INCLUDED */