Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand your library in order for it to could be used with esp8266 #26

Open
elC0mpa opened this issue Nov 27, 2019 · 4 comments
Open

Expand your library in order for it to could be used with esp8266 #26

elC0mpa opened this issue Nov 27, 2019 · 4 comments

Comments

@elC0mpa
Copy link

elC0mpa commented Nov 27, 2019

In this issue #10 you said that the esp8266 Wire library is already a software library. This is true, but it isn't able to create multiple i2c buses. You referenced another library, which works fine but it is not compatible with Wire original library, so if you use a device library which receives a pointer to a Wire object, you must modify the library (something i already did). Because of this, I think that if you improve your library in order for it to be used with esp8266, it will be the BEST SoftwareWire library. I hope you will think about it. I will be waiting for your answer

@Testato
Copy link
Owner

Testato commented Nov 27, 2019

One of the idea about our library is to write a second working modality that will use digitalwrite() instead of registry manipulation.
This will slow down the speed but will work on all mcu with an Arduino core.

Expecially on 32bit world, that normally have a big cpu freq, the speed problem will non be a problem, we can contunue to use the lib like now on 8 bit and with the new modality on 32bit cpu.

@elC0mpa
Copy link
Author

elC0mpa commented Nov 27, 2019

Thanks for your answer, let me know if i can Help you in something

@Koepel
Copy link
Collaborator

Koepel commented Nov 27, 2019

My idea was to use the low-level functions of the OneWire library for other processors. However, I did some tests with the 48MHz SAMD21 processor (Arduino Zero, M0, and many MKR boards) and the digitalWrite() and digitalRead() seems fast enough for those. Using the normal Arduino functions as a fallback might be good enough for most faster boards.

It could be something like this:

#ifdef __AVR__

// Sets SDA low and drives output.
// The SDA may not be HIGH output, so first the output register is cleared 
// (clearing internal pullup resistor), after that the SDA is set as output.
#define i2c_sda_lo()              \
  *_sdaPortReg &= ~_sdaBitMask;   \
  *_sdaDirReg  |=  _sdaBitMask;
  

// sets SCL low and drives output.
// The SCL may not be HIGH output, so first the output register is cleared 
// (clearing internal pullup resistor), after that the SCL is set as output.
#define i2c_scl_lo()              \
  *_sclPortReg &= ~_sclBitMask;   \
  *_sclDirReg  |=  _sclBitMask;


// Set SDA high and to input (releases pin) (i.e. change to input,turnon pullup).
// The SDA may not become HIGH output. Therefor the pin is first set to input,
// after that, a pullup resistor is switched on if needed.
#define i2c_sda_hi()              \
  *_sdaDirReg &= ~_sdaBitMask;    \
  if(_pullups) { *_sdaPortReg |= _sdaBitMask; }


// set SCL high and to input (releases pin) (i.e. change to input,turnon pullup)
// The SCL may not become HIGH output. Therefor the pin is first set to input,
// after that, a pullup resistor is switched on if needed.
#define i2c_scl_hi()              \
  *_sclDirReg &= ~_sclBitMask;    \
  if(_pullups) { *_sclPortReg |= _sclBitMask; }


// Read the bit value of the pin
// Note that is the pin can also be read when it is an output.
#define i2c_sda_read()   ((uint8_t) (*_sdaPinReg & _sdaBitMask) ? 1 : 0)
#define i2c_scl_read()   ((uint8_t) (*_sclPinReg & _sclBitMask) ? 1 : 0)

#else

// Fall back to default functions.

#define i2c_sda_lo()      digitalWrite(_sdaPin, LOW); pinMode(_sdaPin, OUTPUT)
#define i2c_scl_lo()      digitalWrite(_sclPin, LOW); pinMode(_sclPin, OUTPUT)
#define i2c_sda_hi()      pinMode(_sdaPin, _pullups ? INPUT_PULLUP : INPUT)
#define i2c_scl_hi()      pinMode(_sclPin, _pullups ? INPUT_PULLUP : INPUT)
#define i2c_sda_read()    digitalRead(_sdaPin)
#define i2c_scl_read()    digitalRead(_sclPin)

#endif

The ::setClock() needs a better formula, I did some tests with this:

#ifdef __AVR__
  // The _i2cdelay is an uint16_t
  _i2cdelay = ( (F_CPU / 40L) / clock );               // The delay in microseconds, '40' is for this code.
  unsigned int delayByCode = (F_CPU / 5000000L);       // Add some delay for the code, just a guess
  
  if( _i2cdelay > delayByCode)
    _i2cdelay -= delayByCode;
  else
    _i2cdelay = 0;
#else
  _i2cdelay = (F_CPU / 10L) / clock;         // set to a safe number
#endif

@elC0mpa
Copy link
Author

elC0mpa commented Nov 27, 2019

Your idea looks nice @Koepel, now i am busy but maybe in one or two weeks i could Help you. If i do this, I will make you a pull request. Thanks for sharing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants