puuu / usiwire Goto Github PK
View Code? Open in Web Editor NEWUSI based TWI/I2C library for Arduino
License: GNU Lesser General Public License v3.0
USI based TWI/I2C library for Arduino
License: GNU Lesser General Public License v3.0
hi,
I am trying the provided tests but failed to reproduce reliable test results.
the setup:
without modification to the example code, the test keeps failing. I guessed failures were caused by timing, and inserted some delay()
. after trials and errors, sometimes, the test passes, but not always. do you see anything I am missing? AUX_Callback
test fails in most cases, but now always. here is the diff, failed result, and successful one.
--- ../src/TestMaster/TestMaster.ino 2017-07-16 23:03:06.650753365 +0900
+++ src/TestMaster.ino 2017-07-17 00:29:23.520245148 +0900
@@ -611,7 +611,7 @@
Wire.write(CONTROL_ADDR);
Wire.write(AUX_STATE_ON << CONTROL_AUX_POS | slaveSleepMode);
assertEqual(Wire.endTransmission(), 0);
- delay(1);
+ delay(20);
if (slaveSleepMode) delay(2);
assertEqual(digitalRead(AUX_PIN), HIGH);
// AUX pin low
@@ -619,7 +619,7 @@
Wire.write(CONTROL_ADDR);
Wire.write(AUX_STATE_OFF << CONTROL_AUX_POS | slaveSleepMode);
assertEqual(Wire.endTransmission(), 0);
- delay(1);
+ delay(20);
if (slaveSleepMode) delay(2);
assertEqual(digitalRead(AUX_PIN), LOW);
}
@@ -639,8 +639,8 @@
Wire.write(i);
}
assertEqual(Wire.endTransmission(), 3);
- delay(1);
- if (slaveSleepMode) delay(2);
+ delay(10);
+ if (slaveSleepMode) delay(20);
assertEqual(digitalRead(AUX_PIN), HIGH);
// AUX pin low
Wire.beginTransmission(SLAVE_ADDR);
@@ -650,8 +650,8 @@
Wire.write(i);
}
assertEqual(Wire.endTransmission(), 3);
- delay(1);
- if (slaveSleepMode) delay(2);
+ delay(10);
+ if (slaveSleepMode) delay(20);
assertEqual(digitalRead(AUX_PIN), LOW);
}
}
@@ -672,8 +672,9 @@
assertEqual(Wire.endTransmission(false), 0); // send no Stop Condition
assertEqual(digitalRead(AUX_PIN), LOW); // still low
Wire.beginTransmission(SLAVE_ADDR);
+ delay(10);
assertEqual(Wire.endTransmission(false), 0); // repeat start
- delay(1);
+ delay(10);
if (slaveSleepMode) delay(2);
assertEqual(digitalRead(AUX_PIN), HIGH);
// request AUX pin low
@@ -684,7 +685,7 @@
assertEqual(digitalRead(AUX_PIN), HIGH); // still high
Wire.beginTransmission(SLAVE_ADDR);
assertEqual(Wire.endTransmission(false), 0); // repeat start
- delay(1);
+ delay(100);
if (slaveSleepMode) delay(2);
assertEqual(digitalRead(AUX_PIN), LOW);
}
@@ -717,8 +718,8 @@
assertEqual(digitalRead(AUX_PIN), LOW); // still low
Wire.beginTransmission(SLAVE_ADDR);
assertEqual(Wire.endTransmission(false), 0); // repeat start
- delay(1);
- if (slaveSleepMode) delay(2);
+ delay(10);
+ if (slaveSleepMode) delay(20);
assertEqual(digitalRead(AUX_PIN), HIGH);
// request AUX pin low
Wire.beginTransmission(SLAVE_ADDR);
@@ -730,6 +731,7 @@
assertEqual(Wire.endTransmission(false), 3); // send no Stop Condition
assertEqual(digitalRead(AUX_PIN), HIGH); // still high
Wire.beginTransmission(SLAVE_ADDR);
+ delay(10);
assertEqual(Wire.endTransmission(false), 0); // repeat start
delay(1);
if (slaveSleepMode) delay(2);
@@ -752,12 +754,14 @@
assertEqual(digitalRead(AUX_PIN), LOW); // low after write event
// simple read
assertEqual(Wire.requestFrom(SLAVE_ADDR, BYTE), BYTE);
+ delay(1000);
assertEqual(digitalRead(AUX_PIN), HIGH); // high after read event
// simple write
Wire.beginTransmission(SLAVE_ADDR);
Wire.write(BYTE_ADDR0);
Wire.write(DATA1);
assertEqual(Wire.endTransmission(), 0);
+ delay(100);
assertEqual(digitalRead(AUX_PIN), LOW); // low after write event
// read zero
Wire.beginTransmission(SLAVE_ADDR);
@@ -769,6 +773,7 @@
Wire.beginTransmission(SLAVE_ADDR);
Wire.write(ZERO_ADDR);
assertEqual(Wire.endTransmission(), 0);
+ delay(100);
assertEqual(digitalRead(AUX_PIN), LOW); // low after write event
//repeated start, read
Wire.beginTransmission(SLAVE_ADDR);
@@ -810,6 +815,7 @@
assertEqual(digitalRead(AUX_PIN), LOW); // low after write event
// simple read
assertEqual(Wire.requestFrom(SLAVE_ADDR, BYTE+1), BYTE+1);
+ delay(500);
assertEqual(digitalRead(AUX_PIN), HIGH); // high after read event
// simple write
Wire.beginTransmission(SLAVE_ADDR);
@@ -819,7 +825,7 @@
Wire.write(i);
}
assertEqual(Wire.endTransmission(), 3);
- delayMicroseconds(100);
+ delayMicroseconds(1000);
assertEqual(digitalRead(AUX_PIN), LOW); // low after write event
// read zero
Wire.beginTransmission(SLAVE_ADDR);
@@ -834,7 +840,7 @@
Wire.write(i);
}
assertEqual(Wire.endTransmission(), 3);
- delayMicroseconds(100);
+ delayMicroseconds(1000);
assertEqual(digitalRead(AUX_PIN), LOW); // low after write event
//repeated start, read
Wire.beginTransmission(SLAVE_ADDR);
--- Miniterm on /dev/ttyUSB0 9600,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Sleep mode off!
Initialize all tests: . SUCCESS!
SMBus_Quick_Read_Command: . SUCCESS!
SMBus_Quick_Write_Command: . SUCCESS!
SMBus_Receive_Byte: .... SUCCESS!
SMBus_Send_Byte: . SUCCESS!
SMBus_Read_Byte: ... SUCCESS!
SMBus_Read_Word: .... SUCCESS!
SMBus_Write_Byte: .... SUCCESS!
SMBus_Write_Word: ..... SUCCESS!
SMBus_Process_Call: ........ SUCCESS!
SMBus_Block_Read: ................. SUCCESS!
SMBus_Block_Write: ................. SUCCESS!
SMBus_Block_Process_Call: ........................ SUCCESS!
SMBus_Quick_Read_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Quick_Write_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Read_Byte_Multiple_Times: .................. SUCCESS!
Read_Too_Much: .... SUCCESS!
Read_Too_Less: ...................... SUCCESS!
Write_Too_Much: ............ SUCCESS!
Write_Too_Less: .......... SUCCESS!
AUX_On_Off: .................... SUCCESS!
AUX_On_Off_Repeated_Start: ........................................... SUCCESS!
AUX_Callback: ...FAILED!
0x0 != 0x1
Error state!
Sleep mode off!
Initialize all tests: . SUCCESS!
SMBus_Quick_Read_Command: . SUCCESS!
SMBus_Quick_Write_Command: . SUCCESS!
SMBus_Receive_Byte: .... SUCCESS!
SMBus_Send_Byte: . SUCCESS!
SMBus_Read_Byte: ... SUCCESS!
SMBus_Read_Word: .... SUCCESS!
SMBus_Write_Byte: .... SUCCESS!
SMBus_Write_Word: ..... SUCCESS!
SMBus_Process_Call: ........ SUCCESS!
SMBus_Block_Read: ................. SUCCESS!
SMBus_Block_Write: ................. SUCCESS!
SMBus_Block_Process_Call: ........................ SUCCESS!
SMBus_Quick_Read_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Quick_Write_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Read_Byte_Multiple_Times: .................. SUCCESS!
Read_Too_Much: .... SUCCESS!
Read_Too_Less: ...................... SUCCESS!
Write_Too_Much: ............ SUCCESS!
Write_Too_Less: .......... SUCCESS!
AUX_On_Off: .................... SUCCESS!
AUX_On_Off_Repeated_Start: ........................................... SUCCESS!
AUX_Callback: ...FAILED!
0x0 != 0x1
Error state!
Sleep mode off!
Initialize all tests: . SUCCESS!
SMBus_Quick_Read_Command: . SUCCESS!
SMBus_Quick_Write_Command: . SUCCESS!
SMBus_Receive_Byte: .... SUCCESS!
SMBus_Send_Byte: . SUCCESS!
SMBus_Read_Byte: ... SUCCESS!
SMBus_Read_Word: .... SUCCESS!
SMBus_Write_Byte: .... SUCCESS!
SMBus_Write_Word: ..... SUCCESS!
SMBus_Process_Call: ........ SUCCESS!
SMBus_Block_Read: ................. SUCCESS!
SMBus_Block_Write: ................. SUCCESS!
SMBus_Block_Process_Call: ........................ SUCCESS!
SMBus_Quick_Read_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Quick_Write_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Read_Byte_Multiple_Times: .................. SUCCESS!
Read_Too_Much: .... SUCCESS!
Read_Too_Less: ...................... SUCCESS!
Write_Too_Much: ............ SUCCESS!
Write_Too_Less: .......... SUCCESS!
AUX_On_Off: .................... SUCCESS!
AUX_On_Off_Repeated_Start: ........................................... SUCCESS!
AUX_Callback: ...FAILED!
0x0 != 0x1
Error state!
Sleep mode off!
Initialize all tests: . SUCCESS!
SMBus_Quick_Read_Command: . SUCCESS!
SMBus_Quick_Write_Command: . SUCCESS!
SMBus_Receive_Byte: .... SUCCESS!
SMBus_Send_Byte: . SUCCESS!
SMBus_Read_Byte: ... SUCCESS!
SMBus_Read_Word: .... SUCCESS!
SMBus_Write_Byte: .... SUCCESS!
SMBus_Write_Word: ..... SUCCESS!
SMBus_Process_Call: ........ SUCCESS!
SMBus_Block_Read: ................. SUCCESS!
SMBus_Block_Write: ................. SUCCESS!
SMBus_Block_Process_Call: ........................ SUCCESS!
SMBus_Quick_Read_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Quick_Write_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Read_Byte_Multiple_Times: .................. SUCCESS!
Read_Too_Much: .... SUCCESS!
Read_Too_Less: ...................... SUCCESS!
Write_Too_Much: ............ SUCCESS!
Write_Too_Less: .......... SUCCESS!
AUX_On_Off: .................... SUCCESS!
AUX_On_Off_Repeated_Start: ........................................... SUCCESS!
AUX_Callback: ................... SUCCESS!
Fill_Slave_RX_Buffer: ...................... SUCCESS!
AUX_On_Off_Repeated_Start_NACK: ........................................... SUCCESS!
AUX_Callback_NACK: .................. SUCCESS!
AUX_On_Off_NACK: .................... SUCCESS!
All test finished!
Idle sleep mode!
Initialize all tests: . SUCCESS!
SMBus_Quick_Read_Command: . SUCCESS!
SMBus_Quick_Write_Command: . SUCCESS!
SMBus_Receive_Byte: .... SUCCESS!
SMBus_Send_Byte: . SUCCESS!
SMBus_Read_Byte: ... SUCCESS!
SMBus_Read_Word: .... SUCCESS!
SMBus_Write_Byte: .... SUCCESS!
SMBus_Write_Word: ..... SUCCESS!
SMBus_Process_Call: ........ SUCCESS!
SMBus_Block_Read: ................. SUCCESS!
SMBus_Block_Write: ................. SUCCESS!
SMBus_Block_Process_Call: ........................ SUCCESS!
SMBus_Quick_Read_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Quick_Write_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Read_Byte_Multiple_Times: .................. SUCCESS!
Read_Too_Much: .... SUCCESS!
Read_Too_Less: ...................... SUCCESS!
Write_Too_Much: ............ SUCCESS!
Write_Too_Less: .......... SUCCESS!
AUX_On_Off: .................... SUCCESS!
AUX_On_Off_Repeated_Start: ........................................... SUCCESS!
AUX_Callback: ................... SUCCESS!
Fill_Slave_RX_Buffer: ...................... SUCCESS!
AUX_On_Off_Repeated_Start_NACK: ........................................... SUCCESS!
AUX_Callback_NACK: .................. SUCCESS!
AUX_On_Off_NACK: .................... SUCCESS!
All test finished!
Power down sleep mode!
Initialize all tests: . SUCCESS!
SMBus_Quick_Read_Command: . SUCCESS!
SMBus_Quick_Write_Command: . SUCCESS!
SMBus_Receive_Byte: .... SUCCESS!
SMBus_Send_Byte: . SUCCESS!
SMBus_Read_Byte: ... SUCCESS!
SMBus_Read_Word: .... SUCCESS!
SMBus_Write_Byte: .... SUCCESS!
SMBus_Write_Word: ..... SUCCESS!
SMBus_Process_Call: ........ SUCCESS!
SMBus_Block_Read: ................. SUCCESS!
SMBus_Block_Write: ................. SUCCESS!
SMBus_Block_Process_Call: ........................ SUCCESS!
SMBus_Quick_Read_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Quick_Write_Command_Wrong_Addr: ..... SUCCESS!
SMBus_Read_Byte_Multiple_Times: .................. SUCCESS!
Read_Too_Much: .... SUCCESS!
Read_Too_Less: ...................... SUCCESS!
Write_Too_Much: ............ SUCCESS!
Write_Too_Less: .......... SUCCESS!
AUX_On_Off_Repeated_Start: ........................................... SUCCESS!
AUX_Callback: ................... SUCCESS!
Fill_Slave_RX_Buffer: ...................... SUCCESS!
AUX_On_Off_Repeated_Start_NACK: ........................................... SUCCESS!
AUX_Callback_NACK: .................. SUCCESS!
All test finished!
I tried to use this library on an ATtiny85 at the default 1 MHz and can't get the slave to respond. I checked on the oscilloscope and it seems that the SDA hold times are really short (check picture).
Comparison with ESP-WROOM-32 Wire library:
Is there any way to add a delay somewhere between the negative edges of SCL and data change on SDA?
Is this library usable for the SPI communication as well (Three-wire Mode)?
I'm trying to use a SPI accelerometer with the ATtiny1634.
Thanks
I see in usi_io.h:
# define PORT_USI_SDA PORTB0
# define PORT_USI_SCL PORTB2
# define PIN_USI_SDA PINB0
# define PIN_USI_SCL PINB2
can I change them to another pins?
I need
# define PORT_USI_SDA PORTB3
# define PORT_USI_SCL PORTB4
# define PIN_USI_SDA PINB3
# define PIN_USI_SCL PINB4
thanks!
When working with the Watchdog, code has to be executed directly after waking up, otherwise the watchdog resets the Microcontroller.
When USI_Start_Condition_ISR() is called, then the processor might have been woken from any sleep mode, which means that the Watchdog has to be turned off very early during its execution.
I propose a callback for this. I have tested an implementation of this with my current application ATTinyDaemon with different communication partners (RPi3, RPI Zero...) and it works without adverse effects. Here is what my implementation looks like in USI_TWI_Slave.c, line 161ff:
__interrupt void USI_Start_Condition_ISR(void)
#endif
{
unsigned char tmpPin; // Temporary variable for pin state
unsigned char tmpRxHead; // Temporary variable to store volatile
if (USI_TWI_On_Slave_Interrupt) {
USI_TWI_On_Slave_Interrupt();
}
// call slave receive callback on repeated start
...
together with adding the attribute in TWI_Slave.h, line 41,
void (*USI_TWI_On_Slave_Interrupt)(void);
a method declaration in USIWire.h, line 66
void onInterrupt( void (*)(void) );
and the following in USIWire.c, line 282ff:
// sets function called on slave interrupt
void USIWire::onInterrupt( void (*function)(void) ) {
USI_TWI_On_Slave_Interrupt = function;
}
How can I send more that 32 bytes between two Attiny85s? I'm getting nack after sending byte 16.
Hi,
This is not so much of an issue than it is a question for clarification. If I understand the purpose of this library correct, this library utilizes Universal Serial Interface (USI) to provide I2C Master and Slave functionality for the ATtiny family (those having USI capabilities), correct? In other words, when programming an ATtiny (say, ATtiny24a, for instance) using Arduino as an ISP, USIWire will allow the ATtiny (disconnected from the Arduino and running standalone) to act as a master and communicate with a slave, correct?
Also, is #ifdef ESP8266 // default value of 230 us is too short Wire.setClockStretchLimit(1500); #endif
necessary for communication with ANY slave?
Thanks so much!
Jonathan Lee
[email protected]
I have a sketch on my attiny where I need to change between being an i2c master and a slave. This doesn't work.
If I only work as a master and poll some sensors - it works fine.
If I only work as a slave and get polled from another master it works fine.
If I want the functionality of being both a master and a slave (eg switching role with a button on the attiny), then the slave fails. I tried the Wire.end() when I want to go from being slave to master, but without luck.
Any ideas?
Best regards,
Alex.
Hy
I tried to compile Example Mastercode and a Arduino stock wire example with "#include <USIWire.h>" for Attiny2313 always get the error code is to big.
Am I doing something wrong?
Error
<Sketch uses 2518 bytes (122%) of program storage space. Maximum is 2048 bytes.
Global variables use 200 bytes (156%) of dynamic memory, leaving -72 bytes for local variables. Maximum is 128 bytes.
Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.
Error compiling for board ATtiny2313/4313.
Thanks for help.
I've tried the examples with my ATTiny2313, and I get this
Sketch uses 3150 bytes (153%) of program storage space. Maximum is 2048 bytes.text section exceeds available space in board
Global variables use 191 bytes (149%) of dynamic memory, leaving -63 bytes for local variables. Maximum is 128 bytes.
Do you know, what i2c speed is able to use with Attiny85 (1Mhz internal oscillator)
Here is some text with 33kHz limit: https://github.com/felias-fogg/SoftI2CMaster
Can you add change speed option? Thanks a lot!
Is there any compatibility issue with this library and Arduino 1.8.12?
Without Usiwire library I get error about missing library (as expected)
In file included from /Users/adrianmihalko/Downloads/attiny_daemon-master/firmware/ATTinyDaemon/ATTinyDaemon.ino:1:0:
ATTinyDaemon.h:1:10: fatal error: USIWire.h: No such file or directory
#include <USIWire.h>
^~~~~~~~~~~
compilation terminated.
exit status 1
USIWire.h: No such file or directory
Now, I install library as Sketch - Include Library - Add .ZIP Library and I choose USIWire-0.1.0.zip.
I click Very/Compile and I get the error:
In file included from /Users/adrianmihalko/Documents/Arduino/libraries/USIWire-0.1.0/src/USI_TWI_Master/USI_TWI_Master.h:76:0,
from /Users/adrianmihalko/Documents/Arduino/libraries/USIWire-0.1.0/src/USIWire.cpp:27:
/Users/adrianmihalko/Documents/Arduino/libraries/USIWire-0.1.0/src/USI_TWI_Master/usi_io.h:1:1: error: expected unqualified-id before '.' token
../USI_TWI_Slave/usi_io.h
^
/Users/adrianmihalko/Documents/Arduino/libraries/USIWire-0.1.0/src/USIWire.cpp: In member function 'void USIWire::begin()':
/Users/adrianmihalko/Documents/Arduino/libraries/USIWire-0.1.0/src/USIWire.cpp:55:3: error: 'USI_TWI_Master_Initialise' was not declared in this scope
USI_TWI_Master_Initialise();
^~~~~~~~~~~~~~~~~~~~~~~~~
/Users/adrianmihalko/Documents/Arduino/libraries/USIWire-0.1.0/src/USIWire.cpp:55:3: note: suggested alternative: 'USI_TWI_Slave_Initialise'
USI_TWI_Master_Initialise();
^~~~~~~~~~~~~~~~~~~~~~~~~
USI_TWI_Slave_Initialise
exit status 1
Error compiling for board ATtiny25/45/85.
I am not alone with this problem:
Hi!
I'm currently working on adding Arduino support for ATmega165/325/645 and ATmega169/329/649 through an Arduino core called MegaCore. The catch is that they don't have a "standard" TWI interface, but USI instead.
I was wondering. Is it OK for you if I bundle a modified version of this library together with MegaCore? I'll of course give you the credit for your excellent work. The only modifications I'm planning to use is to change the class name from USIWire
to TwoWire
to make it compatible with other libraries that expect a TwoWire
object. I'll also add a little preprocessor glue so that users can include Wire.h, and it automatically includes the USIWire library.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.