I'm attempting to get basic I2C communication running with a WM8731 audio codec (NOT I2S - that comes later).
I'm trying to stay nice and organized with my code, splitting out functions to separate .cpp/.h files, and I'm wondering if that's possibly the source of the issue.
Let's start from the basics. If I set up a simple I2C sketch, using PB3/PB10, things work perfectly fine:
Code: Select all
#include <Wire.h>
TwoWire hI2C(PB3,PB10);
void setup() {
hI2C.begin();
}
void loop() {
hI2C.beginTransmission(0x1B);
hI2C.write(0x00);
hI2C.endTransmission();
}

Now, let's jump into my current code that is causing me all kinds of headaches.
The main .ino file contains this (non-relevant stuff trimmed out):
Code: Select all
// Arduino library includes
#include <Wire.h>
// custom file includes
#include "wm8731.h"
// Primary I2C Device (only used for WM8731 control right now)
TwoWire hI2C(PB3,PB10);
void setup() {
// communication initialization
hI2C.begin(); // hardware I2C for codec comms
// hardware initialization
WM_reset(hI2C, 48000, sampleWidth); // reset and initialize the codec
}
Code: Select all
/**
* basic register write Functions
* returns I2C error code (0: OK, 1: data too long, 2: addr NACK, 3: data NACK, 4: other error)
*/
static uint8_t WM_writeRegister(TwoWire hI2C, unsigned char addr, unsigned char value) {
// initialize error code to 5
uint8_t errorCode = 5;
// split 16-bit value into two 8-bit bytes
unsigned char byte1 = (addr<<1) | ((value>>8) & 0x1);
unsigned char byte2 = value & 0xFF;
// send the message
hI2C.beginTransmission(0x1A);
hI2C.write(byte1);
hI2C.write(byte2);
errorCode = hI2C.endTransmission();
// finally, return the error code (hopefully 0)
return errorCode;
}
/**
* codec reset Function
* resets the entire WM8731 codec chip, and sets all functions back to startup defaults
*/
uint8_t WM_reset(TwoWire hI2C, uint32_t audioFreq, codecSampleWidth_t wordSize) {
uint8_t errorCode = 5;
// send the reset command and make sure it set okay
#ifdef DEBUG_WM_I2C
Serial.print(DEBUG_WM_PREFIX);
Serial.println("Resetting WM8731");
#endif
errorCode = WM_writeRegister(hI2C, WM_REG_RESET, 0); // <-- WM_REG_RESET is 0x1E
}

Both lines just drop to ground and stay there until the board is reset, and then they do the same thing again.
I've got 4k7 pullups on both I2C lines, and right now they're not even connected to anything on the breadboard other than the MCU (a Nucleo F401RE). Can anyone help shed some light on what's going on here? Is passing in a TwoWire object as a function argument not a valid thing you can do with Arduino? Is there something specific to running I2C in a .h/.cpp file that I'm missing? The compiler gives no errors, so I'm out of ideas. It seems like regardless of what data I try and write with that function, it still hangs at the endTransaction() line.
Any and all help or suggestions is appreciated! I know posting full code is recommended, but I've got multiple 100+ line code files in this project so I'm trying to keep the spam to a minimum.