I2c connectivity - could you clarify


#1

Hi guys,

First of all apologies if this question has been answered before, I tried searching the forum but didn't find a clear answer. I am new to axoloti but I am experienced with electronics, Pure Data and C coding, Arduino etc. so this questions is more about specific Axoloti implementation.

I am connecting 8 buttons and 8 LEDs to axoloti via i2c, using the MCP23017-E/SP chip. I have used this setup plenty of times with arduino and I am confident about the hardware side of things.

I am having difficulty figuring out how to setup Axoloti on the software side. I added the i2c config object and I hooked up the chip to PB8 and PB9 pins. I'd like to get 8 boolean outputs (from the switches) and 8 boolean inputs (for the LEDs). What script code should I use to communicate with the chip? Basically, how to setup GPA ports to read and GPB ports to write and how to read/send data between them and axoloti?

I am also using two MCP3208 chips to read 16 pots and the setup was quite straightforward, I just modified the example code from the forum. So if you could point me in the right direction regarding the i2c communication with the MCP23017 that would be fantastic.

Thank you.


#2

I have no code available for the MCP23017, but here's a quick outline:

The I2C communication needs to happen outside the audio processing workload, otherwise buffer underruns will occur cause by waiting time for communication to complete (or fail), to do this we need a "thread". The "script/script2" object shows how to do this, but does not provide the inlets/outlets you want for this application, so we need to customize it.

  • create a "script/script2" object in a patch, and in the object popup menu, select "embed as patch/object"
  • in the object popup menu of the resulting "patch/object", select "edit".
  • in the inlets tab, create 8 inlets of the "bool32" type (in1, in2,...in8)
  • in the outlets tab, create 8 outlets of the "bool32" type (out1, out2,...out8)
  • in the local data tab, replace the declaration of in1, in2, out1, out2 with 8 booleans for input and 8 booleans for output
    bool in1, in2, in3, in4, in5, in6, in7, in8;
    bool out1, out2, out3, out4, out5, out6, out7, out8;

    leave the rest of the local data code untouched, this sets up a thread
  • in the k-rate tab, all inlet values need to be copied to the local data, and all output local data needs to be copied to the respective outlets:
    outlet_out1 = this->out1;
    this->in1 = inlet_in1;
    etc.
  • close the object editor, you'll see the inlets/outlets in the "patch/object"
  • in the object, click the *script edit" button, a text editor window pops open
  • in that script you'll need something like:
    void setup(void){
    }
    void loop(void){
    }
    arduino style...
  • For interacting with I2C, use the Chibios I2C Driver : documentation, use &I2CD1 for I2CDriver. Most relevant calls are i2cMasterTransmitTimeout() and i2cMasterReceiveTimeout().
    I do recommend to use a sensible timeout value (can be obtained by the macro MS2ST(milliseconds), and avoid making a loop inside the void loop(void)... code that does not terminate unconditionally, otherwise you may get a "zombie" thread.
    To configure the I2C driver and GPIO pins, you can use the gpio/i2c/config object.
  • GPIOB,8 is SCL, GPIOB,9 is SDA. Changing the I/O pins to different ones will not work.
  • important: the I2C driver uses DMA (direct memory access) to relieve the processor from copying bytes, but this only works for data that is in suitable memory, which can be declared like this:
    static uint8_t txbuf[8] __attribute__ ((section (".sram2")));
    static uint8_t rxbuf[8] __attribute__ ((section (".sram2")));
  • for debugging, the LogTextMessage() call is useful, works like printf(), but too intensive logging can disrupt communications.

#3

Thank you, this clarifies things. If I understand correctly, I have to implement the specific protocol my I2C chip is using.

On Arduino there is a library called Wire which works with MCP23017 out of the box. I might port specific functions to my script (configuring the pull up on specific pin, setting pins as IN/OUT - there are a few more functions available). I will update this thread if I get it working.

I think it will be worthwhile getting the MCP23017 working with Axoloti as it is a fantastic chip - it has 16 individually configurable IN/OUT pins with built in pull up resistor (configurable per pin as well). More than one can be used with the same 2 pins on Axoloti. As it is I2C it can be used for less time demanding functions, like reading buttons, toggle switches, controlling LEDs etc. That frees up the SPI bus for reading pots and similar.

Thank you again for your help.


#4

@pawelgrudzien ondering if you managed to get the mcp20317 working with the axoloti? Am considering buying an axolotiy, but i need to know if I can get the mcp hooked up or not. otherwise I won't have enough pins for my project :slight_smile: