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