Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAME51J20A: HW-registers not editable through debug #222

Open
pr2zi opened this issue Mar 1, 2024 · 1 comment
Open

SAME51J20A: HW-registers not editable through debug #222

pr2zi opened this issue Mar 1, 2024 · 1 comment

Comments

@pr2zi
Copy link

pr2zi commented Mar 1, 2024

I am currently developing on the SAME51J20A and need to turn down the MCU frequency to 100 MHz or less. I previsouly managed to tune it up to 120 MHz but my program fails when trying to do so.
First of all I was developing on VSC with platformio and realised that the program is stopping at:

while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY || 0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK); //wait for the DPLLSTATUS.bit.CLKRDY = ReadyBit= 1 and LOCKbit = 1;

and is never able to leave that.
I then pasted exakt the same code into my Microchipstudio test project to use their debugger for better clearance and realised that my code works there. Upon further investigations I saw that commands likeOSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = 0;don’t do anything in my Peripherals view. Also closing it and reopening does nothing to the values. It also seems like values that are initialized on MCU startup are also completly ignored by this view.
Some other registers can be changed but i don't undestand why few specific registers seem to be locked for pio. HW register adress are confirmed to be the same.

Below my full Code for clock init:

#define CLOCK100

#define GCLK0 0
#define GCLK1 1
#define GCLK2 2
#define GCLK3 3
#define GCLK4 4
#define GCLK5 5
#define GCLK6 6
//testing

#ifdef CLOCK100 // for higher temperature for up to 125°C
#define F_CPU 11000000
#define LDR_var (((unsigned long)F_CPU * 32) / 32768)
void clock_init()
{
    NVMCTRL->CTRLA.bit.AUTOWS = 1;

    GCLK->CTRLA.bit.SWRST = 1;
    while (GCLK->CTRLA.bit.SWRST);

    //switch on the extern 32,768 KHz Quarz
    OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE |
                              OSC32KCTRL_XOSC32K_XTALEN |
                              OSC32KCTRL_XOSC32K_EN32K |
                              OSC32KCTRL_XOSC32K_RUNSTDBY |
                              OSC32KCTRL_XOSC32K_STARTUP(7);

    while (0 == OSC32KCTRL->STATUS.bit.XOSC32KRDY);

    //XOSC32K -> GCLK2
	PORT->Group[PORTA].PINCFG[16].reg = PORT_PINCFG_PMUXEN| PORT_PINCFG_DRVSTR; // Enable peripheral multiplexer
	PORT->Group[PORTA].PMUX[16/2].reg = 12; // Set peripheral function F (TCC0/WO[2])
    GCLK->GENCTRL[GCLK2].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_XOSC32K) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_OE;

/* disable the DPLL before changing the configuration */
    OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = 0;
    while (OSCCTRL->Dpll[0].DPLLSYNCBUSY.reg) {}

    //XOSC32K -> GCLK2 -> FDPLL0
    GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = GCLK_PCHCTRL_GEN_GCLK2 | GCLK_PCHCTRL_CHEN;

    while (0 == (GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg & GCLK_PCHCTRL_CHEN));

    OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(LDR_var % 32) | OSCCTRL_DPLLRATIO_LDR((LDR_var / 32) - 1);

    OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_XOSC32 |
                                     OSCCTRL_DPLLCTRLB_DIV(1) |
                                     OSCCTRL_DPLLCTRLB_WUF |
                                     OSCCTRL_DPLLCTRLB_LBYPASS;

    //FDPLL0 enable
    OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE | OSCCTRL_DPLLCTRLA_RUNSTDBY;
	
	//REG_OSCCTRL_DPLLCTRLB0 = 0;    
    //REG_OSCCTRL_DPLLCTRLB0 = OSCCTRL_DPLLCTRLB_LBYPASS | OSCCTRL_DPLLCTRLB_REFCLK(0);              // errata says to bypass lock when using internal 32k oscillator as source


    OSCCTRL->Dpll[0].DPLLCTRLA.bit.ENABLE = 1;
    while (OSCCTRL->Dpll[0].DPLLSYNCBUSY.reg) {}

    while (0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY || 0 == OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK);       //wait for the DPLLSTATUS.bit.CLKRDY = ReadyBit= 1 and LOCKbit = 1;

    //FDPLL0 (120MHz) --> CPU
	PORT->Group[PORTB].PINCFG[14].reg = PORT_PINCFG_PMUXEN| PORT_PINCFG_DRVSTR; // Enable peripheral multiplexer
	PORT->Group[PORTB].PMUX[14/2].reg = 12; // Set peripheral function F (TCC0/WO[2])
    GCLK->GENCTRL[GCLK0].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL0) | GCLK_GENCTRL_RUNSTDBY | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_OE;

    while ((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK0) == GCLK_SYNCBUSY_GENCTRL_GCLK0);

    OSCCTRL->DFLLCTRLA.reg = 0;

    OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP(0x1) |
                           OSCCTRL_DFLLMUL_FSTEP(0x1) |
                           OSCCTRL_DFLLMUL_MUL(0xBB80);

    while (OSCCTRL->DFLLSYNC.bit.DFLLMUL);

    OSCCTRL->DFLLCTRLB.reg = 0;
    while (OSCCTRL->DFLLSYNC.bit.DFLLCTRLB);

    OSCCTRL->DFLLCTRLA.bit.ENABLE = 1;
    while (OSCCTRL->DFLLSYNC.bit.ENABLE);

    OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg;
    while (OSCCTRL->DFLLSYNC.bit.DFLLVAL);

    OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_WAITLOCK |
                             OSCCTRL_DFLLCTRLB_CCDIS |
                             OSCCTRL_DFLLCTRLB_USBCRM;

    while (!OSCCTRL->STATUS.bit.DFLLRDY);
    //Switch Generic Clock Generator 5 to DFLL48M. for SERCOM5 48 MHz
    GCLK->GENCTRL[GCLK5].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) |
                               GCLK_GENCTRL_RUNSTDBY |
                               GCLK_GENCTRL_IDC |
                               GCLK_GENCTRL_OE |
                               GCLK_GENCTRL_GENEN;

    while (GCLK->SYNCBUSY.bit.GENCTRL5);
    //Switch Generic Clock Generator 6 to 120MHz. for observation purposeses
    GCLK->GENCTRL[GCLK6].reg = GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL0) |
                               GCLK_GENCTRL_RUNSTDBY |
                               GCLK_GENCTRL_IDC |
                               GCLK_GENCTRL_OE |
                               GCLK_GENCTRL_GENEN;
    while (GCLK->SYNCBUSY.bit.GENCTRL6);

