SAMV71 Xplained Ultra Software Package 1.4

twi.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2011, 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 twi_module Working with TWI
00031  *  \ingroup peripherals_module
00032  * The TWI driver provides the interface to configure and use the TWI
00033  * peripheral.
00034  *
00035  * \section Usage
00036  * <ul>
00037  * <li> Configures a TWI peripheral to operate in master mode, at the given
00038  * frequency (in Hz) using TWI_Configure(). </li>
00039  * <li> Sends a STOP condition on the TWI using TWI_Stop().</li>
00040  * <li> Starts a read operation on the TWI bus with the specified slave using
00041  * TWI_StartRead(). Data must then be read using TWI_ReadByte() whenever
00042  * a byte is available (poll using TWI_ByteReceived()).</li>
00043  * <li> Starts a write operation on the TWI to access the selected slave using
00044  * TWI_StartWrite(). A byte of data must be provided to start the write;
00045  * other bytes are written next.</li>
00046  * <li> Sends a byte of data to one of the TWI slaves on the bus using 
00047  * TWI_WriteByte().
00048  * This function must be called once before TWI_StartWrite() with the first 
00049  * byte of data
00050  * to send, then it shall be called repeatedly after that to send the 
00051  * remaining bytes.</li>
00052  * <li> Check if a byte has been received and can be read on the given TWI
00053  * peripheral using TWI_ByteReceived().<
00054  * Check if a byte has been sent using TWI_ByteSent().</li>
00055  * <li> Check if the current transmission is complete (the STOP has been sent)
00056  * using TWI_TransferComplete().</li>
00057  * <li> Enables & disable the selected interrupts sources on a TWI peripheral
00058  * using TWI_EnableIt() and TWI_DisableIt().</li>
00059  * <li> Get current status register of the given TWI peripheral using
00060  * TWI_GetStatus(). Get current status register of the given TWI peripheral, but
00061  * masking interrupt sources which are not currently enabled using
00062  * TWI_GetMaskedStatus().</li>
00063  * </ul>
00064  * For more accurate information, please look at the TWI section of the
00065  * Datasheet.
00066  *
00067  * Related files :\n
00068  * \ref twi.c\n
00069  * \ref twi.h.\n
00070  */
00071 /*@{*/
00072 /*@}*/
00073 
00074 /**
00075  * \file
00076  *
00077  * Implementation of Two Wire Interface (TWI).
00078  *
00079  */
00080 
00081 /*----------------------------------------------------------------------------
00082  *        Headers
00083  *----------------------------------------------------------------------------*/
00084 
00085 #include "chip.h"
00086 
00087 #include <assert.h>
00088 
00089 #define TWIHS_IT    ( TWIHS_IER_TXCOMP | TWIHS_IER_TXCOMP | TWIHS_IER_RXRDY \
00090                     | TWIHS_IER_TXRDY | TWIHS_IER_SVACC | TWIHS_IER_GACC | \
00091                       TWIHS_IER_OVRE | TWIHS_IER_UNRE | TWIHS_IER_NACK | \
00092                       TWIHS_IER_ARBLST | TWIHS_IER_SCL_WS | TWIHS_IER_EOSACC | \
00093                       TWIHS_IER_MCACK | TWIHS_IER_TOUT | TWIHS_IER_PECERR |\
00094                       TWIHS_IER_SMBDAM | TWIHS_IER_SMBHHM)
00095                       
00096 
00097 /** variable for control thether or not to set both START and STOP
00098   * In single data byte master read, the START and STOP must both be set */
00099 uint32_t twi_send_stop = 0;
00100 
00101 /*----------------------------------------------------------------------------
00102  *        Exported functions
00103  *----------------------------------------------------------------------------*/
00104 
00105 /**
00106  * \brief Configures a TWI peripheral to operate in master mode, at the given
00107  * frequency (in Hz). The duty cycle of the TWI clock is set to 50%.
00108  * \param pTwi  Pointer to an Twihs instance.
00109  * \param twck  Desired TWI clock frequency.
00110  * \param mck  Master clock frequency.
00111  */
00112 void TWI_ConfigureMaster( Twihs *pTwi, uint32_t dwTwCk, uint32_t dwMCk )
00113 {
00114     uint32_t dwCkDiv = 0 ;
00115     uint32_t dwClDiv ;
00116     uint32_t dwOk = 0 ;
00117 
00118     TRACE_DEBUG( "TWI_ConfigureMaster()\n\r" ) ;
00119     assert( pTwi ) ;
00120 
00121     /* SVEN: TWI Slave Mode Enabled */
00122     pTwi->TWIHS_CR = TWIHS_CR_SVEN ;
00123     /* Reset the TWI */
00124     pTwi->TWIHS_CR = TWIHS_CR_SWRST ;
00125     pTwi->TWIHS_RHR ;
00126 
00127     /* TWI Slave Mode Disabled, TWI Master Mode Disabled. */
00128     pTwi->TWIHS_CR = TWIHS_CR_SVDIS ;
00129     pTwi->TWIHS_CR = TWIHS_CR_MSDIS ;
00130 
00131     /* Set master mode */
00132     pTwi->TWIHS_CR = TWIHS_CR_MSEN ;
00133 
00134     /* Configure clock */
00135     while ( !dwOk ) {
00136         dwClDiv = ((dwMCk / (2 * dwTwCk)) - 4) / (1<<dwCkDiv) ;
00137 
00138         if ( dwClDiv <= 255 ) {
00139             dwOk = 1 ;
00140         } else {
00141             dwCkDiv++ ;
00142         }
00143     }
00144     assert( dwCkDiv < 8 ) ;
00145     TRACE_DEBUG( "Using CKDIV = %u and CLDIV/CHDIV = %u\n\r", dwCkDiv, dwClDiv ) ;
00146 
00147     pTwi->TWIHS_CWGR = 0 ;
00148     pTwi->TWIHS_CWGR = (dwCkDiv << 16) | (dwClDiv << 8) | dwClDiv ;
00149 }
00150 
00151 /**
00152  * \brief Configures a TWI peripheral to operate in slave mode.
00153  * \param pTwi  Pointer to an Twihs instance.
00154  * \param slaveAddress Slave address.
00155  */
00156 void TWI_ConfigureSlave(Twihs *pTwi, uint8_t slaveAddress)
00157 {
00158     uint32_t i;
00159 
00160     /* TWI software reset */
00161     pTwi->TWIHS_CR = TWIHS_CR_SWRST;
00162     pTwi->TWIHS_RHR;
00163 
00164     /* Wait at least 10 ms */
00165     for (i=0; i < 1000000; i++);
00166 
00167     /* TWI Slave Mode Disabled, TWI Master Mode Disabled*/
00168     pTwi->TWIHS_CR = TWIHS_CR_SVDIS | TWIHS_CR_MSDIS;
00169 
00170     /* Configure slave address. */
00171     pTwi->TWIHS_SMR = 0;
00172     pTwi->TWIHS_SMR = TWIHS_SMR_SADR(slaveAddress);
00173 
00174     /* SVEN: TWI Slave Mode Enabled */
00175     pTwi->TWIHS_CR = TWIHS_CR_SVEN;
00176 
00177     /* Wait at least 10 ms */
00178     for (i=0; i < 1000000; i++);
00179     assert( (pTwi->TWIHS_CR & TWIHS_CR_SVDIS)!= TWIHS_CR_SVDIS ) ;
00180 }
00181 
00182 /**
00183  * \brief Sends a STOP condition on the TWI.
00184  * \param pTwi  Pointer to an Twihs instance.
00185  */
00186 void TWI_Stop( Twihs *pTwi )
00187 {
00188     assert( pTwi != NULL ) ;
00189 
00190     pTwi->TWIHS_CR = TWIHS_CR_STOP;
00191 }
00192 
00193 /**
00194  * \brief Starts a read operation on the TWI bus with the specified slave, it 
00195  * returns immediately. Data must then be read using TWI_ReadByte() whenever a
00196  * byte is available (poll using TWI_ByteReceived()).
00197  * \param pTwi  Pointer to an Twihs instance.
00198  * \param address  Slave address on the bus.
00199  * \param iaddress  Optional internal address bytes.
00200  * \param isize  Number of internal address bytes.
00201  */
00202 void TWI_StartRead(
00203         Twihs *pTwi,
00204         uint8_t address,
00205         uint32_t iaddress,
00206         uint8_t isize)
00207 {
00208     assert( pTwi != NULL ) ;
00209     assert( (address & 0x80) == 0 ) ;
00210     assert( (iaddress & 0xFF000000) == 0 ) ;
00211     assert( isize < 4 ) ;
00212 
00213     /* Set slave address and number of internal address bytes. */
00214     pTwi->TWIHS_MMR = 0;
00215     pTwi->TWIHS_MMR = (isize << 8) | TWIHS_MMR_MREAD | (address << 16);
00216 
00217     /* Set internal address bytes */
00218     pTwi->TWIHS_IADR = 0;
00219     pTwi->TWIHS_IADR = iaddress;
00220 
00221     /* Send START condition */
00222     if(0 == twi_send_stop) {
00223         pTwi->TWIHS_CR = TWIHS_CR_START;
00224     } else {
00225         twi_send_stop = 0;
00226         pTwi->TWIHS_CR = TWIHS_CR_START|TWIHS_CR_STOP;
00227     }
00228 }
00229 
00230 /**
00231  * \brief Reads a byte from the TWI bus. The read operation must have been started
00232  * using TWI_StartRead() and a byte must be available (check with TWI_ByteReceived()).
00233  * \param pTwi  Pointer to an Twihs instance.
00234  * \return byte read.
00235  */
00236 uint8_t TWI_ReadByte(Twihs *pTwi)
00237 {
00238     assert( pTwi != NULL ) ;
00239 
00240     return pTwi->TWIHS_RHR;
00241 }
00242 
00243 /**
00244  * \brief Sends a byte of data to one of the TWI slaves on the bus.
00245  * \note This function must be called once before TWI_StartWrite() with
00246  * the first byte of data  to send, then it shall be called repeatedly
00247  * after that to send the remaining bytes.
00248  * \param pTwi  Pointer to an Twihs instance.
00249  * \param byte  Byte to send.
00250  */
00251 void TWI_WriteByte(Twihs *pTwi, uint8_t byte)
00252 {
00253     assert( pTwi != NULL ) ;
00254 
00255     pTwi->TWIHS_THR = byte;
00256 }
00257 
00258 /**
00259  * \brief Starts a write operation on the TWI to access the selected slave, then
00260  *  returns immediately. A byte of data must be provided to start the write;
00261  * other bytes are written next.
00262  * after that to send the remaining bytes.
00263  * \param pTwi  Pointer to an Twihs instance.
00264  * \param address  Address of slave to acccess on the bus.
00265  * \param iaddress  Optional slave internal address.
00266  * \param isize  Number of internal address bytes.
00267  * \param byte  First byte to send.
00268  */
00269 void TWI_StartWrite(
00270         Twihs *pTwi,
00271         uint8_t address,
00272         uint32_t iaddress,
00273         uint8_t isize,
00274         uint8_t byte)
00275 {
00276     assert( pTwi != NULL ) ;
00277     assert( (address & 0x80) == 0 ) ;
00278     assert( (iaddress & 0xFF000000) == 0 ) ;
00279     assert( isize < 4 ) ;
00280 
00281     /* Set slave address and number of internal address bytes. */
00282     pTwi->TWIHS_MMR = 0;
00283     pTwi->TWIHS_MMR = (isize << 8) | (address << 16);
00284 
00285     /* Set internal address bytes. */
00286     pTwi->TWIHS_IADR = 0;
00287     pTwi->TWIHS_IADR = iaddress;
00288 
00289     /* Write first byte to send.*/
00290     TWI_WriteByte(pTwi, byte);
00291 }
00292 
00293 /**
00294  * \brief Check if a byte have been received from TWI.
00295  * \param pTwi  Pointer to an Twihs instance.
00296  * \return 1 if a byte has been received and can be read on the given TWI
00297  * peripheral; otherwise, returns 0. This function resets the status register.
00298  */
00299 uint8_t TWI_ByteReceived(Twihs *pTwi)
00300 {
00301     return ((pTwi->TWIHS_SR & TWIHS_SR_RXRDY) == TWIHS_SR_RXRDY);
00302 }
00303 
00304 /**
00305  * \brief Check if a byte have been sent to TWI.
00306  * \param pTwi  Pointer to an Twihs instance.
00307  * \return 1 if a byte has been sent  so another one can be stored for
00308  * transmission; otherwise returns 0. This function clears the status register.
00309  */
00310 uint8_t TWI_ByteSent(Twihs *pTwi)
00311 {
00312     return ((pTwi->TWIHS_SR & TWIHS_SR_TXRDY) == TWIHS_SR_TXRDY);
00313 }
00314 
00315 /**
00316  * \brief Check if current transmission is completed.
00317  * \param pTwi  Pointer to an Twihs instance.
00318  * \return  1 if the current transmission is complete (the STOP has been sent);
00319  * otherwise returns 0.
00320  */
00321 uint8_t TWI_TransferComplete(Twihs *pTwi)
00322 {
00323     return ((pTwi->TWIHS_SR & TWIHS_SR_TXCOMP) == TWIHS_SR_TXCOMP);
00324 }
00325 
00326 /**
00327  * \brief Enables the selected interrupts sources on a TWI peripheral.
00328  * \param pTwi  Pointer to an Twihs instance.
00329  * \param sources  Bitwise OR of selected interrupt sources.
00330  */
00331 void TWI_EnableIt(Twihs *pTwi, uint32_t sources)
00332 {
00333     assert( pTwi != NULL ) ;
00334     assert( (sources & TWIHS_IT) ) ;
00335 
00336     pTwi->TWIHS_IER = sources;
00337 }
00338 
00339 /**
00340  * \brief Disables the selected interrupts sources on a TWI peripheral.
00341  * \param pTwi  Pointer to an Twihs instance.
00342  * \param sources  Bitwise OR of selected interrupt sources.
00343  */
00344 void TWI_DisableIt(Twihs *pTwi, uint32_t sources)
00345 {
00346     assert( pTwi != NULL ) ;
00347     assert(sources & TWIHS_IT ) ;
00348 
00349     pTwi->TWIHS_IDR = sources;
00350 }
00351 
00352 /**
00353  * \brief Get the current status register of the given TWI peripheral.
00354  * \note This resets the internal value of the status register, so further
00355  * read may yield different values.
00356  * \param pTwi  Pointer to an Twihs instance.
00357  * \return  TWI status register.
00358  */
00359 uint32_t TWI_GetStatus(Twihs *pTwi)
00360 {
00361     assert( pTwi != NULL ) ;
00362 
00363     return pTwi->TWIHS_SR;
00364 }
00365 
00366 /**
00367  * \brief Returns the current status register of the given TWI peripheral, but
00368  * masking interrupt sources which are not currently enabled.
00369  * \note This resets the internal value of the status register, so further
00370  * read may yield different values.
00371  * \param pTwi  Pointer to an Twihs instance.
00372  */
00373 uint32_t TWI_GetMaskedStatus(Twihs *pTwi)
00374 {
00375     uint32_t status;
00376 
00377     assert( pTwi != NULL ) ;
00378 
00379     status = pTwi->TWIHS_SR;
00380     status &= pTwi->TWIHS_IMR;
00381 
00382     return status;
00383 }
00384 
00385 /**
00386  * \brief  Sends a STOP condition. STOP Condition is sent just after completing
00387  *  the current byte transmission in master read mode.
00388  * \param pTwi  Pointer to an Twihs instance.
00389  */
00390 void TWI_SendSTOPCondition(Twihs *pTwi)
00391 {
00392     assert( pTwi != NULL ) ;
00393 
00394     pTwi->TWIHS_CR |= TWIHS_CR_STOP;
00395 }
00396 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines