CCS PCM C Compiler, Version 4.046, 36832 15-Dec-07 10:59 Copyright (C) Quaketronics.com Released under a Creative Commons License Attribution-Noncommercial-Share Alike 3.0 United States See http://creativecommons.org/licenses/by-nc-sa/3.0/us/ For attribution link to http://www.quaketronics.com/ Alternative licenses available, contact tom@quaketronics.com Filename: microflash.lst ROM used: 449 words (22%) Largest free fragment is 1599 RAM used: 27 (21%) at main() level 34 (27%) worst case Stack: 3 worst case (1 in main + 2 for interrupts) * 0000: MOVLW 00 0001: MOVWF 0A 0002: GOTO 14D 0003: NOP 0004: BTFSC 03.5 0005: GOTO 00A 0006: MOVWF 25 0007: SWAPF 03,W 0008: MOVWF 26 0009: GOTO 00F 000A: BCF 03.5 000B: MOVWF 25 000C: SWAPF 03,W 000D: MOVWF 26 000E: BSF 26.1 000F: MOVF 0A,W 0010: MOVWF 2D 0011: CLRF 0A 0012: BCF 03.7 0013: SWAPF 25,F 0014: MOVF 04,W 0015: MOVWF 27 0016: MOVF 20,W 0017: MOVWF 28 0018: MOVF 21,W 0019: MOVWF 29 001A: MOVF 22,W 001B: MOVWF 2A 001C: MOVF 23,W 001D: MOVWF 2B 001E: MOVF 24,W 001F: MOVWF 2C 0020: BCF 03.5 0021: MOVLW 8C 0022: MOVWF 04 0023: BTFSS 00.0 0024: GOTO 027 0025: BTFSC 0C.0 0026: GOTO 07D 0027: MOVLW 8C 0028: MOVWF 04 0029: BTFSS 00.6 002A: GOTO 02D 002B: BTFSC 0C.6 002C: GOTO 042 002D: MOVF 27,W 002E: MOVWF 04 002F: MOVF 28,W 0030: MOVWF 20 0031: MOVF 29,W 0032: MOVWF 21 0033: MOVF 2A,W 0034: MOVWF 22 0035: MOVF 2B,W 0036: MOVWF 23 0037: MOVF 2C,W 0038: MOVWF 24 0039: MOVF 2D,W 003A: MOVWF 0A 003B: SWAPF 26,W 003C: MOVWF 03 003D: BCF 03.5 003E: SWAPF 25,W 003F: BTFSC 26.1 0040: BSF 03.5 0041: RETFIE .................... // Firmware for Flash Controller on PIC project .................... // Uses PIC16F616 as a target .................... // uses PICC PCM c compiler(4.048) and MPLab(7.60) .................... .................... // Pin Assignments for 20MHz External Resonator Version .................... .................... // 1 Vdd (+5) .................... // 2 RA5, PIN_A5 [ Spare Input ] .................... // 3 AN3 [ Delay Pot Input ] .................... // 4 /MCLR, Vpp [ Reset, In-Circuit Programming Voltage ] .................... // 5 RC5, PIN_C5 [ Blanking Jumper Input: 0=Blanking (with Jumper), 1=No Blanking (no Jumper) ] .................... // 6 RC4, PIN_C4 [ Delay Jumper Input: 1=Long Delay (16ms - 512ms) (No Jumper), 0=Short Delay (2ms - 16ms) (with Jumper), Zero Delay handled separately ] .................... // 7 RC3, PIN_C3 [ LED Output ] .................... // 8 C12IN2- [ Comparator Input ] .................... // 9 C12IN1- [ Comparator Input ] .................... // 10 C2IN+ [ Comparator Input ] .................... // 11 RA2, PIN_A2 [ Trigger Output ] .................... // 12 ICSPCLK [ In-Circuit Programming Clock ] .................... // 13 C1IN+, ICSPDAT [ Comparator Input, In-Circuit Programming Data ] .................... // 14 Vss (GND) .................... .................... .................... #if defined(__PCM__) .................... #include <16F616.h> .................... //////// Standard Header file for the PIC16F616 device //////////////// .................... #device PIC16F616 .................... #list .................... .................... #fuses INTRC_IO,IOSC4, NOPROTECT // internal 4 MHz Clock; no protection (yet) .................... #fuses MCLR, NOBROWNOUT, NOWDT // 4 MHz Fosc, use /MCLR for reset, no brownout detect, no watchdog timer .................... #priority INT_TIMER1, INT_AD .................... #endif .................... .................... #define BLANK_INTERVAL 183 // ~3 seconds blanking holdoff .................... #define ZERO_LATENCY 0x10 // ~10% of total 10 bit range of the ADC .................... #define ADC_INTERVAL 15 // ~.25 s conversion interval .................... #define SHORT_DELAY ~0x1F40 // set timer for 2 ms delay .................... .................... // states .................... #define IDLE 0 .................... #define DELAY 1 .................... #define PULSE_OUT 2 .................... #define BLANK 3 .................... #define ERROR 4 .................... .................... volatile unsigned long timer_overflows; // holds the number of times trigger timer1 overflowed .................... volatile unsigned int adc_overflows; // holds the number of times adc timer1 overflowed .................... volatile unsigned long flash_delay; // holds the adc value, used to set the delay .................... volatile unsigned int zero_delay; // set for short delays, enables faster response .................... volatile unsigned int state; // see state diagram .................... .................... .................... #INT_AD .................... void adc_isr(void) { .................... flash_delay = read_adc(ADC_READ_ONLY); // starts conversion * 0042: BTFSC 1F.1 0043: GOTO 042 0044: MOVF 1E,W 0045: CLRF 32 0046: MOVWF 31 .................... zero_delay = (flash_delay < ZERO_LATENCY); // zero delay is an int, so it speeds up the compare later 0047: MOVF 32,F 0048: BTFSS 03.2 0049: GOTO 04E 004A: MOVF 31,W 004B: SUBLW 0F 004C: BTFSC 03.0 004D: GOTO 050 004E: MOVLW 00 004F: GOTO 051 0050: MOVLW 01 0051: MOVWF 33 .................... disable_interrupts(INT_AD); 0052: BSF 03.5 0053: BCF 0C.6 .................... return; .................... } .................... 0054: BCF 03.5 0055: BCF 0C.6 0056: BCF 0A.3 0057: GOTO 02D .................... #INT_TIMER1 .................... void timer_isr(void) { // this code replaces all of the 555's .................... switch (state) { * 007D: MOVF 34,W 007E: XORLW 00 007F: BTFSC 03.2 0080: GOTO 08E 0081: XORLW 01 0082: BTFSC 03.2 0083: GOTO 099 0084: XORLW 03 0085: BTFSC 03.2 0086: GOTO 0B3 0087: XORLW 01 0088: BTFSC 03.2 0089: GOTO 0E7 008A: XORLW 07 008B: BTFSC 03.2 008C: GOTO 0ED 008D: GOTO 109 .................... case IDLE: .................... if(adc_overflows++ > ADC_INTERVAL) { 008E: MOVF 30,W 008F: INCF 30,F 0090: SUBLW 0F 0091: BTFSC 03.0 0092: GOTO 098 .................... read_adc(ADC_START_ONLY); 0093: BSF 1F.1 .................... enable_interrupts(INT_AD); 0094: BSF 03.5 0095: BSF 0C.6 .................... adc_overflows = 0; 0096: BCF 03.5 0097: CLRF 30 .................... } .................... break; 0098: GOTO 10C .................... case DELAY: .................... if(!(timer_overflows)) { // use overflows for long delays, timer for short delays 0099: MOVF 2E,W 009A: IORWF 2F,W 009B: BTFSS 03.2 009C: GOTO 0A8 .................... output_high(PIN_A2); // flash trigger output 009D: BSF 03.5 009E: BCF 05.2 009F: BCF 03.5 00A0: BSF 05.2 .................... state = PULSE_OUT; 00A1: MOVLW 02 00A2: MOVWF 34 .................... set_timer1(SHORT_DELAY); // ~15ms trigger out 00A3: MOVLW E0 00A4: MOVWF 0F 00A5: MOVLW BF 00A6: MOVWF 0E .................... } else { 00A7: GOTO 0B2 .................... if(timer_overflows > 0) { 00A8: MOVF 2E,F 00A9: BTFSS 03.2 00AA: GOTO 0AE 00AB: MOVF 2F,F 00AC: BTFSC 03.2 00AD: GOTO 0B2 .................... timer_overflows--; 00AE: MOVF 2E,W 00AF: BTFSC 03.2 00B0: DECF 2F,F 00B1: DECF 2E,F .................... } .................... } .................... break; 00B2: GOTO 10C .................... case PULSE_OUT: .................... output_low(PIN_A2); 00B3: BSF 03.5 00B4: BCF 05.2 00B5: BCF 03.5 00B6: BCF 05.2 .................... if (input(PIN_C5) == 0) { // blanking 00B7: BSF 03.5 00B8: BSF 07.5 00B9: BCF 03.5 00BA: BTFSC 07.5 00BB: GOTO 0E0 .................... if(timer_overflows++ > BLANK_INTERVAL) { 00BC: MOVF 2F,W 00BD: MOVWF 23 00BE: MOVF 2E,W 00BF: INCF 2E,F 00C0: BTFSC 03.2 00C1: INCF 2F,F 00C2: MOVWF 3B 00C3: MOVF 23,W 00C4: MOVWF 3C 00C5: MOVF 3C,F 00C6: BTFSS 03.2 00C7: GOTO 0CC 00C8: MOVF 3B,W 00C9: SUBLW B7 00CA: BTFSC 03.0 00CB: GOTO 0CE .................... state = BLANK; 00CC: MOVLW 03 00CD: MOVWF 34 .................... } .................... if(!(timer_overflows % 5)) { // blink while blanked ~6 Hz rate 00CE: MOVF 2F,W 00CF: MOVWF 3E 00D0: MOVF 2E,W 00D1: MOVWF 3D 00D2: CLRF 40 00D3: MOVLW 05 00D4: MOVWF 3F 00D5: CALL 058 00D6: MOVF 20,W 00D7: IORWF 23,W 00D8: BTFSS 03.2 00D9: GOTO 0DF .................... output_toggle(PIN_C3); 00DA: BSF 03.5 00DB: BCF 07.3 00DC: MOVLW 08 00DD: BCF 03.5 00DE: XORWF 07,F .................... } .................... } else { // no blanking, restart after 00DF: GOTO 0E6 .................... set_timer1(SHORT_DELAY); // a short delay, ~5ms blanking 00E0: MOVLW E0 00E1: MOVWF 0F 00E2: MOVLW BF 00E3: MOVWF 0E .................... state = BLANK; 00E4: MOVLW 03 00E5: MOVWF 34 .................... } .................... break; 00E6: GOTO 10C .................... case BLANK: .................... state = IDLE; 00E7: CLRF 34 .................... timer_overflows = 0; 00E8: CLRF 2F 00E9: CLRF 2E .................... C1IF = 0; 00EA: BCF 0C.3 .................... C2IF = 0; 00EB: BCF 0C.4 .................... break; 00EC: GOTO 10C .................... case ERROR: .................... if(!(timer_overflows++ % 20)) { 00ED: MOVF 2F,W 00EE: MOVWF 23 00EF: MOVF 2E,W 00F0: INCF 2E,F 00F1: BTFSC 03.2 00F2: INCF 2F,F 00F3: MOVWF 3B 00F4: MOVF 23,W 00F5: MOVWF 3C 00F6: MOVWF 3E 00F7: MOVF 3B,W 00F8: MOVWF 3D 00F9: CLRF 40 00FA: MOVLW 14 00FB: MOVWF 3F 00FC: CALL 058 00FD: MOVF 20,W 00FE: IORWF 23,W 00FF: BTFSS 03.2 0100: GOTO 108 .................... output_toggle(PIN_C3); // this is a slower ~2Hz blink rate 0101: BSF 03.5 0102: BCF 07.3 0103: MOVLW 08 0104: BCF 03.5 0105: XORWF 07,F .................... timer_overflows = 0; 0106: CLRF 2F 0107: CLRF 2E .................... } .................... break; 0108: GOTO 10C .................... default: .................... state = ERROR; 0109: MOVLW 04 010A: MOVWF 34 .................... break; 010B: GOTO 10C .................... } .................... return; .................... } .................... 010C: BCF 0C.0 010D: BCF 0A.3 010E: GOTO 02D .................... void init_app(void) { .................... // configure i/o's .................... set_tris_a(~0x04); // PIN_A2 is output, rest inputs -- see page 207 in the CCS book for the set_tris_x routine 010F: MOVLW FB 0110: BSF 03.5 0111: MOVWF 05 .................... set_tris_c(~0x08); // port c pin_C3(LED) is output, rest inputs 0112: MOVLW F7 0113: MOVWF 07 .................... port_a_pullups(0x22); // port A pullups on PIN_A1, PIN_A5 0114: MOVLW 22 0115: MOVWF 15 0116: BCF 01.7 .................... output_high(PIN_C3); // LED ON 0117: BCF 07.3 0118: BCF 03.5 0119: BSF 07.3 .................... output_low(PIN_A2); // flash trigger output OFF 011A: BSF 03.5 011B: BCF 05.2 011C: BCF 03.5 011D: BCF 05.2 .................... .................... // configure adc .................... setup_adc_ports(SAN3); // PIN_A4 011E: BCF 1F.6 011F: MOVLW 00 0120: IORLW 08 0121: BSF 03.5 0122: MOVWF 11 .................... setup_adc(ADC_CLOCK_DIV_64); // see 9.1.3 in PIC16F616 datasheet 0123: BCF 1F.4 0124: BSF 1F.5 0125: BSF 1F.6 0126: BCF 03.5 0127: BCF 1F.7 0128: BSF 1F.0 .................... VCFG = 0; 0129: BCF 1F.6 .................... .................... .................... set_adc_channel(3); // this corresponds to SAN3 from what I can tell 012A: MOVLW 0C 012B: MOVWF 21 012C: MOVF 1F,W 012D: ANDLW C3 012E: IORWF 21,W 012F: MOVWF 1F .................... .................... timer_overflows = 0; 0130: CLRF 2F 0131: CLRF 2E .................... adc_overflows = 0; 0132: CLRF 30 .................... flash_delay = 128; // initial value before reading A/D 0133: CLRF 32 0134: MOVLW 80 0135: MOVWF 31 .................... .................... // configure comparators -- for now, the comparator outputs are copied to external pins .................... // setup_comparator(CP1_C2_A0 | CP2_C1_C0 | CP1_OUT_ON_A2 | CP2_OUT_ON_C4 ); // output comparator value on pins A2, C4 .................... setup_comparator(CP1_C2_A0 | CP1_INVERT | CP2_C1_C0 | CP2_INVERT); // do not use output pins for comparators 0136: MOVLW 92 0137: MOVWF 1A 0138: MOVLW 91 0139: MOVWF 1B 013A: CLRF 1C 013B: BSF 03.5 013C: CLRF 1A 013D: CLRF 19 .................... .................... // configure timer .................... setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // overflows every 16 ms = 2^16/(4 MHz / 1) 013E: MOVLW 85 013F: BCF 03.5 0140: MOVWF 10 .................... T1ACS = 1; // sets timer clock to Fosc (T1ACS = 0 for Fosc/4) 0141: BSF 1C.4 .................... .................... // initialize interrupts .................... state = IDLE; 0142: CLRF 34 .................... set_timer1(0); 0143: CLRF 0F 0144: CLRF 0E .................... .................... clear_interrupt(INT_TIMER1); 0145: BCF 0C.0 .................... clear_interrupt(INT_AD); 0146: BCF 0C.6 .................... enable_interrupts(GLOBAL); 0147: MOVLW C0 0148: IORWF 0B,F .................... enable_interrupts(INT_TIMER1); 0149: BSF 03.5 014A: BSF 0C.0 .................... return; .................... } 014B: BCF 03.5 014C: GOTO 15D (RETURN) .................... .................... void main(void) { 014D: CLRF 04 014E: MOVLW 1F 014F: ANDWF 03,F 0150: BCF 1F.6 0151: MOVLW 00 0152: BSF 03.5 0153: MOVWF 11 0154: BCF 03.5 0155: CLRF 1A 0156: CLRF 1B 0157: CLRF 1C 0158: BSF 03.5 0159: CLRF 1A 015A: CLRF 19 .................... while(1) { .................... init_app(); 015B: BCF 03.5 015C: GOTO 10F .................... while(!(C1OUT || C2OUT)) // busy wait for comparator trigger .................... ; 015D: BTFSC 1A.6 015E: GOTO 161 015F: BTFSS 1B.6 0160: GOTO 15D .................... if(zero_delay) { // zero delay is about 500 ns for instruction cycles + comparator latency (?) 0161: MOVF 33,F 0162: BTFSC 03.2 0163: GOTO 16F .................... #pragma use fast_io(A) // uses pins without changing port direction bits first, must setup port prior with tris_a .................... output_high(PIN_A2); // output trigger high 0164: BSF 05.2 .................... disable_interrupts(INT_AD); 0165: BSF 03.5 0166: BCF 0C.6 .................... set_timer1(SHORT_DELAY); // short delay for trigger out duration ~2 ms 0167: MOVLW E0 0168: BCF 03.5 0169: MOVWF 0F 016A: MOVLW BF 016B: MOVWF 0E .................... state = PULSE_OUT; 016C: MOVLW 02 016D: MOVWF 34 .................... } else { 016E: GOTO 1B4 .................... disable_interrupts(INT_AD); 016F: BSF 03.5 0170: BCF 0C.6 .................... if(input(PIN_C4)) { // long programmed delay 0171: BSF 07.4 0172: BCF 03.5 0173: BTFSS 07.4 0174: GOTO 197 .................... timer_overflows = ((flash_delay - ZERO_LATENCY + 1) >> 3) + 1; // set long delay 16 ms .. 512 ms 0175: MOVLW 10 0176: SUBWF 31,W 0177: MOVWF 35 0178: MOVF 32,W 0179: MOVWF 36 017A: MOVLW 00 017B: BTFSS 03.0 017C: MOVLW 01 017D: SUBWF 36,F 017E: MOVLW 01 017F: ADDWF 35,W 0180: MOVWF 37 0181: MOVF 36,W 0182: MOVWF 38 0183: BTFSC 03.0 0184: INCF 38,F 0185: RRF 38,W 0186: MOVWF 3A 0187: RRF 37,W 0188: MOVWF 39 0189: RRF 3A,F 018A: RRF 39,F 018B: RRF 3A,F 018C: RRF 39,F 018D: MOVLW 1F 018E: ANDWF 3A,F 018F: MOVLW 01 0190: ADDWF 39,W 0191: MOVWF 2E 0192: MOVF 3A,W 0193: MOVWF 2F 0194: BTFSC 03.0 0195: INCF 2F,F .................... } else { // short programmed delay 0196: GOTO 1B2 .................... set_timer1(~((flash_delay - ZERO_LATENCY + 1) << 8)); // set short delay 1 ms .. 16 ms 0197: MOVLW 10 0198: SUBWF 31,W 0199: MOVWF 35 019A: MOVF 32,W 019B: MOVWF 36 019C: MOVLW 00 019D: BTFSS 03.0 019E: MOVLW 01 019F: SUBWF 36,F 01A0: MOVLW 01 01A1: ADDWF 35,W 01A2: MOVWF 37 01A3: MOVF 36,W 01A4: MOVWF 38 01A5: BTFSC 03.0 01A6: INCF 38,F 01A7: MOVLW 00 01A8: XORLW FF 01A9: MOVWF 39 01AA: MOVLW FF 01AB: XORWF 37,W 01AC: MOVWF 3A 01AD: MOVWF 0F 01AE: MOVF 39,W 01AF: MOVWF 0E .................... timer_overflows = 0; 01B0: CLRF 2F 01B1: CLRF 2E .................... } .................... state = DELAY; 01B2: MOVLW 01 01B3: MOVWF 34 .................... } .................... output_low(PIN_C3); // LED Off at trigger 01B4: BSF 03.5 01B5: BCF 07.3 01B6: BCF 03.5 01B7: BCF 07.3 .................... while(state != IDLE) .................... ; 01B8: MOVF 34,F 01B9: BTFSS 03.2 01BA: GOTO 1B8 .................... output_high(PIN_C3); // LED back On waiting for trigger 01BB: BSF 03.5 01BC: BCF 07.3 01BD: BCF 03.5 01BE: BSF 07.3 .................... } 01BF: GOTO 15C .................... } 01C0: SLEEP Configuration Fuses: Word 1: 3C64 INTRC_IO NOPROTECT IOSC4 MCLR NOBROWNOUT NOWDT PUT