Radio icon indicating copy to clipboard operation
Radio copied to clipboard

Feature: Implement TwoWire support for TEA5767

Open FrankVanris2 opened this issue 4 months ago • 1 comments

Summary

This pull request adds support for utilizing a secondary I2C bus via TwoWire to interface with the TEA5767 radio chip. The TEA5767 is known to be sensitive to shared I2C traffic, and when operated on the same bus as other peripherals (e.g., LCDs), it may suffer from degraded audio quality or complete communication failure.

By enabling the use of a dedicated I2C bus, this update allows developers to isolate the TEA5767, mitigating interference and improving overall system reliability.

The Problem

The current TEA5767 implementation is hardcoded to use the global Wire object for I2C communication. This design limitation prevents developers from utilizing alternative I2C interfaces—such as the secondary bus available on the ESP32 or other multi-bus platforms—effectively forcing the TEA5767 to share the primary I2C bus with all other peripherals. This constraint can lead to resource contention and degraded performance, particularly in systems with sensitive or high-traffic devices.

The Solution

This pull request implements the initWire(TwoWire &port) virtual function, which exists in the base RADIO class but was previously unimplemented in the TEA5767 subclass. This enhancement aligns with the library’s architecture for supporting multiple I2C buses.

Key Changes:

  • Utilization of _i2cPort:
    The base RADIO class provides a TwoWire* _i2cPort pointer. This PR updates the TEA5767 class to use _i2cPort for all I2C operations, replacing the previously hardcoded Wire object.

  • Implementation of initWire():
    The initWire(TwoWire &port) method is now implemented. When invoked, it assigns the internal _i2cPort to the user-specified I2C bus, enabling flexible multi-bus support.

  • Centralized Initialization Logic:
    A private helper function _init() has been introduced to handle the TEA5767’s register setup. Both init() and initWire() now delegate to _init(), ensuring consistent configuration and eliminating code duplication.

  • Backwards Compatibility:
    The default constructor continues to set _i2cPort = &Wire;, preserving existing behavior. Users calling the original init() function will experience no changes. As per standard practice, users are responsible for invoking Wire.begin() themselves.

How to Use this Feature

A developer can now choose which I2C bus to use at initialization.

Standard Usage (Default I2C Bus):

#include <Wire.h>
#include <TEA5767.h>

TEA5767 radio;

void setup() {
  // 1. User starts the standard I2C bus.
  Wire.begin(); 

  // 2. User calls the regular init() function.
  //    It will automatically use the 'Wire' object.
  radio.init();

  radio.setFrequency(9810);
}

New Feature (Secondary I2C Bus):

#include <Wire.h>
#include <TEA5767.h>

TEA5767 radio;
TwoWire radioI2C = TwoWire(1); // Create a second I2C instance

void setup() {
  // 1. Initialize the secondary I2C bus on custom pins.
  radioI2C.begin(25, 26); // Example: SDA=GPIO25, SCL=GPIO26

  // 2. Initialize the radio using the initWire function, passing the custom bus.
  radio.initWire(radioI2C);

  // Now, all radio functions will use radioI2C automatically.
  radio.setFrequency(9810);
}

Summary of Changes

TEA5767.h Updates:

  • Declared bool initWire(TwoWire &port) override; to support custom I2C bus initialization.
  • Added private helper function declaration: void _init(); for centralized register setup.

TEA5767.cpp Updates:

  • Updated the constructor to initialize _i2cPort = &Wire; by default.
  • Implemented _init() to handle the TEA5767’s default register configuration.
  • Refactored init() to delegate setup to _init() for consistent behavior.
  • Implemented initWire() to assign _i2cPort to the user-provided I2C bus and invoke _init().
  • Replaced all hardcoded Wire references in methods such as _readRegisters() and _writeRegisters() with the _i2cPort pointer.

Impact: These changes significantly improve the library’s flexibility, enabling seamless integration with multi-bus platforms like the ESP32. The update maintains full backward compatibility, ensuring existing implementations remain unaffected.

FrankVanris2 avatar Aug 23 '25 19:08 FrankVanris2

Future Additions

Will need to implement updated example code for when using the TEA5767 component for any sketch. As of this moment that has not been implemented.

FrankVanris2 avatar Aug 23 '25 20:08 FrankVanris2