The short problem statement: After some problem solving, I found that my micro is hanging/crashing shortly after the program begins any time I'm using the on-chip PLL as a master clock (which is set to 110MHz). I've gone through the motions to reduce the problem set down to the barest essentials, and am unable to determine what I'm doing wrong or missing to make the device happy to run at speed. I'm looking to see if anyone on here has used the SAM CortexM4 series from Atmel and might be able to lend some insight.
-----------------------
Long version:
After fighting to get the USART setup with the G55 project I've built up, I found that data was being written in a very strange manner to a buffer. It appeared as though the device was handling byte sized buffers as if they were full words. I went through a long process, and found that so long as I set the master clock to be source from the main clock (external crystal at 12.288MHz) the device operated correctly without issue on the same code. My finding was that anytime I was running the device on the PLL, be it from 50MHz to 112MHz, the whole processor would crash and stop responding. Having dealt with the CortexM0 and M3 series devices, this told me that I likely failed to provide a clock resource to a peripheral, or failed to provide it a slow enough clock (relative to Master) that it would still run. After configuring the PMC thoroughly, ensuring that everything which needed a clock resource had one, and going over the datasheet a few times, I began purging large sections of code to try and isolate the source of the problem. I've now boiled my code down to the barest essentials to test the problem, and it appears to be something wrong outside of the peripherals. I found mention that the low-voltage regulator needs to be adjusted for high speed operation. I addressed that. There is nothing left that I can find or think of to cause this problem.
In the below example code, set the Master clock to run on the external oscillator (PMC_MCKR=1), and the while loop shifts all the values up one, and increments the value of the last register. Essentially a glorified array of 10 counters. It works at 12.288MHz.
Set PMC_MCKR=2 for PLL usage (and I can confirm the PLL is outputting ~110MHz), and the txBufpage1[] array gets sporadically filled with garbage data instead (if you can pause the debugger quickly enough), and after a moment the processor itself just stops responding/crashes.
#include "g55_device.h"
PIO_Type *pPortA = PORTA;
PIO_Type *pPortB = PORTB;
FLEXCOM_Type *pFlex0 = FLEXCOM0;
SUPC_Type *pSUPC = SUPC;
PMC_Type *pPMC = PMC;
int main(void)
{
volatile uint32_t pointerValue;
volatile uint8_t txBufpage1[10];
for(unsigned char index=0;index<10;index++)
txBufpage1[index]=0;
pPMC->PMC_WPMR = (0x504D43 << 8); // disable write protection for the PMC
pPMC->PMC_SCER = 0x500; // enable PCK2 and PCK0
pPMC->PMC_PCER0 = 0x800; // enable PID11 (PIO A) clock
pPMC->PMC_PCK2 = 0x2; // this is a routing of the master clock to an output pin.
pPMC->PMC_PCK0 = 0x1; // general 'lower level' clock business.
pPMC->CKGR_MCFR = 6110; // let the device know the main clock is about 12.288MHz
pSUPC->SUPC_MR= 0xA5804F00; // set the voltage regulator to 'high performance' mode.
while(0==(pPMC->PMC_SR & 0x10000)); // wait for oscillator to settle.
pPMC->CKGR_MOR = 0x0337000A;
pPMC->PMC_MCKR = 1; // use external osc
// start experimenting with the PLL....
pPMC->CKGR_PLLAR = (3356 <<16) | (0x3F << 8); // start with the thing disabled.
pPMC->CKGR_PLLAR = (3356 <<16) | (0x3F << 8) | 1; // start with the thing now enable it.
while(0==(pPMC->PMC_SR & 0x2)); // wait for PLL to lock...
pPMC->PMC_MCKR = 2; // use PLL =2
while(0==(pPMC->PMC_SR & 0x8)); // wait for master clock to be ready.
while(1){
for(uint8_t index=0;index<9;index++)
txBufpage1[9-index]=txBufpage1[8-index];
txBufpage1[0]++;
}
/* Replace with your application code */
while (1)
{
// okay ... let's try stuffing some data into the serial port.
}
}