I didn't get a load of sleep last night but I finally figured it out, thanks to timemage's post. I'm concerned that my solution is hyper-specific, but I'd rather share it to save someone the trouble in future.
- timemage was right in that the buffer should really be
volatile
qualified and that as little processing as possible should happen in what I now understand is an ISR. I couldn't get their code to work, but I eventually stumbled on i2c_t3, an enhanced I2C library specifically for Teensy 3.0/3.1/LC. Looking at the library's code and especially its basic peripheral example, it looks like it implements similar techniques to those timemage recommended. - The other thing I didn't consider was the way the controller was communicating. I was using the smsbus2 Python library, and at one point I changed the address offset from
0x00
to0x01
. This mysteriously seemed to make the Teensy code work, but I don't know why!
data = [1, 2, 3, 4, 5, 6, 7, 8]
bus.write_i2c_block_data(0x21, 0x01, data)
- Lastly, from reading forum posts about saving data to variables from I2C, it looks like a lot of quite simple code that does work on other Arduino devices doesn't work on the Teensy.1 I'd have to get an Arduino device to test this theory, though.
Because I'm a bad scientist, I haven't checked whether any of my original code or timemage's improved code works when I offset the address in the smbus2 code.1 But for what it's worth, these are the things I did to solve my problem!