/***********************************************************

	pic18dml.c
	
	Version 1.00: 2009/10/10

	Copyright (C) 2008-2009, MicroFan Div., PeopleMedia, Inc.
	All rights reserved.

***********************************************************/

#include "picsys18.h"

#if defined(USE_DML)

#if defined(PIC_DEV_2550URL)
extern BYTE dataPin ; // ドットマトリックスLED用のシフトレジスタのデータピン
extern BYTE clockPin ; // ドットマトリックスLED用のシフトレジスタのクロックピン
BYTE ePin ; // カラム側出力のイネーブルピン
BYTE dbPin[3] ; // カラム側出力の選択ピン
#else
static BYTE dataPin ; // ドットマトリックスLED用のシフトレジスタのデータピン
static BYTE clockPin ; // ドットマトリックスLED用のシフトレジスタのクロックピン
static BYTE ePin ; // カラム側出力のイネーブルピン
static BYTE dbPin[3] ; // カラム側出力の選択ピン
#endif

static BYTE gDL = 0 ; //ドットマトリックスLEDのダイナミック点灯の対象行
/* ドットマトリックスLEDの表示データ格納領域：VRAMのようなもの*/
static BYTE gMXR[8] ; /* 赤 */
static BYTE gMXG[8] ; /* 緑 */


/***********************************************************
	ドットマトリックスLEDの初期化
***********************************************************/

void
DML_init(BYTE rs, BYTE e, BYTE db4, BYTE db5, BYTE db6, BYTE db7)
{
	/* I/Oピンの割付を内部処理用に記録 */
	dataPin = rs ;
	clockPin = e ;
	dbPin[0] = db4 ;
	dbPin[1] = db5 ;
	dbPin[2] = db6 ;
	ePin = db7 ;
  
	pinMode(dataPin, OUTPUT) ; // シフトレジスタへのデータピンを出力に
	pinMode(clockPin, OUTPUT) ; // シフトレジスタへのクロックピンを出力に
  
	/* コモン側の選択ピンとイネーブルピンを出力に */
	pinMode(dbPin[0], OUTPUT) ;
	pinMode(dbPin[1], OUTPUT) ;
	pinMode(dbPin[2], OUTPUT) ;
	pinMode(ePin, OUTPUT) ;

	bitOut(ePin, LOW) ; // カラム側を非アクティブに
  
	DML_clear() ; // 初期化時に表示をクリア
    
    _refreshDevice = REFRESH_DML ;
}

#if defined(SR_DAT)

void
DML_initDefault()
{
	DML_init(SR_DAT, SR_CLK, SEG1, SEG2, SEG3, SEG4) ;
}

#endif


/***********************************************************
	ドットマトリックスLEDへの出力
***********************************************************/

/* ドットマトリックスLEDの表示クリア */
void
DML_clear()
{
	int i ;

	for (i = 0 ; i < 8 ; i++) {
		gMXR[i] = 0 ;
		gMXG[i] = 0 ;
	}
}


/* ドットマトリックスLEDへのプロット */
/* 0:黒、1:赤、2:緑、3:橙 */
void
DML_plot(int x, int y, BYTE color)
{
	BYTE w ;

	w = (1 << x) ;

	/* ドットデータの書き換え */
	switch (0b11 & color) {
		case DML_DOT_BLACK:
			gMXR[y] &= ~w ;
			gMXG[y] &= ~w ;
			break ;
		case DML_DOT_RED:
			gMXR[y] |= w ;
			gMXG[y] &= ~w ;
			break ;
		case DML_DOT_GREEN:
			gMXR[y] &= ~w ;
			gMXG[y] |= w ;
			break ;
		case DML_DOT_ORANGE:
			gMXR[y] |= w ;
			gMXG[y] |= w ;
			break ;
	}
}


/***********************************************************
	ダイナミック表示処理：割り込みサービスルーチンからの呼び出し
***********************************************************/

#ifdef OPTIMIZE
void
isr_DML_update()
{
	/* 今回表示する桁の確認：桁数があふれていたら０に巡回させる */
	if (gDL >= 8)
		gDL = 0 ;

	OPT_SEG4 = 0 ; // データ更新に備えコモン側を非アクティブ化  

#if defined(PIC_DEV_2550URL)
	isr_optShiftOut(MSBFIRST, 0x00) ;
	isr_optShiftOut(MSBFIRST, 0x00) ;

	isr_SW_update() ;
#endif

	isr_optShiftOut(MSBFIRST, gMXR[gDL]) ; // 赤色出力
	isr_optShiftOut(MSBFIRST, gMXG[gDL]) ; // 緑色出力

  /* コモン側の表示行の選択 */
  	OPT_SEG1 = (gDL & 0b001) ? 1: 0 ;
  	OPT_SEG2 = (gDL & 0b010) ? 1: 0 ;
  	OPT_SEG3 = (gDL & 0b100) ? 1: 0 ;
  
  	OPT_SEG4 = 1 ;

	gDL++ ;
}

#else

void
isr_DML_update()
{
	/* 今回表示する桁の確認：桁数があふれていたら０に巡回させる */
	if (gDL >= 8)
		gDL = 0 ;

	isr_bitOut(ePin, LOW) ; // データ更新に備えコモン側を非アクティブ化

#if defined(PIC_DEV_2550URL)
	shiftOut(dataPin, clockPin, MSBFIRST, 0x00) ;
	shiftOut(dataPin, clockPin, MSBFIRST, 0x00) ;

	isr_SW_update() ;
#endif

	shiftOut(dataPin, clockPin, MSBFIRST, gMXR[gDL]) ; // 赤色出力
	shiftOut(dataPin, clockPin, MSBFIRST, gMXG[gDL]) ; // 緑色出力

	/* コモン側の表示行の選択 */
	isr_bitOut(dbPin[0], (gDL & 0b001) ? 1: 0) ;
	isr_bitOut(dbPin[1], (gDL & 0b010) ? 1: 0) ;
	isr_bitOut(dbPin[2], (gDL & 0b100) ? 1: 0) ;

	isr_bitOut(ePin, HIGH) ; // コモン側をアクティブ化し表示再開

	gDL++ ;
}

#endif

#endif
