/*
*   File:       DELAYS.C
*
*   Copyright:  Peter Buitenkant - Consultant, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
*                                              2008, 2009, 2010, 2012
*               Dix Hills, New York  11746
*
*   Purpose:    Contains standard delay routines for different Fosc.
*
*   Comments:
*
*   Programmer: Peter Buitenkant, Consultant
*
*   DATE     INITIALS   CHANGES
*   4/12/01  PGB        1. Initial draft
*
*   5/10/01  PGB        1. Ported from Nardalert to Gel Dryer
*   3/31/02  PGB        1. Ported from Gel Dryer to SDD1
*   4/8/03   PGB        1. Ported from Low Cost Meter to Temp Alarm
*   12/7/03  PGB        1. Made as stand alone file (Fosc = 4.0 MHz)
*                       2. Added delays for 11.0592MHz Fosc
*   5/4/04   PGB        1. Ported from Temperature Alarm to LED975
*   5/6/05   PGB        1. Notes on correct usage added
*                       2. Added delay_5us() from Programmer for Custom Color LU
*   2/8/06   PGB        1. Ported from LED975 to IPA2000
*   4/14/06  PGB        1. Ported from IPA2000 to Mini-IR
*   11/14/06 PGB        1. Ported from Mini-IR to Mini-IR extension bd.
*   4/14/08  PGB        1. Ported from Mini-IR Extension bd to Mini-IR SLAM bd
*   7/4/09   PGB        1. Ported from Mini-IR SLAM to OneLED colorimeter
*   11/1/09  PGB        1. Ported from 1 LED for rectangular bd to 2 legged bd
*   4/29/10  PGB        1. Ported from 2 legged bd to MainMineCap (PIC18F2321)
*   6/14/12  PGB        1. Ported from Gen 4 to Gen 5
*
*
*
*
*
*/


#include "delays.h"
#include "MainMineCap_gen_5.h"



// This is Hi-Tech PICC-18format. Redo for Microchip C-18 format ***************

// ***********************************************
void delay_kus(unsigned char delay_uc)   // ********* Check Fosc setting in header *********
{
// This function is not significantly affected by compiler optimization
//  Measured delays are:
//
//  Note- PICC-18 compiler optimizer had no significant effect on memory size or execution
//        time. Assembler optimizer cut memory size by 20% and execution speed by 60% (for
//        delay of 10).
//
//  Measurements are from the calling routine and include the return time.

//   |----------------------------------- Fosc = 4.0 MHz -----------------------------|
//  delay_uc  |----18F6621,             |----18F6621,         |----18F25F25
//            Hi-Tech PICC-18           Hi-Tech PICC-18       Hi-Tech PICC-18
//            V8.35-------|             V8.35-------|         V8.35-------|
//            actual (us)               actual (us)           actual (us)
//            No optimize               No optimize           No optimize
//
//      1       9                         15                    9
//      2      12                          -
//      5      21                          -
//      6       -                          -
//      9       -                          -
//     10      36  // k ~ 3.6             44                    38
//     50     155  // k ~ 3.0              -
//    100     310  // k ~ 3.1              -
//    255     775                          -


//
//              |-16F877, Hi-Tech PICC V7.87-|      |-18F452, Hi-Tech PICC-18 V8.30-|
//  delay_uc    actual (us)     actual (us)         actual (us)     actual (us)
//              No optimize     Full optimize       No optimize     Full optimize
//
//      1            22.00          16                  16              10
//      2            25.00          20                  19              13
//      5             -             29                  28              22
//      6             -              -                  31              -
//      9             -              -                  40              -
//     10            49.20          44                  43              37
//     50             -            164                 166             156
//    100             -            312                  -              306
//    255           784            780                  -              772


//   |------------------------------ Fosc = 8.0 MHz ----------------------------------|
// delay_ui     |--16F88, tuned
//                 to 8.0MHz
//              Hi-Tech PICC
//              V8.02----------|
//              actual (ms)
//              no optimize
//
//      1      11.6
//      2      14.6
//      5      23.8
//     10      38.8
//     50     158
//    100     312
//    255     780


//   |------------------------------ Fosc = 11.0592 MHz ------------------------------|
//
//            |----18F452,
//            Hi-Tech PICC-18
//  delay_uc  V8.30-------|
//            actual (us)
//            No optimize
//
//      1           8
//      2          11.2
//      5          21
//      6          24.4
//      7          27.6
//      8          30.8
//      9          34
//     10          37.2
//     50         167.5
//    100         330
//    255         840

// ************ NOTE: PICC-18 requires (_xxx)&0xFF or a FIXUP error will result. *******

    delay_var_kus_uc = delay_uc;                        // **** Global var must be near


    // This is Hi-Tech PICC-18 format!
    #ifdef FOSC_1_R_0MHz                                    // Hi-Tech only accepts w,f not 0,1
        asm("_DELAY_US:  decfsz _delay_var_kus_uc,f,c");    // ** Use _var,f,c not _var&0xFF,f
        asm("           GOTO _DELAY_US");                   // PICC-18 must have ":" on label
        return;                                             // f and c are optional
    #endif

/*
    // This is Microchip C-18 format! (For future programs that may use C-18)
        _asm
            DELAY_US:  decfsz _delay_var_kus_uc,?,?
                        GOTO DELAY_US
            done:
        _endasm
 */

    #ifdef FOSC_4_R_0MHz                                // Hi-Tech only accepts w,f not 0,1
        asm("DELAY_US:  decfsz _delay_var_kus_uc,f,c"); // ** Use _var,f,c not _var&0xFF,f
        asm("           GOTO DELAY_US");                // PICC-18 must have ":" on label
        return;                                         // f and c are optional
    #endif


    #ifdef FOSC_8_R_0MHz
        asm("DELAY_US:  NOP");

        asm("           NOP");
        asm("           NOP");
                                                        // Hi-Tech only accepts w,f not 0,1
        asm("           decfsz _delay_var_kus_uc,f,c"); // ** Use _var,f,c not _var&0xFF,f
        asm("           GOTO DELAY_US");                // PICC-18 must have ":" on label
    #endif                                              // f and c are optional


    #ifdef FOSC_11_R_0592MHz
        asm("DELAY_US:  NOP");

        asm("           NOP");
        asm("           NOP");
        asm("           NOP");
        asm("           NOP");
        asm("           NOP");
                                                        // Hi-Tech only accepts w,f not 0,1
        asm("           decfsz _delay_var_kus_uc,f,c"); // ** Use _var,f,c not _var&0xFF,f
        asm("           GOTO DELAY_US");                // PICC-18 must have ":" on label
                                                        // f and c are optional
        return;
    #endif

}


// ***********************************************
void delay_ms(unsigned int delay_ui)      // ********* Check Fosc setting in header *********
{
    unsigned char i_uc;

// This function is not significantly affected by compiler optimization
//  Measured delays are:
//
//
//  Measurements are from the calling routine and include the return time.

//   |-- Fosc = 31 kHz, PIC18F2321,  Hi-Tech PICC-18\PRO\9.63 in PRO mode, measured with simulator ----|
//
//  delay_ui    Actual (ms)
//
//      1       3.1
//      2
//     10
//    100       195
//   1000
//  10000







//   |----------------------------------- Fosc = 4.0 MHz -----------------------------|
//  delay_ui  |----18F6621,         |----18F8627       |----18F2525
//            Hi-Tech PICC-18       Hi-Tech PICC-18    Hi-Tech PICC-18
//            V8.35-------|         V8.35-------|      V8.35-------|
//            actual (ms)           actual (ms)        actual (ms)
//            No optimize           No optimize        No optimize
//
//      1           1.0                 1.0                 1.0
//      2           2.0                 -
//     10          10                  10.                   9.99
//    100         100                   -
//   1000        1000                   -                1000.
//  10000       10000                   -
//                                                     Stretched by 12% duty cycle ISR PLUS
//                                                     variable stacking/destacting = 22%
//                                                     PGB 8/12/06

//
//
//              |-16F877, Hi-Tech PICC V7.87-|      |-18F452, Hi-Tech PICC-18 V8.30-|
//  delay_ui    actual (ms)     actual (ms)         actual (ms)     actual (ms)
//              No optimize     Full optimize       No optimize     Full optimize
//
//     1             1.012             1.004         1.0            1.0
//    10             9.960             9.920         -              -
//   100            99.20              -            99.08          99.08
//  1000           990.0               -             -              -
// 10000          9900              9900             -              -


//   |------------------------------ Fosc = 8.0 MHz ----------------------------------|
// delay_ui     |--16F88, tuned
//                 to 8.0MHz
//              Hi-Tech PICC
//              V8.02----------|
//              actual (ms)
//              no optimize
//
//      1       1.02
//      2       -
//      5       -
//     10      10.1
//     50       -
//    100     101
//    200       -
//    500       -
//   1000    1020


//   |------------------------------ Fosc = 11.0592 MHz ------------------------------|
//
//  delay_uc  |----18F452,       *(delay_uc should be delay_ui ??)
//            Hi-Tech PICC-18
//            V8.30-------|
//            actual (ms)
//            No optimize
//
//      1       1.001
//      2       -
//      5       -
//      6       -
//      9       -
//     10       9.96
//     50       -
//    100      99.52
//    255       -

// NOTE: PICC-18 requires (_xxx)&0xFF or a FIXUP error will result


    do
    {                                       // PICC-18 must have ":" on label
        delay_ui--;                         // Provides multi-ms delay

            // Provides 1.0ms delay, independent of compiler optimization
            // **** Global var must be near


        #ifdef FOSC_1_R_0MHz
            delay_var_ms_uc = 240;
        #endif


        #ifdef FOSC_4_R_0MHz
            delay_var_ms_uc = 245;
        #endif


        #ifdef FOSC_8_R_0MHz
            delay_var_ms_uc = 249;
        #endif


        #ifdef FOSC_11_R_0592MHz
            delay_var_ms_uc = 249;
        #endif


        asm("DELAY_MS:   NOP");

        #ifdef FOSC_8_R_0MHz                          // Lengthen the loop for 8.0MHz
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
        #endif


        #ifdef FOSC_11_R_0592MHz                      // Lengthen the loop for 11.0592MHz
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
            asm("   NOP");
        #endif
                                                    // Hi-Tech only accepts w,f not 0,1
        asm("   decfsz _delay_var_ms_uc,f,c");      // ** Use _var,f,c not _var&0xFF,f
        asm("   GOTO DELAY_MS");                    // (4.0MHz) 4 instruction cycles/loop
                                                    // 245 * 4 = 980 us (Plus some overhead)
    }while(delay_ui > 0);                           // f and c are optional

    return;
}


