#include #include #include #include "pic24f_hal.h" // CONFIG4 #pragma config DSWDTPS = DSWDTPS1F // Deep Sleep Watchdog Timer Postscale Select bits (1:68719476736 (25.7 Days)) #pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock) #pragma config DSBOREN = OFF // Deep Sleep BOR Enable bit (DSBOR Disabled) #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (DSWDT Disabled) #pragma config DSSWEN = ON // DSEN Bit Enable (Deep Sleep is controlled by the register bit DSEN) #pragma config PLLDIV = DISABLED // USB 96 MHz PLL Prescaler Select bits (PLL Disabled) #pragma config I2C1SEL = DISABLE // Alternate I2C1 enable bit (I2C1 uses SCL1 and SDA1 pins) #pragma config IOL1WAY = ON // PPS IOLOCK Set Only Once Enable bit (Once set, the IOLOCK bit cannot be cleared) // CONFIG3 #pragma config WPFP = WPFP127 // Write Protection Flash Page Segment Boundary (Page 127 (0x1FC00)) #pragma config SOSCSEL = ON // SOSC Selection bits (SOSC circuit selected) #pragma config WDTWIN = PS25_0 // Window Mode Watchdog Timer Window Width Select (Watch Dog Timer Window Width is 25 percent) #pragma config PLLSS = PLL_PRI // PLL Secondary Selection Configuration bit (PLL is fed by the Primary oscillator) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset Enable) #pragma config WPDIS = WPDIS // Segment Write Protection Disable (Disabled) #pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select (Disabled) #pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory) // CONFIG2 #pragma config POSCMD = EC // Primary Oscillator Select (External-Clock Mode Enabled) #pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC) #pragma config OSCIOFCN = OFF // OSCO Pin Configuration (OSCO/CLKO/RA3 functions as CLKO (FOSC/2)) #pragma config FCKSM = CSECMD // Clock Switching and Fail-Safe Clock Monitor Configuration bits (Clock switching is enabled, Fail-Safe Clock Monitor is disabled) #pragma config FNOSC = PRI // Initial Oscillator Select (Primary Oscillator (XT, HS, EC)) #pragma config ALTCMPI = CxINC_RB // Alternate Comparator Input bit (C1INC is on RB13, C2INC is on RB9 and C3INC is on RA0) #pragma config WDTCMX = WDTCLK // WDT Clock Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits) #pragma config IESO = OFF // Internal External Switchover (Disabled) // CONFIG1 #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler Select (1:32,768) #pragma config FWPSA = PR128 // WDT Prescaler Ratio Select (1:128) #pragma config WINDIS = OFF // Windowed WDT Disable (Standard Watchdog Timer) #pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT disabled in hardware; SWDTEN bit disabled) #pragma config ICS = PGx1 // Emulator Pin Placement Select bits (Emulator functions are shared with PGEC1/PGED1) #pragma config LPCFG = OFF // Low power regulator control (Disabled - regardless of RETEN) #pragma config GWRP = OFF // General Segment Write Protect (Write to program memory allowed) #pragma config GCP = OFF // General Segment Code Protect (Code protection is disabled) #pragma config JTAGEN = OFF // JTAG Port Enable (Disabled) void __attribute__ ( ( __interrupt__ , auto_psv ) ) _OscillatorFail ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AddressError ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _StackError ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _MathError ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltOscillatorFail ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltAddressError ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltStackError ( void ) ; void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltMathError ( void ) ; /* Init hardware */ void platform_init(void) { /* The following code block shows an example of swtiching oscillator source, but we use fuse bits to come up in external oscillator mode. So it's not needed to switch modes */ #if 0 /* Check clock lock bit */ if (OSCCONL & 0x80){ //If system gets here, the fuse bits are set wrong as cannot change oscillator while(1); } char a , b , c , *p ; a = 0x02; //New source: external clock b = 0x78 ; /* Unlock sequence for high, 78, 9A */ c = 0x9A ; p = (char *) &OSCCONH ; asm volatile ("mov.b %1,[%0] \n" "mov.b %2,[%0] \n" "mov.b %3,[%0] \n" : /* no outputs */ : "r"( p ) , "r"( b ) , "r"( c ) , "r"( a ) ) ; a = 1 ; /* Switch oscillator bit */ b = 0x46 ; /* Unlock sequence for low, 46, 57 */ c = 0x57 ; p = (char *) &OSCCONL ; asm volatile ("mov.b %1,[%0] \n" "mov.b %2,[%0] \n" "mov.b %3,[%0] \n" : /* no outputs */ : "r"( p ) , "r"( b ) , "r"( c ) , "r"( a ) ) ; #endif return; } #if HWCRYPTO /* AES Hardware Peripheral */ void HW_AES128_Init(void) { //TODO: Following assumes reset state - possibly should write all bits instead CRYCONLbits.CRYON = 1; CRYCONLbits.OPMOD = 0x0; // Encrypt CRYCONLbits.CPHRSEL = 1; CRYCONLbits.CPHRMOD = 0; CRYCONHbits.KEYSRC = 0; //Key source - this is just SRAM } void HW_AES128_LoadKey(uint8_t * key) { //Load the key into CRYKEY memcpy((void *)&CRYKEY0, key, 16); } void HW_AES128_Enc_pretrigger(uint8_t * pt) { memcpy((void*)&CRYTXTA0, pt, 16); } void HW_AES128_Enc(uint8_t * pt) { CRYCONLbits.CRYGO = 1; // Wait for completion while (CRYCONLbits.CRYGO == 1) } void HW_AES128_Enc_posttrigger(uint8_t * pt) { memcpy(pt, (void*)&CRYTXTB0, 16); } #endif // ***************************************************************************** // ***************************************************************************** // Section: Primary Exception Vector handlers // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _OscillatorFail(void) Summary: Provides the required exception vector handlers for Oscillator trap Description: This routine is used if INTCON2bits.ALTIVT = 0 and it handles the oscillator trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _OscillatorFail ( void ) { INTCON1bits.OSCFAIL = 0 ; //Clear the trap flag while (1) ; } // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _AddressError(void) Summary: Provides the required exception vector handlers for Address Error trap Description: This routine is used if INTCON2bits.ALTIVT = 0 and it handles the address error trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AddressError ( void ) { INTCON1bits.ADDRERR = 0 ; //Clear the trap flag while (1) ; } // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _StackError(void)) Summary: Provides the required exception vector handlers for Stack Error trap Description: This routine is used if INTCON2bits.ALTIVT = 0 and it handles the stack error trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _StackError ( void ) { INTCON1bits.STKERR = 0 ; //Clear the trap flag while (1) ; } // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _MathError(void)) Summary: Provides the required exception vector handlers for Math Error trap Description: This routine is used if INTCON2bits.ALTIVT = 0 and it handles the math error trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _MathError ( void ) { INTCON1bits.MATHERR = 0 ; //Clear the trap flag while (1) ; } // ***************************************************************************** // ***************************************************************************** // Section: Alternate Exception Vector handlers // ***************************************************************************** // ***************************************************************************** // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _AltOscillatorFail(void) Summary: Provides the required exception vector handlers for Oscillator trap Description: This routine is used if INTCON2bits.ALTIVT = 1 and it handles the oscillator trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltOscillatorFail ( void ) { INTCON1bits.OSCFAIL = 0 ; while (1) ; } // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _AltAddressError(void) Summary: Provides the required exception vector handlers for Address Error trap Description: This routine is used if INTCON2bits.ALTIVT = 1 and it handles the address error trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltAddressError ( void ) { INTCON1bits.ADDRERR = 0 ; while (1) ; } // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _AltStackError(void)) Summary: Provides the required exception vector handlers for Stack Error trap Description: This routine is used if INTCON2bits.ALTIVT = 1 and it handles the stack error trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltStackError ( void ) { INTCON1bits.STKERR = 0 ; while (1) ; } // ***************************************************************************** /* void __attribute__((__interrupt__,auto_psv)) _AltMathError(void)) Summary: Provides the required exception vector handlers for Math Error trap Description: This routine is used if INTCON2bits.ALTIVT = 1 and it handles the math error trap. Remarks: All trap service routines in this file simply ensure that device continuously executes code within the trap service routine. Users may modify the basic framework provided here to suit to the needs of their application. */ void __attribute__ ( ( __interrupt__ , auto_psv ) ) _AltMathError ( void ) { INTCON1bits.MATHERR = 0 ; while (1) ; }