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.
u8glibARM/u8g_com_i2c.c@1:0e75de2a5d21, 2016-06-13 (annotated)
- 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?
| User | Revision | Line number | New 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 |