SoftI2CMaster with megaTinyCore #664
Replies: 6 comments 4 replies
-
megaTinyCore does not have softI2CMaster built in because these parts are
all capable of acting as master and slave, and there is no reason for a
flaky software implementation.
It was added to ATTinyCore because there are 3 parts that not only don't
have hardware I2C master, (only the tinyx8 there does), but also doesn't
have a USI.
Therefore, before that was added, trying to #include Wire.h would error
out, and people had no prayer of using a library that made use of Wire .h
for I2C on those parts. Since two of the three parts (the 841 and 441 - the
828 being the third, and the clear runt of the litter) were the parts that
initially motivated me to make ATTinyCore, and are otherwise among the best
classic tinies, a solution was needed.
The people on the USI parts also complained about the fact that Wire didn't
work, and how they had to use USIWire or some other similar library, **and
then modify the library for the I2C device to use that library**.
That situation was just awful, and everyone involved including myself hated
it.
And so we lashed together the three different versions of Wire, made the
API match, and used #ifdefs to select the one that works on the available
hardware. The same thing was done for SPI, since some parts have
harware SPI (x8, x7, x41 and 1634), but others don't.
I would not expect softI2CMaster to work on a "modern AVR" without serious
work by someone who understood the code deeply (ie,not me). Also,
softI2CMaster ah... kind of sucked. The error reporting is bad, it hogs
space, you can't configure the clock speed (the function call is there, but
it's just a do-nothing to let sketches compile, because for most users
then, the alternative was "give up on using the tinyAVR parts completely"
(a lot of people re not comfortable touching the libraries.
**I don't really understand why you want softI2CMaster on a modern AVR,
period** - since I think 2.4. or 2.5, we have supported simultaneously
acting as a master to and slave on the same I2C bus to handle the use case
you are talking about. See the documentation for the Wire library included
with the core. It has a lot more functionality (and takes like half the
flash) than the "stock" version - it has been almost totally reimplemented.
it's all done with real hardware TWI, and it works considerably better than
SoftI2CMaser ever did.
…On Wed, Mar 9, 2022 at 10:15 AM Ed Mandy ***@***.***> wrote:
I have a project where I want my megaTinyCore attiny to be an i2c slave,
but I want it to aggregate data from its own GPIO and some other i2c slaves
(and then serve that data over i2c to the main host system). I will likely
be using 2-series parts for this (attiny427 and attiny1627).
I thought that using the Wire.h library for serving the data to the host
would be the best approach.
To read data from other i2c slaves, I thought that the SoftI2CMaster
library would be the best option. Please tell me if there are other good
options that I should consider.
I had problems using SoftI2CMaster, as the assembly code didn't like
working with megaTinyCore. In my early searching on the problem, I noticed
that ATTinyCore has a SoftI2CMaster library included (
https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/libraries/Wire/src/SoftI2CMaster.h),
but megaTinyCore does not. That makes me wonder why.
Moving on, I'm no AVR assembly expert, but I dug into it a bit. It seems
that the inline ASM constraints were the main issue here. I dug a bit, and
I figured that the memory mapping of the GPIO registers was the problem
here.
To use SoftI2CMaster, you have to define the pins like this.
#define SDA_PIN 3
#define SDA_PORT PORTA
#define SCL_PIN 5
#define SCL_PORT PORTB
#include <SoftI2CMaster.h>
I tried switching that to VPORTA or VPORTB, becuase the PORTx mappings are
larger than 1 byte (which the inline ASM constraints didn't like). That
didn't work.
Anyway, fast forward a bit, and here's what I came up with that seems to
work (but I think is a hack that should be implemented in a better way for
mass consumption).
I changed the library's SoftI2CMaster.h to add an #if around the
definitions like this.
#if !(defined(SDA_DDR) && defined(SDA_OUT) && defined(SDA_IN) && defined(SCL_DDR) && defined(SCL_OUT) && defined(SCL_IN))
#define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT _SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT _SFR_IO_ADDR(SCL_PORT)
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)
#endif
Then, in my .INO, I would explicity set these (instead of setting SDA_PORT
and SCL_PORT). That looks something like this.
#define SDA_DDR 0x00 //VPORTA_DIR = 0x00, VPORTB_DIR = 0x04, VPORTC_DIR = 0x08
#define SCL_DDR 0x00 //VPORTA_DIR = 0x00, VPORTB_DIR = 0x04, VPORTC_DIR = 0x08
#define SDA_OUT 0x01 //VPORTA_OUT = 0x01, VPORTB_OUT = 0x05, VPORTC_OUT = 0x09
#define SCL_OUT 0x01 //VPORTA_OUT = 0x01, VPORTB_OUT = 0x05, VPORTC_OUT = 0x09
#define SDA_IN 0x02 //VPORTA_IN = 0x02, VPORTB_IN = 0x06, VPORTC_IN = 0x0A
#define SCL_IN 0x02 //VPORTA_IN = 0x02, VPORTB_IN = 0x06, VPORTC_IN = 0x0A
#define SDA_PIN 5
#define SCL_PIN 4
#define I2C_FASTMODE 1
#include <SoftI2CMaster.h>
So, I hope that's helpful. From my quick research, I think this would work
for all the megaTinyCore parts, but I also think there's likely a much
better way to do this. I would guess that SoftI2CMaster.h could be made to
use the "#define SDA_PORT PORTA" method and map that to VPORTA with the
proper offsets for the _DIR, _OUT, and _IN registers.
My point here is to start some discussion in case this helps anyone else
or helps to add SoftI2CMaster into megaTinyCore.
Also, *I would still like to know if SoftI2CMaster is even the right
thing I should be using.*
Thanks!
—
Reply to this email directly, view it on GitHub
<#664>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABTXEW6AMZXYDGPNOUZBNADU7C6CTANCNFSM5QJ24CFA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
--
____________
Spence Konde
Azzy’S Electronics
New products! Check them out at tindie.com/stores/DrAzzy
GitHub: github.com/SpenceKonde
ATTinyCore <https://github.com/SpenceKonde/ATTinyCore>: Arduino support for
all pre-2016 tinyAVR with >2k flash!
megaTinyCore <https://github.com/SpenceKonde/megaTinyCore>: Arduino support
for all post-2016 tinyAVR parts!
DxCore <https://github.com/SpenceKonde/DxCore>: Arduino support for the AVR
Dx-series parts, the latest and greatest from Microchip!
Contact: ***@***.***
|
Beta Was this translation helpful? Give feedback.
-
Oh - and don't use anything from the masteer branch of attinycore, it in
not where any of the updates are. 2.0.0-dev will replace master within a
few weeks, encompassing 18 months of changes, some of them being the
largest in the history of that core. Wire has had major refactoring done
twice in that time iirc
…____________
Spence Konde
Azzy’S Electronics
New products! Check them out at tindie.com/stores/DrAzzy
GitHub: github.com/SpenceKonde
ATTinyCore: Arduino support for almost every ATTiny microcontroller
Contact: ***@***.***
On Wed, Mar 9, 2022, 10:15 Ed Mandy ***@***.***> wrote:
I have a project where I want my megaTinyCore attiny to be an i2c slave,
but I want it to aggregate data from its own GPIO and some other i2c slaves
(and then serve that data over i2c to the main host system). I will likely
be using 2-series parts for this (attiny427 and attiny1627).
I thought that using the Wire.h library for serving the data to the host
would be the best approach.
To read data from other i2c slaves, I thought that the SoftI2CMaster
library would be the best option. Please tell me if there are other good
options that I should consider.
I had problems using SoftI2CMaster, as the assembly code didn't like
working with megaTinyCore. In my early searching on the problem, I noticed
that ATTinyCore has a SoftI2CMaster library included (
https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/libraries/Wire/src/SoftI2CMaster.h),
but megaTinyCore does not. That makes me wonder why.
Moving on, I'm no AVR assembly expert, but I dug into it a bit. It seems
that the inline ASM constraints were the main issue here. I dug a bit, and
I figured that the memory mapping of the GPIO registers was the problem
here.
To use SoftI2CMaster, you have to define the pins like this.
#define SDA_PIN 3
#define SDA_PORT PORTA
#define SCL_PIN 5
#define SCL_PORT PORTB
#include <SoftI2CMaster.h>
I tried switching that to VPORTA or VPORTB, becuase the PORTx mappings are
larger than 1 byte (which the inline ASM constraints didn't like). That
didn't work.
Anyway, fast forward a bit, and here's what I came up with that seems to
work (but I think is a hack that should be implemented in a better way for
mass consumption).
I changed the library's SoftI2CMaster.h to add an #if around the
definitions like this.
#if !(defined(SDA_DDR) && defined(SDA_OUT) && defined(SDA_IN) && defined(SCL_DDR) && defined(SCL_OUT) && defined(SCL_IN))
#define SDA_DDR (_SFR_IO_ADDR(SDA_PORT) - 1)
#define SCL_DDR (_SFR_IO_ADDR(SCL_PORT) - 1)
#define SDA_OUT _SFR_IO_ADDR(SDA_PORT)
#define SCL_OUT _SFR_IO_ADDR(SCL_PORT)
#define SDA_IN (_SFR_IO_ADDR(SDA_PORT) - 2)
#define SCL_IN (_SFR_IO_ADDR(SCL_PORT) - 2)
#endif
Then, in my .INO, I would explicity set these (instead of setting SDA_PORT
and SCL_PORT). That looks something like this.
#define SDA_DDR 0x00 //VPORTA_DIR = 0x00, VPORTB_DIR = 0x04, VPORTC_DIR = 0x08
#define SCL_DDR 0x00 //VPORTA_DIR = 0x00, VPORTB_DIR = 0x04, VPORTC_DIR = 0x08
#define SDA_OUT 0x01 //VPORTA_OUT = 0x01, VPORTB_OUT = 0x05, VPORTC_OUT = 0x09
#define SCL_OUT 0x01 //VPORTA_OUT = 0x01, VPORTB_OUT = 0x05, VPORTC_OUT = 0x09
#define SDA_IN 0x02 //VPORTA_IN = 0x02, VPORTB_IN = 0x06, VPORTC_IN = 0x0A
#define SCL_IN 0x02 //VPORTA_IN = 0x02, VPORTB_IN = 0x06, VPORTC_IN = 0x0A
#define SDA_PIN 5
#define SCL_PIN 4
#define I2C_FASTMODE 1
#include <SoftI2CMaster.h>
So, I hope that's helpful. From my quick research, I think this would work
for all the megaTinyCore parts, but I also think there's likely a much
better way to do this. I would guess that SoftI2CMaster.h could be made to
use the "#define SDA_PORT PORTA" method and map that to VPORTA with the
proper offsets for the _DIR, _OUT, and _IN registers.
My point here is to start some discussion in case this helps anyone else
or helps to add SoftI2CMaster into megaTinyCore.
Also, *I would still like to know if SoftI2CMaster is even the right
thing I should be using.*
Thanks!
—
Reply to this email directly, view it on GitHub
<#664>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABTXEW6AMZXYDGPNOUZBNADU7C6CTANCNFSM5QJ24CFA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
I'm no I2C/TWI expert, so this is all good info. I can look more into using the attiny as a slave and a master on the same bus. However, my host system is the Raspberry Pi, and the datasheet for the BCM that we are testing with shows that it can do "I2C single master only operation". I assume that means that the Pi will not be happy if there are other devices acting as a master on the I2C bus. I had hoped to insulate this by having a "main" i2c bus and then a secondary i2c bus where the attiny talked to the other peripherals (that the Pi didn't need to talk to). I'm definitely open to suggestions. Thank you very much! P.S. I'm not using attinycore at all. I'm only using megaTinyCore. I just came across the SoftI2CMaster stuff in attinycore when I was trying to figure out what was going wrong. |
Beta Was this translation helpful? Give feedback.
-
The tricky thing about that term is that it sometimes means what you
interpreted it as. Other times, it means the device in question acting as
either a master or slave.
The AVR Dx parts address this with "dual mode" which moves the slave
function tona different pair of pins. But it's not offered on the tinies.
If they eve5 get around to releasing the DD- series, that will be available
in 14 and 20 packages (and support dual mode) and will come in 16, 32, and
64k flash sizes. That obviously raises some questions about the future of
the tinyavr product line, particularly seeing as there would be a part
number conflict between a furure 3-series part with 16k flash and 14 pins
ans an existing part...
…____________
Spence Konde
Azzy’S Electronics
New products! Check them out at tindie.com/stores/DrAzzy
GitHub: github.com/SpenceKonde
ATTinyCore: Arduino support for almost every ATTiny microcontroller
Contact: ***@***.***
On Wed, Mar 9, 2022, 12:55 Ed Mandy ***@***.***> wrote:
I'm no I2C/TWI expert, so this is all good info. I can look more into
using the attiny as a slave and a master on the same bus. However, my host
system is the Raspberry Pi, and the datasheet for the BCM that we are
testing with shows that it can do "I2C single master only operation". I
assume that means that the Pi will not be happy if there are other devices
acting as a master on the I2C bus.
I had hoped to insulate this by having a "main" i2c bus and then a
secondary i2c bus where the attiny talked to the other peripherals (that
the Pi didn't need to talk to).
I'm definitely open to suggestions.
Thank you very much!
P.S. I'm not using attinycore at all. I'm only using megaTinyCore. I just
came across the SoftI2CMaster stuff in attinycore when I was trying to
figure out what was going wrong.
—
Reply to this email directly, view it on GitHub
<#664 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABTXEW6I7V6F2TA2AEAVJFLU7DQYZANCNFSM5QJ24CFA>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
You are receiving this because you commented.Message ID:
***@***.***
com>
|
Beta Was this translation helpful? Give feedback.
-
"So, I hope that's helpful. "
|
Beta Was this translation helpful? Give feedback.
-
I created a discussion about this at SoftI2CMaster's Github page. |
Beta Was this translation helpful? Give feedback.
-
I have a project where I want my megaTinyCore attiny to be an i2c slave, but I want it to aggregate data from its own GPIO and some other i2c slaves (and then serve that data over i2c to the main host system). I will likely be using 2-series parts for this (attiny427 and attiny1627).
I thought that using the Wire.h library for serving the data to the host would be the best approach.
To read data from other i2c slaves, I thought that the SoftI2CMaster library would be the best option. Please tell me if there are other good options that I should consider.
I had problems using SoftI2CMaster, as the assembly code didn't like working with megaTinyCore. In my early searching on the problem, I noticed that ATTinyCore has a SoftI2CMaster library included (https://github.com/SpenceKonde/ATTinyCore/blob/master/avr/libraries/Wire/src/SoftI2CMaster.h), but megaTinyCore does not. That makes me wonder why.
Note that I am using the latest code from https://github.com/felias-fogg/SoftI2CMaster which has been updated recently and fairly frequently, and I only mentioned the ATTinyCore link, because it lead me to believe that SpenceKonde might have some knowledge of the library and how it relates to attiny parts. It works! I just need to make the mods below.
Moving on, I'm no AVR assembly expert, but I dug into it a bit. It seems that the inline ASM constraints were the main issue here. I dug a bit, and I figured that the memory mapping of the GPIO registers was the problem here.
To use SoftI2CMaster, you have to define the pins like this.
I tried switching that to VPORTA or VPORTB, becuase the PORTx mappings are larger than 1 byte (which the inline ASM constraints didn't like). That didn't work.
Anyway, fast forward a bit, and here's what I came up with that seems to work (but I think is a hack that should be implemented in a better way for mass consumption).
I changed the library's SoftI2CMaster.h to add an #if around the definitions like this.
Then, in my .INO, I would explicity set these (instead of setting SDA_PORT and SCL_PORT). That looks something like this.
So, I hope that's helpful. From my quick research, I think this would work for all the megaTinyCore parts, but I also think there's likely a much better way to do this. I would guess that SoftI2CMaster.h could be made to use the "#define SDA_PORT PORTA" method and map that to VPORTA with the proper offsets for the _DIR, _OUT, and _IN registers.
My point here is to start some discussion in case this helps anyone else or helps to add SoftI2CMaster into megaTinyCore.
Also, I would still like to know if SoftI2CMaster is even the right thing I should be using.
Thanks!
Note: I should have mentioned this up front, so I'll add it up there for anyone that comes along. I am using the latest code from https://github.com/felias-fogg/SoftI2CMaster which has been updated recently and fairly frequently. I think that my mention of the link to SoftI2CMaster.h in ATTinyCore may have have been misleading. I only mentioned that in reference to searching for SoftI2CMaster for attiny parts and figuring that SpenceKonde must have had some knowledge of it.
Beta Was this translation helpful? Give feedback.
All reactions