00001 /* ---------------------------------------------------------------------------- 00002 * SAM Software Package License 00003 * ---------------------------------------------------------------------------- 00004 * Copyright (c) 2012, Atmel Corporation 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * 00011 * - Redistributions of source code must retain the above copyright notice, 00012 * this list of conditions and the disclaimer below. 00013 * 00014 * Atmel's name may not be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00019 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 00020 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00023 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00024 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00025 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 00026 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 * ---------------------------------------------------------------------------- 00028 */ 00029 00030 /** \addtogroup ssc_module Working with SSC 00031 * The SSC driver provides the interface to configure and use the SSC 00032 * peripheral. 00033 * 00034 * !Usage 00035 * 00036 * -# Enable the SSC interface pins. 00037 * -# Configure the SSC to operate at a specific frequency by calling 00038 * SSC_Configure(). This function enables the peripheral clock of the SSC, 00039 * but not its PIOs. 00040 * -# Configure the transmitter and/or the receiver using the 00041 * SSC_ConfigureTransmitter() and SSC_ConfigureEmitter() functions. 00042 * -# Enable the PIOs or the transmitter and/or the received. 00043 * -# Enable the transmitter and/or the receiver using SSC_EnableTransmitter() 00044 * and SSC_EnableReceiver() 00045 * -# Send data through the transmitter using SSC_Write() 00046 * -# Receive data from the receiver using SSC_Read() 00047 * -# Disable the transmitter and/or the receiver using SSC_DisableTransmitter() 00048 * and SSC_DisableReceiver() 00049 * 00050 * For more accurate information, please look at the SSC section of the 00051 * Datasheet. 00052 * 00053 * Related files :\n 00054 * \ref ssc.c\n 00055 * \ref ssc.h.\n 00056 */ 00057 /*@{*/ 00058 /*@}*/ 00059 00060 00061 /** 00062 * \file 00063 * 00064 * Implementation of Synchronous Serial (SSC) controller. 00065 * 00066 */ 00067 00068 /*---------------------------------------------------------------------------- 00069 * Headers 00070 *----------------------------------------------------------------------------*/ 00071 00072 #include "chip.h" 00073 00074 /*---------------------------------------------------------------------------- 00075 * Exported functions 00076 *----------------------------------------------------------------------------*/ 00077 00078 /** 00079 * \brief Configures a SSC peripheral.If the divided clock is not used, the 00080 * master clock frequency can be set to 0. 00081 * \note The emitter and transmitter are disabled by this function. 00082 * \param ssc Pointer to an SSC instance. 00083 * \param bitRate bit rate. 00084 * \param masterClock master clock. 00085 */ 00086 void SSC_Configure(Ssc *ssc, uint32_t bitRate, uint32_t masterClock) 00087 { 00088 uint32_t id; 00089 // uint32_t maxClock; 00090 id = ID_SSC ; 00091 // maxClock = PMC_SetPeriMaxClock(id, masterClock); 00092 00093 /* Reset, disable receiver & transmitter */ 00094 ssc->SSC_CR = SSC_CR_RXDIS | SSC_CR_TXDIS | SSC_CR_SWRST; 00095 00096 /* Configure clock frequency */ 00097 if (bitRate != 0) { 00098 ssc->SSC_CMR = masterClock / (2 * bitRate); 00099 } else { 00100 ssc->SSC_CMR = 0; 00101 } 00102 /* Enable SSC peripheral clock */ 00103 PMC_EnablePeripheral(id); 00104 } 00105 00106 /** 00107 * \brief Configures the transmitter of a SSC peripheral. 00108 * \param ssc Pointer to an SSC instance. 00109 * \param tcmr Transmit Clock Mode Register value. 00110 * \param tfmr Transmit Frame Mode Register value. 00111 */ 00112 void SSC_ConfigureTransmitter(Ssc *ssc,uint32_t tcmr, uint32_t tfmr) 00113 { 00114 ssc->SSC_TCMR = tcmr; 00115 ssc->SSC_TFMR = tfmr; 00116 } 00117 00118 /** 00119 * \brief Configures the receiver of a SSC peripheral. 00120 * \param ssc Pointer to an SSC instance. 00121 * \param rcmr Receive Clock Mode Register value. 00122 * \param rfmr Receive Frame Mode Register value. 00123 */ 00124 void SSC_ConfigureReceiver(Ssc *ssc, uint32_t rcmr, uint32_t rfmr) 00125 { 00126 ssc->SSC_RCMR = rcmr; 00127 ssc->SSC_RFMR = rfmr; 00128 } 00129 00130 /** 00131 * \brief Enables the transmitter of a SSC peripheral. 00132 * \param ssc Pointer to an SSC instance. 00133 */ 00134 void SSC_EnableTransmitter(Ssc *ssc) 00135 { 00136 ssc->SSC_CR = SSC_CR_TXEN; 00137 } 00138 00139 /** 00140 * \brief Disables the transmitter of a SSC peripheral. 00141 * \param ssc Pointer to an SSC instance. 00142 */ 00143 void SSC_DisableTransmitter(Ssc *ssc) 00144 { 00145 ssc->SSC_CR = SSC_CR_TXDIS; 00146 } 00147 00148 /** 00149 * \brief Enables the receiver of a SSC peripheral. 00150 * \param ssc Pointer to an SSC instance. 00151 */ 00152 void SSC_EnableReceiver(Ssc *ssc) 00153 { 00154 ssc->SSC_CR = SSC_CR_RXEN; 00155 } 00156 00157 /** 00158 * \brief Disables the receiver of a SSC peripheral. 00159 * \param ssc Pointer to an SSC instance. 00160 */ 00161 void SSC_DisableReceiver(Ssc *ssc) 00162 { 00163 ssc->SSC_CR = SSC_CR_RXDIS; 00164 } 00165 00166 /** 00167 * \brief Enables one or more interrupt sources of a SSC peripheral. 00168 * \param ssc Pointer to an SSC instance. 00169 * \param sources Bitwise OR of selected interrupt sources. 00170 */ 00171 void SSC_EnableInterrupts(Ssc *ssc, uint32_t sources) 00172 { 00173 ssc->SSC_IER = sources; 00174 } 00175 00176 /** 00177 * \brief Disables one or more interrupt sources of a SSC peripheral. 00178 * \param ssc Pointer to an SSC instance. 00179 * \param sources Bitwise OR of selected interrupt sources. 00180 */ 00181 void SSC_DisableInterrupts(Ssc *ssc, uint32_t sources) 00182 { 00183 ssc->SSC_IDR = sources; 00184 } 00185 00186 /** 00187 * \brief Sends one data frame through a SSC peripheral. If another frame is currently 00188 * being sent, this function waits for the previous transfer to complete. 00189 * \param ssc Pointer to an SSC instance. 00190 * \param frame Data frame to send. 00191 */ 00192 void SSC_Write(Ssc *ssc, uint32_t frame) 00193 { 00194 while ((ssc->SSC_SR & SSC_SR_TXRDY) == 0); 00195 ssc->SSC_THR = frame; 00196 } 00197 00198 /** 00199 * \brief Waits until one frame is received on a SSC peripheral, and returns it. 00200 * \param ssc Pointer to an SSC instance. 00201 */ 00202 uint32_t SSC_Read(Ssc *ssc) 00203 { 00204 while ((ssc->SSC_SR & SSC_SR_RXRDY) == 0); 00205 return ssc->SSC_RHR; 00206 } 00207 00208 /** 00209 * \brief Return 1 if one frame is received, 0 otherwise. 00210 * \param ssc Pointer to an SSC instance. 00211 */ 00212 uint8_t SSC_IsRxReady(Ssc *ssc) 00213 { 00214 return ((ssc->SSC_SR & SSC_SR_RXRDY) > 0); 00215 } 00216