Thanks for this more foundational information. It's a bit simplified since most displays are flexible now and multi-color, but at least it doesn't ignore the entire OLED material, TFTs, and display driver IC as if the digital communication to the controller was the most important or even remotely common solution.
135 days ago [-]
Liftyee 135 days ago [-]
Fun little project, wonder if DDC could be used as a way to control devices like HDMI capture cards or KVM switches? Honestly surprised that bare i2c interface is exposed to the OS and not hidden by some firmware...
myself248 135 days ago [-]
I don't know about that, but I've used it to reprogram the i2c EEPROM in SFP transceivers. Cooking up a little board to make that easy, actually; I'll publish the files as soon as I prove the prototype works.
1oooqooq 135 days ago [-]
it's hidden on most windows drivers.
on Linux it's exposed and have user tools for most standard things. it's infuriating how changing the settings on random external displays is easier than most integrated laptop screens.
some kvm do abuse that comms channel already. forgot which brand but it completely hijacks it and my brightness hacks wouldn't work
extraduder_ire 135 days ago [-]
DDC works over HDMI on linux? I switched to a displayport cable because I thought it wouldn't, and wanted to use ddcutil for setting brightness. I'll have to check that out. It might make the lack of CEC on PCs less annoying.
sgtnoodle 135 days ago [-]
I've gotten CEC to work in Linux on my desktop computer. The funny thing is that most GPU HDMI ports don't implement CEC, but do implement CEC over DisplayPort. You simply need to find a DisplayPort to HDMI adapter that supports CEC.
1oooqooq 134 days ago [-]
depends on your gpu/motherboard.
on AMD gpus and quality motherboard, i don't even care if i have hdmi or dp cables. i literally use whatever i fish out of a box first.
IshKebab 135 days ago [-]
Yeah, the main issue with I2C for this sort of thing is device discovery. It doesn't have any mechanism for it so you would need to magically know your device's address.
I believe for things like controlling monitors they just hard-code the addresses. I think that's how it works anyway. Unfortunately the DDC/CI spec is really badly written, incomplete, and full of legacy stuff that nobody actually implements.
metaphor 135 days ago [-]
Confusing remark; I haven't sleuthed the standard in over a decade, but DDC/CI v1.1 (available for free here[1]) § 2.3 makes this abundantly clear:
>> The DDC/CI display is considered a fixed address display device at adddress 0x6Eh / 6Fh, and uses only I2C slave mode to communicate with the host.
...while § 3.3.1 specifies addresses for external display dependent devices.
> Yeah, the main issue with I2C for this sort of thing is device discovery. It doesn't have any mechanism for it so you would need to magically know your device's address.
The typical address space is 7-bits, so you can just try a transaction to everyone... Or have some convention about what device number the display is?
dmitrygr 135 days ago [-]
Problem is: every i2c transaction is a READ or a WRITE. The spec is mum on the semantics of what that means. Some devices will get into a weird state or irrevocably pop data off a FIFO if you READ them (eg: some IMUs). Others take a WRITE, even with no data, to have a non-idempotent meaning (eg: SMBUS). Some devices will not even ACK their address on a READ request unless it is preceded by a write and a RESTART. Basically there is no safe way to scan an i2c bus and be sure you did not modify some state or put some device into some weird state.
buescher 135 days ago [-]
Right. But if you have a finite space of possible i2c devices it's not quite that bad. You can scan for known addresses and there are frequently mitigations for clogging FIFOs - like clocking out the bus or forcing a reset - that you might have to do anyway, depending on what your failure modes for power sequencing are. i2c is just fine when it works, but there are reasons why it can be worth spending the extra pins for SPI.
dmitrygr 135 days ago [-]
The post I was replying to was suggesting scanning the bus for any kind of device. That is impossible. I could make a i2c device right now and not tell you how it works. You will have no way to scan for it safely (say I specify that unless the first access to it is a write of 0x55 0xAA, it’ll not talk again, but if it is, the byte sent after 0xAA becomes its i2c address)
I have seen devices that respond to address zero, which is against the spec. Stopped nobody.
I have seen devices that use the bus arbitration meant for multi-master during a READ to allow only one of them to win after responding to a zero-address read.
I’ve used an i2c device that had an additional chip select line for some reason. Unless you lowered that, it would not respond to any traffic on the bus.
You cannot even imagine the fucked up shit that happens over i2c
There is no safe, generic way to scan an i2c bus. If the world of possible devices is limited, it may be possible. But there is no safe generic way.
buescher 134 days ago [-]
Oh yes. I do not have to imagine. That's why I said "Right".
utensil4778 135 days ago [-]
I2C has no concept of a discovery or identification packet. The host can write any data to any address, and you have to already know in advance what address and data structure you need. The device can't tell you what its data format is.
An I2C transaction begins with a client address, and the host waits for an acknowledge signal that a client has answered the message. That's it, that's the only standard part. From there, the host typically sends a register address and then some number of data bytes, or the client sends back some number of bytes. What those addresses and bytes mean are totally application-specific. There is no standard at all here.
You could absolutely broadcast standard DDC commands to all addresses, but you have no way of knowing what actually happened. You might have turned off one monitor and set another to VGA mode. You might have just crashed some random device on the bus. You have no way to tell.
All your host can possibly know is that there is a device at a given address, and it either did or did not send an acknowledge bit after a command. That's all the information available to you, and it is not enough to do what you suggest
FredFS456 135 days ago [-]
That's not technically true - you can probe for I2C devices by only sending a START, an address, waiting for the client device to ACK (or not), and then sending a STOP. I don't think the linux kernel driver allows us to do this, but I've implemented this on some microcontrollers with lower-level control over the I2C hardware. It worked on all clients I tried it on.
joezydeco 135 days ago [-]
You can install i2c-tools and run i2cdetect from userspace.
"Warning
This program can confuse your I2C bus, cause data loss and worse!"
joezydeco 134 days ago [-]
This is true. As stated elsewhere, sending START conditions to random I2C devices may confuse certain parts. It may also interrupt a driver that's already talking to a part on the bus. But in my lifetime working with I2C, I've never seen a part just go haywire because you scanned it this way.
BobbyTables2 135 days ago [-]
Indeed, I’ve also done the same. It’s frustrating how Linux doesn’t allow this.
Part of me wonders if all devices actually handle a STOP before the first data byte correctly — without side effects…
myself248 135 days ago [-]
In recognition of this chaos, https://i2cdevices.org/ is putting together a pretty good list.
The smallest and worst HDMI display - https://news.ycombinator.com/item?id=30869140 - March 2022 (162 comments)
https://www.youtube.com/watch?v=qg8pMUd-tSk
on Linux it's exposed and have user tools for most standard things. it's infuriating how changing the settings on random external displays is easier than most integrated laptop screens.
some kvm do abuse that comms channel already. forgot which brand but it completely hijacks it and my brightness hacks wouldn't work
on AMD gpus and quality motherboard, i don't even care if i have hdmi or dp cables. i literally use whatever i fish out of a box first.
I believe for things like controlling monitors they just hard-code the addresses. I think that's how it works anyway. Unfortunately the DDC/CI spec is really badly written, incomplete, and full of legacy stuff that nobody actually implements.
>> The DDC/CI display is considered a fixed address display device at adddress 0x6Eh / 6Fh, and uses only I2C slave mode to communicate with the host.
...while § 3.3.1 specifies addresses for external display dependent devices.
[1] https://vesa.org/vesa-standards/
The typical address space is 7-bits, so you can just try a transaction to everyone... Or have some convention about what device number the display is?
I have seen devices that respond to address zero, which is against the spec. Stopped nobody.
I have seen devices that use the bus arbitration meant for multi-master during a READ to allow only one of them to win after responding to a zero-address read.
I’ve used an i2c device that had an additional chip select line for some reason. Unless you lowered that, it would not respond to any traffic on the bus.
You cannot even imagine the fucked up shit that happens over i2c
There is no safe, generic way to scan an i2c bus. If the world of possible devices is limited, it may be possible. But there is no safe generic way.
An I2C transaction begins with a client address, and the host waits for an acknowledge signal that a client has answered the message. That's it, that's the only standard part. From there, the host typically sends a register address and then some number of data bytes, or the client sends back some number of bytes. What those addresses and bytes mean are totally application-specific. There is no standard at all here.
You could absolutely broadcast standard DDC commands to all addresses, but you have no way of knowing what actually happened. You might have turned off one monitor and set another to VGA mode. You might have just crashed some random device on the bus. You have no way to tell.
All your host can possibly know is that there is a device at a given address, and it either did or did not send an acknowledge bit after a command. That's all the information available to you, and it is not enough to do what you suggest
https://learn.adafruit.com/scanning-i2c-addresses/raspberry-...
Part of me wonders if all devices actually handle a STOP before the first data byte correctly — without side effects…