Livt packages

Livt.IO

Version 1.8.1

Memory, UART, I2C, SPI, and Ethernet input/output components for Livt hardware designs.

Published files (126)

src/i2c/I2CBusCombiner.lvt

namespace Livt.IO

/**
 * Combines two I2C device attachments into one upstream open-drain bus.
 */
component I2CBusCombiner
{
	// Upstream attachment and the two independently driven device endpoints.
	upstream: I2CBus
	public controller: I2CBus
	public target: I2CBus

	// Combined low-drive requests exposed for observation.
	public scl_drive_low: logic
	public sda_drive_low: logic

	/**
	 * Borrows the upstream bus and exposes two logical device attachments. Each attachment
	 * requests low drive or releases the line.
	 */
	new(upstream: flip I2CBus)
	{
		this.upstream = upstream
	}

	/**
	 * Continuously combines low-drive requests and returns observed line levels to both
	 * attachments; either device pulling low dominates the released state.
	 */
	process Combine[]()
	{
		var observedScl: logic = this.upstream.scl
		var observedSda: logic = this.upstream.sda

		if (this.controller.scl_drive_low == 0b1 || this.target.scl_drive_low == 0b1) {
			this.upstream.scl_drive_low = 0b1
			this.scl_drive_low = 0b1
			observedScl = 0b0
		} else {
			this.upstream.scl_drive_low = 0b0
			this.scl_drive_low = 0b0
		}

		if (this.controller.sda_drive_low == 0b1 || this.target.sda_drive_low == 0b1) {
			this.upstream.sda_drive_low = 0b1
			this.sda_drive_low = 0b1
			observedSda = 0b0
		} else {
			this.upstream.sda_drive_low = 0b0
			this.sda_drive_low = 0b0
		}

		this.controller.scl = observedScl
		this.controller.sda = observedSda
		this.target.scl = observedScl
		this.target.sda = observedSda
	}
}