Displays distance to start location on OLED screen.

Dependencies:   mbed

Committer:
iforce2d
Date:
Wed Mar 07 12:49:14 2018 +0000
Revision:
0:972874f31c98
First commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iforce2d 0:972874f31c98 1 /*
iforce2d 0:972874f31c98 2
iforce2d 0:972874f31c98 3 u8g_com_i2c.c
iforce2d 0:972874f31c98 4
iforce2d 0:972874f31c98 5 generic i2c interface
iforce2d 0:972874f31c98 6
iforce2d 0:972874f31c98 7 Universal 8bit Graphics Library
iforce2d 0:972874f31c98 8
iforce2d 0:972874f31c98 9 Copyright (c) 2011, olikraus@gmail.com
iforce2d 0:972874f31c98 10 All rights reserved.
iforce2d 0:972874f31c98 11
iforce2d 0:972874f31c98 12 Redistribution and use in source and binary forms, with or without modification,
iforce2d 0:972874f31c98 13 are permitted provided that the following conditions are met:
iforce2d 0:972874f31c98 14
iforce2d 0:972874f31c98 15 * Redistributions of source code must retain the above copyright notice, this list
iforce2d 0:972874f31c98 16 of conditions and the following disclaimer.
iforce2d 0:972874f31c98 17
iforce2d 0:972874f31c98 18 * Redistributions in binary form must reproduce the above copyright notice, this
iforce2d 0:972874f31c98 19 list of conditions and the following disclaimer in the documentation and/or other
iforce2d 0:972874f31c98 20 materials provided with the distribution.
iforce2d 0:972874f31c98 21
iforce2d 0:972874f31c98 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
iforce2d 0:972874f31c98 23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
iforce2d 0:972874f31c98 24 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
iforce2d 0:972874f31c98 25 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
iforce2d 0:972874f31c98 26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
iforce2d 0:972874f31c98 27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
iforce2d 0:972874f31c98 28 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
iforce2d 0:972874f31c98 29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
iforce2d 0:972874f31c98 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
iforce2d 0:972874f31c98 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
iforce2d 0:972874f31c98 32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
iforce2d 0:972874f31c98 33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
iforce2d 0:972874f31c98 34 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
iforce2d 0:972874f31c98 35
iforce2d 0:972874f31c98 36 */
iforce2d 0:972874f31c98 37
iforce2d 0:972874f31c98 38 #include "u8g.h"
iforce2d 0:972874f31c98 39
iforce2d 0:972874f31c98 40 static uint8_t u8g_i2c_err_code;
iforce2d 0:972874f31c98 41
iforce2d 0:972874f31c98 42 /*
iforce2d 0:972874f31c98 43 position values
iforce2d 0:972874f31c98 44 1: start condition
iforce2d 0:972874f31c98 45 2: sla transfer
iforce2d 0:972874f31c98 46 */
iforce2d 0:972874f31c98 47 static uint8_t u8g_i2c_err_pos;
iforce2d 0:972874f31c98 48
iforce2d 0:972874f31c98 49
iforce2d 0:972874f31c98 50 void u8g_i2c_clear_error(void)
iforce2d 0:972874f31c98 51 {
iforce2d 0:972874f31c98 52 u8g_i2c_err_code = U8G_I2C_ERR_NONE;
iforce2d 0:972874f31c98 53 u8g_i2c_err_pos = 0;
iforce2d 0:972874f31c98 54 }
iforce2d 0:972874f31c98 55
iforce2d 0:972874f31c98 56 uint8_t u8g_i2c_get_error(void)
iforce2d 0:972874f31c98 57 {
iforce2d 0:972874f31c98 58 return u8g_i2c_err_code;
iforce2d 0:972874f31c98 59 }
iforce2d 0:972874f31c98 60
iforce2d 0:972874f31c98 61 uint8_t u8g_i2c_get_err_pos(void)
iforce2d 0:972874f31c98 62 {
iforce2d 0:972874f31c98 63 return u8g_i2c_err_pos;
iforce2d 0:972874f31c98 64 }
iforce2d 0:972874f31c98 65
iforce2d 0:972874f31c98 66 static void u8g_i2c_set_error(uint8_t code, uint8_t pos)
iforce2d 0:972874f31c98 67 {
iforce2d 0:972874f31c98 68 if ( u8g_i2c_err_code > 0 )
iforce2d 0:972874f31c98 69 return;
iforce2d 0:972874f31c98 70 u8g_i2c_err_code |= code;
iforce2d 0:972874f31c98 71 u8g_i2c_err_pos = pos;
iforce2d 0:972874f31c98 72 }
iforce2d 0:972874f31c98 73
iforce2d 0:972874f31c98 74
iforce2d 0:972874f31c98 75
iforce2d 0:972874f31c98 76 #if defined(__AVR__)
iforce2d 0:972874f31c98 77 #define U8G_ATMEGA_HW_TWI
iforce2d 0:972874f31c98 78
iforce2d 0:972874f31c98 79 /* remove the definition for attiny */
iforce2d 0:972874f31c98 80 #if __AVR_ARCH__ == 2
iforce2d 0:972874f31c98 81 #undef U8G_ATMEGA_HW_TWI
iforce2d 0:972874f31c98 82 #endif
iforce2d 0:972874f31c98 83 #if __AVR_ARCH__ == 25
iforce2d 0:972874f31c98 84 #undef U8G_ATMEGA_HW_TWI
iforce2d 0:972874f31c98 85 #endif
iforce2d 0:972874f31c98 86 #endif
iforce2d 0:972874f31c98 87
iforce2d 0:972874f31c98 88 #if defined(U8G_ATMEGA_HW_TWI)
iforce2d 0:972874f31c98 89
iforce2d 0:972874f31c98 90 #include <avr/io.h>
iforce2d 0:972874f31c98 91 #include <util/twi.h>
iforce2d 0:972874f31c98 92
iforce2d 0:972874f31c98 93
iforce2d 0:972874f31c98 94
iforce2d 0:972874f31c98 95 void u8g_i2c_init(uint8_t options)
iforce2d 0:972874f31c98 96 {
iforce2d 0:972874f31c98 97 /*
iforce2d 0:972874f31c98 98 TWBR: bit rate register
iforce2d 0:972874f31c98 99 TWSR: status register (contains preselector bits)
iforce2d 0:972874f31c98 100
iforce2d 0:972874f31c98 101 prescalar
iforce2d 0:972874f31c98 102 0 1
iforce2d 0:972874f31c98 103 1 4
iforce2d 0:972874f31c98 104 2 16
iforce2d 0:972874f31c98 105 3 64
iforce2d 0:972874f31c98 106
iforce2d 0:972874f31c98 107 f = F_CPU/(16+2*TWBR*prescalar)
iforce2d 0:972874f31c98 108
iforce2d 0:972874f31c98 109 F_CPU = 16MHz
iforce2d 0:972874f31c98 110 TWBR = 152;
iforce2d 0:972874f31c98 111 TWSR = 0;
iforce2d 0:972874f31c98 112 --> 50KHz
iforce2d 0:972874f31c98 113
iforce2d 0:972874f31c98 114 TWBR = 72;
iforce2d 0:972874f31c98 115 TWSR = 0;
iforce2d 0:972874f31c98 116 --> 100KHz
iforce2d 0:972874f31c98 117
iforce2d 0:972874f31c98 118 F_CPU/(2*100000)-8 --> calculate TWBR value for 100KHz
iforce2d 0:972874f31c98 119 */
iforce2d 0:972874f31c98 120 TWSR = 0;
iforce2d 0:972874f31c98 121 TWBR = F_CPU/(2*100000)-8;
iforce2d 0:972874f31c98 122 u8g_i2c_clear_error();
iforce2d 0:972874f31c98 123 }
iforce2d 0:972874f31c98 124
iforce2d 0:972874f31c98 125 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
iforce2d 0:972874f31c98 126 {
iforce2d 0:972874f31c98 127 volatile uint16_t cnt = 2000; /* timout value should be > 280 for 50KHz Bus and 16 Mhz CPU, however the start condition might need longer */
iforce2d 0:972874f31c98 128 while( !(TWCR & mask) )
iforce2d 0:972874f31c98 129 {
iforce2d 0:972874f31c98 130 if ( cnt == 0 )
iforce2d 0:972874f31c98 131 {
iforce2d 0:972874f31c98 132 u8g_i2c_set_error(U8G_I2C_ERR_TIMEOUT, pos);
iforce2d 0:972874f31c98 133 return 0; /* error */
iforce2d 0:972874f31c98 134 }
iforce2d 0:972874f31c98 135 cnt--;
iforce2d 0:972874f31c98 136 }
iforce2d 0:972874f31c98 137 return 1; /* all ok */
iforce2d 0:972874f31c98 138 }
iforce2d 0:972874f31c98 139
iforce2d 0:972874f31c98 140 /* sla includes all 8 bits (with r/w bit), assums master transmit */
iforce2d 0:972874f31c98 141 uint8_t u8g_i2c_start(uint8_t sla)
iforce2d 0:972874f31c98 142 {
iforce2d 0:972874f31c98 143 register uint8_t status;
iforce2d 0:972874f31c98 144
iforce2d 0:972874f31c98 145 /* send start */
iforce2d 0:972874f31c98 146 TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
iforce2d 0:972874f31c98 147
iforce2d 0:972874f31c98 148 /* wait */
iforce2d 0:972874f31c98 149 if ( u8g_i2c_wait(_BV(TWINT), 1) == 0 )
iforce2d 0:972874f31c98 150 return 0;
iforce2d 0:972874f31c98 151
iforce2d 0:972874f31c98 152 status = TW_STATUS;
iforce2d 0:972874f31c98 153
iforce2d 0:972874f31c98 154 /* check status after start */
iforce2d 0:972874f31c98 155 if ( status != TW_START && status != TW_REP_START )
iforce2d 0:972874f31c98 156 {
iforce2d 0:972874f31c98 157 u8g_i2c_set_error(U8G_I2C_ERR_BUS, 1);
iforce2d 0:972874f31c98 158 return 0;
iforce2d 0:972874f31c98 159 }
iforce2d 0:972874f31c98 160
iforce2d 0:972874f31c98 161 /* set slave address */
iforce2d 0:972874f31c98 162 TWDR = sla;
iforce2d 0:972874f31c98 163
iforce2d 0:972874f31c98 164 /* enable sla transfer */
iforce2d 0:972874f31c98 165 TWCR = _BV(TWINT) | _BV(TWEN);
iforce2d 0:972874f31c98 166
iforce2d 0:972874f31c98 167 /* wait */
iforce2d 0:972874f31c98 168 if ( u8g_i2c_wait(_BV(TWINT), 2) == 0 )
iforce2d 0:972874f31c98 169 return 0;
iforce2d 0:972874f31c98 170 status = TW_STATUS;
iforce2d 0:972874f31c98 171
iforce2d 0:972874f31c98 172 /* check status after sla */
iforce2d 0:972874f31c98 173 if ( status != TW_MT_SLA_ACK )
iforce2d 0:972874f31c98 174 {
iforce2d 0:972874f31c98 175 u8g_i2c_set_error(U8G_I2C_ERR_BUS, 2);
iforce2d 0:972874f31c98 176 return 0;
iforce2d 0:972874f31c98 177 }
iforce2d 0:972874f31c98 178
iforce2d 0:972874f31c98 179 return 1;
iforce2d 0:972874f31c98 180 }
iforce2d 0:972874f31c98 181
iforce2d 0:972874f31c98 182 uint8_t u8g_i2c_send_byte(uint8_t data)
iforce2d 0:972874f31c98 183 {
iforce2d 0:972874f31c98 184 register uint8_t status;
iforce2d 0:972874f31c98 185 TWDR = data;
iforce2d 0:972874f31c98 186 TWCR = _BV(TWINT) | _BV(TWEN);
iforce2d 0:972874f31c98 187 if ( u8g_i2c_wait(_BV(TWINT), 3) == 0 )
iforce2d 0:972874f31c98 188 return 0;
iforce2d 0:972874f31c98 189 status = TW_STATUS;
iforce2d 0:972874f31c98 190
iforce2d 0:972874f31c98 191 if ( status != TW_MT_DATA_ACK )
iforce2d 0:972874f31c98 192 {
iforce2d 0:972874f31c98 193 u8g_i2c_set_error(U8G_I2C_ERR_BUS, 3);
iforce2d 0:972874f31c98 194 return 0;
iforce2d 0:972874f31c98 195 }
iforce2d 0:972874f31c98 196
iforce2d 0:972874f31c98 197 return 1;
iforce2d 0:972874f31c98 198 }
iforce2d 0:972874f31c98 199
iforce2d 0:972874f31c98 200 void u8g_i2c_stop(void)
iforce2d 0:972874f31c98 201 {
iforce2d 0:972874f31c98 202 /* write stop */
iforce2d 0:972874f31c98 203 TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);
iforce2d 0:972874f31c98 204
iforce2d 0:972874f31c98 205 /* no error is checked for the stop condition */
iforce2d 0:972874f31c98 206 u8g_i2c_wait(_BV(TWSTO), 4);
iforce2d 0:972874f31c98 207
iforce2d 0:972874f31c98 208 }
iforce2d 0:972874f31c98 209
iforce2d 0:972874f31c98 210 /*
iforce2d 0:972874f31c98 211 void twi_send(uint8_t adr, uint8_t data1, uint8_t data2)
iforce2d 0:972874f31c98 212 {
iforce2d 0:972874f31c98 213 u8g_i2c_start(adr<<1);
iforce2d 0:972874f31c98 214 u8g_i2c_send_byte(data1);
iforce2d 0:972874f31c98 215 u8g_i2c_send_byte(data2);
iforce2d 0:972874f31c98 216 u8g_i2c_stop();
iforce2d 0:972874f31c98 217 }
iforce2d 0:972874f31c98 218 */
iforce2d 0:972874f31c98 219
iforce2d 0:972874f31c98 220 #else
iforce2d 0:972874f31c98 221
iforce2d 0:972874f31c98 222 /* empty interface */
iforce2d 0:972874f31c98 223
iforce2d 0:972874f31c98 224 void u8g_i2c_init(uint8_t options)
iforce2d 0:972874f31c98 225 {
iforce2d 0:972874f31c98 226 u8g_i2c_clear_error();
iforce2d 0:972874f31c98 227 }
iforce2d 0:972874f31c98 228
iforce2d 0:972874f31c98 229 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
iforce2d 0:972874f31c98 230 {
iforce2d 0:972874f31c98 231 return 1;
iforce2d 0:972874f31c98 232 }
iforce2d 0:972874f31c98 233
iforce2d 0:972874f31c98 234 uint8_t u8g_i2c_start(uint8_t sla)
iforce2d 0:972874f31c98 235 {
iforce2d 0:972874f31c98 236 return 1;
iforce2d 0:972874f31c98 237 }
iforce2d 0:972874f31c98 238 uint8_t u8g_i2c_send_byte(uint8_t data)
iforce2d 0:972874f31c98 239 {
iforce2d 0:972874f31c98 240 return 1;
iforce2d 0:972874f31c98 241 }
iforce2d 0:972874f31c98 242
iforce2d 0:972874f31c98 243 void u8g_i2c_stop(void)
iforce2d 0:972874f31c98 244 {
iforce2d 0:972874f31c98 245 }
iforce2d 0:972874f31c98 246
iforce2d 0:972874f31c98 247
iforce2d 0:972874f31c98 248 #endif
iforce2d 0:972874f31c98 249
iforce2d 0:972874f31c98 250