Libavr32 i2c update

i’ve made a breaking-change in i2c processing framework, in order to allow multi-byte transmissions. previously three bytes were packed into an 1 byte index and 16 bit data word, which fit nicely into the event system, though that wasn’t really terribly important.


process_ii(uint8_t i, int d)

is now:

process_ii(uint8_t *data, uint8_t l)

where l is length and *data points to the buffer. it’s very easy to create backwards-compatibility by simply changing the function definitions then adding this to the top of the function:

	uint8_t i;
	int d;

	i = data[0];
	d = (data[1] << 8) + data[2];

i’ve already pushed changes to libavr32, along with the trilogy firmwares.

@bpcmusic @scanner_darkly will be interested in this. very minor update.

but now we can have variable-length i2c packets and the world has opened up widely.

master rx functions are in there also.


excellent! i’ll make the change this weekend, need to also update orca to use libavr32 as a submodule.

this reminds me - when i did the implementation for orca II commands i had problems passing negative values, i think that could be due to bitshifting in tele_ii and handler_II. i’ll take a look at it.

how do we update submodules for the trilogy/tt firmwares? it’s just the submodule checkin # that needs to be updated and then pushed / pulled / merged, right?

thanks @tehn - i’ll merge the repo and integrate over the weekend.

me too; in my implementation for bipolar voltage output i simply moved the values positive on send and moved them back down on receive. i had inconsistent results casting, so ultimately i did it the old fashioned way. :slight_smile:

still trying to figure out why the master rx function is locking the teletype when implemented without a tx before it on the metro script. anyone know of anything fundamental going on when running a script from a timer vs a trigger that would lock a rx command (vs an rx command that follows a tx command)?


i think a simple pull should update the trilogy modules. it’ll resolve the correct checkout.

i can’t think of anything that would cause problems off the top of my head, so i’ll need to look more closely at the code. have you dug into the TT source as to how the scripts are getting executed? check if things are happening in an event vs. interrupt etc.

heads up @bpcmusic that i also updated the master_rx functions for arbitrary buffer length.

tried updating my whitewhale fork:

git merge upstream/master```

at which point it showed that libavr32 was changed, i assumed it was the submodule revision update and just pushed it to my master branch. but looking at it now the change in libavr32 was to change it back to the older revision... so now i'm confused - should i have just reset this change instead of pushing? and do i just revert this latest checkin now?

edit: just reverted the libavr32 change and pushed the revert as this seemed like the safest option. hopefully this won't break things down the road!

it shouldn’t. i changed more things in the i2c lib but they are cosmetic or debugging strings. everything compiles.

yeah, i didn’t mean the code, just the git history. looks like it should be okay, now i just need to rebase my dev branch from my master. still learning my way around git!

…looks like it worked. still not sure why it would pull/merge the revision change for libavr32 from upstream master but then report that i had a local change, as if i manually changed it back to the old revision #.

Submodules don’t update their code automatically with fetch / merge / rebase / pull. You need to git submodule update.

A wrote a post up about it a few months back before we split the repos up.

1 Like

yeah, i should re-read it to refresh my memory - i guess what happened was i didn’t update the submodule, so then from the git’s point of view it was like i had a local change.

you can also just pull from the libavr32 folder


cd whitewhale/libavr32
git pull
1 Like

Yep, though I think that will fetch the current HEAD rather than the commit pointed to by the parent repo.

ah, you’re correct. good clarification.

so that would be the workflow if i want to switch to the latest submodule revision, correct? so just pull from the submodule directory which updates it to the HEAD revision, and if i push it it will basically update the revision number my repo is using for the submodule?

You need to commit the change to the parent repo too, e.g.

cd orca       # or wherever your git repo is

git status    # the following assumes this comes back as clean

cd libavr32   # go into the submodule directory
git remote -v # make sure you know where the pull is coming from!
git pull      # update to the latest HEAD from 'origin'

cd ..         # back to parent repo
git status    # should now indicate that the submodule commit has changed

# add, commit and push
git add libavr32
git commit -m "updating libavr32"
git push

If for some reason your submodules’s origin is not monome/libavr32 (and you don’t know why that is), then ask and I’ll try and help out as much as I can.

1 Like

yeah, that’s what i meant - when i pull the latest submodule this updates both the submodule and the revision number my repo is using for the submodule, so it’s the latter that i will need to push to my repo.

the submodule origin would be different if i, say, needed to make some changes in the submodule, so i just fork it / temporarily point to that, and then change it back to monome/libavr32 once my submodule change is merged, correct?

1 Like

Correct (but you do need to commit the change of commit hash to the parent repo).

Yes, just never change the url in the .gitmodules file. Although I usually find that I leave the libavr32 submodule origin permanently pointing at my fork and just sync up the changes from upstream.

The main thing to remember with submodules is that it’s the commit hash that’s stored in the history, git doesn’t really care which fork it’s from (that’s not how git works). The url from .gitmodules is only used for the initial checkout.

1 Like

@tehn - pulled the update in no problem; thanks. i had already made a very similar mod to your rx command to have a variable length buffer. i am, however, using the addr functionality to send a parameter to the slave that identifies the input # that the teletype wants to poll. i went ahead and integrated your changes into my branch and restored the original function under a new name as follows:

void i2c_master_tx_rx(uint8_t addr, uint8_t idx, uint8_t *data, uint8_t l) {
  int status;

  packet.chip = addr;
  // this allows the index of the input to be sent to the slave transmitter
  packet.addr[0] = idx;
  packet.addr_length = 1;
  // buffer and size of the return data
  packet.buffer = data;
  packet.length = l;

  status = twi_master_read(TWI, &packet);

it is pretty nifty how it works. the input module gets a quick command with the address that is about to be polled and then gets a request for a few bytes. this allows the i2c to be kept pretty lean as only the value that is needed is transmitted. i squeaked with it just worked out of the box.

My fork is here in case you are curious:

still need to explore why this command is causing the unit to lock when called from the metro interrupt. had too much fun playing with quantization this weekend. :wink:

@scanner_darkly @sam - i have a list of the commands that i use to maintain my forked linked project if that would be helpful.



1 Like

quick update @scanner_darkly -

i revisited my “negative values over i2c” code and validated that i can indeed send negative integers by first casting to unsigned, doing the shifting and sending they bytes, unshifting the bytes on receive into an unsigned int, and then casting to signed. values transfer properly. :slight_smile:


1 Like

the tx_rx command does seem useful. how does the slave code look for this transaction? i was separating the two out to explicitly queue up packet responses.