After user lamaral posted a flash image of their Samsung UCCM over in the giant thread about those units, I embarked on attempting to reverse engineer as much of the unit as possible, and have spent way too much time in the past week on that endeavour. It was not a fruitless effort though, there are a great many undocumented commands in the firmware, some of which may be useful for those trying to repair units or otherwise mess around with them. I'm not sure this is the best forum, but it seems as good as any other, move the topic if necessary...
Unfortunately, one of the main things I was trying to conclusively determine - the complete format of the 'TOD' packet - still eludes me. This packet appears to be sent to the microcontroller periodically by the FPGA, but isn't used for anything other than to dump it to the console, so the only thing I was able to determine about it was the header structure and that it contains a timestamp in payload bytes 7-10. A slightly-parsed output can be enabled using 'UDP EN', but it doesn't do anything to illuminate the meaning of the payload.
Much else about the internals has been discovered, and if anyone has any questions or specific avenues of investigation, I can look into it further, but I think I have taken this about as far as I intend to, so I'm going to leave it at more or less documenting the CLI commands which appears to be the only truly useful thing to come out of this.
I have attached my Ghidra project if anyone is interested in continuing that effort.
I did try most of these commands on the Trimble unit I have. `UDP EN` seems to do something, though I don't have spare cables to connect it to an antenna and find out if it is useful. A couple of the other undocumented commands do exist there too, but nothing particularly interesting. Unfortunately I was unable to find a DEBUG mode or enter the bootloader.
All main CLI commands:
Samsung UCCM (Universal Core Clock Module) CLI commands
Mainly determined by reverse engineering. Thank you lamaral@EEVBlog for providing your firmware dump and inspiration to embark on this, and to the NSA (!) for open-sourcing Ghidra which was instrumental in this work.
Notes:
- Where available, I have only include the unabbreviated command names here to attempt to aid in understanding. Many (but not all) allow abbreviated versions.
- 'Standard' notation is used, parameters in brackets [] are optional, those in angle brackets <> are required, unless part of the command in which case they are always required
- * indicates command requires TESTMODE be enabled first
- Effects are mostly the result of experimentation and guesswork
*** USE AT YOUR OWN RISK. DURING TESTING I WAS ABLE TO GET MY UNIT TO GO INTO EFC EXCEED AND WAS UNABLE TO RECOVER IT. EVENTUALLY IT CAME GOOD AFTER FIDDLING AND POWER CYCLING, BUT YMMV ***
MAIN CLI
========
HELP
?
display (incomplete) list of commands
DEBUG
enter debug mode (see debug_commands.txt)
RESET [P|T] [wdt count]
reset to bootloader
- with T, 'watchdog test' - enter infinite loop, WDT should reset
- with P, not sure, possibly reset the saved config, adds message "FPGA Erase"
DIAG:BUILD:VER?
print a version number, doesn't match other version numbers found
- Note: 'long form' of command is not supported
DIAG:BOOT:VER?
print a version number, doesn't match other version numbers found
DAC*
print DAC test mode state and current value
DAC TEST [ON|OFF]*
enable/print DAC test mode (enable writing of DAC values)
DAC W <hex value>*
write hex value to DAC
DAC R*
read current DAC value
WDG MODE [ON|OFF]*
print current watchdog mode
- with ON/OFF, set watchdog mode
WDG TIME [seconds]*
print current watchdog timeout
- with value, set timeout
WDG TEST*
enter infinite loop, WDT should reset board after current timeout
PLL DIS*
toggle PLL info display (see PLLDIS)
PLL CAL*
PLL calibration routine
- details unknown, takes approx. 5 minutes
PLL FAC*
print some PLL seq(?) information
-----------------------------------------------
Seq.s = 2 steps
seq.0 = 6 : 0
seq.1 = 3 : -5
--> seq.2 = 3 : -5 (*)
seq.3 = 2 : -8
seq.4 = 0 : 0
seq.5 = 0 : 0
seq.6 = 0 : 0
seq.7 = 0 : 0
seq.8 = 0 : 0
seq.9 = 0 : 0
Current tAlpha = 8, tBeta = 32
-----------------------------------------------
holdOverDurLimit = 28800 sec
holdOverDelay = 0 sec
holdOverActiveDur = 3600 sec
standbyThr = 60 sec
-----------------------------------------------
PLL SEQ*
increment the PLL seq number
- there seems to be code to handle PLL SEQ [+/-], but this didn't seem to work for me
PLL SEQ INIT*
reinitialize the PLL
- seems to be more aggressive but similar to PLL INIT
PLL OFFSET SHOW*
print some PLL DAC/offset information
Current Dac Offset = 360858 (0005819a)
Current Dac Value = 356166 (00056f46)
Factory Dac Offset = 356284 (00056fbc)
Hour Dac Offset = 356284 (00056fbc)
PLL OFFSET SAVE*
doesn't look like this does much, maybe write to flash config area?
PLL OFFSET WR <hex value>*
write the provided offset to the 'Factory Dac Offset' and 'Hour Dac Offset' fields
PLL OFFSET CHANGE <[+/-]ppb_value>*
print the rate off offset change?
- change the pll offset by the given value
PLL HOLD*
print holdover test mode
PLL HOLD [IN/OUT]*
enter/leave holdover test mode
PLL HOLD TIME <[+/-]hours>*
start holdover mode after given hours
PLL WARMUP*
no idea
PLL ALIGN*
no idea
PLL SHIFT*
pll phase shift test (?)
PLLDIS <EN|DI> [EVEN|ODD]*
PLLDIS?
enable/disable/get dumping of PLL state information
- with even/odd, report on even/odd seconds respectively. with no option, report every second.
*2021/01/12 00:10:46 : -12, 356787, 210.000, 35.000, 5.544, 5.091, 3.300, 1.248, 0, 1, 0, 0
TIME : tIE, EFC, HoldDac(?), Temp, 5.5V, 5V, 3.3V, 1.2V, ?, ?, ?, ?
print state of PLL state dumping
ALARM <EN|DI>*
enable/disable alarms? no obvious effect.
STATUS <EN|DI>*
no obvious effect
PF?/FF?/NORMAL?/ABNORMAL?/HOLDALARM?*
print whether various GPIOs/alarms are enabled/disabled
TEST FPGA
test the FPGA
TEST SFLASH
erase the non-boot bank (!!) and test write/read to it. takes a few minutes. not recommended.
GPSCURRENT
print current GPS module (I assume) current consumption
GPSSAT
print currently visible (tracking?) PRNs
8 10,35,13,42,16,43,18,43,20,50,23,51,26,40,27,36
TESTMODE <EN|DI>
TESTMODE?
enable/disable/get TESTMODE (required for many commands)
RDL:MON <EN|DI>
RDL:MON?
set/get no obvious effect
*IDN?
print device type, serial number and version
ALARM:HARDWARE?
print any asserted hardware alarms
Possible: 0.5Hz|10MHz|Selftest|Power|EFC Limit Exceed|Internal Ref|FPGA
ALARM:OPERATION?
print any asserted operation alarms
Possible: Antenna|Holdover Exceed|Holdover 60minutes|EFC Near Limit|GPS Comm|GPS 1PPS|EXTREF
DIAGNOSTIC:OUTPUT <ON|OFF>
no obvious immediate effect, presumably prints additional information to the serial
DIAGNOSTIC:ROSCILLATOR:EFCONTROL:RELATIVE?
prints a floating point value, not sure the exact meaning, perhaps ppb of EFC applied?
-1.469E+1
DIAGNOSTIC:ROSCILLATOR:EFCONTROL:DATA?
prints a floating point value, not sure of the meaning, it is 0 for me
DIAGNOSTIC:LOOP?
print frequency offsets of available references
OCXO : +3.065E-9
EXT : Unavailable
DIAGNOSTIC:TCODE:[ERROR|STATUS]:[A|O]MASK <decimal value>
DIAGNOSTIC:TCODE:[ERROR|STATUS]:[A|O]MASK?
no idea what these do, but sets/gets some values
DIAGNOSTIC:LOG:READ? <decimal value>
would expect to print a partial log, but doesn't
DIAGNOSTIC:LOG:READ:ALL?
print all entries in the flash status log
DIAGNOSTIC:LOG:CLEAR
clear all entries in the flash status log
DIAGNOSTIC:HOLDOVER:DELAY?
print holdover delay (seconds)
GPS:POSITION <latlong in awkward format, see the output of GPS:POSITION?>
GPS:POSITION?
get/set GPS position
GPS:POSITION:HOLD:LAST?
print a GPS position, probably the last surveyed one?
[LINK|GPS]:REFERENCE:ADELAY <time in seconds, 1e-9 notation>
[LINK|GPS]:REFERENCE:ADELAY?
set/get reference antenna delay
SYNCHRONIZATION:INPUT:PPS:DELAY <time in seconds, 1e-9 notation>
set PPS input delay (not sure if applies to GPS PPS or EXT PPS?)
SYNCHRONIZATION:INPUT:PPS:DELAY
get PPS input delay
DIAGNOSTIC:ANTENNA:CFEED <ON|OFF>
DIAGNOSTIC:ANTENNA:CFEED?
enable/disable/get antenna power supply
GPS:REF:ANT:CURR?
print antenna current
GPS:REF:ANT:[SHORT|OPEN]:CURR:THR <current in ma (float)>
GPS:REF:ANT:[SHORT|OPEN]:CURR:THR?
get/set upper/lower current threshold for antenna alarm
GPS:SATELLITE:TRACKING:COUNT?
print the number of currently tracked satellites
GPS:SATELLITE:TRACKING:EMANGLE <angle>
GPS:SATELLITE:TRACKING:EMANGLE?
set/get the elevation mask angle
GPS:SATELLITE:TRACKING:[INCLUDE|IGNORE] <PRN> [PRN] ...
include or exclude PRNs from being used in the time solution
GPS:SATELLITE:TRACKING:[INCLUDE|IGNORE]:ALL
include or exclude ALL satellites
LED:GPSLOCK?
print state of 'lock' LED
SYNCHRONIZATION:HOLDOVER:DURATION:STATUS:THRESHOLD
SYNCHRONIZATION:HOLDOVER:DURATION:STATUS:THRESHOLD?
set/get holdover duration before going into alarm i think
SYNCHRONIZATION:[T|F]FOM?
get time|frequency figure of merit
for time this is discretized into orders of magnitude in ns
for frequency it is basically PLL lock/unlock
SYNCHRONIZATION:REFERENCE:[ENABLE|DISABLE] <GPS|EXT>
SYNCHRONIZATION:REFERENCE:ENABLE?
set/get enabled references
SYNCHRONIZATION:TINTERVAL?
print what i believe is the current phase error according to the pll
SYSTEM:PRESET
reset all (?) system state to defaults
SYSTEM:PON
power-on-reset the board
SYSTEM:STATUS?
print system status 'dashboard'
SYSTem:COMMUNICATION:[SERIAL1|SERIAL2]:BAUD <baud rate>
SYSTem:COMMUNICATION:[SERIAL1|SERIAL2]:BAUD?
set/get baud rate of serial ports
SYSTem:COMMUNICATION:[SERIAL1|SERIAL2]:PRESET
reset state of serial ports
OUTPUT:MODE?
print output mode (GPS or EXT)
OUTPUT:TP:SELECTION <PP1S|PP2S|8K|NONE>
OUTPUT:TP:SELECTION?
set/get output timepulse format. 8k doesn't seem to work for me, but is accepted.
OUTPUT:STANDBY:THRESHOLD <decimal value>
OUTPUT:STANDBY:THRESHOLD?
set/get output standby threshold
OUTPUT:STANDBY:TIE:THRESHOLD <decimal value>
OUTPUT:STANDBY:TIE:THRESHOLD?
set/get output time-interval-error threshold
OUTPUT:REFERENCE?
get time reference (NONE|GPS|EXT|OCXO) used for output
OUTPUT:ACTIVE:[ENABLE|DISABLE]
enable/disable output?
OUTPUT:ACTIVE:HOLDOVER:DURATION:THRESHOLD <seconds>
OUTPUT:ACTIVE:HOLDOVER:DURATION:THRESHOLD?
set/get output holdover threshold
OUTPUT:STATE?
get status of output (BLOCK|Normal|Abnormal|UNLOCK)
SN
CHANGESN
get current SN / offer to change
STAT
print general status information
STATUS
all signs point to this following the same code path as STAT, but i get different results. not sure how.
POSSTATUS
print GPS status information (pos, DOP, tracking, antenna)
TOD <EN|DI>
enable/disable 'time of day' dump every 1s
structure unknown for now
UDP <EN|DI>
enable/disable 'udp' dump every 1s
structure unknown for now, seems to be the same data as TOD but with decoded header, but not payload
working on this...
TIME:STRING?
print the current time in nonstandard format
2021/01/10 12:25:19
REFERENCE:TYPE GPS|EXT|NONE
REFERENCE:TYPE?
set/get the reference type
REFERENCE:PRIORITY?
no-op
DIAGNOSTIC:REFERENCE:SELECT?
print the currently selected reference (GPS|EXT)
DIAGNOSTIC:MODE:ID?
print the current mode (?). directly from GPIO1 pin 5
if set, EXT(WCDMA), else GPS(WCDMA)
PULLINRANGE <decimal value>
PULLINRANGE?
set/get OCXO pull-in range in ppb
SBAS:SAT <EN|DI>
SBAS:SAT?
enable/disable/get SBAS
IMAGE:INFO?
print information on flash images
IMAGE:ACT <BANK0|BANK1>
i think this activates the given image for next boot, but since i wiped my bank0, it is a no-op for me. use at your own risk.
IMAGE:DEL <BANK0|BANK1|ALL>
delete the given image(s)? seems risky...
All DEBUG mode commands:
Samsung UCCM (Universal Core Clock Module) DEBUG commands
Notes:
- Debug commands are case-sensitive and must be lowercase
- While in debug prompt, additional logs are printed (eg. pll state changes)
*** USE AT YOUR OWN RISK. DURING TESTING I WAS ABLE TO GET MY UNIT TO GO INTO EFC EXCEED AND WAS UNABLE TO RECOVER IT. EVENTUALLY IT CAME GOOD AFTER FIDDLING AND POWER CYCLING, BUT YMMV ***
DEBUG CLI
=========
help
print (incomplete) list of commands
exp
i don't know what this does, but it seems dangerous. sets an exponent or offset or something for something.
cls
clear screen
image info
print flash bank info
image del <bank0|bank1|all>
presumably does what it says. i didn't test it.
image act <bank0|bank1>
presumably sets the active bank
scpi
return to normal cli
reset [P|T] [wdt count]
reset to bootloader
- with T, 'watchdog test' - enter infinite loop, WDT should reset
- with P, not sure, possibly reset the saved config, adds message "FPGA Erase"
test
test something. not sure what or what the output means.
wdg mode [on|off]
print current watchdog mode
- with ON/OFF, set watchdog mode
wdg time [seconds]
print current watchdog timeout
- with value, set timeout
wdg test
enter infinite loop, WDT should reset board after current timeout
system
print system state information
------------------------------------------------------------------------------
TIME : 2021/01/11 22:53:50 (GPS)
Temperature = 33.500
------------------------------------------------------------------------------
SYSTEM MODE : WCDMA
ACT STATE : MASTER (non-Protect)
REF : GPS_REF (ok)
------------------------------------------------------------------------------
x-ACT in : L(other)
A/S in : H(slave)
Ref_sel : L(GPS)
mode_id : H(WCDMA)
------------------------------------------------------------------------------
Task Counts : DebugTask(518037), EngineTask(607414)
TodTask(517072), CtrlTask(1985673)
PllTask(1035348), BackUpTask(1029767)
TodEvenTaskCount(1031624)
------------------------------------------------------------------------------
Int Counts : pllIntCount(51816 - 51816), todIntCount(25907)
dacIntCount(5181602 - 5181601), twIntCount(51815 - 51815)
------------------------------------------------------------------------------
-----------------------------------
TIME := 2021/01/11 22:53:50
LAT := N 49:00:00.000
LON := W 123:00:00.000
HIGT := +18.018 m
system init
"Backup datas will be set to factory values and it will be applied after reset."
presumably resets stored config
ver
print firmware and hardware (fpga) versions
F/W Version := 1.0.0.3
H/W Version := 1.0.0.2
Description := DESCRIPTION TEST
- Samsung & SpringWave
time
print current time
time stemp
this commands toggles a variable, but i don't know what it does
md <hex address> [decimal block count]
dump memory starting at address. blocks are 256 bytes.
mm <hex address> <hex value> <value length>
write to memory. i didn't mess with this, i'm fairly sure of the format but didn't test it.
seems to not allow writes to addresses below the flash entry point, which is weird, since
flash isn't writable this way, so this would only be useful for writing to peripherals?
max value length is probably 4 bytes as it is read into an integer
ram
print the test type, size, and values of the memory test
fpga <r|w> <address> [value]
read/write from the FPGA registers
fpga test <address>
test the fpga? not exactly sure what it does. i think it might be a dedicated fpga command
that echoes the request byte back, and loops over all bytes checking this
fpga dup<rx|tx> [en|di]
without EN/DI, seems to print some info about the last packet received/transmitted?
not sure what EN/DI does
fpga reset
sends a command to the fpga, presumably resetting its state
fpga clock
print the 'clock fail byte'
eng dis
toggle dumping of u-blox debug information
eng [en|di]
enable/disable the GPS engine (pps processing / GPS reference)
eng hex
toggle hex dump of raw u-blox frames
eng init
send the initialization commands to the GPS module
eng baud [9600|19200|38400]
set the u-blox & USART baud rate and re-init engine
eng msg en <id 1-7>
enable u-blox periodic messages (see the u-blox 6 Receiver Description document)
1 = NAV_STATUS
2 = NAV_SVINFO
3 = NAV_POSLLH
4 = NAV_POSECEF
5 = TIM_TP
6 = TIM_SVIN
7 = NAV_DOP
eng reset <clear|set>
clear/set the GPIO attached to the u-blox ~reset line
reset will be detected and recovered
eng restart
restart the engine (not sure how this differs from init)
eng cfg
query various CFG blocks from the u-blox and print to console
eng ant <flags> <pins>
set u-blox CFG-ANT values
# NOTE: Changing any of these will probably just stop the GPSDO from working
# this is the internal GPS->FPGA interface, and doesn't compensate for the settings
eng pps period <decimal us>
set u-blox CFG-TP interval
eng pps width <decimal us>
set u-blox CFG-TP length
eng pps sign <+1|0|-1>
set u-blox CFG-TP status (PPS polarity)
eng pos
print current GPS position and mode
eng pos mode [none|survey|fix]
set u-blox CFG-TMODE2 timeMode. none seems to set fix mode.
eng pos para [svinacc|svindur] [decimal value]
with no parameters, show the CFG-TMODE2 parameters svinMinDur and svinAccLimit
with parameters, set the values
eng pos sbas <en|di>
enable/disable SBAS
dac
print dac testmode state and current value
dac test [on|off]
enable/print DAC test mode (enable writing of DAC values)
dac w <hex value>
write hex value to DAC (requires DAC test mode)
dac r
read current DAC value
adc dis
print raw AVR32 ADC values (voltage monitors)
adc con
print ADC voltages
pll state
print pll state information
pll ref <gps|ext>
set the PLL reference source
pll dis
toggle dumping PLL state every tick
*2021/01/12 01:14:22 : TIE=-17, FIR=-6.019, EFC=357107, HoldDac=-26.200, Temp=34.000, 5V=5.091
pll mon
toggle PLL monitor?
pll cal
start PLL calibration cycle
pll fac
print some PLL seq(?) information
-----------------------------------------------
Seq.s = 2 steps
seq.0 = 6 : 0
seq.1 = 3 : -5
--> seq.2 = 3 : -5 (*)
seq.3 = 2 : -8
seq.4 = 0 : 0
seq.5 = 0 : 0
seq.6 = 0 : 0
seq.7 = 0 : 0
seq.8 = 0 : 0
seq.9 = 0 : 0
Current tAlpha = 8, tBeta = 32
-----------------------------------------------
holdOverDurLimit = 28800 sec
holdOverDelay = 0 sec
holdOverActiveDur = 3600 sec
standbyThr = 60 sec
-----------------------------------------------
pll maxseq <seq>
set the maximum sequence?
pll seq <seq> <val1> <val2>
set the sequence values shown above for a given seq #
pll fac init
not sure, doesn't seem to reset any of the values show in pll fac
pll seq init
move pll to initial state
pll offset show
print PLL offset values
Current Dac Offset = 357098 (000572ea)
Current Dac Value = 357130 (0005730a)
Factory Dac Offset = 356284 (00056fbc)
Hour Dac Offset = 357258 (0005738a)
pll offset save
doesn't look like this does much, maybe write to flash config area?
pll offset wr <hex value>
write the provided offset to the 'Factory Dac Offset' and 'Hour Dac Offset' fields
pll offset change <[+/-]ppb_value>
print the rate of offset change?
- change the pll offset by the given value
pll hold
print holdover test mode
pll hold [in|out]
enter/leave holdover test mode
pll hold time <[+/-]hours>
start holdover mode after given hours
pll warmup
no idea
pll align
no idea
pll freerun <on|off>
put pll into/out of freerun mode
pll shift
pll phase shift test (?)
tod dis
toggle display of TOD packets in a slightly different format from UDP EN or TOD EN
[ TOD (4d27bdee) : 2021/01/12 01:29:18 - c5 00 80 00 00 00 00 28 1c 52 00 00 20 60 c1 91 00 00 00 00 00 00 00 00 00 00 00 4d 27 bd ee 00 12 60 00 05 87 00 00 00 00 08 51 ca ] 12~13
tod send <on|off>
enable/disable sending of TOD packets between FPGA and AVR32
tod cmd
print a Tod command count
tod cmd clr
clear the Tod command count
log all
print the full event log from flash
log last
<unimplemented>
log add <message>
add the provided message to log. spaces don't seem to be supported.
aging factor <holddac|dac|none>
select the aging factor that is in use
aging db
print saved aging data. entries seem to be stored every 10 minutes, save timestamp, temp and holdDac value
----------------------------------------------
slopeDAC = -0.737, Zone_cnt = 82, dacAging = -8.994E-3/sec,
----------------------------------------------
---------------------------------------------------------
...
[058] 1294449224 2021/01/12 01:13:44 34.000 357143.200
----------------------------------------------------- 0 -
dacAging = -8.994E-3/sec, holdDacAging = +0.0E+0/sec
---------------------------------------------------------
aging wr <pos> <timestamp> <temp> <holdDac>
manually write an entry to the aging db
aging fpgatime
aging fpgatime?
set/get fpga 'seccount' presumably secs since startup
aging delay
aging delay?
set/get aging init delay
aging unit
aging unit?
set/get aging unit count
aging sim
start aging simulation (??)
hangs GPSDO long enough that i power cycled it
ant val
read antenna adc values
ShuntVoltage = 7.340mV
BusVoltage = 5.144V
power = 7.570mW
Current = 29.400mA
ant thr
print antenna alarm thresholds
ant thr <open|short> <val>
theoretically should set the threshold values, but i can't figure out how to use it
alarm <all|hard|oper>
print alarms
alarm poll <on|off>
enable/disable periodic printing of alarm state
sat
dump satellite information (identical to SYSTEM:STATUS?)
port
print state of various I/Os
power
print system voltages (raw adc values)
power <5.5|5|3.3|1.2|all> <on|off>
set manual power alarm on given rail(s)
clkalign
reset clock alignment? not sure.
8k
run 8k test procedure? not sure what any of it means/does.
All Bootloader commands:
Samsung UCCM (Universal Core Clock Module) BOOTLOADER commands
Bootloader password: 123qwe
I have been unable to access the bootloader on my unit for some reason. Maybe something with my test setup.
It should be possible to enter it by pressing 'enter' while prompted and entering the password.
help
test
md
mm
fclr
image load <bank0|bank1>
image act <bank0|bank1>
image del <bank0|bank1|flash|all|*>
image crc <on|off>
fusing <bank0|bank1> <check|force>
go