/*
 * Auto Reverse Controller   ver0.9a
 * File:   1823ARC.c
 * Author: nucky
 *
 * Created on 2020/04/19, 13:51
 */

#include <xc.h>

#define _XTAL_FREQ 4000000       // delay用に必要(クロック4MHzを指定)

#define Relay           RC0      // 転極リレー出力
#define ERR_LED         RC1      // エラーＬＥＤ出力
#define NOR_LED         RC2      // 定位ＬＥＤ出力
#define REV_LED         RC3      // 反位ＬＥＤ出力
#define OverLoadin      RC4      // 過負荷検知入力
#define CutOFFout       RC5      // 電子ブレーカ制御出力
#define REV_SW          RA4      // 反位スイッチ入力
#define NOR_SW          RA5      // 定位スイッチ入力

unsigned char   status ;         // status 


// コンフィギュレーション１の設定
#pragma config FOSC     = INTOSC // 内部ｸﾛｯｸ使用する(INTOSC)
#pragma config WDTE     = OFF    // ｳｵｯﾁﾄﾞｯｸﾞﾀｲﾏｰ無し(OFF)
#pragma config PWRTE    = ON     // 電源ONから64ms後にﾌﾟﾛｸﾞﾗﾑを開始する(ON)
#pragma config MCLRE    = ON     // 外部ﾘｾｯﾄ信号は使用する(ON)
#pragma config CP       = OFF    // ﾌﾟﾛｸﾞﾗﾑﾒﾓﾘｰを保護しない(OFF)
#pragma config CPD      = OFF    // ﾃﾞｰﾀﾒﾓﾘｰを保護しない(OFF)
#pragma config BOREN    = ON     // 電源電圧降下常時監視機能ON(ON)
#pragma config CLKOUTEN = OFF    // CLKOUTﾋﾟﾝをRA4ﾋﾟﾝで使用する(OFF)
#pragma config IESO     = OFF    // 外部・内部ｸﾛｯｸの切替えでの起動はなし(OFF)
#pragma config FCMEN    = OFF    // 外部ｸﾛｯｸ監視しない(OFF)

// コンフィギュレーション２の設定
#pragma config WRT    = OFF      // Flashﾒﾓﾘｰを保護しない(OFF)
#pragma config PLLEN  = OFF      // 動作クロックを32MHzでは動作させない(OFF)
#pragma config STVREN = ON       // スタックがフローしたらリセットをする(ON)
#pragma config BORV   = HI       // 電源電圧降下常時監視電圧(2.5V)設定(HI)
#pragma config LVP    = OFF      // 低電圧プログラミング機能使用しない(OFF)


// 電子ブレーカ、リレー出力状態を、各ＬＥＤに表示する
void LEDOUT(void)
{
    if (CutOFFout == 0) {
            ERR_LED = 1 ;       // エラー表示点灯
    } else {
            ERR_LED = 0 ;       // エラー表示滅灯
    }
    
    if (Relay == 0) {
            NOR_LED = 1 ;       // 定位表示
            REV_LED = 0 ;
    } else {
            NOR_LED = 0 ;       // 反位表示
            REV_LED = 1 ;
    }
}

// メイン処理
void main(void) {
    
    OSCCON = 0b01101010 ;           // 内部クロックは４ＭＨｚ
    ANSELA = 0b00000000 ;           // アナログ未使用（すべてデジタルI/O）
    ANSELC = 0B00000000 ;           // アナログ未使用（すべてデジタルI/O）
    TRISA  = 0b00111000 ;           // RA3,4,5は入力。他は出力。
    TRISC  = 0b00010000 ;           // RC4は入力。他は出力。
    PORTA  = 0b00000000 ;           // 出力ピンの初期化(全てLOW)
    PORTC  = 0b00000000 ;           // 出力ピンの初期化(全てLOW)
     
    ERR_LED = 1 ;                   // エラー表示
    __delay_ms(500) ;               // 電源投入後、0.5秒待機
    
    CutOFFout = 1 ;                 // 電子ブレーカ出力
    ERR_LED = 0 ;                   // エラーＬＥＤ消灯
    NOR_LED = 1 ;                   // 定位表示

    status = 0 ;                    // status 初期化
    
     while(1) {
    
        if (OverLoadin == 0) {      // 過負荷検知の処理
            
            CutOFFout = 0 ;         // 電子ブレーカＯＦＦ
            ERR_LED = 1 ;           // エラーＬＥＤ表示
            NOR_LED = 0 ;           // 定位表示滅灯
            REV_LED = 0 ;           // 反位表示滅灯
            
            if (status == 0) {      // status = 0（反転未実施なら）
                
                Relay = !Relay ;    // 出力を反転
                status = 1 ;        // status = 1 に設定（反転実施済）
                __delay_ms(10) ;    // リレーの動作時間待機（10ms待つ）

            } else {                // status = 1（反転実施済なら）
                __delay_ms(500) ;
                //Wait(500) ;         // 500ms後に再度リトライ
                
            }

            CutOFFout = 1 ;         // 電子ブレーカＯＮ
            LEDOUT() ;              // ＬＥＤ表示
            
        } else {                    // 過負荷未検知
            
            status = 0 ;            // 過負荷継続が無くなったら status = 0 に
        
        } 
        
        
        if (NOR_SW == 0) {          // 定位スイッチ押下されたとき
            if (Relay == 1){        // 反位なら反転処理
                CutOFFout = 0 ;     // 電子ブレーカーＯＦＦ
                Relay = 0 ;         // 出力を定位に
                __delay_ms(10) ;    // リレーの動作時間待機（10ms待つ）
                CutOFFout = 1 ;     // 電子ブレーカーＯＮ                   
                LEDOUT() ;
            }
        }
        
        if (REV_SW == 0) {          // 反位スイッチ押下されたとき
            if (Relay == 0){        // 定位なら反転処理
                CutOFFout = 0 ;     // 電子ブレーカーＯＦＦ
                Relay = 1 ;         // 出力を反位に
                __delay_ms(10) ;    // リレーの動作時間待機（10ms待つ）
                CutOFFout = 1 ;     // 電子ブレーカーＯＮ            
                LEDOUT() ;            
            }
        }            
     
    LEDOUT() ;      
            
         
    }
}
