I am working with a 4-channel DAC (MCP4728) which has a "complicated" way of programming its I2C address. One needs to pull its LDAC (latch) pin low during the 8th and 9th clock of the second byte.
I first tried to change the Wire library to my needs but it doesn't provide "clock level" access, so I can't solve it this way.
I was successful in changing the address via bit banging but I can only do it on GPIO pins and not the actual I2C pins. Is there a way to bit bang the I2C pins (pins 16 & 17 on my Zero) with digitalWrite?
Here is the relevant part of the datsheet:
Thanks for help!
"Bit bang" I2C code in C is available on several web sites.
I understand that many websites offer code for bit banging I2C on any arbitrary GPIO pins. That's not what I need since my Zero has an I2C module and it takes care of I2C communication via the Wire library.
My problem is that digitalWrite() commands don't work on the I2C pins. Nothing moves high or low. I'm pretty sure it has to do with the special architecture of those pin, they are either open-drain or open-source (I don't actually know which type the Zero's are).
So I need to know how I can get these pins high or low. I tried using different combinations of pinMode() and digitalWrite() but nothing works.
If you have not yet managed to figure out how to do the very most basic operation with the Zero, do take a moment to reconsider the entire project.
I recommend the $2 eBay Pro Mini for such a trivial task.
Would you mind underpinning your answer with some kind of help? A helpful answer is okay too.
My advice is to use any of the bit-banged I2C implementations (here is one) on a $2 Pro Mini and modify the code to fit your device's very unusual requirements.
Or, use a different DAC. This one has a standard interface, and works fine with Arduino.
You have not explained why you would want to use a Zero, which is a mystery if you don't understand how to do basic I/O. I don't know how to do so on the Zero, and am not the least bit interested to use one.
Okay, I think I need to give more context.
I am working on an embedded project with an Arduino Zero communicating via I2C to multiple DACs, ADCs, PWM drivers, port expanders, etc via an I2C bus. Everything is set up and working, except having multiple (i.e. 4) MCP4728s [DAC] on the bus since they come with a pre-programmed I2C address and changing it is only possible via I2C and simultaneous control over its LDAC latch pin (see my first post for reference).
I have succesfully written a pseudo I2C bit bang routine to change the I2C address of the DAC. This routine works on any of the digital Pins on my Zero. Since the idea is to later implement the project with a "bare" STM32 instead of the Arduino on a PCB, the DAC will be connected to the I2C lines and I can't switch those lines around. I also want to prevent myself from switching hardware jumpers around.
So I am looking into changing the port function multiplexing of my SDA/SCL lines for being able to bit-bang those pins. By default, they are set to be handeled by the SERCOM5 but I need them to be simple digital Pins during my I2C address change bit bang routine.
Changing the port function of a µC is quite above my head, so I need someone to show me how this is done in the Arduino environment. Thank you.
Since the idea is to later implement the project with a "bare" STM32
This is the Arduino forum.
Not sure if you are aware of this, so I'll add it: The Arduino Zero is powered by Atmel’s SAMD21 MCU, which features a 32-bit ARM Cortex® M0+ core.
Sorry, I misread what you are trying to do, which is to bit-bang I2C on the pins owned by the I2C hardware.
That won't work on most, if any modern microprocessor. If pins have been assigned to specific hardware, they are not available as general I/O and digitalWrite() will not work on those pins.
Do the bit banging on other pins, or first disconnect/reassign away the I2C module from those pins (if you can).
Okay, great. Finally we are on the same page 
Anyway, in the meanwhile I found out what I really need to do, which is change the function port of the SDA/SCL pins to be GPIO pins. If I read the datasheet correctly, that should be possible.
I have looked into the pinPeripheral() and pinMode() functions, don't have it working yet but I think I'm on the right way here.
I asked the follow-up question in the "Arduino Zero" forum, here is the answer: Disable I2C functionality on SDA/SCL pins - Arduino Zero - Arduino Forum
For the impatient:
pinMode(SDA, OUTPUT); //sets SDA low
pinMode(SCL, OUTPUT); //sets SCL low
pinMode(SDA, INPUT); //sets SDA high
pinMode(SCL, INPUT); //sets SCL high