// ***********************************************
void delay_30us(void)                        // ********* Check Fosc setting in header *********
{
    // This is a unique function based on delay_kus(6). It is used in the read_a2d function.
    // By using a unique function re-entrancy problems (call-graph) are avoided.

    // **** Global var must be near

    delay_30_uc = 8;                                // From cal table in delay_kus()

    #ifdef FOSC_4_R_0MHz                                // Hi-Tech only accepts w,f not 0,1
        asm("DELAY_30_US:   decfsz _delay_30_uc,f,c");  // ** Use _var,f,c not _var&0xFF,f
        asm("               GOTO DELAY_30_US");         // PICC-18 must have ":" on label
        return;                                         // f and c are optional
    #endif                                              // Meas. 36us on 18F8627, PGB 3/21/06
                                                        // Meas. 30 us on 18F2525 PGB 5/21/06
    #ifdef FOSC_8_R_0MHz
        asm("DELAY_30_US:   NOP");                      // Measured 32.8us PGB 5/9/04

        asm("               NOP");
        asm("               NOP");
        asm("               decfsz _delay_30_uc,f,c");
        asm("               GOTO DELAY_30_US");
    #endif

    #ifdef FOSC_11_R_0592MHz
        asm("DELAY_30_US:   NOP");

        asm("               NOP");
        asm("               NOP");
        asm("               NOP");
        asm("               NOP");
        asm("               NOP");
                                                        // Hi-Tech only accepts w,f not 0,1
        asm("               decfsz _delay_30_uc,f,c");  // ** Use _var,f,c not _var&0xFF,f
        asm("               GOTO DELAY_30_US");         // PICC-18 must have ":" on label
                                                        // f and c are optional
        return;
    #endif

}


// ***********************************************
void delay_5us(void)                        // ********* Check Fosc setting in header *********
{
    asm("               NOP");              // At Fosc = 4MHz, 1 NOP  + (call & return)
                                            /// 14us, pm 18F8627. PGB 3/21/06
    #ifdef FOSC_8_R_0MHz                    // At Fosc = 8MHz, 10 NOPs provide 5us delay
        asm("               NOP");          ///(May need some shaving down to include
        asm("               NOP");          ///call and return time)
        asm("               NOP");
        asm("               NOP");
        asm("               NOP");
    #endif

   return;
}



// ***********************************************
                 // Need 1, 20, 50, 500, 1000 ms delay at Fosc = 500 kHz
void delay_500khz_1ms(void)                  // ********* Check Fosc setting in header *********
{
    unsigned char i_uc;

    for(i_uc = 0; i_uc < 9; i_uc++)         // 1.03 ms on simulator
    {
        NOP();
    }

    return;
}

// ***********************************************
                 // Need 1, 20, 50, 500, 1000 ms delay at Fosc = 500 kHz
void delay_500khz_50ms(void)                 // ********* Check Fosc setting in header *********
{
    unsigned int i_ui;

    for (i_ui= 0; i_ui <= 345; i_ui++)      // 50.01 ms on simulator in Lite mode
    {
        NOP();
        NOP();
    }

    return;
}


// ***********************************************
                 // Need 1, 20, 50, 500, 1000 ms delay at Fosc = 500 kHz
void delay_500khz_20ms_debounce(void)                 // ********* Check Fosc setting in header *********
{
    unsigned int i_ui;

    for (i_ui= 0; i_ui <= 138; i_ui++)      // 20.2 ms on simulator in Lite mode

    {
        NOP();
        NOP();
    }

    return;
}


// ***********************************************
                 // Need 1, 20, 50, 500, 1000 ms delay at Fosc = 500 kHz
void delay_500khz_1000ms(void)               // ********* Check Fosc setting in header *********
{
    unsigned int i_ui;

    for (i_ui= 0; i_ui <= 7000; i_ui++)     // 1008 ms on simulator in Lite mode
    {
        NOP();
        NOP();
    }

    return;
}


// ***********************************************
                 // Need 1, 20, 50, 500, 1000 ms delay at Fosc = 500 kHz
void delay_500khz_500ms(void)               // ********* Check Fosc setting in header *********
{
    unsigned int i_ui;

    for (i_ui= 0; i_ui <= 3500; i_ui++)     //  504.33 ms on simulator in Lite mode
    {
        NOP();
        NOP();
    }

    return;
}