Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Tue Jul 12 2022 17:30:57 by
1.7.2