running embOS on AT91sam7 with PLL turned off

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • running embOS on AT91sam7 with PLL turned off


    I am using an AT91SAM7s256 using embOS.

    I am attempting to switch from PLL to just using the Main Oscillator in order to conserve power as I need this to run off a battery.
    Every time I try to switch off the PLL, the microcontroller does wierd things, such as overwrite the embOS data structures.

    My switching code is:

    _PMC_MCKR = 1; /* (PMC) Clock from PLL is selected */
    while((_PMC_SR & (1 << 3)) == 0); /* Wait until main clock is ready */
    _PMC_MCKR |= (0 << 2);
    while((_PMC_SR & (1 << 3)) == 0); /* Wait until main clock is ready */

    _PMC_PLLR = 0;
    while((_PMC_SR & (1 << 3)) == 0); /* Wait until main clock is ready

    This is driving me crazy :cursing:
  • Hello,

    The reported problem has nothing to do with embOS.
    Perhaps, you have trouble, because of two problems listed under the errata
    of ATMEL SAM7S, MCK: Limited Master Clock Frequency Ranges
    says, that operating frequency range of MCLK has to be below 3MHz or above 19MHz.
    The upper limit depends on wait states for the Flash and may be even higher. PMC: Programming CSS in PMC_MCKR Register
    says, that the device may malfunction when code runs from FLASH and clock source is switched from PLL clock to Main clock or from PLL clock to Slow clock.

    Until now, we did not try to switch back to Main clock or slow clock.
    Therefore we can not offer a solution or deliver any code sample of a correct switching sequence which runs in RAM.
    You may try to use a __ramfunc for the switching sequence and should disable interrupts before calling the function.

    To save power using embOS, you may also switch off the CPU clock in OS_Idle():

    void OS_Idle(void) { /* Idle loop: No task is ready to exec */
    while (1) {
    #if DEBUG == 0
    _PMC_SCDR = 1; // Switch off CPU clock to save power

  • using __ramfunc works, but embosview stops working

    Thank you, I have used a __ramfunc to switch off the PLL after device startup and device continues operation.

    The actual function I used was:

    #pragma object_attribute=__ramfunc
    void ReconfigureMainClock(void)

    AT91C_BASE_PMC->PMC_MCKR = 1; /* (PMC) Switch Clock to Main Oscillator */
    while((AT91C_BASE_PMC->PMC_SR & (1 << 3)) == 0); /* Wait until main clock is ready */
    AT91C_BASE_PMC->PMC_MCKR |= (1 << 2);
    while((AT91C_BASE_PMC->PMC_SR & (1 << 3)) == 0); /* Wait until main clock is ready */
    /* (PMC) Selected clock (no divider) */
    AT91C_BASE_PMC->PMC_PLLR = 0; /* switch PLL off */
    }// void ReconfigureMainClock(void)

    I call this function in a task as follows:

    If I run the main clock at crystal freq/2 (in my case [img][/img]9.216 mhz) then the embOSview at 38400 baud functions.
    If I try run at a lower speed (4.608 mhz) then embOsview stops working. (A uart at 1200 baud still works).
    I am a bit puzzled by this as 4.608 mhz should be enough to transmit at 38400 baud.

  • Hi,

    the UART for embOSView uses the USART Baud Rate Generator Register CD value to generate the baudrate for communication.
    The clock source for the baudrate generator is the system clock divided by 16.
    Using 4.608 MHz as system clock results in a calculated baudrate register value of 7.5 for 38400 baud, which is truncated to 7.
    A value of 7 generates a real baudrate of 41.1 kbaud which is about 7% above the nominal baudrate.
    The frequency error is to big to allow UART communication.
    You may reduce the baudrate for communication with embOSView to 19200 baud which will work with 4.608 MHz,
    or you may initialize the fractional baud rate generator.
    Alternatively, you may select the 8x oversampling method for the USART by setting the OVER bit (bit 19) in the USART mode register during initialization.
    The calculation of the value for the baud rate generator register has to be modified accordingly then.