// sleep_pwm.c // // timers during sleep // pwm for LEDs /* Copyright (C) 2017 H.Poetzl ** ** This program is free software: you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation, either version ** 2 of the License, or (at your option) any later version. */ // ------------------------------------------------ // configuration #define NO_BIT_DEFINES #include #include #define CONFIG(k, n) __code static char __at _ ## k __ ## k = n CONFIG(CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT1 & _CSWEN_ON & _CLKOUTEN_OFF); CONFIG(CONFIG2, _MCLRE_ON & _WDTE_OFF & _PPS1WAY_OFF); #include "tear_leds.h" void irq(void) __interrupt 0 { __asm BANKSEL PIR1 BTFSC PIR1,TMR2IF BRA _tmr2 BANKSEL PIR0 BTFSC PIR0,TMR0IF BRA _tmr0 RETFIE _tmr0: BCF PIR0,TMR0IF BANKSEL TMR0H MOVLW 0xF0 MOVWF TMR0H CLRF TMR0L BANKSEL LEDCL BCF LEDCL,LEDC BSF LEDCL,LEDC RETFIE _tmr2: BCF PIR1,TMR2IF BANKSEL PR2 INCF PR2,F ; BANKSEL T2CON ; BCF T2CON,TMR2ON BANKSEL LEDBL BCF LEDBL,LEDB BSF LEDBL,LEDB RETFIE __endasm; } // -------------------------------------------------- // and our main entry point void main() { uint16_t data = 0; // all digital ANSELA = 0; ANSELB = 0; ANSELC = 0; // all input TRISA = 0xFF; TRISB = 0xFF; TRISC = 0xFF; // all one LATA = 0xFF; LATB = 0xFF; LATC = 0xFF; // all open drain ODCONA = 0xFF; ODCONB = 0xFF; ODCONC = 0xFF; __asm BANKSEL TRISA BCF LED0T,LED0 BCF LED1T,LED1 BCF LED2T,LED2 BCF LED3T,LED3 BCF LED4T,LED4 BCF LED5T,LED5 BCF LED6T,LED6 BCF LED7T,LED7 BCF LED8T,LED8 BCF LED9T,LED9 BCF LEDAT,LEDA BCF LEDBT,LEDB BCF LEDCT,LEDC BCF LEDDT,LEDD BCF LEDET,LEDE BCF LEDFT,LEDF __endasm; OSCCON3bits.CSWHOLD = 0; OSCCON1bits.NDIV = 1; /* configure Timer 0 */ T0CON0 = 0; T0CON0bits.T0EN = 1; T0CON0bits.T016BIT = 1; T0CON0bits.T0OUTPS = 0b0000; /* Postscaler = 1 */ T0CON1 = 0; T0CON1bits.T0CS = 0b100; /* Source = LFINTOSC */ T0CON1bits.T0CS = 0b011; /* Source = HFINTOSC */ T0CON1bits.T0ASYNC = 1; T0CON1bits.T0CKPS = 0b0000; /* Prescaler = 1 */ TMR0H = 0x80; TMR0L = 0x00; /* configure Timer 2 */ T2CON = 0; T2CONbits.TMR2ON = 0; /* Timer is off */ T2CONbits.T2CKPS = 0b00; /* Prescaler = 1 */ T2CONbits.T2OUTPS = 0b0000; /* Postscaler = 1 */ PR2 = 0xFF; TMR2 = 0; /* configure PWM */ PWMTMRSbits.P5TSEL = 0b01; /* Based on Timer2 */ PWM5CON = 0; PWM5CONbits.PWM5EN = 1; /* Enable PWM Module */ PWM5CONbits.PWM5POL = 1; /* Output Active Low */ PWM5DCH = 0; PWM5DCL = 0; PMD0 = 0x43; /* All but Peripherial Clock */ PMD1 = 0xFA; /* All but Timer 0,2 */ PMD2 = 0x66; /* All */ PMD3 = 0xEF; /* All but PWM 5 */ PMD4 = 0x22; /* All */ PMD5 = 0x1F; /* All */ /* PPS */ PPSLOCKbits.PPSLOCKED = 0; PIR0bits.TMR0IF = 0; /* clear TMR0 irq */ PIE0bits.TMR0IE = 1; /* enable TMR0 irq */ PIR1bits.TMR2IF = 0; /* clear TMR2 irq */ PIE1bits.TMR2IE = 1; /* enable TMR2 irq */ INTCONbits.PEIE = 1; /* enable peripheral irq */ INTCONbits.GIE = 1; /* enable global irq */ while (1) { __asm SLEEP __endasm; __asm BANKSEL LATA ; during IRQ BCF LED0L,LED0 BSF LED0L,LED0 __endasm; data++; PWM5DCH = data >> 8; PWM5DCL = 0x40; /* shortest pulse */ TMR2 = 0xFE; /* prime Timer 2 */ PR2 = 0xFF; LED6P = 0b00010; /* put PWM on LED */ T2CONbits.TMR2ON = 1; /* start Timer 2 */ // PWM5CONbits.PWM5EN = 1; /* enable PWM Module */ while (PR2 == 0xFF); LED6P = 0b00000; /* put GPIO on LED */ // PWM5CONbits.PWM5EN = 0; /* disable PWM Module */ T2CONbits.TMR2ON = 0; /* stop Timer 2 */ #if 0 __asm BCF LED1L,LED1 BSF LED1L,LED1 __endasm; #endif } }