Found this thread, pushed a fix. The suggested fix for the 2bit register is wrong. You need (x & 0x3) [0011] not 0x2..
Fix: https://github.com/iceman1001/proxmark3 … e5aa8c7055
The question of clock cycles remain. I set it as @OP. PMC_PLL_COUNT_BEFORE_LOCK(0x10)
]]>The PLLCOUNT field within the 'PMC PLL Clock Generator Register' is 6 bits wide, so the default value of 0x50 in the current bootrom.c source won't fit. The extra bit spills over into the OUT (frequency range) field, setting bit 0 of this field to 1 - which is invalid.
This is then OR'd with 0 (PMC_PLL_FREQUENCY_RANGE(0)) and so the OUT field remains set to 01 - invalid.
notserpe's proposed fix would work:
+#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x & 0x3F)<<8) will limit any data set in the PLLCOUNT field to 6 bits, and
+#define PMC_PLL_FREQUENCY_RANGE(x) ((x & 0x2)<<14) will ensure that bit 0 of the OUT field is always 0.
The question then is did the original coder expect the PLLCOUNT to be 0x50, 80 clock cycles, or 0x10, 16 clock cycles?
If it was 80 clock cycles then the line in bootrom.c should be PMC_PLL_COUNT_BEFORE_LOCK(0x3F) (max 63 clock cycles).
If it was 16 clock cycles then the line in bootrom.c should be PMC_PLL_COUNT_BEFORE_LOCK(0x10), as notserpe proposes.
...
// PLL output clock frequency in range 150 - 180 MHz needs CKGR_PLL = 10
// PLL output is MAINCK * multiplier / divisor = 16Mhz * 12 / 2 = 96Mhz
AT91C_BASE_PMC->PMC_PLLR =
PMC_PLL_DIVISOR(2) |
PMC_PLL_COUNT_BEFORE_LOCK(0x50) |
PMC_PLL_FREQUENCY_RANGE(0) |
PMC_PLL_MULTIPLIER(12) |
PMC_PLL_USB_DIVISOR(1);
// wait for PLL to lock
while ( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) )
...
where from include/proxmark3.h:
#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x)<<8)
#define PMC_PLL_DIVISOR(x) (x)
#define PMC_PLL_MULTIPLIER(x) (((x)-1)<<16)
#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x)<<8)
#define PMC_PLL_FREQUENCY_RANGE(x) ((x)<<14)
#define PMC_PLL_USB_DIVISOR(x) ((x)<<28)
It appears to me from my reading of the AT91SAM7S256 documentation (doc6175.pdf, page 206 and page 564), that
PMC_PLL_COUNT_BEFORE_LOCK(0x50) is pushing a bit into location 14 (of the OUT field) which this code thinks is setting to 0 with PMC_PLL_FREQUENCY_RANGE(0). This consequently gives out the value of (01) which is given as Reserved in some versions of the doc or simply not listed in the others.
Can someone confirm?
Simple patch to fix is included below:
Index: include/proxmark3.h
===================================================================
--- include/proxmark3.h (revision 459)
+++ include/proxmark3.h (working copy)
@@ -43,8 +43,8 @@
#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x)<<8)
#define PMC_PLL_DIVISOR(x) (x)
#define PMC_PLL_MULTIPLIER(x) (((x)-1)<<16)
-#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x)<<8)
-#define PMC_PLL_FREQUENCY_RANGE(x) ((x)<<14)
+#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x & 0x3F)<<8)
+#define PMC_PLL_FREQUENCY_RANGE(x) ((x & 0x2)<<14)
#define PMC_PLL_USB_DIVISOR(x) ((x)<<28)
#define UDP_INTERRUPT_ENDPOINT(x) (1<<(x))
Index: bootrom/bootrom.c
===================================================================
--- bootrom/bootrom.c (revision 459)
+++ bootrom/bootrom.c (working copy)
@@ -47,7 +47,7 @@
// PLL output is MAINCK * multiplier / divisor = 16Mhz * 12 / 2 = 96Mhz
AT91C_BASE_PMC->PMC_PLLR =
PMC_PLL_DIVISOR(2) |
- PMC_PLL_COUNT_BEFORE_LOCK(0x50) |
+ PMC_PLL_COUNT_BEFORE_LOCK(0x10) |
PMC_PLL_FREQUENCY_RANGE(0) |
PMC_PLL_MULTIPLIER(12) |
PMC_PLL_USB_DIVISOR(1);