fix overwriting return value in one case
[RRG-proxmark3.git] / doc / clocks.md
blob9e0384d231f4787823862df4b4cf242c9086f759
1 <a id="Top"></a>
3 # Notes on device side clocks
4 The device side firmware uses a range of different clocks.  Here is an attempt to document the clocks in use and for what they are used.
7 # Table of Contents
8 - [Notes on device side clocks](#notes-on-device-side-clocks)
9 - [Table of Contents](#table-of-contents)
10   - [Units](#units)
11   - [Slow clock](#slow-clock)
12   - [Main Oscillator / MAINCK](#main-oscillator--mainck)
13   - [PLL clock](#pll-clock)
14   - [Master Clock MCK, Processor Clock PCK, USB clock UDPCK](#master-clock-mck-processor-clock-pck-usb-clock-udpck)
15   - [Peripheral clocks](#peripheral-clocks)
16   - [1 kHz RTC: TickCount functions](#1-khz-rtc-tickcount-functions)
17   - [Occasional PWM timer](#occasional-pwm-timer)
18   - [Occasional TC0+TC1 / CountUS functions](#occasional-tc0tc1--countus-functions)
19   - [Occasional TC0+TC1+TC2 SSP\_CLK from FPGA / CountSspClk functions](#occasional-tc0tc1tc2-ssp_clk-from-fpga--countsspclk-functions)
20   - [Occasional TC0+TC1 / Ticks functions](#occasional-tc0tc1--ticks-functions)
23 ## Units
24 ^[Top](#top)
26 Good calculator
27 https://www.unitjuggler.com/convert-frequency-from-MHz-to-ns(p).html?val=3.39
29 Basic units of time measurment or how long in time is a Hertz?
31 ```
32 1 hertz   = 1 second                   =  1000 milli seconds
33 10 Hertz  = 1 / 10         = 0,1       =  100 milli seconds
34 100 Hertz = 1 / 100        = 0,01      =  10 milli seconds
35 1 kHz     = 1 / 1000       = 0,001     =  1 milli seconds 
36 10 kHz    = 1 / 10 000     = 0,000 1   =  100 micro seconds
37 100 kHz   = 1 / 100 000    = 0,000 01  =  10 micro seconds 
38 1 MHZ     = 1 / 1 000 000  = 0,000 001 =  1 micro seconds
39 ```
41 - kHz, Kilo Hertz, 1000 Hertz
42 - MHz, Mega Hertz, 1000 000 Hertz
45 Basic units of time you will run into in the RFID world.
47 ```
48 13.56 MHz = 1 / 13 560 000 = 73,74 nano seconds  = 0,07374 micro seconds
49 125 kHz   = 1/ 125 000     = 8 micro seconds
50 ```
52 Given these units the following clocks used by Proxmark3 will make more sense.
54 Like the SSP Clock running at 3.39 MHz. 
55 3.39 MHz = 1 / 3 390 000 = 294,98 nano seconds   = 0,2949 micro seconds
57 1 tick at 3.39 MHz is 294.98 nano seconds.
61 ## Slow clock
62 ^[Top](#top)
64 ~32kHz internal RC clock
66 Can be between 22 and 42 kHz
68 ## Main Oscillator / MAINCK
69 ^[Top](#top)
71 cf `PMC_MOR` register
73 16 MHz, based on external Xtal
75 ## PLL clock
76 ^[Top](#top)
78 cf `PMC_PLLR` register
80 96 MHz (MAINCK * 12 / 2)
82 ## Master Clock MCK, Processor Clock PCK, USB clock UDPCK
83 ^[Top](#top)
85 cf `common_arm/clocks.c`
87 cf `PMC_MCKR` and `PMC_SCER` registers
89 * MCK starts with RC slow clock (22 to 42 kHz).
90 * Then MCK configured from PLL: 48 MHz (PLL / 2)
92 cf `bootrom.c`:
94 PCK can be disabled to enter idle mode, but on Proxmark3 it's always on, so PCK is also 48 MHz.
96 USB need to be clocked at 48 MHz from the PLL, so PLL / 2 (cf `CKGR_PLLR`).
99 ## Peripheral clocks
100 ^[Top](#top)
102 cf `bootrom.c`:
104 Distribute MCK/PCK? clock to Parallel I/O controller, ADC, SPI, Synchronous Serial controller, PWM controller, USB.
106 cf `appmain.c`
108 Activate PCK0 pin as clock output, based on PLL / 4 = 24 MHz, for the FPGA.
110 ## 1 kHz RTC: TickCount functions
111 ^[Top](#top)
113 cf `armsrc/ticks.c`
115 cf `PMC_MCFR` and `RTTC_RTMR` registers for configuration, `RTTC_RTVR` register for reading value.
117 Characteristics:
119 * 1 kHz, 32b (49 days), if used with 16b: 65s
120 * Configured at boot (or TIA) with `StartTickCount()`
121 * Time events with `GetTickCount()`/`GetTickCountDeltaDelta()`, see example
122 * Coarse, based on the ~32kHz RC slow clock with some adjustment factor computed by TIA
123 * Maybe 2.5% error, can increase if temperature conditions change and no TIA is recomputed
124 * If TimingIntervalAcquisition() is called later, StartTickCount() is called again and RTC is reset
126 Usage:
129 uint32_t ti = GetTickCount();
130 ...do stuff...
131 uint32_t delta = GetTickCountDelta(ti);
134 Current usages:
136 * cheap random for nonces, e.g. `prng_successor(GetTickCount(), 32)`
137 * rough timing of some operations, only for informative purposes
138 * timeouts
139 * USB connection speed measure
141 ## Occasional PWM timer
142 ^[Top](#top)
144 * `void SpinDelayUs(int us)`
145 * `void SpinDelay(int ms)` based on SpinDelayUs
146 * `void SpinDelayUsPrecision(int us)`
148 Busy wait based on 46.875 kHz PWM Channel 0
150 * 21.3 us precision and maximum 1.39 s
151 * *Precision* variant: 0.7 us precision and maximum 43 ms
153 ## Occasional TC0+TC1 / CountUS functions
154 ^[Top](#top)
156 cf `armsrc/ticks.c`
158 About 1 us precision
160 * `void StartCountUS(void)`
161 * `uint32_t RAMFUNC GetCountUS(void)`
163 Use two chained timers TC0 and TC1.
164 TC0 runs at 1.5 MHz and TC1 is clocked when TC0 reaches 0xC000.
166 Maximal value: 0x7fffffff = 2147 s
168 Can't be used at the same time as CountSspClk or Ticks functions.
170 ## Occasional TC0+TC1+TC2 SSP_CLK from FPGA / CountSspClk functions
171 ^[Top](#top)
173 cf `armsrc/ticks.c`
175 About 1 cycle of 13.56 MHz? precision
177 * `void StartCountSspClk(void)`
178 * `void ResetSspClk(void)`
179 * `uint32_t RAMFUNC GetCountSspClk(void)`
180 * `uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start)` <= **TODO** could be used more often
182 Use two chained timers TC0 and TC1.
183 TC0 runs at SSP_CLK from FPGA (13.56 MHz?) and TC1 is clocked when TC0 loops.
185 Usage:
187 * for iso14443 commands to count field cycles
188 * Also usable with FPGA in LF mode ?? cf `armsrc/legicrfsim.c` SSP Clock is clocked by the FPGA at 212 kHz (sub-carrier frequency)
190 Can't be used at the same time as CountUS or Ticks functions.
192 ## Occasional TC0+TC1 / Ticks functions
193 ^[Top](#top)
195 cf `armsrc/ticks.c`
197 1.5 MHz
199 * `void StartTicks(void)`
200 * `uint32_t GetTicks(void)` <= **TODO** why no GetTicksDelta ?
201 * `void WaitTicks(uint32_t ticks)`
202 * `void WaitUS(uint32_t us)`
203 * `void WaitMS(uint32_t ms)`
204 * `void StopTicks(void)` <= **TODO** why a stop for this timer and not for CountUS / CountSspClk ?
206 Use two chained timers TC0 and TC1.
207 TC0 runs at 1.5 MHz and TC1 is clocked when TC0 loops.
209 Maximal value: 0xffffffff = 2863 s (but don't use high value with WaitTicks else you'll trigger WDT)
211 Usage:
213 * Timer for bitbanging, or LF stuff when you need a very precise timer
215 Can't be used at the same time as CountUS or CountSspClk functions.