﻿/*
 *  複数のスイッチを押す操作と離す操作による LED 表示
 *
 *  OS: T-Kernel
 *
 */

#include <tk/tkernel.h>  /* T-Kernel ヘッダ */
#include <tm/tmonitor.h> /* tm_printf() など */
#include <tk/sysdef.h>   /* ハードウェア定義 */

/* オブジェクト ID 番号 */
LOCAL ID tidA;           /* タスク A の ID */
LOCAL ID tidB;           /* タスク B の ID */

/* 割込みハンドラ A */
LOCAL void inthdrA(UINT intno)
{
    /* タスク A を起床する */
    /*??*/;

    /* intnoの割込みをクリアする */
    /*??*/;
    /*??*/;
}

/* 割込みハンドラ B */
LOCAL void inthdrB(UINT intno)
{
    /* タスク B を起床する */
    /*??*/;

    /* intnoの割込みをクリアする */
    /*??*/;
    /*??*/;
}

/* タスク A */
LOCAL void taskA(INT stacd, void *exinf)
{
    /* LED3 (PF3) に出力するように設定する */
    PIO_IE(F) &= ~(1 << 3);
    PIO_CR(F) |=  (1 << 3);
    PIO_DATA(F) |= (1 << 3);

    /* SW3 (PA3) から入力するように設定する */
    PIO_CR(A) &= ~(1 << 3);
    PIO_IE(A) |=  (1 << 3);

    /* SW3 (INT3) の割込みのモード設定を行う : 両エッジ */
    CLKCTRL_CGIMCGA = (CLKCTRL_CGIMCGA & ~(7 << (8 * 3 + 4))) | (4 << (8 * 3 + 4));

    /* SW3 (INT3) の割込みを許可する */
    CLKCTRL_CGIMCGA |= (1 << (8 * 3));
    /*??*/; /* 割込みをクリア */
    /*??*/; /* 割込みを許可 */
    /* 優先度は INTPRI_GROUP(5, 0) を指定 */

    for (;;) {
        /* 割込みハンドラから起床されるまで待つ */
        /*??*/;

        /* LEDとメッセージを表示する */
        if (PIO_DATA(A) & (1 << 3)) {
           /*??*/;
            tm_printf((UB*)"SW3: 0->1, LED3: 1\n");
        } else {
           /*??*/;
            tm_printf((UB*)"SW3: 1->0, LED3: 0\n");
        }
    }

    /* このタスクは終了しない */
}

/* タスク B */
LOCAL void taskB(INT stacd, void *exinf)
{
    /* LED4 (PB0) に出力するように設定する */
    PIO_IE(B) &= ~(1 << 0);
    PIO_CR(B) |=  (1 << 0);
    PIO_DATA(B) |= (1 << 0);

    /* SW4 (PE7) から入力するように設定する */
    PIO_CR(E) &= ~(1 << 7);
    PIO_IE(E) |=  (1 << 7);

    /* SW4 (INT6) の割込みのモード設定を行う : 両エッジ */
    CLKCTRL_CGIMCGB = (CLKCTRL_CGIMCGB & ~(7 << (8 * (6 - 4) + 4))) | (4 << (8 * (6 - 4) + 4));

    /* SW4 (INT6) の割込みを許可する */
    CLKCTRL_CGIMCGB |= (1 << (8 * (6 - 4)));
    /*??*/; /* 割込みをクリア */
    /*??*/; /* 割込みを許可 */
    /* 優先度は INTPRI_GROUP(5, 0) を指定 */

    for (;;) {
        /* 割込みハンドラから起床されるまで待つ */
        /*??*/;

        /* LEDとメッセージを表示する */
        if (PIO_DATA(E) & (1 << 7)) {
            /*??*/;
            tm_printf((UB*)"SW4: 0->1, LED4: 1\n");
        } else {
            /*??*/;
            tm_printf((UB*)"SW4: 1->0, LED4: 0\n");
        }
    }

    /* このタスクは終了しない */
}

/* 初期化処理 */
EXPORT INT usermain(void)
{
    ER er;
    T_DINT di;
    T_CTSK ct;

    /* 割込みハンドラ A を定義する */
    di.intatr = TA_HLNG;     /* 割込みハンドラ属性 */
    di.inthdr = inthdrA;     /* 割込みハンドラアドレス */
    er = /*??*/; /* 割込みハンドラ A を定義 */
    /* 割込み番号は3 */
    if (er < E_OK) goto e4;

    /* 割込みハンドラ B を定義する */
    di.intatr = TA_HLNG;     /* 割込みハンドラ属性 */
    di.inthdr = inthdrB;     /* 割込みハンドラアドレス */
    er = /*??*/; /* 割込みハンドラ B を定義 */
     /* 割込み番号は6 */
    if (er < E_OK) goto e3;

    /* タスク A を生成する */
    ct.exinf = (void*)('t' | 's' << 8 | 'k' << 16 | 'A' << 24); /* 拡張情報 */
    ct.tskatr = TA_HLNG | TA_RNG0; /* タスク属性 */
    ct.task = taskA;               /* タスク起動アドレス */
    ct.itskpri = 1;                /* タスク起動時優先度 */
    ct.stksz = 1024;               /* スタックサイズ */
    tidA = /*??*/;        /* タスク A を生成 */
    if (tidA < E_OK) { er = tidA; goto e2; } /* タスク生成失敗時 */

    /* タスク B を生成する */
    ct.exinf = (void*)('t' | 's' << 8 | 'k' << 16 | 'B' << 24); /* 拡張情報 */
    ct.tskatr = TA_HLNG | TA_RNG0; /* タスク属性 */
    ct.task = taskB;               /* タスク起動アドレス */
    ct.itskpri = 1;                /* タスク起動時優先度 */
    ct.stksz = 1024;               /* スタックサイズ */
    tidB = /*??*/;        /* タスク B を生成 */
    if (tidB < E_OK) { er = tidB; goto e1; } /* タスク生成失敗時 */

    /*??*/;           /* タスク A を起動 */
    /*??*/;           /* タスク B を起動 */

    return E_OK;

e1: tk_del_tsk(tidA);
e2: tk_def_int(6, NULL);
e3: tk_def_int(3, NULL);
e4: return er;
}
