nebulous / infinitude

Open control of Carrier/Bryant thermostats
MIT License
225 stars 50 forks source link

Infinity Touch hardware documentation #64

Closed Zhentar closed 9 months ago

Zhentar commented 5 years ago

Since the wiki here is some of the best documentation available on this system, I wanted to jot down some things as I figure them out. Hopefully someone can update the wikis from it as appropriate :)

SYSTXCCITC01-B CPU is upgraded from the SH7267 to an SH7269. Comm chip is replaced with a WiLink 8 CC1835. The equivalent Bryant part number is SYSTXBBECC01-B.

SYSTXCCITC01 firmware 131493-12 can be downloaded from here: http://cacbdpapps.net/marketing/eula/Infinity_Touch_V12_h-eula.html The latest "A" version, 131493-14.01, along with the latest B version 131626-01.30 are here: http://cacbdpapps.net/marketing/eula/Infinity_Touch_V1401-0130_h-eula.html

The firmware files are Intel hex encoded. But none of the ihex to bin file converters worked on them, despite being perfectly valid ihex files, so I wrote my own https://github.com/Zhentar/ihex_to_bin/ (batteries not included - I just used hardcoded file paths 😅)

131493-12 has a ~1.3MB code section, so it's definitely not running anything easy to work with like a linux kernel; I haven't come across any strings identifying a standard OS yet (the MRF24WB0MA on the other hand may be running MQX RTOS).

Zhentar commented 5 years ago

SYSTXCCITC01 has an 8MB ROM mapped from addresses 0x40000 to 0x00800000. SYSTXCCITC01-B has a 16MB ROM mapped from addresses 0x18040000 to 0x18F40000.

SH7269 has a 64kB region of "fast" RAM at 0xFFF80000 to 0xFFF90000. I think SH7267 has similar, not sure about the addresses though. There's also a much larger region of "slow" RAM (1.5MB for SH7267, 2.5MB for SH7269).

Zhentar commented 5 years ago

I was noticing a lot of strings had punctuation for their first character... for example, DATE*ANUARY&EBRUARY-ARCH!PRIL-AY*UNE*ULY!UGUST3EPTEMBER/CTOBER.OVEMBER$ECEMBERDAYLIGHT. I was confused; even if my ihex converter had corrupted the data, always hitting the first character would be rather unlikely. Until I realized... it's ASCII with the control characters subtracted out! "$ECEMBER" is "December", with 0x20 subtracted from each byte. Which has one particularly interesting implication: space becomes null. And the strings aren't length prefixed either, which means whatever code is referencing these strings has the length embedded.

Zhentar commented 5 years ago

BINF0130's wireless stack was compiled in debug mode, which means it includes strings like "C:\VirtualBox_Shared_1\UTC\Bing\ClarinoxSoftFrame_UTC_Bing\Build\embOS\Projects\Bing\SHC..........\System\Common\ClxStaticPointer.h". So it looks like the thermostat is running embOS. ("UTC" is "United Technologies Corporation", for those unfamiliar with HVAC genealogy)

Zhentar commented 5 years ago

A correction on my previous code size statement - The "A" models only have about 250kB of code. The "B" versions have the 1.25MB claimed.

Curiously, the "A" models have the serial bus definitions directly in the firmware image, e.g.

.data.b h'3B            
.data.b 1               
.data.b h'19            
.data.b    0            
.data.b h'20
.sdata "SAMINFO"        
.data.b 0
.data.b    1            
.data.b h'16
.data.b    6
.data.b h'19
.data.b    1
.data.b h'1D
.data.b    3
.data.b h'96
.data.b    3
.data.b  h'B
.data.b    3
.data.b  h'B
.data.b    3
.data.b h'34
.data.b    3

But I've found no trace of those definitions in the B firmware

Zhentar commented 5 years ago

Operator error, I just wasn't looking right!

brybus stopped scanning at table 3F - but there were ten more tables hiding in the 0x40s!

Table Name Row count (base 10)
40 SCHEDULE 23
41 TEMP 2
42 LASTTEN 4
46 MISC1 16
47 RESTMR 2
48 HEALTH 2
49 SYSCTRL 11
4A MISC2 4
4C SYSMETRC 3
4E CHARGING 2
Zhentar commented 5 years ago

SCHEDULE rows: 0x2-0x9: 1 row for each zone, 10 bytes per day of week 0xA-0x11: 1 row for each zone, 5 bytes per day of week 0x16: 7 bytes for each zone

LASTTEN: I've seen some strings for "Last 10 faults" and "Last 10 wifi events" so I would guess this is related to one or both.