//GCLK5 -> SERCOM5 48 MHz
    GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK5 | GCLK_PCHCTRL_CHEN;
    while ((GCLK->PCHCTRL[SERCOM5_GCLK_ID_CORE].reg & GCLK_PCHCTRL_CHEN) != GCLK_PCHCTRL_CHEN);

    //FDPLL0 -> GCLK1 -> GCLK6 -> Pb12 -> LED Alive 120MHz
//--------------------------------------------------------------------------------------------------
//                                                                                    !!! with Bit12 = 1 !!!
    GCLK->GENCTRL[GCLK1].reg =
            GCLK_GENCTRL_DIV(120) | GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DPLL0) | GCLK_GENCTRL_DIVSEL | GCLK_GENCTRL_GENEN;
//							120 : 120 = 1 MHz with GCLK_GENCTRL_DIVSEL 100KHz     ^------------------------------0x07 (Manual page 166)
    while ((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK1) == GCLK_SYNCBUSY_GENCTRL_GCLK1) {
        //wait for the GCLK1 Generator 1 synchronization
    }
//--------------------------------------------------------------------------------------------------
//                                                                                        !!! with Bit12 = 1 !!!   v---PB12 Pin25
    GCLK->GENCTRL[GCLK6].reg =
            GCLK_GENCTRL_DIV(100) | GCLK_GENCTRL_SRC(GCLK_SOURCE_GCLKGEN1) | GCLK_GENCTRL_DIVSEL | GCLK_GENCTRL_OE |
            GCLK_GENCTRL_GENEN;
//							1MHz : 100 = 10 kHz with GCLK_GENCTRL_DIVSEL 1,8Hz 0,56 ms Periode                     ^------------------------------0x03 (Manual page 166)
    while ((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK6) == GCLK_SYNCBUSY_GENCTRL_GCLK6) {
        //wait for the GCLK1 Generator 6 synchronization
    }


    //FDPLL0 -> GCLK4
    GCLK->GENCTRL[GCLK4].reg = GCLK_GENCTRL_DIV(2) | GCLK_GENCTRL_SRC(GCLK_SOURCE_DPLL0) | GCLK_GENCTRL_GENEN;
//                                120Mhz :  2 = 60MHz             ^---------------------------------------------0x07 DPLL0 DPLL0 output (Manual Seite 166)
//                                120Mhz :  5 = 24MHz
//                                120Mhz : 15 =  8MHz
    while((GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL_GCLK4) == GCLK_SYNCBUSY_GENCTRL_GCLK4)
    {
        // wait for GCLK4 synchronization
    }
}
@ivankravets ivankravets changed the title HW-registers not editable through debug SAME51J20A: HW-registers not editable through debug Mar 1, 2024
@ivankravets ivankravets transferred this issue from platformio/platformio-core Mar 1, 2024
@valeros
Copy link
Member

valeros commented Mar 1, 2024

Hi @pr2zi, there is no support for SAME51J20A in this development platform, besides the atmelsam dev-platform only supports Arduino and Zephyr, but to you code doesn't seem to be either of those.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants