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 * Exported functions 00098 *----------------------------------------------------------------------------*/ 00099 00100 /** 00101 * \brief Configures a TWI peripheral to operate in master mode, at the given 00102 * frequency (in Hz). The duty cycle of the TWI clock is set to 50%. 00103 * \param pTwi Pointer to an Twihs instance. 00104 * \param twck Desired TWI clock frequency. 00105 * \param mck Master clock frequency. 00106 */ 00107 void TWI_ConfigureMaster( Twihs *pTwi, uint32_t dwTwCk, uint32_t dwMCk ) 00108 { 00109 uint32_t dwCkDiv = 0 ; 00110 uint32_t dwClDiv ; 00111 uint32_t dwOk = 0 ; 00112 00113 TRACE_DEBUG( "TWI_ConfigureMaster()\n\r" ) ; 00114 assert( pTwi ) ; 00115 00116 /* SVEN: TWI Slave Mode Enabled */ 00117 pTwi->TWIHS_CR = TWIHS_CR_SVEN ; 00118 /* Reset the TWI */ 00119 pTwi->TWIHS_CR = TWIHS_CR_SWRST ; 00120 pTwi->TWIHS_RHR ; 00121 00122 /* TWI Slave Mode Disabled, TWI Master Mode Disabled. */ 00123 pTwi->TWIHS_CR = TWIHS_CR_SVDIS ; 00124 pTwi->TWIHS_CR = TWIHS_CR_MSDIS ; 00125 00126 /* Set master mode */ 00127 pTwi->TWIHS_CR = TWIHS_CR_MSEN ; 00128 00129 /* Configure clock */ 00130 while ( !dwOk ) { 00131 dwClDiv = ((dwMCk / (2 * dwTwCk)) - 4) / (1<<dwCkDiv) ; 00132 00133 if ( dwClDiv <= 255 ) { 00134 dwOk = 1 ; 00135 } else { 00136 dwCkDiv++ ; 00137 } 00138 } 00139 assert( dwCkDiv < 8 ) ; 00140 TRACE_DEBUG( "Using CKDIV = %u and CLDIV/CHDIV = %u\n\r", dwCkDiv, dwClDiv ) ; 00141 00142 pTwi->TWIHS_CWGR = 0 ; 00143 pTwi->TWIHS_CWGR = (dwCkDiv << 16) | (dwClDiv << 8) | dwClDiv ; 00144 } 00145 00146 /** 00147 * \brief Configures a TWI peripheral to operate in slave mode. 00148 * \param pTwi Pointer to an Twihs instance. 00149 * \param slaveAddress Slave address. 00150 */ 00151 void TWI_ConfigureSlave(Twihs *pTwi, uint8_t slaveAddress) 00152 { 00153 uint32_t i; 00154 00155 /* TWI software reset */ 00156 pTwi->TWIHS_CR = TWIHS_CR_SWRST; 00157 pTwi->TWIHS_RHR; 00158 00159 /* Wait at least 10 ms */ 00160 for (i=0; i < 1000000; i++); 00161 00162 /* TWI Slave Mode Disabled, TWI Master Mode Disabled*/ 00163 pTwi->TWIHS_CR = TWIHS_CR_SVDIS | TWIHS_CR_MSDIS; 00164 00165 /* Configure slave address. */ 00166 pTwi->TWIHS_SMR = 0; 00167 pTwi->TWIHS_SMR = TWIHS_SMR_SADR(slaveAddress); 00168 00169 /* SVEN: TWI Slave Mode Enabled */ 00170 pTwi->TWIHS_CR = TWIHS_CR_SVEN; 00171 00172 /* Wait at least 10 ms */ 00173 for (i=0; i < 1000000; i++); 00174 assert( (pTwi->TWIHS_CR & TWIHS_CR_SVDIS)!= TWIHS_CR_SVDIS ) ; 00175 } 00176 00177 /** 00178 * \brief Sends a STOP condition on the TWI. 00179 * \param pTwi Pointer to an Twihs instance. 00180 */ 00181 void TWI_Stop( Twihs *pTwi ) 00182 { 00183 assert( pTwi != NULL ) ; 00184 00185 pTwi->TWIHS_CR = TWIHS_CR_STOP; 00186 } 00187 00188 /** 00189 * \brief Starts a read operation on the TWI bus with the specified slave, it 00190 * returns immediately. Data must then be read using TWI_ReadByte() whenever a 00191 * byte is available (poll using TWI_ByteReceived()). 00192 * \param pTwi Pointer to an Twihs instance. 00193 * \param address Slave address on the bus. 00194 * \param iaddress Optional internal address bytes. 00195 * \param isize Number of internal address bytes. 00196 */ 00197 void TWI_StartRead( 00198 Twihs *pTwi, 00199 uint8_t address, 00200 uint32_t iaddress, 00201 uint8_t isize) 00202 { 00203 assert( pTwi != NULL ) ; 00204 assert( (address & 0x80) == 0 ) ; 00205 assert( (iaddress & 0xFF000000) == 0 ) ; 00206 assert( isize < 4 ) ; 00207 00208 /* Set slave address and number of internal address bytes. */ 00209 pTwi->TWIHS_MMR = 0; 00210 pTwi->TWIHS_MMR = (isize << 8) | TWIHS_MMR_MREAD | (address << 16); 00211 00212 /* Set internal address bytes */ 00213 pTwi->TWIHS_IADR = 0; 00214 pTwi->TWIHS_IADR = iaddress; 00215 00216 /* Send START condition */ 00217 pTwi->TWIHS_CR = TWIHS_CR_START; 00218 } 00219 00220 /** 00221 * \brief Reads a byte from the TWI bus. The read operation must have been started 00222 * using TWI_StartRead() and a byte must be available (check with TWI_ByteReceived()). 00223 * \param pTwi Pointer to an Twihs instance. 00224 * \return byte read. 00225 */ 00226 uint8_t TWI_ReadByte(Twihs *pTwi) 00227 { 00228 assert( pTwi != NULL ) ; 00229 00230 return pTwi->TWIHS_RHR; 00231 } 00232 00233 /** 00234 * \brief Sends a byte of data to one of the TWI slaves on the bus. 00235 * \note This function must be called once before TWI_StartWrite() with 00236 * the first byte of data to send, then it shall be called repeatedly 00237 * after that to send the remaining bytes. 00238 * \param pTwi Pointer to an Twihs instance. 00239 * \param byte Byte to send. 00240 */ 00241 void TWI_WriteByte(Twihs *pTwi, uint8_t byte) 00242 { 00243 assert( pTwi != NULL ) ; 00244 00245 pTwi->TWIHS_THR = byte; 00246 } 00247 00248 /** 00249 * \brief Starts a write operation on the TWI to access the selected slave, then 00250 * returns immediately. A byte of data must be provided to start the write; 00251 * other bytes are written next. 00252 * after that to send the remaining bytes. 00253 * \param pTwi Pointer to an Twihs instance. 00254 * \param address Address of slave to acccess on the bus. 00255 * \param iaddress Optional slave internal address. 00256 * \param isize Number of internal address bytes. 00257 * \param byte First byte to send. 00258 */ 00259 void TWI_StartWrite( 00260 Twihs *pTwi, 00261 uint8_t address, 00262 uint32_t iaddress, 00263 uint8_t isize, 00264 uint8_t byte) 00265 { 00266 assert( pTwi != NULL ) ; 00267 assert( (address & 0x80) == 0 ) ; 00268 assert( (iaddress & 0xFF000000) == 0 ) ; 00269 assert( isize < 4 ) ; 00270 00271 /* Set slave address and number of internal address bytes. */ 00272 pTwi->TWIHS_MMR = 0; 00273 pTwi->TWIHS_MMR = (isize << 8) | (address << 16); 00274 00275 /* Set internal address bytes. */ 00276 pTwi->TWIHS_IADR = 0; 00277 pTwi->TWIHS_IADR = iaddress; 00278 00279 /* Write first byte to send.*/ 00280 TWI_WriteByte(pTwi, byte); 00281 } 00282 00283 /** 00284 * \brief Check if a byte have been received from TWI. 00285 * \param pTwi Pointer to an Twihs instance. 00286 * \return 1 if a byte has been received and can be read on the given TWI 00287 * peripheral; otherwise, returns 0. This function resets the status register. 00288 */ 00289 uint8_t TWI_ByteReceived(Twihs *pTwi) 00290 { 00291 return ((pTwi->TWIHS_SR & TWIHS_SR_RXRDY) == TWIHS_SR_RXRDY); 00292 } 00293 00294 /** 00295 * \brief Check if a byte have been sent to TWI. 00296 * \param pTwi Pointer to an Twihs instance. 00297 * \return 1 if a byte has been sent so another one can be stored for 00298 * transmission; otherwise returns 0. This function clears the status register. 00299 */ 00300 uint8_t TWI_ByteSent(Twihs *pTwi) 00301 { 00302 return ((pTwi->TWIHS_SR & TWIHS_SR_TXRDY) == TWIHS_SR_TXRDY); 00303 } 00304 00305 /** 00306 * \brief Check if current transmission is completed. 00307 * \param pTwi Pointer to an Twihs instance. 00308 * \return 1 if the current transmission is complete (the STOP has been sent); 00309 * otherwise returns 0. 00310 */ 00311 uint8_t TWI_TransferComplete(Twihs *pTwi) 00312 { 00313 return ((pTwi->TWIHS_SR & TWIHS_SR_TXCOMP) == TWIHS_SR_TXCOMP); 00314 } 00315 00316 /** 00317 * \brief Enables the selected interrupts sources on a TWI peripheral. 00318 * \param pTwi Pointer to an Twihs instance. 00319 * \param sources Bitwise OR of selected interrupt sources. 00320 */ 00321 void TWI_EnableIt(Twihs *pTwi, uint32_t sources) 00322 { 00323 assert( pTwi != NULL ) ; 00324 assert( (sources & TWIHS_IT) ) ; 00325 00326 pTwi->TWIHS_IER = sources; 00327 } 00328 00329 /** 00330 * \brief Disables the selected interrupts sources on a TWI peripheral. 00331 * \param pTwi Pointer to an Twihs instance. 00332 * \param sources Bitwise OR of selected interrupt sources. 00333 */ 00334 void TWI_DisableIt(Twihs *pTwi, uint32_t sources) 00335 { 00336 assert( pTwi != NULL ) ; 00337 assert(sources & TWIHS_IT ) ; 00338 00339 pTwi->TWIHS_IDR = sources; 00340 } 00341 00342 /** 00343 * \brief Get the current status register of the given TWI peripheral. 00344 * \note This resets the internal value of the status register, so further 00345 * read may yield different values. 00346 * \param pTwi Pointer to an Twihs instance. 00347 * \return TWI status register. 00348 */ 00349 uint32_t TWI_GetStatus(Twihs *pTwi) 00350 { 00351 assert( pTwi != NULL ) ; 00352 00353 return pTwi->TWIHS_SR; 00354 } 00355 00356 /** 00357 * \brief Returns the current status register of the given TWI peripheral, but 00358 * masking interrupt sources which are not currently enabled. 00359 * \note This resets the internal value of the status register, so further 00360 * read may yield different values. 00361 * \param pTwi Pointer to an Twihs instance. 00362 */ 00363 uint32_t TWI_GetMaskedStatus(Twihs *pTwi) 00364 { 00365 uint32_t status; 00366 00367 assert( pTwi != NULL ) ; 00368 00369 status = pTwi->TWIHS_SR; 00370 status &= pTwi->TWIHS_IMR; 00371 00372 return status; 00373 } 00374 00375 /** 00376 * \brief Sends a STOP condition. STOP Condition is sent just after completing 00377 * the current byte transmission in master read mode. 00378 * \param pTwi Pointer to an Twihs instance. 00379 */ 00380 void TWI_SendSTOPCondition(Twihs *pTwi) 00381 { 00382 assert( pTwi != NULL ) ; 00383 00384 pTwi->TWIHS_CR |= TWIHS_CR_STOP; 00385 } 00386