MISC1: row 0x08 contains wifi configuration details. row 0x09 has the DNS server and Infinity API server addresses. Row 0xA has the device customer service name/phone number/website. Row 0xB contains all nearby access points.

RESTMR: just one byte. Zero in my observations. Write to it to schedule a system reset, perhaps?

Zhentar commented 5 years ago

It looks like "SYSCTRL" serves as a replacement for SAMINFO. So then SAMINFO being all zeros for SYSTXCCITC01-B is probably why the older SAM modules aren't compatible with it, and why Infinitive doesn't work with it. Now, it's just a matter of mapping out the fields in it...

Zhentar commented 5 years ago

Or maybe SAMINFO equivalents are spread across TEMP, SCHEDULE, and SYSCTRL.

I haven't looked at SCHEDULE at all yet. SYSCTRL and possibly TEMP have changed from SAMINFO's convention of eight one-byte fields to each zone+value to a convention of 8 groups of four bytes for each zone in group. Not knowing the data types I'm choosing to call each set of four bytes "quad" and the 32 byte 4x8 blocks "zone quads". The temperature-related quads on my system seem to follow a convention of 0x42??0000, where ?? is the temperature in half degree Fahrenheit units; for example 80 degrees is 0x42960000. Nothing I've tried has influenced the other three bytes of the quads, but I suspect that they are pairs of 2-byte values.

A rough sketch of what I've determined about the field layout: ("ZQ" for zone quads, "#B" # of bytes) TEMP 4102: 10B 2B 73B -- the 2 byte field in the middle is the current indoor temperature. Haven't determined a pattern for the other fields (which are all either too dynamic or too static to be possible integer representations of the outdoor temperature).

SYSCTRL 4902: ZQ1 ZQ2 ZQ3 -- changes without input --- ZQ1 might be fan related? --- ZQ2 may be heat pump related? 4903: ZQ1 ZQ2 ZQ3 -- ZQ1 = Heating setpoint, ZQ3 = Cooling setpoint. ZQ2 is always zero for me. 4904: ZQ1 4B 4B 1B -- changes without input. The first trailing quad mirrors 4902 Z1Q2, and the second reflects the currently active setpoint in 4903 (i.e. Z1Q1 in heat mode, Z1Q3 in cool mode) 4905: 88B -- Almost always zero for me (did see a few 01 in the first 8 bytes once) 4906: 4B ZQ1 4B ZQ2 ZQ3 ZQ4 -- changes without input. First quad zero, Second quad mirrors Z1Q1. 4907: 92B -- changes without input. Q7 possibly fan related 4908: 3B -- all zeros for me 4909: 100B -- all zeros for me 490A: 3B ZQ1 ZQ2 3B -- ZQ1 mirrors 4903 ZQ3. ZQ2 highly similar to 4903 ZQ1. 490B: ZQ1 ZQ2 ZQ3 -- changes without input

Holds, schedule, vacation mode settings don't seem to have any effect on SYSCTRL (presumably being in SCHEDULE). Values definitely changed in response to changing fan modes, but it's not yet clear to me which values represent what.

nebulous commented 5 years ago

Thanks for the research, keep it coming! I understand that you're using Issues as a general consciousness/comment thread, which is fine in this case, but do feel free to edit the wiki as you learn things.

Zhentar commented 5 years ago

I tried to find a source to back up the pull request @jameshilliard made. I did not succeed, but I can say that the modern Carrier Infitinity/Bryant Evolution ABCD bus is definitely derived from (if not entirely compatible with) the commercial Carrier Comfort Network developed in the late '90s. It appears that CCN supports discovery of table definitions to a much finer definition than than the table names we have discovered, but unfortunately there are few hints as to how we might do so.

jameshilliard commented 5 years ago

@Zhentar If you want to send an email to the address in my profile I can give you some more info.

Zhentar commented 5 years ago

James' secret source has provided me with the explanation for why the table + row descriptor in packets is 3 bytes with the first byte always zero: The table number is actually 2 byte value.

It also appears that one can provide a table number of zero and then follow the 3 byte descriptor with the 8-byte table name (unfortunately I won't be able to test this for a couple days)

Zhentar commented 5 years ago

There also appears to be a third mechanism where it provides a table descriptor of 0xFFFF, and then provides after the row number provides a two byte 'table type' (which appear to be the same value as the first two unknown bytes of the row 1 value for a table) and a 1 byte "instance" of at least 1. Presumably this means there could be more than one value set of values for a given row/table (though I doubt this is ever actually done with the residential systems)

github-actions[bot] commented 9 months ago

Stale issue message