Thanks for using Compiler Explorer
Sponsors
C++
LLVM IR
Cppx
Cppx-Gold
Cppx-Blue
C
OpenCL C
C++ for OpenCL
Rust
D
Erlang
Go
ispc
Haskell
Java
Kotlin
Scala
OCaml
Python
Swift
Pascal
Fortran
Assembly
Analysis
CUDA C++
Zig
Clean
Ada
Nim
Crystal
C++ (Circle)
Ruby
CMake
C#
F#
Visual Basic
Dart
TypeScript
Solidity
c source #1
Output
Compile to binary
Execute the code
Intel asm syntax
Demangle identifiers
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Compiler
6502 cc65 2.17
6502 cc65 2.18
6502 cc65 2.19
6502 cc65 trunk
ARM gcc 10.2 (linux)
ARM gcc 10.2.1 (none)
ARM gcc 10.3 (linux)
ARM gcc 11.1 (linux)
ARM gcc 11.2 (linux)
ARM gcc 4.5.4 (linux)
ARM gcc 4.6.4 (linux)
ARM gcc 5.4 (linux)
ARM gcc 5.4.1 (none)
ARM gcc 6.3.0 (linux)
ARM gcc 6.4 (linux)
ARM gcc 7.2.1 (none)
ARM gcc 7.3 (linux)
ARM gcc 7.5 (linux)
ARM gcc 8.2 (WinCE)
ARM gcc 8.2 (linux)
ARM gcc 8.3.1 (none)
ARM gcc 8.5 (linux)
ARM gcc 9.2.1 (none)
ARM gcc 9.3 (linux)
ARM gcc trunk (linux)
ARM msvc v19.0 (WINE)
ARM msvc v19.10 (WINE)
ARM msvc v19.14 (WINE)
ARM64 gcc 10.2
ARM64 gcc 10.3
ARM64 gcc 11.1
ARM64 gcc 11.2
ARM64 gcc 5.4
ARM64 gcc 6.3
ARM64 gcc 6.4
ARM64 gcc 7.3
ARM64 gcc 7.5
ARM64 gcc 8.2
ARM64 gcc 8.5
ARM64 gcc 9.3
ARM64 gcc trunk
ARM64 msvc v19.14 (WINE)
AVR gcc 10.3.0
AVR gcc 11.1.0
AVR gcc 4.5.4
AVR gcc 4.6.4
AVR gcc 5.4.0
AVR gcc 9.2.0
AVR gcc 9.3.0
Arduino Mega (1.8.9)
Arduino Uno (1.8.9)
Chibicc 2020-12-07
FRC 2019
FRC 2020
K1C gcc 7.4
K1C gcc 7.5
KVX gcc 7.5 (ACB 4.1.0)
KVX gcc 7.5 (ACB 4.1.0-cd1)
KVX gcc 7.5 (ACB 4.2.0)
KVX gcc 7.5 (ACB 4.3.0)
KVX gcc 7.5 (ACB 4.4.0)
KVX gcc 9.4 (ACB 4.6.0)
MRISC32 gcc (trunk)
MSP430 gcc 4.5.3
MSP430 gcc 5.3.0
MSP430 gcc 6.2.1
RISC-V rv32gc clang (trunk)
RISC-V rv32gc clang 10.0.0
RISC-V rv32gc clang 10.0.1
RISC-V rv32gc clang 11.0.0
RISC-V rv32gc clang 11.0.1
RISC-V rv32gc clang 12.0.0
RISC-V rv32gc clang 12.0.1
RISC-V rv32gc clang 13.0.0
RISC-V rv32gc clang 13.0.1
RISC-V rv32gc clang 14.0.0
RISC-V rv32gc clang 9.0.0
RISC-V rv32gc clang 9.0.1
RISC-V rv32gc gcc 10.2.0
RISC-V rv32gc gcc 8.2.0
RISC-V rv64gc clang (trunk)
RISC-V rv64gc clang 10.0.0
RISC-V rv64gc clang 10.0.1
RISC-V rv64gc clang 11.0.0
RISC-V rv64gc clang 11.0.1
RISC-V rv64gc clang 12.0.0
RISC-V rv64gc clang 12.0.1
RISC-V rv64gc clang 13.0.0
RISC-V rv64gc clang 13.0.1
RISC-V rv64gc clang 14.0.0
RISC-V rv64gc clang 9.0.0
RISC-V rv64gc clang 9.0.1
RISC-V rv64gc gcc 10.2.0
RISC-V rv64gc gcc 8.2.0
Raspbian Buster
Raspbian Stretch
SDCC 4.0.0
SDCC 4.1.0
TCC (trunk)
TCC 0.9.27
WebAssembly clang (trunk)
Xtensa ESP32 gcc 8.2.0 (2019r2)
Xtensa ESP32 gcc 8.2.0 (2020r1)
Xtensa ESP32 gcc 8.2.0 (2020r2)
Xtensa ESP32 gcc 8.4.0 (2020r3)
Xtensa ESP32 gcc 8.4.0 (2021r1)
Xtensa ESP32 gcc 8.4.0 (2021r2)
Xtensa ESP32-S2 gcc 8.2.0 (2019r2)
Xtensa ESP32-S2 gcc 8.2.0 (2020r1)
Xtensa ESP32-S2 gcc 8.2.0 (2020r2)
Xtensa ESP32-S2 gcc 8.4.0 (2020r3)
Xtensa ESP32-S2 gcc 8.4.0 (2021r1)
Xtensa ESP32-S2 gcc 8.4.0 (2021r2)
Xtensa ESP32-S3 gcc 8.4.0 (2020r3)
Xtensa ESP32-S3 gcc 8.4.0 (2021r1)
Xtensa ESP32-S3 gcc 8.4.0 (2021r2)
armv7-a clang (trunk)
armv7-a clang 10.0.0
armv7-a clang 10.0.1
armv7-a clang 11.0.0
armv7-a clang 11.0.1
armv7-a clang 9.0.0
armv7-a clang 9.0.1
armv8-a clang (trunk)
armv8-a clang (trunk, all architectural features)
armv8-a clang 10.0.0
armv8-a clang 10.0.1
armv8-a clang 11.0.0
armv8-a clang 11.0.1
armv8-a clang 9.0.0
armv8-a clang 9.0.1
cproc-master
mips (el) gcc 5.4
mips gcc 11.2.0
mips gcc 5.4
mips gcc 9.3.0
mips64 (el) gcc 5.4
mips64 gcc 11.2.0
mips64 gcc 5.4
nanoMIPS gcc 6.3.0
power gcc 11.2.0
power gcc 4.8.5
power64 AT12.0 (gcc8)
power64 AT13.0 (gcc9)
power64 gcc 11.2.0
power64le AT12.0 (gcc8)
power64le AT13.0 (gcc9)
power64le clang (trunk)
power64le gcc 11.2.0
power64le gcc 6.3.0
powerpc64 clang (trunk)
ppci 0.5.5
s390x GCC 11.2.0
x64 msvc v19.0 (WINE)
x64 msvc v19.10 (WINE)
x64 msvc v19.14 (WINE)
x86 gcc 1.27
x86 msvc v19.0 (WINE)
x86 msvc v19.10 (WINE)
x86 msvc v19.14 (WINE)
x86 tendra (trunk)
x86-64 clang (assertions trunk)
x86-64 clang (thephd.dev)
x86-64 clang (trunk)
x86-64 clang (widberg)
x86-64 clang 10.0.0
x86-64 clang 10.0.1
x86-64 clang 11.0.0
x86-64 clang 11.0.1
x86-64 clang 12.0.0
x86-64 clang 12.0.1
x86-64 clang 13.0.0
x86-64 clang 13.0.1
x86-64 clang 14.0.0
x86-64 clang 3.0.0
x86-64 clang 3.1
x86-64 clang 3.2
x86-64 clang 3.3
x86-64 clang 3.4.1
x86-64 clang 3.5
x86-64 clang 3.5.1
x86-64 clang 3.5.2
x86-64 clang 3.6
x86-64 clang 3.7
x86-64 clang 3.7.1
x86-64 clang 3.8
x86-64 clang 3.8.1
x86-64 clang 3.9.0
x86-64 clang 3.9.1
x86-64 clang 4.0.0
x86-64 clang 4.0.1
x86-64 clang 5.0.0
x86-64 clang 5.0.1
x86-64 clang 5.0.2
x86-64 clang 6.0.0
x86-64 clang 6.0.1
x86-64 clang 7.0.0
x86-64 clang 7.0.1
x86-64 clang 7.1.0
x86-64 clang 8.0.0
x86-64 clang 8.0.1
x86-64 clang 9.0.0
x86-64 clang 9.0.1
x86-64 gcc (static analysis)
x86-64 gcc (trunk)
x86-64 gcc 10.1
x86-64 gcc 10.2
x86-64 gcc 10.3
x86-64 gcc 11.1
x86-64 gcc 11.2
x86-64 gcc 11.3
x86-64 gcc 12.1
x86-64 gcc 4.1.2
x86-64 gcc 4.4.7
x86-64 gcc 4.5.3
x86-64 gcc 4.6.4
x86-64 gcc 4.7.1
x86-64 gcc 4.7.2
x86-64 gcc 4.7.3
x86-64 gcc 4.7.4
x86-64 gcc 4.8.1
x86-64 gcc 4.8.2
x86-64 gcc 4.8.3
x86-64 gcc 4.8.4
x86-64 gcc 4.8.5
x86-64 gcc 4.9.0
x86-64 gcc 4.9.1
x86-64 gcc 4.9.2
x86-64 gcc 4.9.3
x86-64 gcc 4.9.4
x86-64 gcc 5.1
x86-64 gcc 5.2
x86-64 gcc 5.3
x86-64 gcc 5.4
x86-64 gcc 6.1
x86-64 gcc 6.2
x86-64 gcc 6.3
x86-64 gcc 7.1
x86-64 gcc 7.2
x86-64 gcc 7.3
x86-64 gcc 7.4
x86-64 gcc 8.1
x86-64 gcc 8.2
x86-64 gcc 8.3
x86-64 gcc 8.4
x86-64 gcc 8.5
x86-64 gcc 9.1
x86-64 gcc 9.2
x86-64 gcc 9.3
x86-64 gcc 9.4
x86-64 icc 13.0.1
x86-64 icc 16.0.3
x86-64 icc 17.0.0
x86-64 icc 18.0.0
x86-64 icc 19.0.0
x86-64 icc 19.0.1
x86-64 icc 2021.1.2
x86-64 icc 2021.2.0
x86-64 icc 2021.3.0
x86-64 icc 2021.4.0
x86-64 icc 2021.5.0
x86-64 icx 2021.1.2
x86-64 icx 2021.2.0
x86-64 icx 2021.3.0
x86-64 icx 2021.4.0
x86-64 icx 2022.0.0
zig cc 0.6.0
zig cc 0.7.0
zig cc 0.7.1
zig cc 0.8.0
zig cc 0.9.0
zig cc trunk
Options
Source code
/*---------------------------------------------------- Twi.h header avr0/1 Twi_function is global function ----------------------------------------------------*/ #include <stdint.h> #include <stdbool.h> #define U8 uint8_t void Twi_baudReg (U8 v); void Twi_on (); bool Twi_readBytes (U8* buf, const U8 len, bool doStop); bool Twi_writeBytes (const U8* buf, const U8 len, bool doStop); #undef U8 /*---------------------------------------------------- end Twi.h ----------------------------------------------------*/ /*---------------------------------------------------- Twi.c avr0/1 Twi_function is global function, the rest are local and can be made static if wanted ----------------------------------------------------*/ #include <avr/io.h> #include <stdint.h> #include <stdbool.h> //#include "Twi.h" #define U8 uint8_t bool isAnyFlag () { return TWI0.MSTATUS & 0b11101100; } //rif,wif,hold,arblost,buserr bool isAnyErrFlag () { return TWI0.MSTATUS & 0b00001100; } //arblost,buserr void clearErrFlags () { TWI0.MSTATUS = 0b00001100; } //arblost,buserr void addressRead (U8 v) { TWI0.MADDR = (v<<1) | 1; } void addressWrite (U8 v) { TWI0.MADDR = v<<1; } void dataWR (U8 v) { TWI0.MDATA = v; } U8 dataRD () { return TWI0.MDATA; } void toStateIdle () { TWI0.MSTATUS = 0b11101101; } //clear all flags, IDLE void NACKstop () { TWI0.MCTRLB = 0b0111; } //NACK,stop void stop () { TWI0.MCTRLB = 0b0011; } //ACK,stop void ackActionACK () { TWI0.MCTRLB = 0b0000; } //ACk,no cmd void ACKread () { TWI0.MCTRLB = 0b0010; } //ACK,read bool isWriteOK () { return TWI0.MSTATUS == 0b01100010; } //wif,hold,rxack=0,owner = ok bool isReadOK () { return TWI0.MSTATUS == 0b10100010; } //rif,hold,rxack=0(from a previous write ack),owner = ok void Twi_baudReg (U8 v) { TWI0.MBAUD = v; } void Twi_on () { toStateIdle(); TWI0.MCTRLA = 1; } /* can make timeout whatever you want, is 256 in this case which is 256x whatever clocks this code needs (loop code + isAnyFlags() ) and is probably plenty an scl bit takes at most 200 clocks (when using 95 as baud value) so 9 bits = 1800 clocks 256x maybe 25 clocks for this loop code, so maybe 6000+ clocks as timeout, or about 30+ scl bit times */ bool waitTimeout () { U8 t = 0; while( ++t && !isAnyFlag() ); return t != 0; //if t==0, is timeout, t!=0 is any flag set } //if any error flags, just clear error flags, else send stop static void anyFail () { if( isAnyErrFlag() ) clearErrFlags(); //or toStateIdle() if want to force state else stop(); } //wait for timeout or any flag, //return true if flags are what we want static bool waitWriteOK () { if( waitTimeout() && isWriteOK() ) return true; anyFail(); return false; } //wait for timeout or any flag, //return true if flags are what we want static bool waitReadOK () { if( waitTimeout() && isReadOK() ) return true; anyFail(); return false; } // buf[0] = address, len = bytes to read into buf, doStop = true = stop when done // return true if bytes read == len bool Twi_readBytes (U8* buf, const U8 len, bool doStop) { U8 readLen = 0; ackActionACK(); //we ack reads addressRead(*buf); //start, ack, read 1 byte //if was ok, we already have 1 byte while( true ){ if( ! waitReadOK() ) return false; //error? *buf++ = dataRD(); //store data if( ++readLen >= len ) break; //done? ACKread(); //allow read next byte } if( doStop ) NACKstop(); //send stop? (also NACK last read) return true; } // buf[0] = address, len = bytes to write from buf, doStop = true = stop when done // return true if bytes written == len bool Twi_writeBytes (const U8* buf, const U8 len, bool doStop) { U8 writeLen = 0; addressWrite(*buf++); //start while( true ){ if( ! waitWriteOK() ) return false; //error? (or NACK) if( ++writeLen >= len ) break; //more? dataWR(*buf++); //send next byte } if( doStop ) stop(); //send stop? return true; } #undef U8 /*---------------------------------------------------- end Twi.c ----------------------------------------------------*/ // #include "Twi.h" // #include <stdint.h> uint16_t id = 0; int main(){ Twi_baudReg( 95 ); //100kHz@20MHz, 50kHz@10Mhz, etc. Twi_on(); //to IDLE, enable const uint8_t addr = 0x48; //TMP117 address uint8_t buf[2] = { addr, 15 }; //use same buffer for write and read in this case if( Twi_writeBytes(buf, 2, false) && //no stop, so read will Twi_readBytes(buf, 2, true) ) { //be a repeat start id = (buf[0]<<8) | buf[1]; //big endian to little endian //id was read ok } }
Become a Patron
Sponsor on GitHub
Donate via PayPal
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
About the author
Changelog
Version tree