iforce2d Chris / Mbed 2 deprecated ubxDistanceMeter

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers u8g_com_i2c.c Source File

u8g_com_i2c.c

00001 /*
00002   
00003   u8g_com_i2c.c
00004 
00005   generic i2c interface
00006 
00007   Universal 8bit Graphics Library
00008   
00009   Copyright (c) 2011, olikraus@gmail.com
00010   All rights reserved.
00011 
00012   Redistribution and use in source and binary forms, with or without modification, 
00013   are permitted provided that the following conditions are met:
00014 
00015   * Redistributions of source code must retain the above copyright notice, this list 
00016     of conditions and the following disclaimer.
00017     
00018   * Redistributions in binary form must reproduce the above copyright notice, this 
00019     list of conditions and the following disclaimer in the documentation and/or other 
00020     materials provided with the distribution.
00021 
00022   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
00023   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
00024   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00025   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
00027   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00028   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
00029   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
00030   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
00031   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
00032   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00033   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00034   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
00035   
00036 */
00037 
00038 #include "u8g.h"
00039 
00040 static uint8_t u8g_i2c_err_code;
00041 
00042 /*
00043   position values
00044     1: start condition
00045     2: sla transfer
00046 */
00047 static uint8_t u8g_i2c_err_pos;
00048 
00049 
00050 void u8g_i2c_clear_error(void)
00051 {
00052   u8g_i2c_err_code = U8G_I2C_ERR_NONE;
00053   u8g_i2c_err_pos = 0;
00054 }
00055 
00056 uint8_t  u8g_i2c_get_error(void)
00057 {
00058   return u8g_i2c_err_code;
00059 }
00060 
00061 uint8_t u8g_i2c_get_err_pos(void)
00062 {
00063   return u8g_i2c_err_pos;
00064 }
00065 
00066 static void u8g_i2c_set_error(uint8_t code, uint8_t pos)
00067 {
00068   if ( u8g_i2c_err_code > 0 )
00069     return;
00070   u8g_i2c_err_code |= code;
00071   u8g_i2c_err_pos = pos;
00072 }
00073 
00074 
00075 
00076 #if defined(__AVR__)
00077 #define U8G_ATMEGA_HW_TWI
00078 
00079 /* remove the definition for attiny */
00080 #if __AVR_ARCH__ == 2
00081 #undef U8G_ATMEGA_HW_TWI
00082 #endif
00083 #if __AVR_ARCH__ == 25
00084 #undef U8G_ATMEGA_HW_TWI
00085 #endif
00086 #endif
00087 
00088 #if defined(U8G_ATMEGA_HW_TWI)
00089 
00090 #include <avr/io.h>
00091 #include <util/twi.h>
00092 
00093 
00094 
00095 void u8g_i2c_init(uint8_t options)
00096 {
00097   /*
00098   TWBR: bit rate register
00099   TWSR: status register (contains preselector bits)
00100 
00101   prescalar
00102     0       1
00103     1       4
00104     2       16
00105     3       64
00106 
00107   f = F_CPU/(16+2*TWBR*prescalar)
00108   
00109   F_CPU = 16MHz
00110     TWBR = 152;
00111     TWSR = 0;
00112     --> 50KHz
00113 
00114     TWBR = 72;
00115     TWSR = 0;
00116     --> 100KHz
00117 
00118     F_CPU/(2*100000)-8  --> calculate TWBR value for 100KHz
00119 */
00120   TWSR = 0;
00121   TWBR = F_CPU/(2*100000)-8;
00122   u8g_i2c_clear_error();
00123 }
00124 
00125 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
00126 {
00127   volatile uint16_t cnt = 2000; /* timout value should be > 280 for 50KHz Bus and 16 Mhz CPU, however the start condition might need longer */
00128   while( !(TWCR & mask) )
00129   {
00130       if ( cnt == 0 )
00131       {
00132     u8g_i2c_set_error(U8G_I2C_ERR_TIMEOUT, pos);
00133     return 0; /* error */
00134       }
00135       cnt--;
00136     }
00137   return 1; /* all ok */
00138 }
00139 
00140 /* sla includes all 8 bits (with r/w bit), assums master transmit */
00141 uint8_t u8g_i2c_start(uint8_t sla)
00142 {
00143   register uint8_t status;
00144   
00145   /* send start */
00146   TWCR = _BV(TWINT) |  _BV(TWSTA)  |  _BV(TWEN);
00147    
00148   /* wait */
00149   if ( u8g_i2c_wait(_BV(TWINT), 1) == 0 )
00150     return 0;
00151   
00152   status = TW_STATUS;
00153  
00154   /* check status after start */  
00155   if ( status != TW_START && status != TW_REP_START )
00156   {
00157     u8g_i2c_set_error(U8G_I2C_ERR_BUS, 1);
00158     return 0;
00159   }
00160 
00161   /* set slave address */  
00162   TWDR = sla;
00163   
00164   /* enable sla transfer */
00165   TWCR = _BV(TWINT)  |  _BV(TWEN);
00166 
00167   /* wait */
00168   if ( u8g_i2c_wait(_BV(TWINT), 2) == 0 )
00169     return 0;
00170   status = TW_STATUS;
00171 
00172   /* check status after sla */  
00173   if ( status != TW_MT_SLA_ACK )
00174   {
00175     u8g_i2c_set_error(U8G_I2C_ERR_BUS, 2);
00176     return 0;
00177   }
00178 
00179    return 1;
00180 }
00181 
00182 uint8_t u8g_i2c_send_byte(uint8_t data)
00183 {
00184   register uint8_t status;
00185   TWDR = data;
00186   TWCR = _BV(TWINT)  |  _BV(TWEN);
00187   if ( u8g_i2c_wait(_BV(TWINT), 3) == 0 )
00188     return 0;
00189   status = TW_STATUS;
00190   
00191   if ( status != TW_MT_DATA_ACK )
00192   {
00193     u8g_i2c_set_error(U8G_I2C_ERR_BUS, 3);
00194     return 0;
00195   }
00196   
00197   return 1;  
00198 }
00199 
00200 void u8g_i2c_stop(void)
00201 {
00202   /* write stop */
00203   TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);
00204 
00205   /* no error is checked for the stop condition */  
00206   u8g_i2c_wait(_BV(TWSTO), 4);
00207   
00208 }
00209 
00210 /*
00211 void twi_send(uint8_t adr, uint8_t data1, uint8_t data2)
00212 {
00213   u8g_i2c_start(adr<<1);
00214   u8g_i2c_send_byte(data1);
00215   u8g_i2c_send_byte(data2);
00216   u8g_i2c_stop();
00217 }
00218 */
00219 
00220 #else
00221 
00222 /* empty interface */
00223 
00224 void u8g_i2c_init(uint8_t options)
00225 {
00226   u8g_i2c_clear_error();
00227 }
00228 
00229 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
00230 {
00231   return 1;
00232 }
00233 
00234 uint8_t u8g_i2c_start(uint8_t sla)
00235 {
00236   return 1;
00237 }
00238 uint8_t u8g_i2c_send_byte(uint8_t data)
00239 {
00240   return 1;
00241 }
00242 
00243 void u8g_i2c_stop(void)
00244 {
00245 }
00246 
00247 
00248 #endif
00249 
00250