FreeCalypso > hg > freecalypso-reveng
view pirelli/rfcal @ 389:623316d1ece7
compal/iMelody: capturing initial observations
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 31 Mar 2022 20:56:56 +0000 |
parents | 2cc7a17c3859 |
children |
line wrap: on
line source
The 64 KiB flash sector at 0x027F0000 (the last sector of the 2nd flash bank) 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. 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 092C /gsm/rf/tx/levels.900 09AC checksum byte 09AD /gsm/rf/tx/calchan.900 0A2D checksum byte 0A2E /gsm/rf/tx/ramps.1800 0C2E checksum byte 0C2F /gsm/rf/tx/levels.1800 0CAF checksum byte 0CB0 /gsm/rf/tx/calchan.1800 0D30 checksum byte 0D31 /gsm/rf/tx/ramps.1900 0F31 checksum byte 0F32 /gsm/rf/tx/levels.1900 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 10D8 /gsm/rf/rx/agcparams.900 10E0 checksum byte 10E1 /gsm/rf/rx/calchan.1800 1109 checksum byte 110A /gsm/rf/rx/agcparams.1800 1112 checksum byte 1113 /gsm/rf/rx/calchan.1900 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. 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 ============================== 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. 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 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.