hadif azli / Mbed 2 deprecated TEST123

Dependencies:   mbed Blynk

Committer:
lixianyu
Date:
Mon Jun 13 02:21:11 2016 +0000
Revision:
1:0e75de2a5d21
Parent:
0:d8f4c441e032
u8glib???????????????????????????Adafruit_GFX????OLED????????bitmap??????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lixianyu 0:d8f4c441e032 1 /*
lixianyu 0:d8f4c441e032 2
lixianyu 0:d8f4c441e032 3 u8g_com_i2c.c
lixianyu 0:d8f4c441e032 4
lixianyu 0:d8f4c441e032 5 generic i2c interface
lixianyu 0:d8f4c441e032 6
lixianyu 0:d8f4c441e032 7 Universal 8bit Graphics Library
lixianyu 0:d8f4c441e032 8
lixianyu 0:d8f4c441e032 9 Copyright (c) 2011, olikraus@gmail.com
lixianyu 0:d8f4c441e032 10 All rights reserved.
lixianyu 0:d8f4c441e032 11
lixianyu 0:d8f4c441e032 12 Redistribution and use in source and binary forms, with or without modification,
lixianyu 0:d8f4c441e032 13 are permitted provided that the following conditions are met:
lixianyu 0:d8f4c441e032 14
lixianyu 0:d8f4c441e032 15 * Redistributions of source code must retain the above copyright notice, this list
lixianyu 0:d8f4c441e032 16 of conditions and the following disclaimer.
lixianyu 0:d8f4c441e032 17
lixianyu 0:d8f4c441e032 18 * Redistributions in binary form must reproduce the above copyright notice, this
lixianyu 0:d8f4c441e032 19 list of conditions and the following disclaimer in the documentation and/or other
lixianyu 0:d8f4c441e032 20 materials provided with the distribution.
lixianyu 0:d8f4c441e032 21
lixianyu 0:d8f4c441e032 22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
lixianyu 0:d8f4c441e032 23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
lixianyu 0:d8f4c441e032 24 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
lixianyu 0:d8f4c441e032 25 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
lixianyu 0:d8f4c441e032 26 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
lixianyu 0:d8f4c441e032 27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
lixianyu 0:d8f4c441e032 28 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
lixianyu 0:d8f4c441e032 29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
lixianyu 0:d8f4c441e032 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
lixianyu 0:d8f4c441e032 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
lixianyu 0:d8f4c441e032 32 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
lixianyu 0:d8f4c441e032 33 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
lixianyu 0:d8f4c441e032 34 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
lixianyu 0:d8f4c441e032 35
lixianyu 0:d8f4c441e032 36 */
lixianyu 0:d8f4c441e032 37
lixianyu 0:d8f4c441e032 38
lixianyu 0:d8f4c441e032 39 #include "u8g.h"
lixianyu 0:d8f4c441e032 40
lixianyu 0:d8f4c441e032 41 //#define U8G_I2C_WITH_NO_ACK
lixianyu 0:d8f4c441e032 42
lixianyu 0:d8f4c441e032 43 static uint8_t u8g_i2c_err_code;
lixianyu 0:d8f4c441e032 44 static uint8_t u8g_i2c_opt; /* U8G_I2C_OPT_NO_ACK, SAM: U8G_I2C_OPT_DEV_1 */
lixianyu 0:d8f4c441e032 45 /*
lixianyu 0:d8f4c441e032 46 position values
lixianyu 0:d8f4c441e032 47 1: start condition
lixianyu 0:d8f4c441e032 48 2: sla transfer
lixianyu 0:d8f4c441e032 49 */
lixianyu 0:d8f4c441e032 50 static uint8_t u8g_i2c_err_pos;
lixianyu 0:d8f4c441e032 51
lixianyu 0:d8f4c441e032 52
lixianyu 0:d8f4c441e032 53 void u8g_i2c_clear_error(void)
lixianyu 0:d8f4c441e032 54 {
lixianyu 0:d8f4c441e032 55 u8g_i2c_err_code = U8G_I2C_ERR_NONE;
lixianyu 0:d8f4c441e032 56 u8g_i2c_err_pos = 0;
lixianyu 0:d8f4c441e032 57 }
lixianyu 0:d8f4c441e032 58
lixianyu 0:d8f4c441e032 59 uint8_t u8g_i2c_get_error(void)
lixianyu 0:d8f4c441e032 60 {
lixianyu 0:d8f4c441e032 61 return u8g_i2c_err_code;
lixianyu 0:d8f4c441e032 62 }
lixianyu 0:d8f4c441e032 63
lixianyu 0:d8f4c441e032 64 uint8_t u8g_i2c_get_err_pos(void)
lixianyu 0:d8f4c441e032 65 {
lixianyu 0:d8f4c441e032 66 return u8g_i2c_err_pos;
lixianyu 0:d8f4c441e032 67 }
lixianyu 0:d8f4c441e032 68
lixianyu 0:d8f4c441e032 69
lixianyu 0:d8f4c441e032 70
lixianyu 0:d8f4c441e032 71 #if defined(__AVR__)
lixianyu 0:d8f4c441e032 72
lixianyu 0:d8f4c441e032 73 static void u8g_i2c_set_error(uint8_t code, uint8_t pos)
lixianyu 0:d8f4c441e032 74 {
lixianyu 0:d8f4c441e032 75 if ( u8g_i2c_err_code > 0 )
lixianyu 0:d8f4c441e032 76 return;
lixianyu 0:d8f4c441e032 77 u8g_i2c_err_code |= code;
lixianyu 0:d8f4c441e032 78 u8g_i2c_err_pos = pos;
lixianyu 0:d8f4c441e032 79 }
lixianyu 0:d8f4c441e032 80
lixianyu 0:d8f4c441e032 81 #define U8G_ATMEGA_HW_TWI
lixianyu 0:d8f4c441e032 82
lixianyu 0:d8f4c441e032 83 /* remove the definition for attiny */
lixianyu 0:d8f4c441e032 84 #if __AVR_ARCH__ == 2
lixianyu 0:d8f4c441e032 85 #undef U8G_ATMEGA_HW_TWI
lixianyu 0:d8f4c441e032 86 #endif
lixianyu 0:d8f4c441e032 87 #if __AVR_ARCH__ == 25
lixianyu 0:d8f4c441e032 88 #undef U8G_ATMEGA_HW_TWI
lixianyu 0:d8f4c441e032 89 #endif
lixianyu 0:d8f4c441e032 90 #endif
lixianyu 0:d8f4c441e032 91
lixianyu 0:d8f4c441e032 92 #if defined(U8G_ATMEGA_HW_TWI)
lixianyu 0:d8f4c441e032 93
lixianyu 0:d8f4c441e032 94 #include <avr/io.h>
lixianyu 0:d8f4c441e032 95 #include <util/twi.h>
lixianyu 0:d8f4c441e032 96
lixianyu 0:d8f4c441e032 97
lixianyu 0:d8f4c441e032 98
lixianyu 0:d8f4c441e032 99 void u8g_i2c_init(uint8_t options)
lixianyu 0:d8f4c441e032 100 {
lixianyu 0:d8f4c441e032 101 /*
lixianyu 0:d8f4c441e032 102 TWBR: bit rate register
lixianyu 0:d8f4c441e032 103 TWSR: status register (contains preselector bits)
lixianyu 0:d8f4c441e032 104
lixianyu 0:d8f4c441e032 105 prescalar
lixianyu 0:d8f4c441e032 106 0 1
lixianyu 0:d8f4c441e032 107 1 4
lixianyu 0:d8f4c441e032 108 2 16
lixianyu 0:d8f4c441e032 109 3 64
lixianyu 0:d8f4c441e032 110
lixianyu 0:d8f4c441e032 111 f = F_CPU/(16+2*TWBR*prescalar)
lixianyu 0:d8f4c441e032 112
lixianyu 0:d8f4c441e032 113 F_CPU = 16MHz
lixianyu 0:d8f4c441e032 114 TWBR = 152;
lixianyu 0:d8f4c441e032 115 TWSR = 0;
lixianyu 0:d8f4c441e032 116 --> 50KHz
lixianyu 0:d8f4c441e032 117
lixianyu 0:d8f4c441e032 118 TWBR = 72;
lixianyu 0:d8f4c441e032 119 TWSR = 0;
lixianyu 0:d8f4c441e032 120 --> 100KHz
lixianyu 0:d8f4c441e032 121
lixianyu 0:d8f4c441e032 122 TWBR = 12;
lixianyu 0:d8f4c441e032 123 TWSR = 0;
lixianyu 0:d8f4c441e032 124 --> 400KHz
lixianyu 0:d8f4c441e032 125
lixianyu 0:d8f4c441e032 126 F_CPU/(2*100000)-8 --> calculate TWBR value for 100KHz
lixianyu 0:d8f4c441e032 127 */
lixianyu 0:d8f4c441e032 128 u8g_i2c_opt = options;
lixianyu 0:d8f4c441e032 129 TWSR = 0;
lixianyu 0:d8f4c441e032 130 if ( options & U8G_I2C_OPT_FAST )
lixianyu 0:d8f4c441e032 131 {
lixianyu 0:d8f4c441e032 132 TWBR = F_CPU/(2*400000)-8;
lixianyu 0:d8f4c441e032 133 }
lixianyu 0:d8f4c441e032 134 else
lixianyu 0:d8f4c441e032 135 {
lixianyu 0:d8f4c441e032 136 TWBR = F_CPU/(2*100000)-8;
lixianyu 0:d8f4c441e032 137 }
lixianyu 0:d8f4c441e032 138 u8g_i2c_clear_error();
lixianyu 0:d8f4c441e032 139 }
lixianyu 0:d8f4c441e032 140
lixianyu 0:d8f4c441e032 141 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
lixianyu 0:d8f4c441e032 142 {
lixianyu 0:d8f4c441e032 143 volatile uint16_t cnt = 2000; /* timout value should be > 280 for 50KHz Bus and 16 Mhz CPU, however the start condition might need longer */
lixianyu 0:d8f4c441e032 144 while( !(TWCR & mask) )
lixianyu 0:d8f4c441e032 145 {
lixianyu 0:d8f4c441e032 146 if ( cnt == 0 )
lixianyu 0:d8f4c441e032 147 {
lixianyu 0:d8f4c441e032 148 if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK )
lixianyu 0:d8f4c441e032 149 {
lixianyu 0:d8f4c441e032 150 return 1; /* all ok */
lixianyu 0:d8f4c441e032 151 }
lixianyu 0:d8f4c441e032 152 else
lixianyu 0:d8f4c441e032 153 {
lixianyu 0:d8f4c441e032 154 u8g_i2c_set_error(U8G_I2C_ERR_TIMEOUT, pos);
lixianyu 0:d8f4c441e032 155 return 0; /* error */
lixianyu 0:d8f4c441e032 156 }
lixianyu 0:d8f4c441e032 157 }
lixianyu 0:d8f4c441e032 158 cnt--;
lixianyu 0:d8f4c441e032 159 }
lixianyu 0:d8f4c441e032 160 return 1; /* all ok */
lixianyu 0:d8f4c441e032 161 }
lixianyu 0:d8f4c441e032 162
lixianyu 0:d8f4c441e032 163 /* sla includes all 8 bits (with r/w bit), assums master transmit */
lixianyu 0:d8f4c441e032 164 uint8_t u8g_i2c_start(uint8_t sla)
lixianyu 0:d8f4c441e032 165 {
lixianyu 0:d8f4c441e032 166 register uint8_t status;
lixianyu 0:d8f4c441e032 167
lixianyu 0:d8f4c441e032 168 /* send start */
lixianyu 0:d8f4c441e032 169 TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
lixianyu 0:d8f4c441e032 170
lixianyu 0:d8f4c441e032 171 /* wait */
lixianyu 0:d8f4c441e032 172 if ( u8g_i2c_wait(_BV(TWINT), 1) == 0 )
lixianyu 0:d8f4c441e032 173 return 0;
lixianyu 0:d8f4c441e032 174
lixianyu 0:d8f4c441e032 175 status = TW_STATUS;
lixianyu 0:d8f4c441e032 176
lixianyu 0:d8f4c441e032 177 /* check status after start */
lixianyu 0:d8f4c441e032 178 if ( status != TW_START && status != TW_REP_START )
lixianyu 0:d8f4c441e032 179 {
lixianyu 0:d8f4c441e032 180 u8g_i2c_set_error(U8G_I2C_ERR_BUS, 1);
lixianyu 0:d8f4c441e032 181 return 0;
lixianyu 0:d8f4c441e032 182 }
lixianyu 0:d8f4c441e032 183
lixianyu 0:d8f4c441e032 184 /* set slave address */
lixianyu 0:d8f4c441e032 185 TWDR = sla;
lixianyu 0:d8f4c441e032 186
lixianyu 0:d8f4c441e032 187 /* enable sla transfer */
lixianyu 0:d8f4c441e032 188 TWCR = _BV(TWINT) | _BV(TWEN);
lixianyu 0:d8f4c441e032 189
lixianyu 0:d8f4c441e032 190 /* wait */
lixianyu 0:d8f4c441e032 191 if ( u8g_i2c_wait(_BV(TWINT), 2) == 0 )
lixianyu 0:d8f4c441e032 192 return 0;
lixianyu 0:d8f4c441e032 193
lixianyu 0:d8f4c441e032 194 if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK )
lixianyu 0:d8f4c441e032 195 {
lixianyu 0:d8f4c441e032 196 /* do not check for ACK */
lixianyu 0:d8f4c441e032 197 }
lixianyu 0:d8f4c441e032 198 else
lixianyu 0:d8f4c441e032 199 {
lixianyu 0:d8f4c441e032 200 status = TW_STATUS;
lixianyu 0:d8f4c441e032 201 /* check status after sla */
lixianyu 0:d8f4c441e032 202 if ( status != TW_MT_SLA_ACK )
lixianyu 0:d8f4c441e032 203 {
lixianyu 0:d8f4c441e032 204 u8g_i2c_set_error(U8G_I2C_ERR_BUS, 2);
lixianyu 0:d8f4c441e032 205 return 0;
lixianyu 0:d8f4c441e032 206 }
lixianyu 0:d8f4c441e032 207 }
lixianyu 0:d8f4c441e032 208
lixianyu 0:d8f4c441e032 209 return 1;
lixianyu 0:d8f4c441e032 210 }
lixianyu 0:d8f4c441e032 211
lixianyu 0:d8f4c441e032 212 uint8_t u8g_i2c_send_byte(uint8_t data)
lixianyu 0:d8f4c441e032 213 {
lixianyu 0:d8f4c441e032 214 register uint8_t status;
lixianyu 0:d8f4c441e032 215 TWDR = data;
lixianyu 0:d8f4c441e032 216 TWCR = _BV(TWINT) | _BV(TWEN);
lixianyu 0:d8f4c441e032 217 if ( u8g_i2c_wait(_BV(TWINT), 3) == 0 )
lixianyu 0:d8f4c441e032 218 return 0;
lixianyu 0:d8f4c441e032 219
lixianyu 0:d8f4c441e032 220 if ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK )
lixianyu 0:d8f4c441e032 221 {
lixianyu 0:d8f4c441e032 222 /* do not check for ACK */
lixianyu 0:d8f4c441e032 223 }
lixianyu 0:d8f4c441e032 224 else
lixianyu 0:d8f4c441e032 225 {
lixianyu 0:d8f4c441e032 226 status = TW_STATUS;
lixianyu 0:d8f4c441e032 227 if ( status != TW_MT_DATA_ACK )
lixianyu 0:d8f4c441e032 228 {
lixianyu 0:d8f4c441e032 229 u8g_i2c_set_error(U8G_I2C_ERR_BUS, 3);
lixianyu 0:d8f4c441e032 230 return 0;
lixianyu 0:d8f4c441e032 231 }
lixianyu 0:d8f4c441e032 232 }
lixianyu 0:d8f4c441e032 233
lixianyu 0:d8f4c441e032 234 return 1;
lixianyu 0:d8f4c441e032 235 }
lixianyu 0:d8f4c441e032 236
lixianyu 0:d8f4c441e032 237 void u8g_i2c_stop(void)
lixianyu 0:d8f4c441e032 238 {
lixianyu 0:d8f4c441e032 239 /* write stop */
lixianyu 0:d8f4c441e032 240 TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO);
lixianyu 0:d8f4c441e032 241
lixianyu 0:d8f4c441e032 242 /* no error is checked for the stop condition */
lixianyu 0:d8f4c441e032 243 u8g_i2c_wait(_BV(TWSTO), 4);
lixianyu 0:d8f4c441e032 244
lixianyu 0:d8f4c441e032 245 }
lixianyu 0:d8f4c441e032 246
lixianyu 0:d8f4c441e032 247 /*
lixianyu 0:d8f4c441e032 248 void twi_send(uint8_t adr, uint8_t data1, uint8_t data2)
lixianyu 0:d8f4c441e032 249 {
lixianyu 0:d8f4c441e032 250 u8g_i2c_start(adr<<1);
lixianyu 0:d8f4c441e032 251 u8g_i2c_send_byte(data1);
lixianyu 0:d8f4c441e032 252 u8g_i2c_send_byte(data2);
lixianyu 0:d8f4c441e032 253 u8g_i2c_stop();
lixianyu 0:d8f4c441e032 254 }
lixianyu 0:d8f4c441e032 255 */
lixianyu 0:d8f4c441e032 256
lixianyu 0:d8f4c441e032 257 #elif defined(ARDUINO) && defined(__SAM3X8E__)
lixianyu 0:d8f4c441e032 258 /* Arduino Due */
lixianyu 0:d8f4c441e032 259 #include "Arduino.h"
lixianyu 0:d8f4c441e032 260 #include "sam.h"
lixianyu 0:d8f4c441e032 261
lixianyu 0:d8f4c441e032 262 /*
lixianyu 0:d8f4c441e032 263
lixianyu 0:d8f4c441e032 264 Controller
lixianyu 0:d8f4c441e032 265
lixianyu 0:d8f4c441e032 266 TWI0 TWCK0 PA18 A DUE PCB: SCL1
lixianyu 0:d8f4c441e032 267 TWI0 TWD0 PA17 A DUE PCB: SDA1
lixianyu 0:d8f4c441e032 268 TWI1 TWCK1 PB13 A DUE PCB: SCL 21
lixianyu 0:d8f4c441e032 269 TWI1 TWD1 PB12 A DUE PCB: SDA 20
lixianyu 0:d8f4c441e032 270
lixianyu 0:d8f4c441e032 271 Arduino definitions
lixianyu 0:d8f4c441e032 272
lixianyu 0:d8f4c441e032 273 #define PIN_WIRE_SDA (20u)
lixianyu 0:d8f4c441e032 274 #define PIN_WIRE_SCL (21u)
lixianyu 0:d8f4c441e032 275 #define WIRE_INTERFACE TWI1
lixianyu 0:d8f4c441e032 276 #define WIRE_INTERFACE_ID ID_TWI1
lixianyu 0:d8f4c441e032 277 #define WIRE_ISR_HANDLER TWI1_Handler
lixianyu 0:d8f4c441e032 278
lixianyu 0:d8f4c441e032 279 #define PIN_WIRE1_SDA (70u)
lixianyu 0:d8f4c441e032 280 #define PIN_WIRE1_SCL (71u)
lixianyu 0:d8f4c441e032 281 #define WIRE1_INTERFACE TWI0
lixianyu 0:d8f4c441e032 282 #define WIRE1_INTERFACE_ID ID_TWI0
lixianyu 0:d8f4c441e032 283 #define WIRE1_ISR_HANDLER TWI0_Handler
lixianyu 0:d8f4c441e032 284
lixianyu 0:d8f4c441e032 285
lixianyu 0:d8f4c441e032 286 */
lixianyu 0:d8f4c441e032 287
lixianyu 0:d8f4c441e032 288 static void i2c_400KHz_delay(void)
lixianyu 0:d8f4c441e032 289 {
lixianyu 0:d8f4c441e032 290 /* should be at least 4 */
lixianyu 0:d8f4c441e032 291 /* should be 5 for 100KHz transfer speed */
lixianyu 0:d8f4c441e032 292
lixianyu 0:d8f4c441e032 293
lixianyu 0:d8f4c441e032 294 /*
lixianyu 0:d8f4c441e032 295 Arduino Due
lixianyu 0:d8f4c441e032 296 0x NOP: 470KHz
lixianyu 0:d8f4c441e032 297 4x NOP: 450KHz
lixianyu 0:d8f4c441e032 298 8x NOP: 430KHz
lixianyu 0:d8f4c441e032 299 16x NOP: 400KHz
lixianyu 0:d8f4c441e032 300 */
lixianyu 0:d8f4c441e032 301
lixianyu 0:d8f4c441e032 302 __NOP();
lixianyu 0:d8f4c441e032 303 __NOP();
lixianyu 0:d8f4c441e032 304 __NOP();
lixianyu 0:d8f4c441e032 305 __NOP();
lixianyu 0:d8f4c441e032 306
lixianyu 0:d8f4c441e032 307 __NOP();
lixianyu 0:d8f4c441e032 308 __NOP();
lixianyu 0:d8f4c441e032 309 __NOP();
lixianyu 0:d8f4c441e032 310 __NOP();
lixianyu 0:d8f4c441e032 311
lixianyu 0:d8f4c441e032 312 __NOP();
lixianyu 0:d8f4c441e032 313 __NOP();
lixianyu 0:d8f4c441e032 314 __NOP();
lixianyu 0:d8f4c441e032 315 __NOP();
lixianyu 0:d8f4c441e032 316
lixianyu 0:d8f4c441e032 317 __NOP();
lixianyu 0:d8f4c441e032 318 __NOP();
lixianyu 0:d8f4c441e032 319 __NOP();
lixianyu 0:d8f4c441e032 320 __NOP();
lixianyu 0:d8f4c441e032 321 }
lixianyu 0:d8f4c441e032 322
lixianyu 0:d8f4c441e032 323 static void i2c_100KHz_delay(void)
lixianyu 0:d8f4c441e032 324 {
lixianyu 0:d8f4c441e032 325 /*
lixianyu 0:d8f4c441e032 326 1x u8g_MicroDelay() ca. 130KHz
lixianyu 0:d8f4c441e032 327 2x u8g_MicroDelay() ca. 80KHz
lixianyu 0:d8f4c441e032 328 */
lixianyu 0:d8f4c441e032 329 u8g_MicroDelay();
lixianyu 0:d8f4c441e032 330 u8g_MicroDelay();
lixianyu 0:d8f4c441e032 331 }
lixianyu 0:d8f4c441e032 332
lixianyu 0:d8f4c441e032 333
lixianyu 0:d8f4c441e032 334 uint32_t i2c_started = 0;
lixianyu 0:d8f4c441e032 335 uint32_t i2c_scl_pin = 0;
lixianyu 0:d8f4c441e032 336 uint32_t i2c_sda_pin = 0;
lixianyu 0:d8f4c441e032 337 void (*i2c_delay)(void) = i2c_100KHz_delay;
lixianyu 0:d8f4c441e032 338
lixianyu 0:d8f4c441e032 339 const PinDescription *i2c_scl_pin_desc;
lixianyu 0:d8f4c441e032 340 const PinDescription *i2c_sda_pin_desc;
lixianyu 0:d8f4c441e032 341
lixianyu 0:d8f4c441e032 342
lixianyu 0:d8f4c441e032 343 /* maybe this can be optimized */
lixianyu 0:d8f4c441e032 344 static void i2c_init(void)
lixianyu 0:d8f4c441e032 345 {
lixianyu 0:d8f4c441e032 346 i2c_sda_pin_desc = &(g_APinDescription[i2c_sda_pin]);
lixianyu 0:d8f4c441e032 347 i2c_scl_pin_desc = &(g_APinDescription[i2c_scl_pin]);
lixianyu 0:d8f4c441e032 348 pinMode(i2c_sda_pin, OUTPUT);
lixianyu 0:d8f4c441e032 349 digitalWrite(i2c_sda_pin, HIGH);
lixianyu 0:d8f4c441e032 350 pinMode(i2c_scl_pin, OUTPUT);
lixianyu 0:d8f4c441e032 351 digitalWrite(i2c_scl_pin, HIGH);
lixianyu 0:d8f4c441e032 352 PIO_Configure( i2c_sda_pin_desc->pPort, PIO_OUTPUT_0, i2c_sda_pin_desc->ulPin, PIO_OPENDRAIN );
lixianyu 0:d8f4c441e032 353 PIO_Configure( i2c_scl_pin_desc->pPort, PIO_OUTPUT_0, i2c_scl_pin_desc->ulPin, PIO_OPENDRAIN );
lixianyu 0:d8f4c441e032 354 PIO_Clear( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin) ;
lixianyu 0:d8f4c441e032 355 PIO_Clear( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin) ;
lixianyu 0:d8f4c441e032 356 PIO_Configure( i2c_sda_pin_desc->pPort, PIO_INPUT, i2c_sda_pin_desc->ulPin, PIO_DEFAULT ) ;
lixianyu 0:d8f4c441e032 357 PIO_Configure( i2c_scl_pin_desc->pPort, PIO_INPUT, i2c_scl_pin_desc->ulPin, PIO_DEFAULT ) ;
lixianyu 0:d8f4c441e032 358 i2c_delay();
lixianyu 0:d8f4c441e032 359 }
lixianyu 0:d8f4c441e032 360
lixianyu 0:d8f4c441e032 361 /* actually, the scl line is not observed, so this procedure does not return a value */
lixianyu 0:d8f4c441e032 362 static void i2c_read_scl_and_delay(void)
lixianyu 0:d8f4c441e032 363 {
lixianyu 0:d8f4c441e032 364 uint32_t dwMask = i2c_scl_pin_desc->ulPin;
lixianyu 0:d8f4c441e032 365 //PIO_Configure( i2c_scl_pin_desc->pPort, PIO_INPUT, i2c_scl_pin_desc->ulPin, PIO_DEFAULT ) ;
lixianyu 0:d8f4c441e032 366 //PIO_SetInput( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin, PIO_DEFAULT ) ;
lixianyu 0:d8f4c441e032 367
lixianyu 0:d8f4c441e032 368 /* set as input */
lixianyu 0:d8f4c441e032 369 i2c_scl_pin_desc->pPort->PIO_ODR = dwMask ;
lixianyu 0:d8f4c441e032 370 i2c_scl_pin_desc->pPort->PIO_PER = dwMask ;
lixianyu 0:d8f4c441e032 371
lixianyu 0:d8f4c441e032 372 i2c_delay();
lixianyu 0:d8f4c441e032 373 }
lixianyu 0:d8f4c441e032 374
lixianyu 0:d8f4c441e032 375 static void i2c_clear_scl(void)
lixianyu 0:d8f4c441e032 376 {
lixianyu 0:d8f4c441e032 377 uint32_t dwMask = i2c_scl_pin_desc->ulPin;
lixianyu 0:d8f4c441e032 378
lixianyu 0:d8f4c441e032 379 /* set open collector and drive low */
lixianyu 0:d8f4c441e032 380 //PIO_Configure( i2c_scl_pin_desc->pPort, PIO_OUTPUT_0, i2c_scl_pin_desc->ulPin, PIO_OPENDRAIN );
lixianyu 0:d8f4c441e032 381 //PIO_SetOutput( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin, 0, 1, 0);
lixianyu 0:d8f4c441e032 382
lixianyu 0:d8f4c441e032 383 /* open drain, zero default output */
lixianyu 0:d8f4c441e032 384 i2c_scl_pin_desc->pPort->PIO_MDER = dwMask;
lixianyu 0:d8f4c441e032 385 i2c_scl_pin_desc->pPort->PIO_CODR = dwMask;
lixianyu 0:d8f4c441e032 386 i2c_scl_pin_desc->pPort->PIO_OER = dwMask;
lixianyu 0:d8f4c441e032 387 i2c_scl_pin_desc->pPort->PIO_PER = dwMask;
lixianyu 0:d8f4c441e032 388
lixianyu 0:d8f4c441e032 389 //PIO_Clear( i2c_scl_pin_desc->pPort, i2c_scl_pin_desc->ulPin) ;
lixianyu 0:d8f4c441e032 390 }
lixianyu 0:d8f4c441e032 391
lixianyu 0:d8f4c441e032 392 static uint8_t i2c_read_sda(void)
lixianyu 0:d8f4c441e032 393 {
lixianyu 0:d8f4c441e032 394 uint32_t dwMask = i2c_sda_pin_desc->ulPin;
lixianyu 0:d8f4c441e032 395 //PIO_Configure( i2c_sda_pin_desc->pPort, PIO_INPUT, i2c_sda_pin_desc->ulPin, PIO_DEFAULT ) ;
lixianyu 0:d8f4c441e032 396 //PIO_SetInput( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin, PIO_DEFAULT ) ;
lixianyu 0:d8f4c441e032 397
lixianyu 0:d8f4c441e032 398 /* set as input */
lixianyu 0:d8f4c441e032 399 i2c_sda_pin_desc->pPort->PIO_ODR = dwMask ;
lixianyu 0:d8f4c441e032 400 i2c_sda_pin_desc->pPort->PIO_PER = dwMask ;
lixianyu 0:d8f4c441e032 401
lixianyu 0:d8f4c441e032 402
lixianyu 0:d8f4c441e032 403 return 1;
lixianyu 0:d8f4c441e032 404 }
lixianyu 0:d8f4c441e032 405
lixianyu 0:d8f4c441e032 406 static void i2c_clear_sda(void)
lixianyu 0:d8f4c441e032 407 {
lixianyu 0:d8f4c441e032 408 uint32_t dwMask = i2c_sda_pin_desc->ulPin;
lixianyu 0:d8f4c441e032 409
lixianyu 0:d8f4c441e032 410 /* set open collector and drive low */
lixianyu 0:d8f4c441e032 411 //PIO_Configure( i2c_sda_pin_desc->pPort, PIO_OUTPUT_0, i2c_sda_pin_desc->ulPin, PIO_OPENDRAIN );
lixianyu 0:d8f4c441e032 412 //PIO_SetOutput( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin, 0, 1, 0);
lixianyu 0:d8f4c441e032 413
lixianyu 0:d8f4c441e032 414 /* open drain, zero default output */
lixianyu 0:d8f4c441e032 415 i2c_sda_pin_desc->pPort->PIO_MDER = dwMask ;
lixianyu 0:d8f4c441e032 416 i2c_sda_pin_desc->pPort->PIO_CODR = dwMask ;
lixianyu 0:d8f4c441e032 417 i2c_sda_pin_desc->pPort->PIO_OER = dwMask ;
lixianyu 0:d8f4c441e032 418 i2c_sda_pin_desc->pPort->PIO_PER = dwMask ;
lixianyu 0:d8f4c441e032 419
lixianyu 0:d8f4c441e032 420 //PIO_Clear( i2c_sda_pin_desc->pPort, i2c_sda_pin_desc->ulPin) ;
lixianyu 0:d8f4c441e032 421 }
lixianyu 0:d8f4c441e032 422
lixianyu 0:d8f4c441e032 423 static void i2c_start(void)
lixianyu 0:d8f4c441e032 424 {
lixianyu 0:d8f4c441e032 425 if ( i2c_started != 0 )
lixianyu 0:d8f4c441e032 426 {
lixianyu 0:d8f4c441e032 427 /* if already started: do restart */
lixianyu 0:d8f4c441e032 428 i2c_read_sda(); /* SDA = 1 */
lixianyu 0:d8f4c441e032 429 i2c_delay();
lixianyu 0:d8f4c441e032 430 i2c_read_scl_and_delay();
lixianyu 0:d8f4c441e032 431 }
lixianyu 0:d8f4c441e032 432 i2c_read_sda();
lixianyu 0:d8f4c441e032 433 /*
lixianyu 0:d8f4c441e032 434 if (i2c_read_sda() == 0)
lixianyu 0:d8f4c441e032 435 {
lixianyu 0:d8f4c441e032 436 // do something because arbitration is lost
lixianyu 0:d8f4c441e032 437 }
lixianyu 0:d8f4c441e032 438 */
lixianyu 0:d8f4c441e032 439 /* send the start condition, both lines go from 1 to 0 */
lixianyu 0:d8f4c441e032 440 i2c_clear_sda();
lixianyu 0:d8f4c441e032 441 i2c_delay();
lixianyu 0:d8f4c441e032 442 i2c_clear_scl();
lixianyu 0:d8f4c441e032 443 i2c_started = 1;
lixianyu 0:d8f4c441e032 444 }
lixianyu 0:d8f4c441e032 445
lixianyu 0:d8f4c441e032 446
lixianyu 0:d8f4c441e032 447 static void i2c_stop(void)
lixianyu 0:d8f4c441e032 448 {
lixianyu 0:d8f4c441e032 449 /* set SDA to 0 */
lixianyu 0:d8f4c441e032 450 i2c_clear_sda();
lixianyu 0:d8f4c441e032 451 i2c_delay();
lixianyu 0:d8f4c441e032 452
lixianyu 0:d8f4c441e032 453 /* now release all lines */
lixianyu 0:d8f4c441e032 454 i2c_read_scl_and_delay();
lixianyu 0:d8f4c441e032 455
lixianyu 0:d8f4c441e032 456 /* set SDA to 1 */
lixianyu 0:d8f4c441e032 457 i2c_read_sda();
lixianyu 0:d8f4c441e032 458 i2c_delay();
lixianyu 0:d8f4c441e032 459 i2c_started = 0;
lixianyu 0:d8f4c441e032 460 }
lixianyu 0:d8f4c441e032 461
lixianyu 0:d8f4c441e032 462 static void i2c_write_bit(uint8_t val)
lixianyu 0:d8f4c441e032 463 {
lixianyu 0:d8f4c441e032 464 if (val)
lixianyu 0:d8f4c441e032 465 i2c_read_sda();
lixianyu 0:d8f4c441e032 466 else
lixianyu 0:d8f4c441e032 467 i2c_clear_sda();
lixianyu 0:d8f4c441e032 468
lixianyu 0:d8f4c441e032 469 i2c_delay();
lixianyu 0:d8f4c441e032 470 i2c_read_scl_and_delay();
lixianyu 0:d8f4c441e032 471 i2c_clear_scl();
lixianyu 0:d8f4c441e032 472 }
lixianyu 0:d8f4c441e032 473
lixianyu 0:d8f4c441e032 474 static uint8_t i2c_read_bit(void)
lixianyu 0:d8f4c441e032 475 {
lixianyu 0:d8f4c441e032 476 uint8_t val;
lixianyu 0:d8f4c441e032 477 /* do not drive SDA */
lixianyu 0:d8f4c441e032 478 i2c_read_sda();
lixianyu 0:d8f4c441e032 479 i2c_delay();
lixianyu 0:d8f4c441e032 480 i2c_read_scl_and_delay();
lixianyu 0:d8f4c441e032 481 val = i2c_read_sda();
lixianyu 0:d8f4c441e032 482 i2c_delay();
lixianyu 0:d8f4c441e032 483 i2c_clear_scl();
lixianyu 0:d8f4c441e032 484 return val;
lixianyu 0:d8f4c441e032 485 }
lixianyu 0:d8f4c441e032 486
lixianyu 0:d8f4c441e032 487 static uint8_t i2c_write_byte(uint8_t b)
lixianyu 0:d8f4c441e032 488 {
lixianyu 0:d8f4c441e032 489 i2c_write_bit(b & 128);
lixianyu 0:d8f4c441e032 490 i2c_write_bit(b & 64);
lixianyu 0:d8f4c441e032 491 i2c_write_bit(b & 32);
lixianyu 0:d8f4c441e032 492 i2c_write_bit(b & 16);
lixianyu 0:d8f4c441e032 493 i2c_write_bit(b & 8);
lixianyu 0:d8f4c441e032 494 i2c_write_bit(b & 4);
lixianyu 0:d8f4c441e032 495 i2c_write_bit(b & 2);
lixianyu 0:d8f4c441e032 496 i2c_write_bit(b & 1);
lixianyu 0:d8f4c441e032 497
lixianyu 0:d8f4c441e032 498 /* read ack from client */
lixianyu 0:d8f4c441e032 499 /* 0: ack was given by client */
lixianyu 0:d8f4c441e032 500 /* 1: nothing happend during ack cycle */
lixianyu 0:d8f4c441e032 501 return i2c_read_bit();
lixianyu 0:d8f4c441e032 502 }
lixianyu 0:d8f4c441e032 503
lixianyu 0:d8f4c441e032 504
lixianyu 0:d8f4c441e032 505
lixianyu 0:d8f4c441e032 506 void u8g_i2c_init(uint8_t options)
lixianyu 0:d8f4c441e032 507 {
lixianyu 0:d8f4c441e032 508 u8g_i2c_opt = options;
lixianyu 0:d8f4c441e032 509 u8g_i2c_clear_error();
lixianyu 0:d8f4c441e032 510
lixianyu 0:d8f4c441e032 511 if ( u8g_i2c_opt & U8G_I2C_OPT_FAST )
lixianyu 0:d8f4c441e032 512 {
lixianyu 0:d8f4c441e032 513 i2c_delay = i2c_400KHz_delay;
lixianyu 0:d8f4c441e032 514 }
lixianyu 0:d8f4c441e032 515 else
lixianyu 0:d8f4c441e032 516 {
lixianyu 0:d8f4c441e032 517 i2c_delay = i2c_100KHz_delay;
lixianyu 0:d8f4c441e032 518 }
lixianyu 0:d8f4c441e032 519
lixianyu 0:d8f4c441e032 520
lixianyu 0:d8f4c441e032 521 if ( u8g_i2c_opt & U8G_I2C_OPT_DEV_1 )
lixianyu 0:d8f4c441e032 522 {
lixianyu 0:d8f4c441e032 523 i2c_scl_pin = PIN_WIRE1_SCL;
lixianyu 0:d8f4c441e032 524 i2c_sda_pin = PIN_WIRE1_SDA;
lixianyu 0:d8f4c441e032 525
lixianyu 0:d8f4c441e032 526 //REG_PIOA_PDR = PIO_PB12A_TWD1 | PIO_PB13A_TWCK1;
lixianyu 0:d8f4c441e032 527 }
lixianyu 0:d8f4c441e032 528 else
lixianyu 0:d8f4c441e032 529 {
lixianyu 0:d8f4c441e032 530
lixianyu 0:d8f4c441e032 531 i2c_scl_pin = PIN_WIRE_SCL;
lixianyu 0:d8f4c441e032 532 i2c_sda_pin = PIN_WIRE_SDA;
lixianyu 0:d8f4c441e032 533
lixianyu 0:d8f4c441e032 534 //REG_PIOA_PDR = PIO_PA17A_TWD0 | PIO_PA18A_TWCK0;
lixianyu 0:d8f4c441e032 535 }
lixianyu 0:d8f4c441e032 536
lixianyu 0:d8f4c441e032 537 i2c_init();
lixianyu 0:d8f4c441e032 538
lixianyu 0:d8f4c441e032 539 }
lixianyu 0:d8f4c441e032 540
lixianyu 0:d8f4c441e032 541 /* sla includes also the r/w bit */
lixianyu 0:d8f4c441e032 542 uint8_t u8g_i2c_start(uint8_t sla)
lixianyu 0:d8f4c441e032 543 {
lixianyu 0:d8f4c441e032 544 i2c_start();
lixianyu 0:d8f4c441e032 545 i2c_write_byte(sla);
lixianyu 0:d8f4c441e032 546 return 1;
lixianyu 0:d8f4c441e032 547 }
lixianyu 0:d8f4c441e032 548
lixianyu 0:d8f4c441e032 549 uint8_t u8g_i2c_send_byte(uint8_t data)
lixianyu 0:d8f4c441e032 550 {
lixianyu 0:d8f4c441e032 551 return i2c_write_byte(data);
lixianyu 0:d8f4c441e032 552 }
lixianyu 0:d8f4c441e032 553
lixianyu 0:d8f4c441e032 554 void u8g_i2c_stop(void)
lixianyu 0:d8f4c441e032 555 {
lixianyu 0:d8f4c441e032 556 i2c_stop();
lixianyu 0:d8f4c441e032 557 }
lixianyu 0:d8f4c441e032 558
lixianyu 0:d8f4c441e032 559
lixianyu 0:d8f4c441e032 560 #elif defined(U8G_RASPBERRY_PI)
lixianyu 0:d8f4c441e032 561
lixianyu 0:d8f4c441e032 562 #include <wiringPi.h>
lixianyu 0:d8f4c441e032 563 #include <wiringPiI2C.h>
lixianyu 0:d8f4c441e032 564 #include <stdio.h>
lixianyu 0:d8f4c441e032 565 #include <stdlib.h>
lixianyu 0:d8f4c441e032 566 #include <errno.h>
lixianyu 0:d8f4c441e032 567
lixianyu 0:d8f4c441e032 568 #define I2C_SLA 0x3c
lixianyu 0:d8f4c441e032 569
lixianyu 0:d8f4c441e032 570 static int fd=-1;
lixianyu 0:d8f4c441e032 571 static uint8_t i2cMode = 0;
lixianyu 0:d8f4c441e032 572
lixianyu 0:d8f4c441e032 573 void u8g_i2c_init(uint8_t options) {
lixianyu 0:d8f4c441e032 574 u8g_i2c_clear_error();
lixianyu 0:d8f4c441e032 575 u8g_i2c_opt = options;
lixianyu 0:d8f4c441e032 576
lixianyu 0:d8f4c441e032 577 if (wiringPiSetup() == -1) {
lixianyu 0:d8f4c441e032 578 printf("wiringPi-Error\n");
lixianyu 0:d8f4c441e032 579 exit(1);
lixianyu 0:d8f4c441e032 580 }
lixianyu 0:d8f4c441e032 581
lixianyu 0:d8f4c441e032 582 fd = wiringPiI2CSetup(I2C_SLA);
lixianyu 0:d8f4c441e032 583 if (fd < 0) {
lixianyu 0:d8f4c441e032 584 printf ("Unable to open I2C device 0: %s\n", strerror (errno)) ;
lixianyu 0:d8f4c441e032 585 exit (1) ;
lixianyu 0:d8f4c441e032 586 }
lixianyu 0:d8f4c441e032 587 //u8g_SetPIOutput(u8g, U8G_PI_RESET);
lixianyu 0:d8f4c441e032 588 //u8g_SetPIOutput(u8g, U8G_PI_A0);
lixianyu 0:d8f4c441e032 589 }
lixianyu 0:d8f4c441e032 590 uint8_t u8g_i2c_start(uint8_t sla) {
lixianyu 0:d8f4c441e032 591 u8g_i2c_send_mode(0);
lixianyu 0:d8f4c441e032 592
lixianyu 0:d8f4c441e032 593 return 1;
lixianyu 0:d8f4c441e032 594 }
lixianyu 0:d8f4c441e032 595
lixianyu 0:d8f4c441e032 596 void u8g_i2c_stop(void) {
lixianyu 0:d8f4c441e032 597 }
lixianyu 0:d8f4c441e032 598
lixianyu 0:d8f4c441e032 599 uint8_t u8g_i2c_send_mode(uint8_t mode) {
lixianyu 0:d8f4c441e032 600 i2cMode = mode;
lixianyu 0:d8f4c441e032 601 }
lixianyu 0:d8f4c441e032 602
lixianyu 0:d8f4c441e032 603 uint8_t u8g_i2c_send_byte(uint8_t data) {
lixianyu 0:d8f4c441e032 604 wiringPiI2CWriteReg8(fd, i2cMode, data);
lixianyu 0:d8f4c441e032 605
lixianyu 0:d8f4c441e032 606 return 1;
lixianyu 0:d8f4c441e032 607 }
lixianyu 0:d8f4c441e032 608
lixianyu 0:d8f4c441e032 609 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
lixianyu 0:d8f4c441e032 610 {
lixianyu 0:d8f4c441e032 611 return 1;
lixianyu 0:d8f4c441e032 612 }
lixianyu 0:d8f4c441e032 613
lixianyu 0:d8f4c441e032 614 #else
lixianyu 0:d8f4c441e032 615
lixianyu 0:d8f4c441e032 616 /* empty interface */
lixianyu 0:d8f4c441e032 617
lixianyu 0:d8f4c441e032 618 void u8g_i2c_init(uint8_t options)
lixianyu 0:d8f4c441e032 619 {
lixianyu 0:d8f4c441e032 620 u8g_i2c_clear_error();
lixianyu 0:d8f4c441e032 621 }
lixianyu 0:d8f4c441e032 622
lixianyu 0:d8f4c441e032 623 uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos)
lixianyu 0:d8f4c441e032 624 {
lixianyu 0:d8f4c441e032 625 return 1;
lixianyu 0:d8f4c441e032 626 }
lixianyu 0:d8f4c441e032 627
lixianyu 0:d8f4c441e032 628 uint8_t u8g_i2c_start(uint8_t sla)
lixianyu 0:d8f4c441e032 629 {
lixianyu 0:d8f4c441e032 630 return 1;
lixianyu 0:d8f4c441e032 631 }
lixianyu 0:d8f4c441e032 632 uint8_t u8g_i2c_send_byte(uint8_t data)
lixianyu 0:d8f4c441e032 633 {
lixianyu 0:d8f4c441e032 634 return 1;
lixianyu 0:d8f4c441e032 635 }
lixianyu 0:d8f4c441e032 636
lixianyu 0:d8f4c441e032 637 void u8g_i2c_stop(void)
lixianyu 0:d8f4c441e032 638 {
lixianyu 0:d8f4c441e032 639 }
lixianyu 0:d8f4c441e032 640
lixianyu 0:d8f4c441e032 641
lixianyu 0:d8f4c441e032 642 #endif
lixianyu 0:d8f4c441e032 643
lixianyu 0:d8f4c441e032 644