/********************************************************
	Interface2012年6月号付属 FM3マイコン基板企画
	CQBB-EL サンプルプログラム
*********************************************************/

#include "cpu_init.h"
#include "cpu_uart.h"
#include "tinylib.h"

/* ポートコントローラ制御レジスタ */
#define GPIO_PFR1   ((volatile unsigned int *)0x40033004)
#define GPIO_PFR4   ((volatile unsigned int *)0x40033010)
#define GPIO_PFR7   ((volatile unsigned int *)0x4003301C)
#define GPIO_PFRF   ((volatile unsigned int *)0x4003303C)
#define GPIO_DDR1   ((volatile unsigned int *)0x40033204)
#define GPIO_DDR4   ((volatile unsigned int *)0x40033210)
#define GPIO_DDR7   ((volatile unsigned int *)0x4003321C)
#define GPIO_DDRF   ((volatile unsigned int *)0x4003323C)
#define GPIO_PDIR1  ((volatile unsigned int *)0x40033304)
#define GPIO_PDIR7  ((volatile unsigned int *)0x4003331C)
#define GPIO_PDIRF  ((volatile unsigned int *)0x4003333C)
#define GPIO_PDOR4  ((volatile unsigned int *)0x40033410)
#define GPIO_PDOR7  ((volatile unsigned int *)0x4003341C)
#define GPIO_ADE	((volatile unsigned int *)0x40033500)


/* 7セグメントLED点灯パターン定義(16進数) */
const unsigned char BIN2LED7[] = {
/* 0     1     2     3     4     5     6     7     8     9     A     b     C     d     E     F */
 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
};


/* CQBB-EL タクトスイッチ初期化 */
void PUSHSW_Initialize(void)
{
	/* ビット0(SW2) */
	*GPIO_PFR7  = *GPIO_PFR7  & 0xFFFFDFFF;	/* P7D:GPIOを選択 */
	*GPIO_DDR7  = *GPIO_DDR7  & 0xDFFF;		/* P7D:入力方向 */
	/* ビット3〜1(SW5〜3) */
	*GPIO_PFRF  = *GPIO_PFRF  & 0xFFFFFFF8;	/* PF2〜F0:GPIOを選択 */
	*GPIO_DDRF  = *GPIO_DDRF  & 0xFFF8;		/* PF2〜F0:入力方向 */
}

/* CQBB-EL タクトスイッチ状態取得 */
int PUSHSW_GetSW(void)
{
	return ( (
		((*GPIO_PDIRF <<  1) & 0xE)	/* ビット3〜1:PF2〜0 */
		 |
		((*GPIO_PDIR7 >> 13) & 0x1)	/* ビット0:P7D */
	) ^ 3);	/* ビット1/0のみ論理反転(負論理のため) */
}


/* CQBB-EL ディップスイッチ入力初期化 */
void DIPSW_Initialize(void)
{
	*GPIO_ADE   = *GPIO_ADE   & 0xFFFFF00F;	/* A-D入力チャネル11(P1B)〜4(P14):ディセーブル */
	*GPIO_PFR1  = *GPIO_PFR1  & 0x00000FF0;	/* P1B〜P14:GPIOを選択 */
	*GPIO_DDR1  = *GPIO_DDR1  & 0xF00F;		/* P1B〜P14:入力方向 */
}

/* CQBB-EL ディップスイッチ状態取得 */
int DIPSW_GetSW(void)
{
	return ( (~(*GPIO_PDIR1 >> 4)) & 0xFF);	/* 負論理なので論理反転 */
}


/* CQBB-EL 7セグメントLED初期化 */
void LED7_Initialize(void)
{
	/* LED点灯初期化 */
	*GPIO_PFR4  = *GPIO_PFR4  & 0xFFFF83FF;	/* P4E〜P4A:GPIOを選択 */
	*GPIO_PFR7  = *GPIO_PFR7  & 0xFFFFF800;	/* P7A〜P70:GPIOを選択 */
	*GPIO_PDOR4 = *GPIO_PDOR4 | 0x7C00;		/* P4E〜P4A:"H"レベル出力 */
	*GPIO_PDOR7 = *GPIO_PDOR7 | 0x07FF;		/* P7A〜P70:"H"レベル出力 */
	*GPIO_DDR4  = *GPIO_DDR4  | 0x7C00;		/* P4E〜P4A:出力方向 */
	*GPIO_DDR7  = *GPIO_DDR7  | 0x07FF;		/* P7A〜P70:出力方向 */
}

/* CQBB-EL 7セグメント上位桁LED点灯制御 */
void LED7h_SetLED(int d)
{
	/* ビット7:P7A 〜 ビット0:P73 (負論理) */
	*GPIO_PDOR7 = (*GPIO_PDOR7 & 0xF807) | ((~d & 0xFF) <<  3);
}

/* CQBB-EL 7セグメント下位桁LED点灯制御 */
void LED7l_SetLED(int d)
{
	/* ビット7:P72 〜 ビット5:P70 (負論理) */
	*GPIO_PDOR7 = (*GPIO_PDOR7 & 0xFFF8) | ((~d & 0xE0) >>  5);
	/* ビット4:P4E 〜 ビット0:P4A (負論理) */
	*GPIO_PDOR4 = (*GPIO_PDOR4 & 0x83FF) | ((~d & 0x1F) << 10);
}



int main(void)
{
	int i, sw, count;

	/* CPU固有初期化処理 */
	CPU_Initialize();

	/* コンソール用UART初期化 */
	CPU_UartInitialize();

	/* CQBB-EL 7セグメントLED初期化 */
	LED7_Initialize();

	/* CQBB-EL ディップスイッチ入力初期化 */
	DIPSW_Initialize();

	/* CQBB-EL タクトスイッチ初期化 */
	PUSHSW_Initialize();

	/* 7セグメント ディップスイッチ状態表示 */
	count = DIPSW_GetSW();
	LED7l_SetLED( BIN2LED7[ (count % 16) ]); /* 下位桁 */
	LED7h_SetLED( BIN2LED7[ (count / 16) ]); /* 上位桁 */

	/* 起動メッセージをUARTに出力 */
	t_printf("\nFM3 + CQBB-EL sample program\n");

	while(1){

		while(1){
			/* プッシュスイッチの状態取得 */
			sw = PUSHSW_GetSW();
			/* SW2プッシュ時 カウント + 1 */
			if (sw & 1) count = count + 1;
			/* SW3プッシュ時 ディップスイッチ状態をリロード */
			if (sw & 2) count = DIPSW_GetSW();
			/* SW4プッシュ時 カウント 0xFF */
			if (sw & 4) count = 0xFF;
			/* SW5プッシュ時 カウント - 1 */
			if (sw & 8) count = count - 1;
			if (sw) break;
		}
		count = count & 0xFF;

		/* 7セグメント LEDカウント値表示 */
		LED7l_SetLED( BIN2LED7[ (count % 16) ]); /* 下位桁 */
		LED7h_SetLED( BIN2LED7[ (count / 16) ]); /* 上位桁 */

		/* 数値をUARTに出力 */
		t_printf("count = %02Xh\n", count);

		/* キーが離されるまで待つ */
		while(PUSHSW_GetSW()){}

	}

}
