# HG changeset patch # User Mychaela Falconia # Date 1510805998 0 # Node ID 2cc7a17c38595d388629cd57918c4315c0f6e615 # Parent e3bbb8cfbbc0cb1545d33aa43f4ce4dddf91d923 pirelli/rfcal: new understanding diff -r e3bbb8cfbbc0 -r 2cc7a17c3859 pirelli/rfcal --- a/pirelli/rfcal Sun May 28 20:33:26 2017 +0000 +++ b/pirelli/rfcal Thu Nov 16 04:19:58 2017 +0000 @@ -2,13 +2,30 @@ contains per-unit factory data, including the IMEI and RF calibration values. The location of the IMEI record (at offset 0x504) was found back in 2013-07 and its encryption was figured out in 2013-11, but it took a bit longer to find the -RF calibration data. But I finally found most of the latter as well. Here -they are: +RF calibration data. Most of the RF calibration bits were found in 2014-07, +but the complete picture presented below has only been reconstructed in 2017-11. + +The data structure corresponding to TI's RF calibration files listed in the +config_files_common[] and config_files_band[] arrays in l1_cust.c begins at +offset 0x528, and has space allocated for each and every one of the files +listed in those arrays in TI's canonical version, in the same order as in that +canonical version, with the single exception of /sys/uartswitch. Behold: Hex offset Corresponding FFS file in TI's canonical version ---------------------------------------------------------------- +0528 /gsm/rf/afcdac +052A checksum byte +052B 442 (0x1BA) unused (all FF) bytes making room for: + /gsm/rf/stdmap + /gsm/rf/afcparams + /gsm/rf/rx/agcglobals + /gsm/rf/rx/il2agc + /gsm/rf/rx/agcwords + 06E5 /sys/adccal 0709 checksum byte +070A 33 (0x21) unused (all FF) bytes making room for: + /sys/abb 072B /gsm/rf/tx/ramps.900 092B checksum byte @@ -28,6 +45,10 @@ 0FB2 checksum byte 0FB3 /gsm/rf/tx/calchan.1900 1033 checksum byte +1034 123 (0x7B) unused (all FF) bytes making room for: + /gsm/rf/tx/caltemp.900 + /gsm/rf/tx/caltemp.1800 + /gsm/rf/tx/caltemp.1900 10AF /gsm/rf/rx/calchan.900 10D7 checksum byte @@ -41,25 +62,103 @@ 113B checksum byte 113C /gsm/rf/rx/agcparams.1900 1144 checksum byte +1145 more than enough unused (all FF) bytes to fit: + /gsm/rf/rx/caltemp.900 + /gsm/rf/rx/caltemp.1800 + /gsm/rf/rx/caltemp.1900 + +TI's canonical version classifies each of the files listed in those +config_files_common[] and config_files_band[] arrays into one of 8 categories: + +f = RF calibration +F = RF config +r = Rx calibration +R = Rx config +t = Tx calibration +T = Tx config +s = system calibration +S = system config + +Pirelli's factory data structure allocates space for all of the possible files +in all 8 categories, but out of all these spaces, the only ones that are +actually filled with bits (not all FF) are the ones corresponding to the 4 +"calibration" categories, and not the "config" ones. It is my (Mychaela's) +guess that Foxconn folks probably preserved the logic invoked by me 102 through +me 109 commands unchanged from TI's original, and thus had the theoretical +ability to write everything into their invented data structure, but only issued +the me 102/104/106/108 commands in their factory production flow, hence only +the "calibration" record slots got filled. + +Please note that the slots corresponding to the missing files in the "config" +categories are filled with all FF bytes, and do NOT contain the "standard" or +"never changed" bits compiled into the firmware. Because these bits are not +present in the factory record in the flash, any aftermarket firmware running on +these phones needs to provide these bits on its own. This category very notably +includes the afcparams table. Each calibration record is followed by a checksum byte. It is a simple ripple- carry sum of all bytes in the preceding record. Note that this checksum byte is always 0 for the ramps records, as each correctly-formed ramp adds up to 128 -(0x80), and the array has an even number of ramps in total. +(0x80), and the array has an even number of ramps in total. It is also my +(Mychaela's) guess that Pirelli's fw probably uses this checksum byte to detect +that the "config" files are missing and avoid loading the FF bytes into the +corresponding L1 RAM data structures: the sum of all FF bytes in the data space +does not equal FF unless the record length is 1 byte or 257 or 513... bytes, +and none of TI's calibration/config records match those byte lengths. + +Absence of the afcparams table +============================== -Unfortunately though, I have not been able to locate these two records: - -/gsm/rf/afcdac -/gsm/rf/afcparams +The afcparams table is placed in the "RF config" category in TI's TCS211 +reference fw, rather than "RF calibration". It appears that in the very old +days of Sara RF (before the D-Sample) this table contained only the Psi +constants (no min/max/nominal DAC), and these Psi constants were tweaked in the +source code in l1_rfN.h, rather than via per-unit calibration - hence the +"config" rather than "calibration" classification. Then RF 10 (Clara) came +along, TI started using "plain" VCXOs without the "TC" part, they implemented a +new AFC algorithm (VCXO_ALGO), and the min/max/nominal DAC fields got added to +the afcparams table. The complete story is not clear, but the end result is +that when the days of Openmoko came around, FIC (OM's factory) had a production +line calibration program, presumably from TI (I never got a copy of it, but I +was told it was a Windows binary sans source), that performed individual +per-unit calibration of the VCXO along with the expected Rx and Tx band +calibrations, and the afcparams table is calibrated per unit on Openmoko +devices. -These two files appear in Openmoko's FFS on GTA02 modems, and the byte content -differs for each physical unit, so I assume that these values really do need to -be calibrated per unit, but I haven't been able to locate them in Pirelli's -factory data block. /gsm/rf/afcdac is only 2 bytes long, thus very hard to -spot visually in a hex dump of an unknown larger data structure; -/gsm/rf/afcparams is 24 bytes long and has some structure to it, so I was -hoping to recognize the latter, but no luck. +Both theory and practice indicate that OM's way of calibrating the afcparams +table on a per-unit basis is not the only way: the per-unit calibration does +not help much in practice because of the strong temperature sensitivity, and +the new AFC algorithm implemented by TI has to deal with wide uncertainties in +the initial VCXO frequency. Instead it appears to be sufficient to calibrate +the VCXO and the settings in the afcparams table on a per-design basis, rather +than per unit, and it appears that Motorola/Compal did just that on their C1xx +phones - which use a "plain" VCXO and not a VCTCXO like the Pirelli. + +Querying Pirelli's fw for the actively used afcparams table via rftr 9 returns +the following: + +rf_table afcparams + + 6974 # psi_sta_inv + 8 # psi_st + 492713 # psi_st_32 + 8717 # psi_st_inv -We will have to try running uncalibrated, or perhaps we'll find the code in -Pirelli's fw that fills the parts of the T_RF structure that are normally read -from these files. + 888 # dac_center + -9568 # dac_min + 11352 # dac_max + 2560 # snr_thr + +Because the slot in the factory data structure where the afcparams record ought +to go is all FF bytes, the table returned by the fw above can only be hard-coded +in the fw itself. The 4 numbers in the second group are exactly the same as +the hard-coded numbers in l1_rf12.h in TI's reference fw, but the Psi numbers +are different - Foxconn/Pirelli folks must have tuned them for their VCTCXO. + +In this light, it is worthy to note that the afcdac record *is* present in +Pirelli's factory data block, and it differs from one unit to the next, i.e., +it has been calibrated on a per-unit basis. TI's reference fw selects the +ALGO_AFC_LQG_PREDICTOR AFC algorithm which does not use this afcdac setting +at all, but perhaps Pirelli's fw does something different because of their use +of a VCTCXO instead of a "plain" VCXO - we don't know, and the reverse eng +effort to find the needed answers would be more than we can currently justify.