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