Beispiel #1
0
/**
 * Calculate the necessary values in order to have the peripheral
 * clock running at the desired frequency. As this value is only a
 * divider, this normally requires a call to
 * SystemClocksCalcCpuClockSettings() before, because the CPU
 * frequency is needed to find the divider value.
 *
 * @see system.c::SystemConfig()
 *
 * @return Nothing (the result is put into the struct)
 */
void SystemClocksCalcPeripheralClockSettings(SystemClocksSettings *s, 
					     uint32_t peripheralFrequency) 
{
  #ifdef EXTENDED_TEST_CASE
    s->error = Error_None;
  #endif

  if (peripheralFrequency > CPUCOREMAXFREQUENCY) 
    {
      peripheralFrequency = CPUCOREMAXFREQUENCY;

      #ifdef EXTENDED_TEST_CASE
        s->error = Error_RequestedFrequencyTooHigh;
      #endif
    }

  const uint32_t cpuFrequency = SystemClocksGetCpuFrequency(s);

  uint8_t i;
  for (i = 0; i < pbDivsCount; i++) 
    {
      if (cpuFrequency == peripheralFrequency * pbDivs[i]) 
	{
	  s->PBDIV = i;
	  // Match found
	  return;
	}
    }

  // No match: Use default value
  s->PBDIV = 0; // /1
  #ifdef EXTENDED_TEST_CASE
    s->error = Error_NoCombinationFound;
  #endif
}
Beispiel #2
0
/**
 * Write the clock settings into the registers; this effectively applies the
 * new settings, and will change the CPU frequency, peripheral
 * frequency, and the number of flash wait states.
 *
 * This normally requires a call to
 * SystemClocksCalcCpuClockSettings(), and
 * SystemClocksCalcPeripheralClockSettings() before.
 *
 * @see system.c::SystemConfig()
 *
 * @return Nothing
 */
void SystemClocksWriteSettings(const SystemClocksSettings *s) 
{
    SystemUnlock();

    /**
    * @page 186 
    *
    * PIC32MX Family Clock Diagram
    *
    * @page 189
    *
    * OSCCON: Oscillator Control Register
    */

    /* 
    * bit 10-8 NOSC<2:0>: New Oscillator Selection bits
    *     011 = Primary Oscillator with PLL module (XTPLL, HSPLL or ECPLL)
    */
    OSCCONbits.NOSC = POSCPLL;

    /*
    * bit 29-27 PLLODIV<2:0>: Output Divider for PLL
    */
    OSCCONbits.PLLODIV = s->PLLODIV;

    /*
    * bit 18-16 PLLMULT<2:0>: PLL Multiplier bits
    */
    OSCCONbits.PLLMULT = s->PLLMULT;

    /*
    * bit 0 OSWEN: Oscillator Switch Enable bit
    *   1 = Initiate an osc switch to selection specified by NOSC2:NOSC0 bits
    *   0 = Oscillator switch is complete
    */
    OSCCONbits.OSWEN = 1;
    // Busy wait until osc switch has been completed
    while (OSCCONbits.OSWEN == 1) 
    {
      asm("nop");
    }

    /*
    * bit 20-19 PBDIV<1:0>: Peripheral Bus Clock Divisor
    */
    OSCCONbits.PBDIV = s->PBDIV;

    // Set wait states
    #if !defined(PIC32_PINGUINO_220) && \
        !defined(PINGUINO32MX220)    && \
        !defined(PINGUINO32MX250)    && \
        !defined(PINGUINO32MX270)

    CHECON = (SystemClocksGetCpuFrequency(s) / 20) - 1;		// FlashWaitStates

    #endif
  
    //
    SystemLock();
}
Beispiel #3
0
u32 GetSystemClock(void)
{
	SystemClocksSettings s;
	SystemClocksReadSettings(&s);
	return SystemClocksGetCpuFrequency(&s);
}
Beispiel #4
0
/**
 * Calculates the peripheral clock frequency based on the values which
 * are passed in. This normally requires a call to
 * SystemClocksReadSettings() before.
 *
 * @see system.c::GetPeripheralClock()
 *
 * @return The peripheral clock frequency
 */
uint32_t SystemClocksGetPeripheralFrequency(const SystemClocksSettings *s) 
{
  return SystemClocksGetCpuFrequency(s) / pbDivs[s->PBDIV];
}