// File: swleddemo.c
/////////////////////////////////////////////////////////////////////
//
// Switch & LED Demo by M.O.B.
// Copyright (C) 2008 by Mikael O. Bonnier, Lund, Sweden.
// All rights reserved. This program is free software licensed under 
// the terms of "GNU General Public License" v3 or later, see
// <http://www.gnu.org/copyleft/gpl.html>. Donations are welcome.
// The source code is at <http://www.df.lth.se/~mikaelb/micro/k8048/>.
//
// A simple demo C program for the PIC programmer & experimentation board.
// Press switches SW1-SW4 and see the effects on leds LD1-LD6.
//
// Target platform is Velleman K8048/VM111 with Microchip PIC 16F627 micro 
// controller with original configuration (JP3-JP4 on, all other jumpers off). 
// It was developed in C using Piklab in Kubuntu Linux 8.04 and MPLAB IDE v8.10 
// in Windows 2000 with CC5X v3.3A (FREE edition) from B Knudsen Data.
// In MPLAB IDE with CC5X it is necessary to set Build Options For 
// Project/CC5X C Compiler/Additional Command-Line Options 
//  to -p- in order to remove the effect of  MPLAB's chip definition. 
//
// In Windows I programmed the chip using Velleman ProgPIC2 V2.6.0 and 
// PicProg2006 V2.2.0.0, and in Linux: K14 and Piklab (with delay 10 on my computer). 
// In Linux you can usually install Piklab from the distribution, but it is a KDE 
// program. You can download K14 from <http://dev.kewl.org/k8048/Doc/>.
//
// Road map:
// * make generated code shorter
// * make it simpler.
//
// Revision history:
// 2008-Nov-13:     v.0.0.1
//
// Suggestions, improvements, and bug-reports
// are always welcome to:
//                  Mikael Bonnier
//                  Osten Undens gata 88
//                  SE-227 62  LUND
//                  SWEDEN
//
// Or use my electronic addresses:
//     Web: http://www.df.lth.se/~mikaelb/
//     E-mail/MSN: mikaelb@df.lth.se
//     ICQ # 114635318
//     Skype: mikael4u
//              _____
// :           /   / \           :
// ***********/   /   \***********
// :         /   /     \         :
// *********/   /       \*********
// :       /   /   / \   \       :
// *******/   /   /   \   \*******
// :     /   /   / \   \   \     :
// *****/   /   /***\   \   \*****
// :   /   /__ /_____\   \   \   :
// ***/               \   \   \***
// : /_________________\   \   \ :
// **\                      \  /**
// :  \______________________\/  :
//
// Mikael O. Bonnier
/////////////////////////////////////////////////////////////////////

#include <16f627.h> // Comes with CC5X.
#include "config16f627.h" // In the same directory as this file.

#pragma config = _BODEN_ON & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC


void menu();
void reset(void);
void effect1(void);
void effect2(void);
void effect3(void);
void effect4(void);
bit delay(void);

unsigned int keyb;

void main(void)
{
    reset();
    keyb = 0b0001;
    menu();
}

void menu() 
{
    for(;;)
    {
        switch(keyb) {
            case 0b0001: 
                effect1();
                break;
            case 0b0010:
                effect2();
                break;
            case 0b0100:
                effect3();
                break;
            case 0b1000:
                effect4();
                break;
            default:
                keyb = 0b0001;
                break;
        }
    }
}

void reset(void) 
{
    CMCON = 0b00000111; // Disable Comparator module's
        // Disable pull-ups
        // INT on rising edge
        // TMR0 to CLKOUT
        // TMR0 Incr low2high trans.
        // Prescaler assign to Timer0
        // Prescaler rate is 1:256
    OPTION_REG = 0b11010111; // Set PIC options (see datasheet).
    INTCON = 0; // Disable interrupts.
    TRISB = 0b11000000; // RB7 & RB6 are inputs. 
                        // RB5...RB0 are outputs.
    TRISA = 0b11111111; // All RA ports are inputs.
    PORTB = 0;
}

void effect1(void) 
{
    for(;;)
    {
        PORTB = 0b00000001;
        if(delay())
            break;
        PORTB = 0b00000010;
        if(delay())
            break;
        PORTB = 0b00000100;
        if(delay())
            break;
        PORTB = 0b00001000;
        if(delay())
            break;
        PORTB = 0b00010000;
        if(delay())
            break;
        PORTB = 0b00100000;
        if(delay())
            break;
    }
}

void effect2(void) 
{
    for(;;)
    {
        PORTB = 0b00000011;
        if(delay())
            break;
        PORTB = 0b00001100;
        if(delay())
            break;
        PORTB = 0b00110000;
        if(delay())
            break;
        PORTB = 0b00001100;
        if(delay())
            break;
    }
}

void effect3(void) 
{
    for(;;)
    {
        PORTB = 0b00110011;
        if(delay())
            break;
        PORTB = 0b00011110;
        if(delay())
            break;
        if(delay())
            break;
        PORTB = 0b00001100;
        if(delay())
            break;
        PORTB = 0b00000000;
        if(delay())
            break;
    }
}

void effect4(void) 
{
    for(;;)
    {
        PORTB = 0b00111111;
        if(delay())
            break;
        PORTB = 0b00000000;
        if(delay())
            break;
        if(delay())
            break;
        if(delay())
            break;
        if(delay())
            break;
        if(delay())
            break;
        if(delay())
            break;
    }
}

bit delay(void)
{
    unsigned int i;
    unsigned int j;
    for(i = 32; i > 0; --i)
        for(j = 255; j > 0; --j)
        {
            keyb = PORTA & 0b00001111;
            if(keyb)
                return 1;
        }
    return 0;
}

