int set_new_osc(int arg){ char *txt_result; int result = 0; switch( arg ){ case 0: result = PwrMgnt_OscSel(FRC_OSC); txt_result = "new Oscillator is FRC_OSC\r\n"; break; case 1: result = PwrMgnt_OscSel(FRC_OSC_WITH_POSTSCALER_PLL); txt_result = "FRC_OSC_WITH_POSTSCALER_PLL\r\n"; break; case 2: result = (PwrMgnt_OscSel(PRIMARY_OSC) ); txt_result = "PRIMARY_OSC\r\n"; break; case 3: result = (PwrMgnt_OscSel(PRIMARY_OSC_WITH_PLL) ); txt_result = "PRIMARY_OSC_WITH_PLL\r\n"; break; case 4: result = (PwrMgnt_OscSel(SECONDRY_OSC) ); txt_result = "SECONDRY_OSC\r\n"; break; case 5: result = (PwrMgnt_OscSel(LOW_POWER_RC) ); txt_result = "LOW_POWER_RC\r\n"; break; case 7: result = (PwrMgnt_OscSel(FRC_OSC_WITH_POSTSCALER) ); txt_result = "FRC_OSC_WITH_POSTSCALER\r\n"; break; } #if(SCH_PIC_PC104_CONFIG_VERBOSE>=1) if(result){ printf(txt_result); } else{ printf("Failed to set new oscilator\r\n"); } #endif return result; }
/* _____GLOBAL FUNCTIONS_____________________________________________________ */ void board_lowlevel_init(void) { #if __DEBUG // Reset "reasons for reset" flags RCONbits.POR = 0; // Power-on Reset RCONbits.BOR = 0; // Brown-out Reset RCONbits.WDTO = 0; // Watchdog Timer Time-out RCONbits.SWR = 0; // Software Reset RCONbits.EXTR = 0; // External Reset RCONbits.CM = 0; // Configuration Word Mismatch Reset RCONbits.TRAPR = 0; // Trap Conflict Reset #endif #if BOARD_CLK_SWITCHING_ENABLED /* * Select Fast RC oscillator with PLL. * * During a /MCLR, WDTO or SWR reset, the oscillator selection is not reset * to the default value as specified in Configuration Word 2 (_CONFIG2(...). * Thus it must be explicitely reset in case the firmware changed the * oscillator during execution. */ PwrMgnt_OscSel(FRC_OSC_WITH_POSTSCALER_PLL); #endif // Explicitely disable watchdog, because it may have been enabled in bootloader RCONbits.SWDTEN = 0; /* * Explicitely enable interrupt nesting, because it may be disabled in * the bootloader. */ INTCON1bits.NSTDIS = 0; /* * Fix CPU peripheral clock ratio to 1:1 * Set FRC Postscaler to 8 MHz (divide by 1) */ CLKDIV = 0x0000; // Wait until PLL has lock while(OSCCONbits.LOCK != 1) { ; } /* * Configure all analog pins to digital mode; I/O port read enabled * Disable Bandgap reference voltage */ AD1PCFG = 0xffff; // Set Port A initial state TRISA =0x0010; //0000 0000 0001 0000 1=input, 0=output LATA = 0x0009; //0000 0000 0000 1001 // Set Port B initial state TRISB =0x90d5; //1001 0000 1101 0101 1=input, 0=output LATB = 0x602a; //0110 0000 0010 1010 // Map peripheral functions to PIO pins board_peripheral_pin_select(); }
/* read out configuration from HW */ return systemClockGetFcy( ); } u32 systemClockGetFcy ( ) { u32 frequency = 0; switch ( OSCCONbits.COSC ) { case CLK_SRC_LPRC: frequency = LPRC_NOMINAL; break; case CLK_SRC_SOSC: frequency = SOSC_NOMINAL; break; case CLK_SRC_POSC_PLL: if ( POSC_NOMINAL ) { frequency = systemClockFromPllPrescaler( ); } break; case CLK_SRC_POSC: frequency = POSC_NOMINAL; break; case CLK_SRC_FRCDIV: frequency = systemClockFromFrcPostscaler( ); break; case CLK_SRC_FRCPLL: frequency = systemClockFromPllPrescaler( ); break; case CLK_SRC_FRC: frequency = FRC_NOMINAL; break; } theSystemClock = frequency / 2; /* the theSystemClock is always half the system clock frequency */ return theSystemClock; } u8 systemClockGetClockSource ( ) { return OSCCONbits.COSC; } #if !defined(__PIC24FJ256GB110__) /* TODO: adapt this for GB110 (has no PLLEN but PLLDIS in config words) */ u32 systemClockChangeClockSource ( u16 source, u32 newFcy ) { u32 frequency = newFcy * 2; PwrMgnt_OscSel( source ); #if 0 /* if necessary change the source */ if ( OSCCONbits.COSC != source ) { /* change source */ OSCCONBITS newOSCCONbits = OSCCONbits; WORD_VAL newOSCCON; /* NOTE: the Config Word2 must have either FCKSM_CSECME or FCKSM_CSECMD This means that clock-switching is enabled. We could read out the config-word2 and check that the corresponding bit is cleared. */ newOSCCONbits.NOSC = source; newOSCCONbits.LOCK = 0; /* read-only - so don't care */ newOSCCONbits.OSWEN = 1; /* switch clock */ /* convert from struct to word - need to go via the "void*" as we compile with strict-aliasing */ newOSCCON.Val = *(WORD*)((void*)(&newOSCCONbits)); __builtin_write_OSCCONH( newOSCCON.byte.HB ); __builtin_write_OSCCONL( newOSCCON.byte.LB ); while ( OSCCONbits.OSWEN ); /* wait for switch */ } #endif /* now depending on clock source we can trim the frequency or not */ switch ( OSCCONbits.COSC ) { case CLK_SRC_LPRC: frequency = LPRC_NOMINAL; CLKDIVbits.PLLEN = 0; /* disable pll */ break; case CLK_SRC_SOSC: frequency = SOSC_NOMINAL; CLKDIVbits.PLLEN = 0; /* disable pll */ break; case CLK_SRC_POSC_PLL: if ( POSC_NOMINAL ) { /* find desired fcy in either 4, 8, 16, or 32 MHz */ systemClockFindPllPrescaler( frequency ); frequency = systemClockFromPllPrescaler( ); } break; case CLK_SRC_POSC: frequency = POSC_NOMINAL; CLKDIVbits.PLLEN = 0; /* disable pll */ break; case CLK_SRC_FRCDIV: /* find desired fcy in either 8, 4, 2, .... 32.25kHz */ systemClockFindFrcPostscaler( frequency ); frequency = systemClockFromFrcPostscaler( ); CLKDIVbits.PLLEN = 0; /* disable pll */ break; case CLK_SRC_FRCPLL: /* find desired fcy in either 4, 8, 16, or 32 MHz */ systemClockFindPllPrescaler( frequency ); frequency = systemClockFromPllPrescaler( ); break; case CLK_SRC_FRC: frequency = FRC_NOMINAL; CLKDIVbits.PLLEN = 0; /* disable pll */ break; } theSystemClock = frequency / 2; /* the theSystemClock is always half the system clock frequency */ return theSystemClock; }