We have wired a 12 MHz ceramic oscillator to an Arduino Due. We need to adjust the clock initialization code for this to work. However, we cannot figure out how to modify this code. Following the reset handler with a Black Magic debugger, it seems that it calls init in variant.cpp, which calls SystemInit(), which appears to be in system_sam3xa.c. However, I cannot step into SystemInit and any code I add to SystemInit or anywhere in system_sam3xa.c does not execute. I also cannot add breakpoints, and it does not appear to compile in the verbose build output.
Any advice on where clock initialization occurs? If the Arduino toolchain clock configuration does not execute for Platformio projects, that is a concern, as the Due would then not run at the 84 MHz PLL (to my understanding)
It appears that system_sam3xa.c is precompiled into libsam_sam3x8e_gcc_rel.a, which I discovered by attempting to copy the SystemInit functionality into variant.cpp, and getting the error that SystemCoreClock is already defined in libsam_sam3x8e_gcc_rel.a(system_sam3xa.o).
This appears to get compiled prior to the project compilation, as system_sam3xa does not come up in the verbose build output. Any advice on how to edit the version of system_sam3xa that gets compiled into this .a file, and where it would exist on a Windows machine?
And it’s not a possibility to keep the default SystemInit() and call your correct clock init code afterwards? Even if it boots the freuqency too low / not to the optimal one, if the resulting frequency is not too high, you should be able to reach the regular setup()
function of your firmware in which you can reconfigure the clocks. With the regular CMSIS system_...
system, the SystemCoreClock
variable should be updatable, though some peripherals might need a reinit if they explicitly calculated dividers / baud rates (such as hardware UART), e.g., Serial.end()
, Serial.begin(115200)
etc.
Another possibility is that you can, with an extra script,
- make a temporary copy of
C:\Users\<user>\.platformio\packages\framework-arduino-sam\variants\arduino_due_x\libsam_sam3x8e_gcc_rel.a
- delete the
SystemInit()
symbol or the whole system_sam3xa.o
object file from the library, arm-none-eabi-ar dv libsam_sam3x8e_gcc_rel.a system_sam3xa.o
- link against the modified temporary copy of that library, meaning the
SystemInit()
etc symbols will now be taken from your code
(from libsam_sam3x8e_gcc_rel.a.txt
)
system_sam3xa.o:
00000000 D SystemCoreClock
00000000 T SystemCoreClockUpdate
00000000 T SystemInit
00000000 T system_init_flash
Yet another possibility is to use the provided makefile fror the libvariant_arduino_due_x.mk
to generate a new version of libsam_sam3x8e_gcc_rel.a
, which you can then link against, see
The issue with keeping the default SystemInit() is that it attempts to use a double-ended crystal resonator to set up the PLL, which does not exist on our board - we have replaced it with a single ended ceramic oscillator - so the program crashes before getting to our setup() function. I will attempt your other suggestions and get back to you - thank you.
Solved! Thank you so much. The next step for us is to get this working on our custom PCB with the SAM3X8A, rather than this frankenstein Due board. I may have to return to this forum for help with that.