/**
 * @fileOverview LPC1769ネームスペース、定数値を定義する。
 */

/**
 * LPC1769用の高レベルAPIのネームスペースである。
 * MCU,Pin,peripheralのクラスと、識別子を定義する。
 * このネームスペースのにある宣言は、LPC1769プロセッサに依存する。
 * @namespace
 */
var LPC1769;

(function(){
	var isUndef=MiMicLib.isUndef;
	var DEV=
	{
		/**
		 * エラーIDテーブルの拡張
		 * @private
		 */
		_EE:function(i_base){
		return{
			NG:[i_base|0x00,"Unknown exception in LPC1769"],
			INVALID_ARG :[i_base|0x01,"Invalid argument"],
			INVALID_PIN :[i_base|0x02,"Invalid pin"],
			INVALID_CFG :[i_base|0x03,"Invalid configulation"],
			VM_RUNTIME  :[i_base|0x04,"MVM runtime error"],
		};}(MiMicError.NG[0]|MiMicError.MID_MiMic|MiMicError.CAID_LPCXPresso1769),
		/**
		 * BCフラグメント・ライブラリ
		 * @private
		 */
		_BCF:{
			/**
			 * ([i_addr]&(~(i_mask<<i_shl))|((i_mask & i_val)<<i_shl)を実行するMimicBCを生成する。
			 * [S0]のアドレスのメモリ値に[S1]の値でマスクして,[S2]の値とORして[S0]に書き戻す。
			 * <pre>
			 * SGET #0;
			 * SGET #1;
			 * SGET #2;
			 * MGET #7,#0;
			 * AND #7,#1;
			 * OR #7,#2;
			 * MPUT #7,#0;
			 * </pre>
			 * @private
			 * @param i_mask
			 * ビットマスク
			 * @param i_val
			 * ビット値
			 */
			setBit:function setBit(i_addr,i_mask,i_val,i_shl,i_db)
			{
				try{
					i_db.push(i_addr);
					i_db.push(~(i_mask<<i_shl));
					i_db.push((i_mask & i_val) << i_shl);
					return "EA00EA01EA02DB0700AA0701AE0702DF0700";
				}catch(e){
					throw new MiMicException(e);
				}			
			},
			/**
			 * 値をメモリに設定する。
			 * <pre>
			 * SGET #0
			 * SGET #1
			 * MPUT #1,#0
			 * </pre>
			 * @private
			 */
			setMem:function setMem(i_addr,i_val,i_db)
			{
				try{
					i_db.push(i_addr);
					i_db.push(i_val);
					return "EA00EA01DF0100";
				}catch(e){
					throw new MiMicException(e);
				}			
			},
			/**
			 * メモリを32bit読む
			 * <pre>
			 * SGET #0
			 * MGET #0,#0
			 * SPUT #0
			 * </pre>
			 * @private
			 */			
			getMem:function getMem(i_addr,i_db)
			{
				try{
					i_db.push(i_addr);
					return "EA00DB0000EE00";
				}catch(e){
					throw new MiMicException(e);
				}			
			},
			/**
			 * メモリを32bit読む
			 * <pre>
			 * SGET #0
			 * MGET #0,#0
			 * SPUT #0
			 * </pre>
			 @private
			 */
			READMEM:"EA00DB0000EE00",
			
			/**
			 * BCフラグメントを終了する。
			 * <pre>
			 * EXIT;
			 * .END
			 * </pre>
			 @private
			 */
			END:"ZZ.E"	
		},
		/**
		 * 機能名のテーブル。
		 * 機能名として使用できる文字列の一覧表である。機能名は、機能を識別する目的で定義する。
		 * この値は一覧の定義のみであるので、使用することは無い。
		 * <ul>
		 * 	<li>GPIO - GPIO機能を表す。</li>
		 * 	<li>AD - AD convert機能を表す。</li>
		 * 	<li>DA - DA convert機能を表す。</li>
		 * 	<li>PWM - PWM機能を表す。</li>
		 * </ul>
		 * @name LPC1769#FUNC_NAME
		 * @constant
		 * @field
		 */
		FUNC_NAME:[
			"GPIO","AD","DA","PWM"
		],
		/**
		 * ペリフェラル名のテーブル。
		 * ペリフェラル名として使用できる文字列の一覧表である。ペリフェラル名は、ペリフェラルを識別する目的で定義する。
		 * この値は一覧の定義のみであるので、使用することは無い。
		 * <ul>
		 * 	<li>GPIO - GPIO peripheral</li>
		 * 	<li>ADC - AD peripheral</li>
		 * 	<li>DAC - DA peripheral</li>
		 * 	<li>PWM - PWM peripheral</li>
		 * </ul>
		 * @name LPC1769#PHL_NAME
		 * @constant
		 * @field
		 */
		PHL_NAME:[
			"GPIO","ADC","DAC","PWM"
		],
		/**
		 * LPCXpressoのPeripheralパラメタを格納したテーブルである。要素はペリフェラル識別子である。
		 * UM10360のChapter 4: LPC17xx Clocking and power controlを元に定義している。
		 * ペリフェラル識別子はペリフェラルのレジスタ番号とビット番号を格納した配列である。
		 * <pre>
		 * PHL:{PHL_NAME:[PCLKSELreg#,PCLKSELbit#,PCONPbit#]}
		 * </pre>
		 * nullはそのビットが無効であることを示す。
		 * @name LPC1769#PHL
		 * @constant
		 * @field
		 * @example
		 * LPC1769.PHLADC //ADC peripheral
		 */
		PHL:{
			WDT:	[0,0,null],
			TIMER0:	[0,2,1],
			TIMER1:	[0,4,2],
			UART0:	[0,6,3],
			UART1:	[0,8,4],
			PWM1:	[0,12,6],
			I2C0:	[0,14,7],
			SPI:	[0,16,8],
			RTC:	[null,null,9],
			SSPI1:	[0,20,10],
			DAC:	[0,22,null],
			ADC:	[0,24,12],
			CAN1:	[0,26,13],
			CAN2:	[0,28,14],
			ACF:	[0,30,null],
			QEI:	[1,0,18],
			GPIOINT:[1,2,15],
			PCB:	[1,4,null],
			I2C1:	[1,6,19],
			SSP0:	[1,10,21],
			TIMER2:	[1,12,22],
			TIMER3:	[1,14,23],
			UART2:	[1,16,24],
			UART3:	[1,18,25],
			I2C2:	[1,20,26],
			I2S:	[1,22,27],
			RIT:	[1,26,16],
			SYSCON:	[1,28,null],
			PWM_MC:[1,30,17],//MC?
			GPDMA:[null,null,29],
			ENET:[null,null,30],
			USB:[null,null,31]
		},
		/**
		 * PCXpressoのPINに対応する識別子のテーブルである。要素はPIN識別子である。テーブルは、P0[n]~p4[m]まで存在する。
		 * ピン識別子は、ピンP?[?]を、P0[0]のように表現する。これは、UM10360のTable 73. Pin descriptionのSymbol P?[?]に対応している。
		 * Pn[m]のn,mの使用できる値は、Table 73. Pin descriptionに一致する。
		 * PIN識別子から値を取り出すときは、専用の関数を使用するべきである。
		 * ピン識別子は、ピンを制御するレジスタ番号とビット番号を格納した配列である。
		 * <pre>
		 * Pn:[[PINSELreg#,PINMODEreg#,PINMODEODreg#,bitidx,[ピン機能名]]]
		 * </pre>
		 * <ul>
		 * <li>PINFUNC,PINMODEのビット位置は、(bitidx%16)*2で計算する。ODRegについては、そのままの数値を使う。</li>
		 * <li>[ピン機能名]は、PINSEL設定値に対応するテーブルである。配列のインデクス値が、そのままPINSELの値に対応する。</li>
		 * <li>設定できない値のフィールドはnullである。ピン機能名はPin Function Select registerのテーブルの定義値そのもである。ただし、GPIOについては"GPIO Port "を"GPIO"に省略していることに注意。</li>
		 * <li>nullはそのビットが無効であることを示す。</li>
		 * </ul>
		 * @name LPC1769#P0
		 * @constant
		 * @field
		 * @example
		 * //1
		 * LPC1769.P0[0]; //P0[0]
		 * LPC1769.P1[1]; //P0[01]
		 * //2
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * var gpiopin=mcu.getPin(LPC1769.P0[0],"GPIO");//bind P0[0] with GPIO function
		 */
		P0:[
			[0,0,0,0,["GPIO0.0","RD1","TXD3","SDA1"]],//0
			[0,0,0,1,["GPIO0.1","TD1","RXD3","SCL1"]],//1
			[0,0,0,2,["GPIO0.2","TXD0","AD0.7",null]],//2
			[0,0,0,3,["GPIO0.3","RXD0","AD0.6",null]],//3
			[0,0,0,4,["GPIO0.4","I2SRX_CLK","RD2","CAP2.0"]],//4
			[0,0,0,5,["GPIO0.5","I2SRX_WS","TD2","CAP2.1"]],//5
			[0,0,0,6,["GPIO0.6","I2SRX_SDA","SSEL1","MAT2.0"]],//6
			[0,0,0,7,["GPIO0.7","I2STX_CLK","SCK1",	"MAT2.1"]],//7
			[0,0,0,8,["GPIO0.8","I2STX_WS","MISO1","MAT2.2"]],//8
			[0,0,0,9,["GPIO0.9","I2STX_SDA","MOSI1","MAT2.3"]],//9
			[0,0,0,10,["GPIO0.10","TXD2","SDA2","MAT3.0"]],//10
			[0,0,0,11,["GPIO0.11","RXD2","SCL2","MAT3.1"]],//11
			null,null,null,//12,13,14
			[0,0,0,15,["GPIO0.15","TXD1","SCK0","SCK"]],//15
			[1,1,0,16,["GPIO0.16","RXD1","SSEL0","SSEL"]],//16
			[1,1,0,17,["GPIO0.17","CTS1","MISO0","MISO"]],//17
			[1,1,0,18,["GPIO0.18","DCD1","MOSI0","MOSI"]],//18
			[1,1,0,19,["GPIO0.19","DSR1",null,"SDA1"]],//19
			[1,1,0,20,["GPIO0.20","DTR1",null,"SCL1"]],//20
			[1,1,0,21,["GPIO0.21","RI1",null,"RD1"]],//21
			[1,1,0,22,["GPIO0.22","RTS1",null,"TD1"]],//22
			[1,1,0,23,["GPIO0.23","AD0.0","I2SRX_CLK","CAP3.0"]],//23
			[1,1,0,24,["GPIO0.24","AD0.1","I2SRX_WS","CAP3.1"]],//24
			[1,1,0,25,["GPIO0.25","AD0.2","I2SRX_SDA","TXD3"]],//25
			[1,1,0,26,["GPIO0.26","AD0.3","AOUT","RXD3"]],//26
			[1,null,null,22,["GPIO0.27","SDA0",	"USB_SDA",null]],//27
			[1,null,null,24,["GPIO0.28","SCL0",	"USB_SCL",null]],//28
			[1,null,0,29,["GPIO0.29","USB_D+",null,null]],//29
			[1,null,0,30,["GPIO0.30","USB_D-",null,null]],//30
			],
		/**
		 * P1に対する定義である。詳細はP0のドキュメントを参照。
		 * @name LPC1769#P1
		 * @constant
		 * @field
		 * @see LPC1769#P0
		 */
		P1:[	//P1[x]
			[2,2,1,0,["GPIO1.0","ENET_TXD0",null,null]],//0
			[2,2,1,1,["GPIO1.1","ENET_TXD1",null,null]],//1
			null,null,//2,3
			[2,2,1,4,["GPIO1.4","ENET_TX_EN",null,null]],//4
			null,null,null,//5,6,7
			[2,2,1,8,["GPIO1.8","ENET_CRS",null,null]],//8
			[2,2,1,9,["GPIO1.9","ENET_RXD0",null,null]],//9
			[2,2,1,10,["GPIO1.10","ENET_RXD1",null,null]],//10
			null,null,null,//11,12,13
			[2,2,1,14,["GPIO1.14","ENET_RX_ER",null,null]],//14
			[2,2,1,15,["GPIO1.15","ENET_REF_CLK",null,null]],//15
			[3,3,1,16,["GPIO1.16","ENET_MDC",null,null]],//16
			[3,3,1,17,["GPIO1.17","ENET_MDIO",null,null]],//17
			[3,3,1,18,["GPIO1.18","USB_UP_LED","PWM1.1","CAP1.0"]],//18
			[3,3,1,19,["GPIO1.19","MCOA0","USB_PPWR","CAP1.1"]],//19
			[3,3,1,20,["GPIO1.20","MCI0","PWM1.2","SCK0"]],//20
			[3,3,1,21,["GPIO1.21","MCABORT","PWM1.3","SSEL0"]],//21
			[3,3,1,22,["GPIO1.22","MCOB0","USB_PWRD","MAT1.0"]],//22
			[3,3,1,23,["GPIO1.23","MCI1","PWM1.4","MISO0"]],//23
			[3,3,1,24,["GPIO1.24","MCI2","PWM1.5","MOSI0"]],//24
			[3,3,1,25,["GPIO1.25","MCOA1",null,"MAT1.1"]],//25
			[3,3,1,26,["GPIO1.26","MCOB1","PWM1.6","CAP0.0"]],//26
			[3,3,1,27,["GPIO1.27","CLKOUT","USB_OVRCR","CAP0.1"]],//27
			[3,3,1,28,["GPIO1.28","MCOA2","PCAP1.0","MAT0.0"]],//28
			[3,3,1,29,["GPIO1.29","MCOB2","PCAP1.1","MAT0.1"]],//29
			[3,3,1,30,["GPIO1.30",null,"VBUS","AD0.4"]],//30
			[3,3,1,31,["GPIO1.31",null,"SCK1","AD0.5"]],//31
			],
		/**
		 * P2に対する定義である。詳細はP0のドキュメントを参照。
		 * @name LPC1769#P2
		 * @constant
		 * @field
		 * @see LPC1769#P0
		 */
		P2:[	//P2[x]
			[4,4,2,0,["GPIO2.0","PWM1.1","TXD1",null]],//0
			[4,4,2,1,["GPIO2.1","PWM1.2","RXD1",null]],//1
			[4,4,2,2,["GPIO2.2","PWM1.3","CTS1",null]],//2
			[4,4,2,3,["GPIO2.3","PWM1.4","DCD1",null]],//3
			[4,4,2,4,["GPIO2.4","PWM1.5","DSR1",null]],//4
			[4,4,2,5,["GPIO2.5","PWM1.6","DTR1",null]],//5
			[4,4,2,6,["GPIO2.6","PCAP1.0","RI1",null]],//6
			[4,4,2,7,["GPIO2.7","RD2","RTS1",null]],//7
			[4,4,2,8,["GPIO2.8","TD2","TXD2","ENET_MDC"]],//8
			[4,4,2,9,["GPIO2.9","USB_CONNECT","RXD2","ENET_MDIO"]],//9
			[4,4,2,10,["GPIO2.10","EINT0","NMI",null]],//10
			[4,4,2,11,["GPIO2.11","EINT1",null,"I2STX_CLK"]],//11
			[4,4,2,12,["GPIO2.12","EINT2",null,"I2STX_WS"]],//12
			[4,4,2,13,["GPIO2.13","EINT3",null,"I2STX_SDA"]],//13
			],
		/**
		 * P3に対する定義である。詳細はP0のドキュメントを参照。
		 * @name LPC1769#P3
		 * @constant
		 * @field
		 * @see LPC1769#P0
		 */
		P3:[	//P3[x]
			null/* 0*/,null/* 1*/,null/* 2*/,null/* 3*/,null/* 4*/,null/* 5*/,null/* 6*/,null/* 7*/,null/* 8*/,null/* 9*/,
			null/*10*/,null/*11*/,null/*12*/,null/*13*/,null/*14*/,null/*15*/,null/*16*/,null/*17*/,null/*18*/,null/*19*/,
			null/*20*/,null/*21*/,null/*22*/,null/*23*/,null/*24*/,
			[7,7,3,25,["GPIO3.25",null,"MAT0.0","PWM1.2"]],//25
			[7,7,3,26,["GPIO3.26","STCLK","MAT0.1","PWM1.3"]],//26
		],
		/**
		 * P4に対する定義である。詳細はP0のドキュメントを参照。
		 * @name LPC1769#P4
		 * @constant
		 * @field
		 * @see LPC1769#P0
		 */
		P4:[	//P4[x]
			null/* 0*/,null/* 1*/,null/* 2*/,null/* 3*/,null/* 4*/,null/* 5*/,null/* 6*/,null/* 7*/,null/* 8*/,null/* 9*/,
			null/*10*/,null/*11*/,null/*12*/,null/*13*/,null/*14*/,null/*15*/,null/*16*/,null/*17*/,null/*18*/,null/*19*/,
			null/*20*/,null/*21*/,null/*22*/,null/*23*/,null/*24*/,null/*25*/,null/*26*/,null/*27*/,
			[9,9,4,28,["GPIO4.28","RX_MCLK","MAT2.0","TXD3"]],//28
			[9,9,4,29,["GPIO4.29","TX_MCLK","MAT2.1","RXD3"]]//29
		],
		/**
		 * [forSystem]ピン識別子のアクセス関数である。
		 * ピン機能シンボルのプレフィクス（機能シンボル）を、 ピン識別子を元に、完全な名称に変換する。
		 * ピンにFunctionが含まれているか調べることが出来る。
		 * @private
		 */
		completePinFunctionName:function completePinFunctionName(i_pin,i_prefix)
		{
			try{
				//配列探索
				for(var i=0;i<i_pin[4].length;i++){
					if(i_pin[4][i].indexOf(i_prefix)==0){
						//ピン情報の構成
						return i_pin[4][i];
					}
				}
				throw new MiMicException("The function name '"+i_prefix+"' is not unknown.");
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * [forSystem]ピン識別子のアクセス関数。
		 * ピン識別値から、Pinレジスタの番号と、ビット位置を取り出す。
		 * @private
		 * @return
		 * {s:pinselのレジスタ番号、m:modeのレジスタ番号、,o:odのレジスタ番号,sbm:mode,selのビット位置,ob:odのビット位置}
		 */
		getPinRegInfo:function getPinRegInfo(i_pin)
		{
			try{
				return {s:i_pin[0],m:i_pin[1],o:i_pin[2],smb:(i_pin[3]%16)*2,ob:i_pin[3]};
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * [forSystem]ピン識別子のアクセス関数。
		 * PIN機能名に一致するPinsel値を取り出す。
		 * @private
		 */
		getPinSelByFunctionName:function getPinSelByFunctionName(i_pin,i_name)
		{
			try{
				for(var i=0;i<i_pin[4].length;i++){
					if(i_pin[4][i]==i_name){
						//ピン情報の構成
						return i;
					}
				}
				throw new MiMicException("The function name '"+i_name+"' has not function.");
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * [forSystem]ピンが、ピン機能シンボルを持つか返す。
		 * @private
		 */
		hasPinFunctionName:function hasPinFunctionName(i_pin,i_name)
		{
			return i_pin[4].indexOf(i_name)>=0;
		}
	}

/**
 * @private
 */
DEV.I2c=function I2c()
{
	throw new MiMicException("Not imprement.");
}

/**
 * @private
 */
DEV.Dma=function Dma()
{
	throw new MiMicException("Not imprement.");
}
/**
 * @private
 */
DEV.Uart=function Uart()
{
	throw new MiMicException("Not imprement.");
}
/**
 * @private
 */
DEV.Usb=function Usb()
{
	throw new MiMicException("Not imprement.");
}


LPC1769=DEV;
}());

/**
 * @fileOverview LPC1769のMCU制御クラスを定義する。
 */
(function(){
	/** @ignore */
	var DEV=LPC1769;
	var BCF=DEV._BCF;
	var EE=DEV._EE;
	var isUndef=MiMicLib.isUndef;

	/**
	 * 配列をMiMicDBへ変換する。
	 @private
	 @throws
	 変換失敗時は例外
	 */
	function array2MimicDb(i_array)
	{
		try{
			var p="";
			for(var i=0;i<i_array.length;i++){
				p+=MiMicLib.hexout(i_array[i],8);
			}
			return p;
		}catch(e){
			throw new MiMicException(e);
		}
	}
	
	/**
	 * PINの機能名を含むPin識別子を得る。
	 @private
	 */
	function getPinByFuncName(i_name)
	{
		try{
			function getPinByFName(i_pintbl,i_name)
			{
				for(var i=0;i<i_pintbl.length;i++){
					if(i_pintbl[i]==null){
						continue;
					}
					if(DEV.hasPinFunctionName(i_pintbl[i],i_name)){
						return i_pintbl[i];
					}
				}
				return null;
			}
			var tbl=[DEV.P0,DEV.P1,DEV.P2,DEV.P3,DEV.P4];
			for(var i=0;i<tbl.length;i++){
				var pin=getPinByFName(tbl[i],i_name);
				if(pin!=null){
					return pin;
				}
			}
			throw new MiMicException("pin function '"+i_name+"' not found");
		}catch(e){
			throw new MiMicException(e);
		}
	}
	/**
	 * PIN機能名から使用するペリフェラルシンボルを推定する。
	 @private
	 */
	function pinFuncName2PhlName(i_pinfuncname)
	{
		try{
			//Pin function nameプレフィクスとペリフェラル名の対比表
			var TBL={
				"GPIO":"GPIO",
				"AD":"ADC",
				"DA":"DAC",
				"PWM":"PWM"
			};
			for(var key in TBL){
				if(i_pinfuncname==key){
					return TBL[key];
				}
			}
			//見つからぬ。
			throw new MiMicException("Peripheral for "+i_pinfuncname+" not found.");
		}catch(e){
			throw new MiMicException(e);
		}
	}
	
	/**
	 * LPCXPresso1769.MCU(MCU)クラスのコンストラクタ。
	 * MCUクラスは、物理MCUとのインタフェイスを定義する。MiMicRemoteMcuInterfaceの管理機能と、MCUの物理機能への接続手段を定義する。
	 * 提供する機能は次のリストである。
	 * <ul>
	 * <li>物理MCUとの接続管理機能。
	 * <li>MCUの管理するペリフェラル操作インスタンスの生存管理機能。
	 * <li>MCUの持つ物理デバイスの操作オブジェクト(Pin,Peripheral等)の生成機能（インテリジェント接続）。
	 * </ul>
	 * @name LPC1769.Mcu
	 * @constructor
	 * @param {string} i_mimic_addr
	 * 接続するMiMicRemoteMcuのホストアドレスを指定する。IPアドレス、ホスト名等。
	 * <pre>ex. “127.0.0.1” , “127.0.0.1:3939”</pre>
	 * @param {boolean} i_is_activate
	 * インスタンス生成と同時にMiMicRemoteMcuとの接続を確立するかのフラグ。省略時はtrueとみなす。
	 * trueの場合、関数は即座にMiMicRemoteMCUに接続する。このとき、events.onActivateChangedをハンドリングすることが出来ないので注意すること。ハンドリングが必要なら、falseを指定して、改めてactivate関数をコールする。
	 * @example
	 * //create a controlable MCU via network.
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 */
	DEV.Mcu=function Mcu(i_mimic_addr,i_is_activate)
	{
		try{
			//メンバの初期化
			this.events={onActivateChanged:null};
			this._phl_holder=[];
			//リモートインタフェイスの取得
			this._mif=new MiMicRemoteMcuInterface(i_mimic_addr);
			var ac=isUndef(i_is_activate)?true:i_is_activate;
			if(ac){
				this.activate();
			};
		}catch(e){
			throw new MiMicException(e);
		}
	};

	DEV.Mcu.prototype=
	{
		/**
		 * MiMicInterface
		 @private
		 */
		_mif:null,
		/**
		 * インスタンスがMCUと接続されているかをtrue/falseで返す。
		 * @name LPC1769.Mcu#isActive
		 * @function
		 * @return {boolean}
		 * インスタンスが接続中ならtrue
		 * @example
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”,false);
		 * mcu.events.onActivateChanged=function(f){
		 * 	if(!f){alert(f)};
		 * 	}
		 * mcu.activate(); 
		 */
		isActive:function isActive()
		{
			try{
				return this._mif.isConnected();
			}catch(e){
				throw new MiMicException(e);
			}
		},
		
		/**
		 * イベントハンドラの連想配列。メンバにイベントハンドラ関数を格納する。
		 イベントハンドラは以下の通り。
		 <ul>
		 <li>onActivateChanged as function(f:boolean) - インスタンスのアクティブ状態が変化したときに呼び出されるイベントである。fパラメータには、状態変化後のアクティブ状態値が入る。このハンドラが呼び出されるのは、ユーザが状態を切り替えたときと、システムが状態を維持できなくなったとき（例えばMCUが応答しない）である。</li>
		 </ul>
		 * @name LPC1769.Mcu#events
 		 * @field
 		 * @example
 		 * //show that MCU became active. 
 		 * var mcu=new LPC1769.Mcu("192.168.0.39",false);
 		 * mcu.events.onActivateChanged=function(f){
 		 * 	if(!f){alert(f)};
 		 * }
 		 * mcu.activate(); 		 
		 */
		events:null,
		/**
		 * ペリフェラルオブジェクトのホルダ。ペリフェラル名をキーにした、ペリフェラルオブジェクトの連想配列。
		 * MCUが、自身のペリフェラルオブジェクトを管理する為に使う。
		 * @private
		 */
		_phl_holder:null,
		/**
		 * SystemClockに関する情報を返す。
		 * @name LPC1769.Mcu#getClockInfo
		 * @function
		 * @return {cclk:MCUクロック [Hz] as int}
		 * クロック値を格納した連想配列である。
		 * @example
		 * // alert MCU clock
		 * var mcu=new LPC1769.Mcu("192.168.0.39");
		 * alert(mcu.getClockInfo().cclk);
		 */
		getClockInfo:function getClockInfo()
		{
			//CCLCK値(RemoteMCU側と合わせること。将来的にはactivateの時に決定する。)
			return {cclk:100*1000*1000};
		},
		/**
		 * インスタンスの状態をアクティブに切り替える。
		 * アクティブ化に成功すると、インスタンスは物理MCUと接続状態になる。
		 * コンストラクタで生成と同時にアクティブ化した場合は、コンストラクタ内で自動的にコールされる。
		 * 既にアクティブの場合、アクティブ化に失敗した場合に例外が発生する。
		 * @name LPC1769.Mcu#activate
		 * @function
		 * @example
		 * // MCU will be active.
		 * var mcu=new LPC1769.Mcu("192.168.0.39",false);
		 * mcu.activate();
		 */
		activate:function activate()
		{
			try{
				var _t=this;
				//既にアクティブならエラー。
				if(this.isActive()){
					throw new MiMicException("Already activated!");
				}
				//接続
				this._mif.connect(
					function(b){
						if(!b){
							//非同期切断を検出。
							if(_t.events.onActivateChanged!=null){
								_t.events.onActivateChanged(false);
							}
						}
					}
				);
				if(this.events.onActivateChanged!=null){
					this.events.onActivateChanged(true);
				}
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * インスタンスの状態を非アクティブに切り替える。
		 * 成功すると、インスタンスと物理MCUは切断状態になる。
		 * 既に非アクティブの場合、例外が発生する。
		 * @name LPC1769.Mcu#deactivate
		 * @function
		 * @example
		 * // MCU will be deactive.
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * mcu.events.onActivateChanged=function(f){
		 * 	if(!f){alert(f)};
		 * }
		 * mcu.deactivate();
		 */
		deactivate:function deactivate()
		{
			try{
				if(!this.isActive()){
					throw new MiMicException("Already activated!");
				}
	
				this._mif.disconnect();
				if(this.events.onActivateChanged!=null){
					this.events.onActivateChanged(false);
				}
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * 整形済みのMiMicBCを送信する。整形済みのMiMicBCは、MiMicTXT,MiMicDBを連結した文字列である。固定命令を送信するときに使う。
		 * @name LPC1769.Mcu#callMiMic^2
		 * @function
		 * @param {string} i_mimicbc
		 * MiMicBC。MiMicBCのフォーマットは、MiMicVM.pdf MiMicBCで定義する。
		 * @return {object as {MiMic result}}
		 * @example
		 * //send MiMic operations.
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * mcu.callMiMic(“ZAZZ.E”);//NOP .END	
		 */
		/**
		 * 整形済みのMiMicTXTと、数値配列のMiMicDBを連結して送信する。固定命令+パラメータで擬似関数を実現するときに便利である。
		 * @name LPC1769.Mcu#callMiMic^3
		 * @function
		 * @param {string} i_mimictxt
		 * MiMicTXT。MiMicTXTのフォーマットは、MiMicVM.pdf MiMicBCで定義する。
		 * @param {Array[int]} mimicdb
		 * 配列のINT値。値は関数によりMiMicDBに変換され、MiMicTXTに連結され、送信される。		 
		 * @return {object as {MiMic result}}
		 * @example
		 * //send MiMic operations.
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * mcu.callMiMic(“ZAZZ.E”,[]); //NOP .END
		 */
		/**
		 * MiMicBCをリンクしているMCUへMiMic Low level APIで同期送信し、結果を取得する。
		 * MiMic Low level APIのresult値が得られない場合、例外が発生する。この状況は、TCP/IPエラー、HTTPエラー、HTTPステータスエラー、MiMicVMのラインタイムエラー、MiMicRemoteMCUのフォールト等の原因で発生する。
		 * 関数が値を返した場合は、MiMicRemoteMCUが処理を完了し、正しい形式のステータスを受信できた場合である。例外が発生した場合は、リンクが破壊されている場合がある。リンクが破壊された場合は、1分以内にアクティブ状態が変化するので、それを検出して判断する。<br/>
		 * 引数の違いにより、数種類の呼び出し方がある。詳細は、callMiMic^nを参照。
		 * @name LPC1769.Mcu#callMiMic^1
		 * @function
		 * @param ...
		 * LPC1769.Mcu#callMiMic^nを参照
		 * @return {object as {MiMic result}}
		 * 応答値を格納した連想配列である。
		 * 詳細は 低レベルAPI。MiMicRemoteMcuInterface.execBc関数、または、MiMicVM.pdf Appendix 1. MiMicVM HTTP Interfaceを参照。 
		 */
		callMiMic:function callMiMic(/**/)
		{
			try{
				var bc;
				switch(arguments.length){
				case 1:
					//mimicBC
					bc=arguments[0];
					break;
				case 2:
					//mimicBC:string,db:array[int]
					bc=arguments[0]+array2MimicDb(arguments[1]);
					break;
				default:
					throw new MiMicException(e);
				}
				return this._mif.execBc(bc);
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * callMiMic関数のラッパーである。
		 * callMiMic関数成功後に、resultが成功(MVM_OK=0x0)であるかを確認し、それ以外であれば例外を発生させる。
		 * resultが0以外想定されないMiMicBCを実行するときに、便利である。<br/>
		 * 引数、戻り値については、callMiMic関数を参照。
		 * @name LPC1769.Mcu#callMiMicWithCheck
		 * @function
		 * @example
		 * //send 2 MiMic operations.
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * mcu.callMiMicWithCheck(“ZAZZ.E”,[]);
		 * mcu.callMiMicWithCheck(“ZAZZ.ENOOOO”);//exception!
		 */
		callMiMicWithCheck:function execBc2WithException(/**/)
		{
			try{
				var ret=this.callMiMic.apply(this,arguments);
				if(ret.result!=0x0){
					throw new MiMicException(EE.VM_RUNTIME,"Result="+ret.toString());
				}
				return ret;
			}catch(e){
				throw new MiMicException(e);
			}
		},
		/**
		 * ピン機能名から、Pinインスタンスを生成する。
		 * 生成されたピンは、ピン機能名の割り当てられている物理ピンで実現される。
		 * ピン機能名は、 LPC1769.P?[?]の[ピン機能名]で定義する文字列である。これは、UM10360　3.1.2.3  Chapter 8: LPC17xx Pin connect blockのfunction nameで定義される、PINSELレジスタに設定する文字列と一致する。
		 * @name LPC1769.Mcu#getPin^2
		 * @function
		 * @param {string} i_pin_function_name
		 * ピン機能名の文字列。 ex. “GPIO0.0” ,”AD0.0”
		 * GPIOについては、”GPIO Port 0.0”を”GPIO0.0”のように、省略すること。		 
		 * @return {object as PinObject}
		 * @example
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * //create gpio pin at PIN0[0]
		 * var gpiopin1=mcu.getPin("GPIO0.0");
		 */
		/**
		 * ピン識別子と機能名から、機能を割り当てたピンを生成する。組み合せにより、ピンを生成できない可能性もある。
		 * 組み合わせは、UM10360 3.1.2.3  Chapter 8: LPC17xx Pin connect blockを参照すること。
		 * @name LPC1769.Mcu#getPin^3
		 * @function
		 * @param {object as pin識別子} i_pin
		 * ピン識別子。指定できるのは、LPCXpresso1796.P?[?]である。
		 * @param {string as 機能名} i_function_name
		 * 機能名の文字列である。 指定できる文字列は、LPC1769.FUNC_NAMEで定義する。
		 * @return {object as PinObject}
		 * @example
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 *
		 * //create gpio pin at PIN0[1]
		 * var gpiopin2=mcu.getPin(LPC1769.P0[1],"GPIO");
		 * //or  mcu.getPin(LPC1769.P0[1],LPC1769.FUNC_SYMBOL.GPIO);
		 *
		 * //create AD at PIN0[23]
		 * var adpin1=mcu.getPin(LPC1769.P0[23],"AD"); 
		 * //or  mcu.getPin(LPC1769.P0[23],LPC1769.FUNC_SYMBOL.AD);
		 *
		 * //create AD at PIN0[3] (exception)
		 * var adpin2=mcu.getPin(LPC1769.P0[3],"AD");
		 */
		/**
		 * 物理ピンを制御するPinインスタンスを得る。
		 * 制御ペリフェラル、Pinを順に生成する方法と異なり、機能の実現に必要なインスタンスを自動的に準備できる。
		 * Pinが生成できない場合、例外が発生する。
		 * ペリフェラルが自動生成された場合、そのオプションはデフォルト値が採用される。既に生成済みのペリフェラルの場合は何もしない。PINのオプションは、デフォルト値が採用される。
		 * 引数の違いにより、数種類の呼び出し方がある。
		 * @name LPC1769.Mcu#getPin^1
		 * @function
		 * @param ...
		 * LPC1769.Mcu#getPin^nを参照
		 * @return {object as PinObject}
		 * 返却されるPinインスタンスの型は、機能により異なる。機能とPinインスタンスのクラスの対応は、以下の通りである。
		 * <ul>
		 * <li>GPIO - LPC1769.GpioPin</li>
		 * <li>AD - LPC1769.AdcPin</li>
		 * <li>PWM - LPC1769.PwmPin</li>
		 * </ul>
		 */
		getPin:function getPin(/*...*/)
		{
			switch(arguments.length){
			case 1://getPin:function getPin(i_pin_function)
				//pin_functionを持ってるPINを探す。
				var pin=getPinByFuncName(arguments[0]);
				//function名からペリフェラル名を得る。
				var phl_name=pinFuncName2PhlName(arguments[0]);
				//ピンコンストラクタとペリフェラルを使ってピンを生成。
				return this.getPeripheral(phl_name).getPin(pin);
			case 2://getPin:function getPin(i_pin,i_function_name)
				//function名からペリフェラル名を得る。(PINシンボル変換を流用)
				var phl_name=pinFuncName2PhlName(arguments[1]);
				return this.getPeripheral(phl_name).getPin(arguments[0]);
			default:
				throw new MiMicException();
			}
		},
		/**
		 * ポート（複数ピンで構成するIO）を制御するPortインスタンスを得るする。
		 * 制御ペリフェラル、Portを順に生成する方法と異なり、機能の実現に必要なインスタンスを自動的に生成する。
		 * Portが生成できない場合、例外が発生する。
		 * @name LPC1769.Mcu#getPort
		 * @function 
		 * @param {array[PIN識別子]} i_pins
		 * ポートを構成するピン識別子の配列。順序は生成するポートの説明を参照。
		 * @param {string} i_function_name
		 * 機能名の文字列である。 指定できる文字列は、LPC1769.FUNC_NAMEで定義する。
		 * @return {object as PortObject}
		 * 返却されるインスタンスのクラスは、機能により異なる。機能とインスタンスのクラスの対応は、以下の通りである。
		 * <ul>
		 * <li>GPIO - LPC1769.GpioPin</li>
		 * <li>AD - LPC1769.AdcPin</li>
		 * <li>PWM - LPC1769.PwmPin</li>
		 * </ul>		 
		 */
		getPort:function getPort(i_pins,i_function_name)
		{
			switch(arguments.length){
			case 2://getPin:function getPin(i_pins,i_function_name)
				//function名からペリフェラル名を得る。(PINシンボル変換を流用)
				var phl_name=pinFuncName2PhlName(i_function_name);
				return this.getPeripheral(phl_name).getPort(i_pins);
			default:
				throw new MiMicException();
			}
		},
		/**
		 * ペリフェラル名から、ペリフェラルオブジェクトを得る。
		 * 関数は、初めて要求されたペリフェラルについては、オブジェクトを生成し、MCUインスタンスに保存する。同じ名前のペリフェラルが再度要求されると、過去に生成したペリフェラルを返す。
		 * @name LPC1769.Mcu#getPeripheral
		 * @function
		 * @param {string as ペリフェラル名} i_phl_name
		 * ペリフェラル名は文字列である。指定できる文字列は、LPC1769.PHL_NAMEで定義する。
		 * @param {object as ペリフェラルオプション} i_opt
		 * ペリフェラルに渡すオプション値である。省略可能。ペリフェラルが新しく生成される場合（はじめてペリフェラルが設定されようとしているとき）に、コンストラクタのi_optに設定する。2回目以降の参照で設定されると、例外を発生する。値の構文は、取得しようとするペリフェラルのsetOpt関数のi_optパラメータの説明を参照すること。		 
		 * @return {object as Peripheral}
		 * 返却されるインスタンスのクラスは、ペリフェラル名により異なる。その対応は以下の通りである。
		 * <ul>
		 * 	<li>GPIO - LPC1769.Gpio</li>
		 * 	<li>ADC - LPC1769.Adc</li>
		 * 	<li>PWM - LPC1769.Pwm</li>
		 * </ul>
		 * @example
		 * //get GPIO peripheral
		 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
		 * var gpio=mcu.getPeripheral(“GPIO”);		 
		 */
		getPeripheral:function getPeripheral(i_phl_symbol,i_opt)
		{
			//ペリフェラルアイテムが生成済か確認
			if(isUndef(this._phl_holder[i_phl_symbol])){
				//存在しなければPhlを生成。
				switch(i_phl_symbol){
				case "GPIO":new DEV.Gpio(this,i_opt);break;
				case "ADC":new DEV.Adc(this,i_opt);break;
				case "PWM":new DEV.Pwm(this,i_opt);break;
				default:
					throw new MiMicException("Unknown peripheral symbol "+i_phl_symbol);
				}
			}else{
				//2回目以降でi_optが設定されている？それはだめだよ。
				if(!isUndef(i_opt)){
					throw new MiMicException();
				}
			}
			//phlからregisterのコールバックがかかるはず。
			return this._phl_holder[i_phl_symbol];
		},
		/**
		 * [forSystem]システム関数。MCU依存のペリフェラルオブジェクトを登録する。
		 @private
		 */
		registerPhl:function registerPhl(i_phl,i_symbol)
		{
			try{
				//登録済みのシンボルは登録できない。
				if(!isUndef(this._phl_holder[i_symbol])){
					throw new MiMicException("Peripheral symbol "+i_symbol+" is already exist on mcu.");
				}
				this._phl_holder[i_symbol]=i_phl;
			}catch(e){
				throw new MiMicException(e);
			}
		}
	}
}());/**
 * @fileOverview LPC1769のメモリアクセスクラスを定義する。
 */

(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;

function checkAlign(v){
	if(v%4!=0){
		throw new MiMicException(EE.INVALID_ARG,"An alignment is not 32bit unit.");
	}
}

/**
 * LPC1769.Memory (Memory)クラスのコンストラクタ。
 * Memoryクラスは、MCUのメモリ空間へアクセスする手段を提供する。
 * このクラスは、メモリアクセス対してなんら保護機能を持たない。MCUのメモリマップに十分に注意する必要がある。
 * @name LPC1769.Memory
 * @constructor
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {int} i_base
 * メモリにアクセスするときのベースアドレス。省略可能である。省略時は0x0とみなす。4バイト境界でなければならない。クラスの提供する関数でアドレスを指定した時には、全てこの値が加算される。
 * @example
 * //create a controlable MCU via network.
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var memory=new LPC1769.Memory(mcu); 
 */
DEV.Memory=function Memory(i_mcu,i_base)
{
	if(!isUndef(i_base)){
		this._base=i_base;
	}
	this._mcu=i_mcu;
}
DEV.Memory.prototype=
{
	_base:0x00000000,
	_mcu:null,
	/**
	 * 指定したアドレスの32ビット値を取得する。
	 * @name LPC1769.Memory#read32^2
	 * @function
	 * @param {int} i_offset
	 * コンストラクタで指定したアドレスからのオフセット位置を指定する。4バイト境界でなければならない。
	 * @return {int}
	 * 1個のint値。
	 * @example
	 * var　mcu=new LPC1769.Mcu("192.168.0.39");
	 * var mem=new LPC1769.Memory(mcu);　//create instance
	 * alert(mem.read32(0x00000000)); //show 1 value 
	 */
	/**
	 * 指定したオフセットから、i_sizeバイトのメモリに格納した値を、それぞれ32ビット単位で値を取得する。i_offsetの位置から、32bit単位でi_size/4個の値を取得することになる。シーケンシャルアクセスに使用する。
	 * @name LPC1769.Memory#read32^3
	 * @function
	 * @param {int} i_offset
	 * コンストラクタで指定したアドレスからのオフセット位置を指定する。4バイト境界でなければならない。
	 * @param {int} i_size
	 * 取得するバイト数を指定する。4バイト単位でなければならない。	 
	 * @return {int or Array[int]}
	 * 取得する値の個数は、i_size/4個である。個数により、戻り値の型が異なるので注意すること。
	 * @example
	 * var　mcu=new LPC1769.Mcu("192.168.0.39");
	 * var mem=new LPC1769.Memory(mcu);　//create instance
	 * mem.read32(0x0,8); //return 2 values.
	 */
	/**
	 * オフセットの配列要素に対応した値を、それぞれ32ビット単位で取得する。
	 * ランダムアクセスに使用する。
	 * @name LPC1769.Memory#read32^4
	 * @function
	 * @param {array[int]} i_offsets
	 * オフセットアドレスの配列。それぞれ4バイト境界でなければならない。
	 * @return {int or Array[int]}
	 * 返却される値の個数は、i_offsetの長さと同じになる。個数により、戻り値の型が異なるので注意すること。
	 * @example
	 * var　mcu=new LPC1769.Mcu("192.168.0.39");
	 * var mem=new LPC1769.Memory(mcu);　//create instance
	 * mem.read32([0x0,0x14,0x08]); //return 3 values by specified order.
	 */
	/**
	 * メモリから値を読み出して、値セットの配列、又は値を返す。
	 * 関数は4バイト単位のアライメントでメモリにアクセスする。メモリアドレス、取得サイズは4バイト境界に一致させなければならない。
	 * 引数の違いにより、数種類の呼び出し方がある。
	 * @name LPC1769.Memory#read32^1
	 * @function
	 * @param ...
	 * 詳細は、read32^nを参照。
	 * @return {int or Array[int]}
	 * 返却値の数により、型が異なる。1個の場合はint値、複数の場合はint型の配列である。
	 */
	read32:function read32(/*arguments*/)
	{
		try{
			var bc="";
			var ar=new Array();
			var offset=arguments[0];
			switch(arguments.length){
			case 1:
				if(!isNaN(offset)){
					//read32(i_offset:int)
					checkAlign(offset);
					bc=BCF.READMEM;
					ar.push(this._base+offset);
				}else{
					//read32(i_offsets:array)
					for(var i=0;i<offset.length;i++){
						checkAlign(offset[i]);
						bc+=BCF.getMem(this._base+offset[i],ar);
					}
				}
				break;
			case 2:
				//read32(i_offset:int,i_size:int)
				checkAlign(offset);
				checkAlign(arguments[1]);
				var l=arguments[1]/4;
				for(var i=0;i<l;i++){
					bc+=BCF.READMEM;
					ar.push(this._base+offset+i*4);
				}
				break;
			default:
				break;
			}
			var ret=this._mcu.callMiMicWithCheck(bc+BCF.END,ar).stream;
			return ret.length==1?ret[0]:ret;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * 指定したアドレスに32ビット値を書き込む。
	 * @name LPC1769.Memory#write32^2
	 * @function
	 * @param {int} i_offset
	 * コンストラクタで指定したアドレスからのオフセット位置を指定する。4バイト境界でなければならない。
	 * @param {int} i_value
	 * 1個のint値。
	 * @example
	 * var　mcu=new LPC1769.Mcu("192.168.0.39");
	 * var mem=new LPC1769.Memory(mcu);　//create instance
	 * mem.write32(0x20080000,139);
	 */
	/**
	 * 指定したオフセットから、n個の32bit値を書き込む。シーケンシャルアクセスに使用する。
	 * @name LPC1769.Memory#write32^3
	 * @function
	 * @param {int} i_offset
	 * コンストラクタで指定したアドレスからのオフセット位置を指定する。4バイト境界でなければならない。
	 * @param {array[int]} i_values
	 * 書きこむバイト数を指定する。4バイト単位でなければならない。	 
	 * @example
	 * var　mcu=new LPC1769.Mcu("192.168.0.39");
	 * var mem=new LPC1769.Memory(mcu);　//create instance
	 * mem.write32(0x20080008,[439,539,639]);
	 */
	/**
	 * オフセットの配列要素に対応した値を、それぞれ32ビット単位で書きこむ。
	 * ランダムアクセスに使用する。
	 * @name LPC1769.Memory#write32^4
	 * @function
	 * @param {array[int]} i_offsets
	 * オフセットアドレスの配列。それぞれ4バイト境界でなければならない。
	 * @param {array[int]} i_values
	 * セットする値。個数は、i_offsetsと一致していなければならない。
	 * @example
	 * var　mcu=new LPC1769.Mcu("192.168.0.39");
	 * var mem=new LPC1769.Memory(mcu);　//create instance
	 * mem.write32([0x20080020,0x20080024],[239,339]);
	 */
	/**
	 * メモリアドレスを指定して、値を書き込む。
	 * 関数は4バイト単位のアライメントでメモリにアクセスする。メモリアドレス、取得サイズは4バイト境界に一致させなければならない。
	 * 引数の違いにより、数種類の呼び出し方がある。
	 * @name LPC1769.Memory#write32^1
	 * @function
	 * @param ...
	 * 詳細は、write32^nを参照。
	 */
	write32:function write32(/*arguments*/)
	{
		try{
			var bc="";
			var ar=new Array();
			var offset=arguments[0];
			switch(arguments.length){
			case 2:
				if((!isNaN(offset))){
					if(!isNaN(arguments[1])){
						//write32(i_offset:int,i_value:int)
						checkAlign(offset);
						bc+=BCF.setMem(this._base+offset,arguments[1],ar);
					}else if(arguments[1].length>0){
						//read32(i_offset:int,i_value:array)
						checkAlign(offset);
						var l=arguments[1].length;
						for(var i=0;i<l;i++){
							bc+=BCF.setMem(this._base+offset+i*4,arguments[1][i],ar);
						}
					}else{
						throw new MiMicException();
					}
				}else if(offset.length==arguments[1].length){
					//write32(i_offsets:array,i_value:array)
					for(var i=0;i<offset.length;i++){
						checkAlign(offset[i]);
						bc+=BCF.setMem(this._base+offset[i],arguments[1][i],ar);
						
					}
				}else{
					throw new MiMicException();
				}
				break;
			default:
				break;
			}
			this._mcu.callMiMicWithCheck(bc+BCF.END,ar).stream;
			return;
		}catch(e){
			throw new MiMicException(e);
		}
	}	
}

}());/**
 * @fileOverview LPC1769の物理ペリフェラルを制御するクラスを定義する。
 */
(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;
/**
 * LPC1769.Peripheral (Peripheral)クラスのコンストラクタ。
 * ペリフェラル識別子を元に、MCUに関連付けしたPeripheral インスタンスを生成する。
 * Peripheralクラスは、物理Peripheral（主に電源/クロックブロック単位）単位に操作インタフェイスを定義する。
 * PCLKSEL,PCONPレジスタを管理する。
 * このクラスは、抽象ペリフェラルクラスへ物理ペリフェラルの基本的な操作機能を提供する為のものであり、ユーザが直接使用することは（あまり）ない。
 * 関数はMiMicの管理しているペリフェラル（ENET）も操作することが出来るが、操作してしまうとMiMicRemoteMcuとのコネクションが破壊されるので、注意すること。
 * @name LPC1769.Peripheral
 * @constructor
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {object as ペリフェラル識別子} i_phl
 * 生成するペリフェラルのペリフェラル識別子。この値は、LPC1769.PHLの要素である。
 * @param {object as associative array} i_opt
 * インスタンス生成と同時にsetOpt関数で設定する値。省略時は無視する。
 * 詳細はsetOpt関数を参照。
 * @example
 * //create GPIO peripheral
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var phl=new LPC1769.Pheripheral(mcu,LPC1769.PHL.GPIO); 
 */
DEV.Peripheral=function(i_mcu,i_phl,i_opt)
{
	try{
		if(isUndef(i_phl)){
			throw new MiMicException(EE.INVALID_PHL);
		}
		this._mcu=i_mcu;
		this._phl=i_phl;
		//オプション設定するならする。
		if(!isUndef(i_opt)){
			this.setOpt(i_opt);
		}
	}catch(e){
		throw new MiMicException(e);
	}	
}
DEV.Peripheral.prototype=
{
	_PCLKSEL:[0x400FC1A8,0x400FC1AC],
	_PCONP:0x400FC0C4,
	_phl:null,
	_mcu:null,
	_cache:{
		pclk:0
	},
	/**
	 * BCフラグメントを生成して、_cacheを更新します。
	 * @private
	 */
	BCF_setOpt:function BCF_setOpt(i_opt,i_db)
	{
		try{
			var bc="";
			//pconp
			if(!isUndef(i_opt.power)){
				if(this._phl[2]==null){
					throw new MiMicException(EE.INVALID_CFG,"The pin does not support PCONP.");
				}
				//pinselAddrを得る
				bc+=BCF.setBit(this._PCONP,0x00000001,i_opt.power,this._phl[2],i_db);
			}
			//clock
			if(!isUndef(i_opt.clock)){
				if(this._phl[0]==null){
					throw new MiMicException(EE.INVALID_CFG,"The pin does not support PCLKSEL.");
				}
				//キャッシュ更新
				this._cache.pclk=i_opt.clock;
				bc+=BCF.setBit(this._PCLKSEL[this._phl[0]],0x00000003,i_opt.clock,this._phl[1],i_db);
			}
			return bc;
		}catch(e){
			throw new MiMicException(e);
		}		
	},
	/**
	 * ペリフェラルにオプションパラメータをセットする。
	 * 関数は、物理ペリフェラルのレジスタに、i_optで与えられる値を設定する。
	 * 関数は、レジスタの位置に合わせてパラメータ値を自動的にシフトする。	 
	 * @name LPC1769.Peripheral#setOpt
	 * @function
	 * @param {object} i_opt
	 * ペリフェラルピンコンフィグレーションのパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{power:int,clock:int}</pre>
	 * <ul>
	 * <li>power:int -
	 * 1bitのint値。 PCONP? レジスタに指定する値。Chapter 4: LPC17xx Clocking and power controlを参照。
	 * </li>
	 * <li>clock:int - 
	 * 2bitのint値。PCLKSEL? レジスタに指定する値。Chapter 4: LPC17xx Clocking and power controlを参照。
	 * </li>
	 * @example 
	 * //set DAC power on
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 * var phl=new LPC1769.Peripheral(mcu,LPCXpresso.PHL.ADC);
	 * phl.setOpt({power:1});	 
	 */
	setOpt:function setOpt(i_opt)
	{
		try{
			var db=new Array();
			var bc=this.BCF_setOpt(i_opt,db);
			if(bc.length==0){
				throw new MiMicException("i_opt is empty or invalid.");
			}
			//MiMicBCを生成して実行
			this._mcu.callMiMicWithCheck(bc+BCF.END,db);

		}catch(e){
			throw new MiMicException(e);
		}
		return;		
	},
	/**
	 * ペリフェラルのクロックを[Hz]単位で返す。
	 * クロックは、Table 42. Peripheral Clock Selection register bit valuesと、MCUのクロック(LPC1769.Mcuの提供する値)から計算する。
	 * 動作中のPLL0の変更には対応していない。注意すること。
	 * @name LPC1769.Peripheral#getPCLK
	 * @function
	 * @return {int}
	 * Hz単位のペリフェラルクロック
	 * @example
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 * var phl=new LPC1769.Peripheral(mcu,LPCXpresso.PHL.PWM);
	 * alert(phl.getPCLK());
	 */
	getPCLK:function getPCLK()
	{
		try{
			//倍率変換テーブル
			var m=[4,1,2,0];
			var t=m[this._cache.pclk];
			var r;
			if(t==0){
				if(this._phl===DEV.PHL.CAN1 || this._phl===DEV.PHL.CAN2){
					r=this._mcu.getClockInfo().cclk/6;
				}else{
					r=this._mcu.getClockInfo().cclk/8;
				}
			}else{
				r=this._mcu.getClockInfo().cclk/t;
			}
			return Math.round(r);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}

}());/**
 * @fileOverview LPC1769のポート(ピンセット)を制御するクラスを定義する。
 */

(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;

/**
 * @private
 * レジスタの内容
 */
var REG={
	_PINSEL:[0x4002C000,0x4002C004,0x4002C008,0x4002C00C,0x4002C010,null,null,0x4002C0C0,null,0x4002C024,0x4002C028],
	_PINMODE:[0x4002C040,0x4002C044,0x4002C048,0x4002C04C,0x4002C050,0x4002C054,0x4002C058,0x4002C05C,null,0x4002C064],
	_PINMODE_OD:[0x4002C068,0x4002C06C,0x4002C070,0x4002C074,0x4002C078],
};
/**
 * LPCXPresso1769.Port (Port)クラスのコンストラクタ。
 * ピン識別子を元に、MCUに関連付けたPortインスタンスを生成する。
 * Portクラスは、複数の物理ピンをまとめて、操作インタフェイスを定義する。
 * PINSEL,PINMODE,PINMODE_ODレジスタを管理する。
 * @name LPC1769.Port
 * @constructor
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {array[object as ピン識別子]} i_pin
 * ポートを構成するピンの配列。
 * @param {array[object as associative array]} i_opt
 * インスタンス生成と同時にsetOpt関数で設定する値。省略時は無視する。
 * 詳細はsetOpt関数を参照。
 * このクラスは、上位クラスへピンの基本的な操作機能を提供する為のものであり、ユーザが直接使用することは（あまり）ない。
 * この関数は、MiMicの管理しているピン（ENET_?）も操作することが出来るが、操作してしまうとMiMicRemoteMcuとのコネクションが破壊されるので、注意すること。
 * @example
 * //create pin instance at P0[0]
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var port=new LPC1769.Port(mcu,[LPCXpresso.P0[0]]);
 */
DEV.Port=function Port(i_mcu,i_pins,i_opts)
{
	try{
		this._mcu=i_mcu;
		this._pininfo=new Array();
		//ピン情報に変換
		for(var i=0;i<i_pins.length;i++){
			this._pininfo.push(DEV.getPinRegInfo(i_pins[i]));
		}
		if(!isUndef(i_opts)){
			this.setOpts(i_opts);
		}
	}catch(e){
		throw new MiMicException(e);
	}		
}

DEV.Port.prototype=
{
	_mcu:null,
	/**
	 * 複数のピン設定をレジスタごとにまとめたBCを生成する。
	 @private
	 */
	BCF_setOpts:function BCF_setOpts(i_opts,i_db)
	{
		try{
			//10/5レジスタ分のワーク領域を作る。
			var d={
				selr:[0,0,0,0,0,0,0,0,0,0],
				selr_mask:[0,0,0,0,0,0,0,0,0,0],
				modr:[0,0,0,0,0,0,0,0,0,0],
				modr_mask:[0,0,0,0,0,0,0,0,0,0],
				odr:[0,0,0,0,0],
				odr_mask:[0,0,0,0,0]};
	
			//pinsとoptsの数は同じだよね？
			if(this._pininfo.length!=i_opts.length){
				throw new MiMicException();
			}
			
			//レジスタ値、マスクの生成
			for(var i=0;i<i_opts.length;i++)
			{
				var pi=this._pininfo[i];
				var opt=i_opts[i];
				if(!isUndef(opt.sel))
				{
					d.selr[pi.s]|=(opt.sel<<pi.smb);
					d.selr_mask[pi.s]|=(0x3<<pi.smb);
				}
				if(!isUndef(opt.mode))
				{
					d.modr[pi.m]|=(opt.mode<<pi.smb);
					d.modr_mask[pi.m]|=(0x3<<pi.smb);
				}
				if(!isUndef(opt.od))
				{
					d.odr[pi.o]|=(opt.od<<pi.ob);
					d.odr_mask[pi.o]|=(0x1<<pi.ob);
				}
			}
			//BCFを生成
			var bc="";
			for(var i=0;i<10;i++){
				if(d.selr_mask[i]!=0x0){
					bc+=BCF.setBit(REG._PINSEL[i],d.selr_mask[i],d.selr[i],0,i_db);
				}
				if(d.modr_mask[i]!=0x0){
					bc+=BCF.setBit(REG._PINMODE[i],d.modr_mask[i],d.modr[i],0,i_db);
				}
			}
			for(var i=0;i<5;i++){
				if(d.odr_mask[i]!=0x0){
					bc+=BCF.setBit(REG._PINMODE_OD[i],d.odr_mask[i],d.odr[i],0,i_db);
				}
			}
			return bc;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ポートにオプションパラメータをセットする。
	 * 関数は、ポートを構成するピンに、ピンオプション配列の値を個別に設定する。
	 * @name LPC1769.Port#setOpts
	 * @function
	 * @param {array[object as associative array]} i_opts
	 * ピンコンフィグレーションのパラメタの配列である。個々の要素は、ピンオプションである。ピンオプションの構造は、Pin#setOptを参照。
	 * 配列の要素数は、ポートを構成するピンの数と同じでなければならない。
	 * @example
	 * //set GPIO,mode=1,open drain=0
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 * var port=new LPC1769.Port(mcu,[LPCXpresso.P2[3],LPCXpresso.P2[4]]);
	 * port.setOpts([{sel:0,mode:1,od:0},{sel:0,mode:1,od:0}]);	
	 */	
	setOpts:function setOpts(i_opts)
	{
		try{
			var db=new Array();
			var bc=this.BCF_setOpts(i_opts,db);
			if(bc.length==0){
				throw new MiMicException("i_opt is empty or invalid.");
			}
			//MiMicBCを生成して実行
			this._mcu.callMiMicWithCheck(bc+BCF.END,db);
		}catch(e){
			throw new MiMicException(e);
		}
		return;
	}	
}

}());/**
 * @fileOverview LPC1769の物理ピンを制御するクラスを定義する。
 */

(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;

/**
 * LPCXPresso1769.Pin (Pin)クラスのコンストラクタ。
 * ピン識別子を元に、MCUに関連付けたPinインスタンスを生成する。
 * Pinクラスは、MCUの物理ピン単位に、操作インタフェイスを定義する。
 * クラスは、1ピンのポートとして実装する。
 * @name LPC1769.Pin
 * @constructor
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {object as ピン識別子} i_pin
 * 生成するピンのピン識別子。
 * @param {object as associative array} i_opt
 * インスタンス生成と同時にsetOpt関数で設定する値。省略時は無視する。
 * 詳細はsetOpt関数を参照。
 * このクラスは、上位クラスへピンの基本的な操作機能を提供する為のものであり、ユーザが直接使用することは（あまり）ない。
 * この関数は、MiMicの管理しているピン（ENET_?）も操作することが出来るが、操作してしまうとMiMicRemoteMcuとのコネクションが破壊されるので、注意すること。
 * @example
 * //create pin instance at P0[0]
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var pin=new LPC1769.Pin(mcu,LPCXpresso.P0[0]);
 */
DEV.Pin=function Pin(i_mcu,i_pin,i_opt)
{
	try{
		if(isUndef(i_pin)){
			throw new MiMicException(EE.INVALID_PIN);
		}
		//1ピンのポートとして実装する。
		this._port=new DEV.Port(i_mcu,[i_pin],isUndef(i_opt)?undefined:[i_opt]);
	}catch(e){
		throw new MiMicException(e);
	}
}
DEV.Pin.prototype=
{	
	_port:null,
	/**
	 * ピンにオプションパラメータをセットする。
	 * 関数は、物理ピンのレジスタに、i_optで与えられる値を設定する。
	 * 関数は、レジスタの位置に合わせてパラメータ値を自動的にシフトする。
	 * @name LPC1769.Pin#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * ピンコンフィグレーションのパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{sel,mode,od}</pre>
	 * <ul>
	 * <li>sel:int - 2bitのint値。 PINSEL? レジスタに指定する値。UM10360 Chapter8.LPC17xx Pin connect block を参照。</li>
	 * <li>mode:int - 1bitのint値。PINMODE? レジスタに指定する値。UM10360 Chapter8.LPC17xx Pin connect block を参照。</li>
	 * <li>od:int - 1bitのbit値　PINMODE_OD? レジスタに指定する値。UM10360 Chapter8.LPC17xx Pin connect block を参照。</li>
	 * </ul>
	 * @example
	 * //set GPIO,mode=1,open drain=0
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 * var pin=new LPC1769.Pin(mcu,LPCXpresso.P2[3]);
	 * pin.setOpt({sel:0,mode:1,od:0});	 
	 */
	setOpt:function setOpt(i_opt)
	{
		try{
			//portのsetOptで合成
			this._port.setOpts([i_opt]);
		}catch(e){
			throw new MiMicException(e);
		}
		return;
	}
}

}());/**
 * @fileOverview LPC1769の、ADコンバータペリフェラル、ピンの制御クラスを定義する。
 */
(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;
var cloneAssoc=MiMicLib.cloneAssoc;


/**
 * LPCXPresso1769.Adc (Adc)クラスのコンストラクタ。
 * MCUに関連付けしたADペリフェラルを生成する。
 * ADペリフェラルは、MCUのADCペリフェラル全体を管理する。
 * 関数は、ADCRレジスタのPDN,BURSTを1にセットする。
 * ADCペリフェラルはバーストモードで動作し、サンプリングレートは200KHz固定である。取得タイミングの制御はハードウェア依存である。
 * @constructor
 * @name LPC1769.Adc
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {object as associative array} i_opt
 * インスタンス生成と同時にsetOpt関数で設定する値。省略時は、{phl:{power:1}}とみなす。
 * 詳細はsetOpt関数を参照。 
 * @example
 * //create AD (logical)pheripheral
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var ad=new LPC1769.Adc(mcu); 
 */
DEV.Adc=function Adc(i_mcu,i_opt)
{
	try{
		this._mcu=i_mcu;
		//PHL生成。
		this._phl=new DEV.Peripheral(i_mcu,DEV.PHL.ADC);
		//設定値のロード
		var opt=isUndef(i_opt)?{phl:{}}:
		{//i_optある。
			phl:isUndef(i_opt.phl)?{}:cloneAssoc(i_opt.phl),
		};
		//デフォルト値設定
		if(isUndef(opt.phl.power)){opt.phl.power=1;};

		//初期化。
		var bc="";
		var db=new Array();
		bc+=this.BCF_setOpt(opt,db);
		//0x00210000(PDN,BURSTを1)
		bc+=BCF.setMem(this._AD0CR,0x00200400,db);
		bc+=BCF.setMem(this._AD0CR,0x00210400,db);
		//
		this._mcu.callMiMicWithCheck(bc+BCF.END,db);
		//ペリフェラルをMCUに登録
		this._mcu.registerPhl(this,"ADC");
	}catch(e){
		throw new MiMicException(e);
	}

}
DEV.Adc.prototype=
{
	_AD0CR:0x40034000,
	_AD0DR:[0x40034010,0x40034014,0x40034018,0x4003401C,0x40034020,0x40034024,0x40034028,0x4003402C],
	_phl:null,
	_mcu:null,

	BCF_setOpt:function BCF_setOpt(i_opt,i_db)
	{
		try{
			var bc="";
			if(!isUndef(i_opt.phl)){
				bc+=this._phl.BCF_setOpt(i_opt.phl,i_db);
			}
			return bc;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * AD0CRのSELフィールドの値を更新するBC
	 @param i_val
	 0 or 1
	 @private
	 */
	BCF_setSels:function BCF_setSels(i_mask,i_val,i_db)
	{
		try{
			return BCF.setBit(this._AD0CR,i_mask,i_val*i_mask,0,i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * n番のAD0DRの値を得るBC
	 @private
	 */
	BCF_getAD0DR:function BCF_getAD0DR(i_ch,i_db)
	{
		try{
			return BCF.getMem(this._AD0DR[i_ch],i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ADCペリフェラルに、i_optのオプション値を設定する。
	 * @name LPC1769.Adc#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * ADCペリフェラルのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{phl:object as associative array}</pre>
	 * <ul>
	 * <li>phl - LPC1769.Peripheral#setOpt関数のi_optに渡すパラメタである。</li>
	 * </ul>
	 * @example
	 * //AD power on/off
	 * //create AD (logical)pheripheral
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 * var ad=new LPC1769.Adc(mcu);
	 * ad.setOpt(phl:{power:0});
	 */
	setOpt:function setOpt(i_opt)
	{
		try{
			var db=new Array();
			var bc=this.BCF_setOpt(i_opt,db);
			this._mcu.callMiMicWithCheck(bc+BCF.END,db);
		}catch(e){
			throw new MiMicException(e);
		}
	},	
	/**
	 * AD機能を持つピンを取得する。
	 * ピン識別子で指定されるピンをADペリフェラルと結合して、AdcPinを生成する。
	 * 関数は、AdcPinオブジェクトのコンストラクタをコールして、AdcPinを生成する。失敗すると、例外をスローする。
	 * 生成ルールについての詳細は、AdcPinを参照。
	 * @name LPC1769.Adc#getPin
	 * @function
	 * @param {object as ピン識別子} i_pin
	 * AD機能を割り当てるPINの識別子である。値は、LPC1769.Pn[m]のメンバ変数である。
	 * @param {object as associative array} i_opt
	 * AdcPinのコンストラクタに渡すオプション値。省略時はundefinedである。詳細はLPCXpresso1769.AdcPin.setOptを参照。
	 * @return {object as LPC1769.AdcPin}
	 * LPC1769.AdcPinクラスのオブジェクトである。
	 * @example
	 * //create AdcPin
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var adc=new LPC1769.Adc(mcu);
	 * var adpin=adc.getPin(LPC1769.P0[23]);
	 */
	getPin:function getPin(i_pin,i_opt)
	{
		try{
			return new DEV.AdcPin(this,i_pin,i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * AD機能を持つポート(Pin集合)を取得する。
	 * ピン識別子で指定されるピンのセットをADペリフェラルと結合して、AdcPortを生成する。
	 * 関数は、AdcPortのコンストラクタをコールする。
	 * 生成ルールについては、AdcPort関数を参照すること。
	 * @name LPC1769.Adc#getPort
	 * @function
	 * @param {array[ピン識別子]} i_pin
	 * AD機能を割り当てるPINの識別子の配列である。値は、LPC1769.Pn[m]のメンバ変数である。
	 * @param {object as associative array} i_opt
	 * AdcPortのコンストラクタに渡すオプション値。省略時はundefinedである。詳細はLPCXpresso1769.AdcPort.setOptを参照。
	 * @return {object as LPC1769.AdcPort}
	 * LPC1769.AdcPortクラスのオブジェクトである。
	 * @example
	 * //create 2AdcPort that has 2 pins.
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var adc=new LPC1769.Adc(mcu);
	 * var port=adc.getPort([LPC1769.P0[23],LPC1769.P0[24]]);
	 */
	getPort:function getPort(i_pins,i_opt)
	{
		try{
			return new DEV.AdcPort(this,i_pins,i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}


/**
 * AD pinからADInfoを取得
 * @private
 */
function pin2AdcPinInfo(i_pin)
{
	try{
		//pinの完全な機能名を得る。(得られれば機能がある。)
		var func_name=DEV.completePinFunctionName(i_pin,"AD");
		//portとbitを得る(AD0だけしか管理しないよ)
		var a=func_name.substring(2).split(".");
		var r={port:0,ch:parseInt(a[1]),pin_sel:DEV.getPinSelByFunctionName(i_pin,func_name)};
		if(!isNaN(r.ch)){
			return r;
		}
		throw new MiMicException(EE.INVALID_CFG,"The pin has not AD fuction.");
	}catch(e){
		throw new MiMicException(e);	
	}
}
/**
 * LPC1769.AdcPort (AdcPort)クラスのコンストラクタ。複数のADピンから一括で値を取得するときに使用する。
 * Adcペリフェラルオブジェクトにピン識別子の配列で指定されたピン集合を関連付けて、AD機能を持つポートを生成する。
 * 関数は、ピン識別子を元に、そのピンがAD機能に接続できるかを調べる。全てのピンにAD機能を割り当てられない場合、例外が発生する。どのピンにAD機能が割り当てられるかは、MCUのスペックシートを参照すること。
 * @constructor
 * @name LPC1769.AdcPort
 * @param {object as LPC1769.Adc} i_adc
 * インスタンスを結びつけるAdcオブジェクト。
 * @param {array[pin識別子]} i_pins
 * ピン識別子の配列。指定できるのは、LPC1769.P?[?]である。順番は、このインスタンスの返す値の順序に影響する。
 * @param {object as associative array} i_opt
 * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{pin:{sel:auto}}を設定する。
 * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
 * @example
 * //create [AD0.0,AD0.1]
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var adc=new LPC1769.Adc(mcu);
 * var port=new LPC1769.AdcPort(adc,[LPC1769.P0[23],LPC1769.P0[24]]); 
 */
DEV.AdcPort=function AdcPort(i_adc,i_pins,i_opt)
{
	try{
		this._adc=i_adc;
		//ピンセットを取得
		this._pins=new Array();
		//pinに変換する。
		for(var i=0;i<i_pins.length;i++){
			this._pins.push(pin2AdcPinInfo(i_pins[i]));
		}
		//pinが全て同じポートに所属しているか確認
		var p=this._pins[0].port;
		for(var i=1;i<this._pins.length;i++){
			if(p!=this._pins[i].port){
				throw new MiMicException("Invalid pin combination.");
			}
		}
		//ポートの生成
		this._port=new DEV.Port(i_adc._mcu,i_pins);
		this._port_no=p;
		//AD0CR用のマスクを生成。
		this._adcr_mask=0;
		for(var i=0;i<this._pins.length;i++){
			this._adcr_mask|=(0x1<<this._pins[i].ch);
		}
		//ピンオプションの生成
		var opt=isUndef(i_opt)?{}:cloneAssoc(i_opt);
		opt.sel=1;//ADxCRの値
		opt.pin=isUndef(opt.pin)?{}:cloneAssoc(opt.pin);
		//設定が無ければ、ピンセレクタを自動に設定
		if(isUndef(opt.pin.sel)){opt.pin.sel=this._PINSEL_AUTO_DETECT;}
		//ピンオプションの設定
		this.setOpt(opt);
	}catch(e){
		throw new MiMicException(e);
	}	
}
DEV.AdcPort.prototype=
{
	_PINSEL_AUTO_DETECT:0x0fffffff,
	_adc:null,
	_pins:null,
	_port_no:0,
	_port:null,
	_adcr_mask:0,
	/**
	 * ADポートにオプション値を設定する。
	 *　関数は、ポートを構成する全てのピンに、同一なオプション値を設定する。
	 * 設定可能な値は、LPC1769.AdcPin#setOptと同じである。
	 * @name LPC1769.AdcPort#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * LPC1769.AdcPin#setOptを参照。
	 */	
	setOpt:function setOpt(i_opt)
	{
		try{
			var db=new Array();
			//BCの生成
			var bc="";
			//i_optの展開
			if(!isUndef(i_opt.pin)){
				var optset=new Array();
				for(var i=0;i<this._pins.length;i++){
					//pinselが_PINSEL_AUTO_DETECTならばauto。そうでなければundefinedも含めて設定
					var s=(i_opt.pin.sel==this._PINSEL_AUTO_DETECT)?this._pins[i].pin_sel:i_opt.pin.sel;
					optset.push({sel:s,mode:i_opt.pin.mode,od:i_opt.pin.od});
				}
				//portの設定
				bc+=this._port.BCF_setOpts(optset,db);
			}
			//隠し。ADxCR
			if(!isUndef(i_opt.sel)){
				bc+=this._adc.BCF_setSels(this._adcr_mask,i_opt.sel,db);
			}
			this._adc._mcu.callMiMicWithCheck(bc+BCF.END,db);
			return;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ポートからAD変換した値を得る。
	 * @name LPC1769.AdcPort#getValues
	 * @function
	 * @return {array[int]}
	 * 12bitのAD変換値の配列である。値の意味は、UM10360 Chapter 29: LPC17xx Analog-to-Digital Converter (ADC)を参照。
	 * 値の順番は、コンストラクタで指定したピン配列の順序と同じである。
	 * @example
	 * //show value of AD0.0,AD0.1 pin
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var pin=mcu.getPort("AD",[LPC1769.P0[23],LPC1769.P0[24]]);
	 * alert(pin.getValues());
	 */	
	getValues:function getValues()
	{
		try{
			//メモリから値取得
			var db=new Array();
			var bc="";
			for(var i=0;i<this._pins.length;i++){
				bc+=this._adc.BCF_getAD0DR(this._pins[i].ch,db);
			}
			var ret=this._adc._mcu.callMiMicWithCheck(bc+BCF.END,db);
			//値の整形
			var r=new Array();
			for(var i=0;i<this._pins.length;i++){
				r.push((ret.stream[i]>>4)&0x00000fff);
			}
			return r;
		}catch(e){
			throw new MiMicException(e);
		}
	}
}
/**
 * LPC1769.AdcPin (AdcPin)クラスのコンストラクタ。
 * Adcペリフェラルオブジェクトにピン識別子で指定されたピンを関連付けて、AD機能を持つピンを生成する。
 * 関数は、ピン識別子を元に、そのピンがAD機能に接続できるかを調べる。ピンにAD機能を割り当てられない場合、例外が発生する。どのピンにAD機能が割り当てられるかは、MCUのスペックシートを参照すること。
 * @constructor
 * @name LPC1769.AdcPin
 * @param {object as LPC1769.Adc} i_adc
 * インスタンスを結びつけるAdcオブジェクト。
 * @param {object as pin識別子} i_pin
 * ピン識別子。指定できるのは、LPCXpresso1796.P?[?]である。
 * @param {object as associative array} i_opt
 * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{pin:{sel:auto}}を設定する。
 * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
 * @example
 * //create AD0.0
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var adc=new LPC1769.Adc(mcu);
 * var adcpin=new  LPC1769.AdcPin(adc,LPC1769.P0[23]); 
 */
DEV.AdcPin=function AdcPin(i_adc,i_pin,i_opt)
{
	try{
		this._aport=new DEV.AdcPort(i_adc,[i_pin],i_opt);
	}catch(e){
		throw new MiMicException(e);
	}
}

DEV.AdcPin.prototype=
{
	_aport:null,
	/**
	 * ピンからAD変換した値を得る。
	 * @name LPC1769.AdcPin#getValue
	 * @function
	 * @return {int}
	 * 12bitのAD変換値を返す。値の意味は、UM10360 Chapter 29: LPC17xx Analog-to-Digital Converter (ADC)を参照。
	 * @example
	 * //show value of AD0.0 pin
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var pin=mcu.getPin("AD0.0");
	 * alert(pin.getValue());	 
	 */
	getValue:function getValue()
	{
		try{
			return this._aport.getValues()[0];
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ADピンにオプション値を設定する。
	 * @name LPC1769.AdcPin#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * ADピンのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{pin:object as associative array}</pre>
	 * <ul>
	 * <li>pin - LPC1769.Pin#setOpt関数のi_optに渡すパラメタである。</li>
	 * </ul>
	 */	
	setOpt:function setOpt(i_opt)
	{
		try{
			this._aport.setOpt(i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}
	


}());
/**
 * @fileOverview LPC1769の、GPIOペリフェラル、ピンの制御クラスを定義する。
 */

(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;
var cloneAssoc=MiMicLib.cloneAssoc;

/**
 * LPCXPresso1769.Gpio (Gpio)クラスのコンストラクタ。
 * MCUに関連付けしたGpioペリフェラルを生成する。
 * GPIOペリフェラルは、物理的には存在しない仮想ペリフェラルである。GPIOを集中管理するために定義している。
 * @name LPC1769.Gpio
 * @constructor
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {oject as associative array} i_opt
 * 常に無視する。省略すること。
 * @example
 * //create GPIO (logical)pheripheral
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var gpio=new LPC1769.Gpio(mcu);
 */
DEV.Gpio=function Gpio(i_mcu,i_opt)
{
	try{
		this._mcu=i_mcu;
		i_mcu.registerPhl(this,"GPIO");
	}catch(e){
		throw new MiMicException(e);
	}
}
DEV.Gpio.prototype=
{
	_FIO_DIR :[0x2009C000,0x2009C020,0x2009C040,0x2009C060,0x2009C080],
	_FIO_PIN :[0x2009C014,0x2009C034,0x2009C054,0x2009C074,0x2009C094],
	_FIO_SET :[0x2009C018,0x2009C038,0x2009C058,0x2009C078,0x2009C098],
	_FIO_CLR :[0x2009C01C,0x2009C03C,0x2009C05C,0x2009C07C,0x2009C09C],
	_FIO_MASK:[0x2009C010,0x2009C030,0x2009C050,0x2009C070,0x2009C090],
	_mcu:null,
	BCF_getValues:function BCF_getValues(i_ch,i_mask,i_db)
	{
		/*GPIOレジスタからとってくるBC
		SGET #0;//GPIOの値レジスタアドレス
		SGET #1;//GPIOのMASKレジスタアドレス
		SGET #2;//MASKレジスタの値
		MSET #2,#1;//MASK設定
		MGET #3,#0;//値取得
		SPUT #3;//SPUT
		 */
		try{
			i_db.push(this._FIO_PIN[i_ch],this._FIO_MASK[i_ch],~i_mask);
			return "EA00EA01EA02DF0201DB0300EE03";
		}catch(e){
			throw new MiMicException(e);
		}		
	},
	/**
	 FIOPINとFIOMASKに値をセットする。
	 SGET #0;//GPIOの値レジスタアドレス
	 SGET #1;//GPIOのMASKレジスタアドレス
	 SGET #2;//MASKレジスタの値
	 SGET #3;//GPIO値
	 MPUT #2,#1;//MASK設定
	 MPUT #3,#0;//値設定
	* @private
	*/
	BCF_setValues:function BCF_setValues(i_ch,i_mask,i_value,i_db)
	{
		try{
			i_db.push(this._FIO_PIN[i_ch],this._FIO_MASK[i_ch],~i_mask,i_value);
			return "EA00EA01EA02EA03DF0201DF0300";
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * 
	 @param i_dir 1 or 0
	 @private
	 */
	BCF_setDirs:function BCF_setDirs(i_ch,i_mask,i_dir,i_db)
	{
		try{
			return BCF.setBit(this._FIO_DIR[i_ch],i_mask,i_mask*i_dir,0,i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},	
	/**
	 * GPIO機能を持つピンを取得する。
	 * ピン識別子で指定されるピンをGPIOペリフェラルと結合して、GpioPinを生成する。
	 * 関数は、LPC1769.GpioPinクラスのコンストラクタをコールして、GpioPinを生成する。失敗すると、例外をスローする。
	 * 生成ルールについての詳細は、LPC1769.GpioPinを参照。
	 * @name LPC1769.Gpio#getPin
	 * @function
	 * @param {object as ピン識別子} i_pin
	 * GPIO機能を割り当てるPINの識別子である。
	 * @param {object as associative array} i_opt
	 * GpioPinのコンストラクタに渡すオプション値を指定する。省略可能。省略時はundefinedとみなす。詳細はGpioPinのコンストラクタを参照。
	 * @return {object as GpioPin}
	 * GpioPinクラスのオブジェクトである。
	 * @example
	 * //create GpioPin direction=out
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var gpio=new LPC1769.Gpio(mcu);
	 * var pin=gpio.getPin(LPC1769.P0[0],{dir:1});
	 */
	getPin:function getPin(i_pin,i_opt)
	{
		try{
			return new DEV.GpioPin(this,i_pin,i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * Gpio機能を持つポート(Pin集合)を取得する。
	 * ピン識別子で指定されるピンのセットをGpioペリフェラルと結合して、GpioPortを生成する。
	 * 関数は、GpioPortのコンストラクタをコールする。
	 * 生成ルールについては、GpioPort関数を参照すること。
	 * @name LPC1769.Gpio#getPort
	 * @function
	 * @param {array[ピン識別子]} i_pin
	 * Gpioポートを構成するPINの識別子の配列である。値は、LPC1769.Pn[m]のメンバ変数である。
	 * @param {object as associative array} i_opt
	 * GpioPortのコンストラクタに渡すオプション値。省略時はundefinedである。詳細はLPCXpresso1769.GpioPort.setOptを参照。
	 * @return {object as LPC1769.GpioPort}
	 * LPC1769.GpioPortクラスのオブジェクトである。
	 * @example
	 * //create 2AdcPort that has 2 pins.
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var gpio=new LPC1769.Gpio(mcu);
	 * var port=gpio.getPort([LPC1769.P0[0],LPC1769.P0[1]]);
	 */	
	getPort:function getPort(i_pins,i_opt)
	{
		try{
			return new DEV.GpioPort(this,i_pins,i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}

/**
 * GPIO pinからGPIOInfoを取得
 * @private
 */
function pin2GpioPinInfo(i_pin)
{
	try{
		//pinの完全な機能名を得る。(得られれば機能がある。)
		var fn=DEV.completePinFunctionName(i_pin,"GPIO");
		//pin名からポートとビットを得る。
		var a=fn.substring(4).split(".");
		//pin情報を構成。
		var r={port:parseInt(a[0]),bit:parseInt(a[1]),pin_sel:DEV.getPinSelByFunctionName(i_pin,fn)};
		if(!isNaN(r.port) && !isNaN(r.bit)){
			return r;
		}
		throw new MiMicException(EE.INVALID_CFG,"The pin has not GPIO fuction.");
	}catch(e){
		throw new MiMicException(e);	
	}
}

/**
 * LPC1769.GpioPort (GpioPort)クラスのコンストラクタ。複数のGPIOピンを一括して操作する、パラレルポート等に使用する。
 * Gpioペリフェラルオブジェクトに、ピン識別子の配列で指定されたピン集合を関連付けて、GPIO機能を持つポートを生成する。
 * 関数は、ピン識別子を元に、そのピンがGPIO機能に接続できるかを調べる。全てのピンにGPIO機能を割り当てられない場合、例外が発生する。どのピンにGPIO機能が割り当てられるかは、MCUのスペックシートを参照すること。
 * @constructor
 * @name LPC1769.GpioPort
 * @param {object as LPC1769.Gpio} i_gpio
 * インスタンスを結びつけるGpioオブジェクト。
 * @param {array[pin識別子]} i_pins
 * ピン識別子の配列。指定できるのは、LPCXpresso1796.P?[?]である。順番は、このインスタンスの返す値の順序に影響する。
 * 0番目のピンはビット0に対応する。同様に、1番目のピンはビット1に対応する。
 * 組み合わせるピンは、同じ物理ポートに所属している必要がある。例えば、GPIO0.0とGPIO0.1は組み合わせられるが、GPIO0.0とGPIO1.1は組み合わせることが出来ない。
 * @param {object as associative array} i_opt
 * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{pin:{sel:auto}}を設定する。
 * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
 * @example
 * //create [AD0.0,AD0.1]
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var gpio=new LPC1769.Gpio(mcu);
 * var port=new LPC1769.GpioPort(adc,[LPC1769.P0[0],LPC1769.P0[1]]); 
 */
DEV.GpioPort=function GpioPort(i_gpio,i_pins,i_opt)
{
	try{
		this._gpio=i_gpio;
		//ピンセットを取得
		this._pins=new Array();
		//pinに変換する。
		for(var i=0;i<i_pins.length;i++){
			this._pins.push(pin2GpioPinInfo(i_pins[i]));
		}
		//pinが全て同じポートに所属しているか確認
		var p=this._pins[0].port;
		for(var i=1;i<this._pins.length;i++){
			if(p!=this._pins[i].port){
				throw new MiMicException("Invalid pin combination.");
			}
		}
		//ポートの生成
		this._port=new DEV.Port(i_gpio._mcu,i_pins);
		this._port_no=p;
		//GPIO用のマスクを生成。
		this._mask=0;
		for(var i=0;i<this._pins.length;i++){
			this._mask|=(0x1<<this._pins[i].bit);
		}
		//ピンオプションの生成
		var opt=cloneAssoc(i_opt);
		//ピンプロパティの複製
		opt.pin=isUndef(opt.pin)?{}:cloneAssoc(opt.pin);
		//設定が無ければ、ピンセレクタを自動に設定
		if(isUndef(opt.pin.sel)){opt.pin.sel=this._PINSEL_AUTO_DETECT;}
		//ピンオプションの設定
		this.setOpt(opt);
	}catch(e){
		throw new MiMicException(e);
	}		
}
DEV.GpioPort.prototype=
{
	_PINSEL_AUTO_DETECT:0x0fffffff,//setoptに自動を伝えるときに使う
	_pins:null,
	_gpio:null,
	_port_no:0,
	_port:null,
	_mask:0,
	/**
	 * Gpioポートにオプション値を設定する。
	 *　関数は、ポートを構成する全てのピンに、同一なオプション値を設定する。
	 * 設定可能な値は、LPC1769.GpioPin#setOptと同じである。
	 * @name LPC1769.GpioPort#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * LPC1769.GpioPin#setOptを参照。
	 */	
	setOpt:function setOpt(i_opt)
	{
		try{
			var db=new Array();
			//BCの生成
			var bc="";
			//dir設定
			if(!isUndef(i_opt.dir)){
				bc+=this._gpio.BCF_setDirs(this._port_no,this._mask,i_opt.dir,db);
			}
			//i_optの展開
			if(!isUndef(i_opt.pin)){
				var optset=new Array();
				for(var i=0;i<this._pins.length;i++){
					//pinselが_PINSEL_AUTO_DETECTならばauto。そうでなければundefinedも含めて設定
					var s=(i_opt.pin.sel==this._PINSEL_AUTO_DETECT)?this._pins[i].pin_sel:i_opt.pin.sel;
					optset.push({sel:s,mode:i_opt.pin.mode,od:i_opt.pin.od});
				}
				//portの設定
				bc+=this._port.BCF_setOpts(optset,db);
			}
			this._gpio._mcu.callMiMicWithCheck(bc+BCF.END,db);
			return;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ポートの出力状態を設定する。
	 * 値は、nビットの整数値で指定する。nは、ポートを構成するピン数である。
	 * この関数は、directionを1(output)に設定したポートで使用できる。inputに設定したピンには使用できない。
	 * @name LPC1769.GpioPort#setValue
	 * @function
	 * @param {int} i_val
	 * nビットの出力値。ビット数は、このポートを構成するピンの数に一致する。2ビットのポートを構成したときに0x03を指定すると、2本のピンがON状態になる。
	 * @example
	 * //set P0[0] pin to “on”. If LED was connected pin it will turn on.
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * port=mcu.getPort([LPC1769.P0[0],LPC1769.P0[1]],"GPIO");
	 * port.setOpt({dir:1,pin:{mode:1,od:0}});
	 * port.setValue(0x3);	 
	 */	
	setValue:function setValue(i_val)
	{
		try{
			var v=0;
			var l=this._pins.length;
			for(var i=0;i<l;i++){
				//セットするbit値を得る。
				var sv=((i_val>>i)&0x01);
				//値のセット
				v|=(sv<<this._pins[i].bit);
			}
			//値をセット
			var db=new Array();
			var bc=this._gpio.BCF_setValues(this._port_no,this._mask,v,db);
			this._gpio._mcu.callMiMicWithCheck(bc+BCF.END,db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ポートの入力状態を返す。
	 * 値は、nビットの整数値である。nは、ポートを構成するピン数である。
	 * この関数は、directionを0(input)に設定したポートで使用できる。outputに設定したピンには使用できない。
	 * @function
	 * @return {int}
	 * nビットの整数値。ビット数は、このポートを構成するピンの数に一致する。2ビットのポートを構成したときに1,1の入力があると、0x03が返る。
	 * @name LPC1769.GpioPort#getValue
	 * @example
	 * //show P0[0] value
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var port=mcu.getPort([LPC1769.P0[0],LPC1769.P0[1]],"GPIO");
	 * port.setOpt({dir:0,pin:{mode:0,od:0}});
	 * alert(port.getValue());	 
	 */	
	getValue:function getValue()
	{
		try{
			var db=new Array();
			var bc=this._gpio.BCF_getValues(this._port_no,this._mask,db);
			var retval=this._gpio._mcu.callMiMicWithCheck(bc+BCF.END,db).stream[0];
			//値の再構成
			var v=0;
			for(var i=this._pins.length-1;i>=0;i--){
				//セットするbit値を得る。
				var sv=((retval>>this._pins[i].bit)&0x1);
				//値のセット(pinArrayの並びとビット並びが同じになるようにする)
				v=(v<<1)|sv;
			}
			return v;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * 直列化された値パターンを出力する。
	 * ポートに連続した値パターンを出力するときに使用する。
	 * 出力速度はMCU依存であり、コントロールできない。
	 * この関数は、directionを1(output)に設定したポートで使用できる。inputに設定したピンには使用できない。
	 * @name LPC1769.GpioPort#outPatt
	 * @function
	 * @param {array[int]} i_val_array
	 * ビットパターンの配列。nビットの値(0 or 1)の配列を指定する。最大数は20である。ビット数は、このポートを構成するピンの数に一致する。
	 * [3,0,3,0]の場合、0,3,0,3の順に、パターンを出力する。
	 * @example
	 * //output  0x01,0x02 to P0[0]+P0[1]
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var port=mcu.getPin([LPC1769.P0[0],LPC1769.P0[1]],"GPIO");
	 * port.setOpt({dir:1,pin:{mode:1,od:0}});
	 * port.outPatt([0x01,0x02]);
	 */	
	outPatt:function outPatt(i_val_array)
	{
		try{
			var db=new Array();
			var bc="";
			for(var i2=0;i2<i_val_array.length;i2++){
				var v=0;
				var l=this._pins.length;
				for(var i=0;i<l;i++){
					//セットするbit値を得る。
					var sv=((i_val_array[i2]>>i)&0x01);
					//値のセット(pinArrayの並びと最下位ビットの位置が同じになるように反転)
					v|=(sv<<this._pins[i].bit);
				}
				//値をセット
				bc+=this._gpio.BCF_setValues(this._port_no,this._mask,v,db);
			}
			this._gpio._mcu.callMiMicWithCheck(bc+BCF.END,db);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}


/**
 * LPC1769.GpioPin (GpioPin)クラスのコンストラクタ。
 * Gpioペリフェラルオブジェクトにピン識別子で指定されたピンを関連付けて、GPIO機能を持つピンを生成する。
 * 関数は、ピン識別子を元に、そのピンがGPIO機能に接続できるかを調べる。ピンにGPIO機能を割り当てられない場合、例外が発生する。どのピンにGPIO機能が割り当てられるかは、MCUのスペックシートを参照すること。
 * ピンがGPIO機能を持たない場合、例外が発生する。
 * @name LPC1769.GpioPin
 * @constructor
 * @param i_gpio
 * インスタンスを結びつけるGpioオブジェクト。
 * @param {object as pin識別子} i_pin
 * ピン識別子。指定できるのは、LPCXpresso1796.P?[?]である。
 * @param i_opt
 * setOpt関数のi_optに渡すパラメタ。省略可能。
 * 省略時は、{pin:{sel:auto}}を使用する。autoは関数が自動的に決定PINSEL値である。
 * 詳細はsetOpt関数を参照。
 * @example
 * //create GPIO Port 0.0 dir=out
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var gpio=new LPC1769.Gpio(mcu);
 * var pin=new  LPC1769.GpioPin(gpio,P0[0],{dir:1}); 
 */
DEV.GpioPin=function GpioPin(i_gpio,i_pin,i_opt)
{
	try{
		//1ピンのポート
		this._gport=new DEV.GpioPort(i_gpio,[i_pin],i_opt);
	}catch(e){
		throw new MiMicException(e);
	}
}
DEV.GpioPin.prototype=
{
	_gport:null,
	/**
	 * ADピンにオプション値を設定する。
	 * @name LPC1769.GpioPin#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * GPIOピンのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{dir:int,pin:object as associative array}</pre>
	 * <ul>
	 * <li>dir - ピンのIN/OUTを指定する1bitの値。1=out,0=in</li>
	 * <li>pin - LPC1769.Pin#setOpt関数のi_optに渡すパラメタである。</li>
	 * </ul>
	 * @example
	 * //set P0[0] to output  GPIO and mode=repeter and open drain=1
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var gpiopin=mcu.getPin(LPC1769.P0[0],"GPIO");
	 * gpiopin.setOpt({dir:1,pin:{mode:1,od:0}});
	 * gpiopin.setValue(1);	 
	 */	
	setOpt:function setOpt(i_opt)
	{
		try{
			this._gport.setOpt(i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * ピンの出力状態を設定する。
	 * この関数は、directionを1(output)に設定したピンで使用できる。inputに設定したピンには使用できない。
	 * @name LPC1769.GpioPin#setValue
	 * @function
	 * @param {int} i_val
	 * 1ビットの出力値。
	 * @example
	 * //set P0[0] pin to “on”. If LED was connected pin it will turn on.
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var gpiopin=mcu.getPin(LPC1769.P0[0],"GPIO");
	 * gpiopin.setOpt({dir:1,pin:{mode:1,od:0}});
	 * gpiopin.setValue(1);	 
	 */
	setValue:function setValue(i_val)
	{
		try{
			this._gport.setValue(i_val);
		}catch(e){
			throw new MiMicException(e);
		}
	},	
	/**
	 * ピンの入力状態を1/0で返す。
	 * この関数は、directionを0(input)に設定したピンで使用できる。outputに設定したピンには使用できない。
	 * @function
	 * @return {int}
	 * 1,又は0
	 * @name LPC1769.GpioPin#getValue
	 * @example
	 * //show P0[0] value
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var gpiopin=mcu.getPin(LPC1769.P0[0],"GPIO");
	 * gpiopin.setOpt({dir:0,pin:{mode:0,od:0}});
	 * alert(gpiopin.getValue());	 
	 */
	getValue:function getValue()
	{
		try{
			return this._gport.getValue();
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * 直列化されたビットパターンを出力する。
	 *　単純なビットパターンをピンに出力するときに使用する。
	 * 出力速度はMCU依存であり、コントロールできない。
	 * この関数は、directionを1(output)に設定したピンで使用できる。inputに設定したピンには使用できない。
	 * @name LPC1769.GpioPin#outPatt
	 * @function
	 * @param {array[int]} i_val_array
	 * ビットパターンの配列。1ビットの値(0 or 1)の配列を指定する。最大数は20である。
	 * [0,1,0,1]の場合、0,1,0,1の順に、パターンを出力します。
	 * @example
	 * //output  0101010100001010 to P0[0]
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var gpiopin=mcu.getPin(LPC1769.P0[0],"GPIO");
	 * gpiopin.setOpt({dir:1,pin:{mode:1,od:0}});
	 * gpiopin.outPatt([0,1,0,1,0,1,0,1,0,0,0,0,1,0,1,0]);
	 */
	outPatt:function outPatt(i_val_array)
	{
		try{
			this._gport.outPatt(i_val_array);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	
}

}());
/**
 * @fileOverview LPC1769のPwmペリフェラル、ピンを制御するクラスを定義する。
 */
(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;
var cloneAssoc=MiMicLib.cloneAssoc;



/**
 * LPCXPresso1769.Pwm (Pwm)クラスのコンストラクタ。
 * MCUに関連付けしたPwmペリフェラルを生成する。
 * Pwmクラスは、PWM1ペリフェラルを管理して、PWMペリフェラル全体の設定を管理する。
 * Pwmの分解能は、無指定の場合25MHz(1/4クロック)設定である。関数は、PWMのマッチレジスタ以外に、PCR,CTCR,TCRを同時に初期化する。
 * @name LPC1769.Pwm
 * @constructor
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @param {aobject as associative array} i_opt
 * インスタンス生成と同時にsetOpt関数でセットする値を指定する。省略時は、{freq:100,phl:{power:1,clock:0}}である。
 * 詳細は、setOpt関数を参照。 
 * @example
 * //create PWM  pheripheral
 * var mcu=new LPC1769.Mcu("192.168.0.39");
 * var pwm=new LPC1769.Pwm(mcu,"");
 */
DEV.Pwm=function Pwm(i_mcu,i_opt)
{
	try{
		this._mcu=i_mcu;
		//PHL生成。
		this._phl=new DEV.Peripheral(i_mcu,DEV.PHL.PWM1);
		//設定値のロード
		var opt=isUndef(i_opt)?{phl:{}}:
		{//i_optある。
			phl:isUndef(i_opt.phl)?{}:cloneAssoc(i_opt.phl),
			freq:i_opt.freq
		};
		//デフォルト値設定
		if(isUndef(opt.phl.power)){opt.phl.power=1;};
		if(isUndef(opt.phl.clock)){opt.phl.clock=0;};
		if(isUndef(opt.freq)){opt.freq=100;}
		
		var bc="";
		var db=new Array();
		//optionの設定
		bc+=this.BCF_setOpt(opt,db);
		bc+=BCF.setMem(this._PC,0x0,db);
		//PCR
		bc+=BCF.setMem(this._PCR,0x0,db);
		//CTCR
		bc+=BCF.setMem(this._CTCR,0x0,db);
		//TCRに値設定(カウンタとPWMモードを無効化)
		bc+=BCF.setMem(this._TCR,0x0,db);
		bc+=BCF.setMem(this._TC,0x0,db);
		//TCRに値設定(カウンタとPWMモードを有効化)
		bc+=BCF.setMem(this._TCR,0x9,db);
		//初期化
		this._mcu.callMiMicWithCheck(bc+BCF.END,db);
		//ペリフェラルをMCUに登録
		this._mcu.registerPhl(this,"PWM");
	}catch(e){
		throw new MiMicException(e);
	}

}
DEV.Pwm.prototype=
{
	_cache:{
		mr0:0
	},
	_TCR:0x40018004,
	_TC:0x40018008,
	_PR:0x4001800C,
	_PC:0x40018010,
	_MCR:0x40018018,
	_PCR:0x4001804C,
	_LER:0x40018050,
	_CTCR:0x40018070,
	_MRn:[0x40018018,0x4001801C,0x40018020,0x40018024,0x40018040,0x40018044,0x40018048],
	_phl:null,
	_mcu:null,

	/**
	 * @private
	 */
	BCF_setOpt:function BCF_setOpt(i_opt,i_db)
	{
		try{
			var bc="";
			var mr0;
			//ペリフェラルの設定
			if(!isUndef(i_opt.phl)){
				bc+=this._phl.BCF_setOpt(i_opt.phl,i_db);
			}
			if(!isUndef(i_opt.freq)){
				//サイクル(Hz)とペリフェラルのクロックから、MR0のサイクルを決定
				mr0=Math.round(this._phl.getPCLK()/i_opt.freq);
				if(mr0<=0){
					//ペリフェラルクロック小さすぎﾜﾛﾀ
					throw new MiMicException("The peripheral clock too small.");
				}
				//MR0に値設定
				bc+=this.BCF_setMRn(0,mr0,i_db);
				//LERにビットセット
				bc+=this.BCF_setLER(0,i_db);
				this._cache.mr0=mr0;
			}
			return bc;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	BCF_setLER:function BCF_setLER(i_ch,i_db)
	{
		try{
			//LERにビットをセット
			return BCF.setBit(this._LER,0x01,0x01,i_ch,i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	BCF_setLERs:function BCF_setLERs(i_mask,i_value,i_db)
	{
		try{
			//LERにビットをセット
			return BCF.setBit(this._LER,i_mask,i_value*i_mask,0,i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	
	/**
	 * MRnに値を設定するBC
	 @private
	 */
	BCF_setMRn:function BCF_setMRn(i_ch,i_val,i_db)
	{
		try{
			return BCF.setMem(this._MRn[i_ch],i_val,i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	BCF_setMRnByDuty:function BCF_setMRnByDuty(i_ch,i_duty,i_db)
	{
		try{
			return this.BCF_setMRn(i_ch,Math.round(i_duty*this._cache.mr0),i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * PCRに値を設定するBC
	 i_ch=1の場合、エッジモードは無視します。
	 @private
	 @param i_mask
	 @param i_edge
	 エッジモード(1/0)
	 @param i_en
	有効/無効の選択
	 */
	BCF_setPCRbits:function BCF_setPCRbits(i_mask,i_edge,i_en,i_db)
	{
		try{
			var m,v;
			m=v=0;
			if(!isUndef(i_edge)){
				var t=0xff&i_mask;
				v|=i_edge*t;
				m|=t;
			}
			if(!isUndef(i_en)){
				var t=0xff00&i_mask;
				v|=(i_en*t);
				m|=t;
			}
			//ビットの設定
			return BCF.setBit(this._PCR,m,v,0,i_db);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	
	/**
	 * Pwmペリフェラルに値を設定する。
	 * 設定する値は、全てのPWMチャンネル（PIN）に共通な項目である。
	 * @name LPC1769.Pwm#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * GPIOピンのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{freq:int,phl:object as associative array}</pre>
	 * <ul>
	 * <li>freq - PWMの基本周波数(Hz)である。この値は、全てのPWMチャンネルで共通である。</li>
	 * <li>phl - ペリフェラルの共通パラメタである。LPC1769.Peripheral.setOpt関数のi_optに渡すパラメタである。詳細はLPC1769.Peripheral#setOptを参照。</li>
	 * </ul>
	 * @example
	 * //create PWM (logical)peripheral
	 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
	 * var pwm=new LPC1769.Pwm(mcu);
	 * pwm.setOpt({freq:1000});
	 */
	setOpt:function setOpt(i_opt)
	{
		try{
			var db=new Array();
			var bc=this.BCF_setOpt(i_opt,db);
			this._mcu.callMiMicWithCheck(bc+BCF.END,db);
		}catch(e){
			throw new MiMicException(e);
		}
	},	
	/**
	 * PWM機能を持つピンを取得する。
	 * ピン識別子で指定されるピンをPWMペリフェラルと結合して、PwmPinを生成する。
	 * 関数は、PwmPinオブジェクトのコンストラクタをコールして、PwmPinを生成する。失敗すると、例外をスローする。
	 * 生成ルールについての詳細は、PwmPinを参照。
	 * @name LPC1769.Pwm#getPin
	 * @function
	 * @param {object as ピン識別子} i_pin
	 * PWM機能を割り当てるPINの識別子である。
	 * @param {object as associative array} i_opt
	 * PemPinのコンストラクタに渡すオプション値。省略時は{duty:0,enable:1,pin:{sel:auto}}である。
	 * @return {object as LPC1769.PwmPin}
	 * LPC1769.PwmPinクラスのオブジェクトである。
	 * @example
	 * //create 100hz d=0.5 pwm
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var pwm=new LPC1769.Pwm(mcu);
	 * var pwmpin=pwm.getPin(LPC1769.P2[0],{duty:0.5});
	 */
	getPin:function getPin(i_pin,i_opt)
	{
		try{
			return new DEV.PwmPin(this,i_pin,i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * PWM機能を持つポート(Pin集合)を取得する。
	 * ピン識別子で指定されるピンのセットをPWMペリフェラルと結合して、PwmPortを生成する。
	 * 関数は、PwmPortのコンストラクタをコールする。
	 * 生成ルールについては、PwmPort関数を参照すること。
	 * @name LPC1769.Pwm#getPort
	 * @function
	 * @param {array[ピン識別子]} i_pin
	 * Pwm機能を割り当てるPINの識別子の配列である。値は、LPC1769.Pn[m]のメンバ変数である。
	 * @param {object as associative array} i_opt
	 * AdcPortのコンストラクタに渡すオプション値。省略時はundefinedである。詳細はLPC1769.PwmPort#setOptを参照。
	 * @return {object as LPC1769.PwmPort}
	 * LPC1769.PwmPortクラスのオブジェクトである。
	 * @example
	 * //create 2AdcPort that has 2 pins.
	 * var mcu=new LPC1769.Mcu("192.168.0.39");
	 * var pwm=new LPC1769.Pwm(mcu);
	 * var port=pwm.getPort([LPC1769.P0[23],LPC1769.P0[24]]);
	 */
	getPort:function getPort(i_pins,i_opt)
	{
		try{
			return new DEV.PwmPort(this,i_pins,i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	}	
}

/**
 * Pwm pinからPwmInfoを取得
 * @private
 */
function pin2PwmPinInfo(i_pin)
{
	try{
		//pinの完全な機能名を得る。(得られれば機能がある。)
		var fn=DEV.completePinFunctionName(i_pin,"PWM");
		//portとbitを得る(AD0だけしか管理しないよ)
		var a=fn.substring(2).split(".");
		var r={port:0,ch:parseInt(a[1]),pin_sel:DEV.getPinSelByFunctionName(i_pin,fn)};
		if(!isNaN(r.ch)){
			return r;
		}
		throw new MiMicException(EE.INVALID_CFG,"The pin has not PWM fuction.");
	}catch(e){
		throw new MiMicException(e);	
	}
}
/**
 * Pwmペリフェラルと複数のPin識別子から、シングルエッジPwmポートを構成する。
 * Pwmペリフェラルオブジェクトにピン識別子の配列で指定されたピンを関連付けて、PWM機能を持つポートを生成する。
 * 関数は、ピン識別子を元に、それぞれのピンがPWM機能に接続できるかを調べる。
 * ピンにPWM機能を割り当てられない場合、例外が発生する。どのピンにPWM機能が割り当てられるかは、MCUのスペックシートを参照すること。
 * PWMポートは、複数の同一周期のPWMピンのデューティ比を、同期して操作するときに便利である。
 * @constructor
 * @name LPC1769.PwmPort
 * @param {object as LPC1769.Pwm} i_pwm
 * インスタンスを結びつけるPwmオブジェクト。
 * @param {array[pin識別子]} i_pins
 * ピン識別子の配列。指定できるのは、LPC1769.P?[?]である。
 * @param {object as associative array} i_opt
 * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{duty:100,enable:1,pin{sel:auto}}を設定する。
 * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
 * dutyをピン毎に設定する場合は、setDuty関数を使うこと。
 * @example
 * //create PWM1.0,PWM1.1
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var pwm=new LPC1769.Pwm(mcu,{freq:100});
 * var port=new LPC1769.PwmPort(pwm,[LPC1769.P2[0],LPC1769.P2[1]]); 
 */
DEV.PwmPort=function PwmPort(i_pwm,i_pins,i_opt)
{
	try{
		this._pwm=i_pwm;
		//ピンセットを取得
		this._pins=new Array();
		//pinに変換する。
		for(var i=0;i<i_pins.length;i++){
			this._pins.push(pin2PwmPinInfo(i_pins[i]));
		}
		//pinが全て同じポートに所属しているか確認
		var p=this._pins[0].port;
		for(var i=1;i<this._pins.length;i++){
			if(p!=this._pins[i].port){
				throw new MiMicException("Invalid pin combination.");
			}
		}
		//ポートの生成
		this._port=new DEV.Port(i_pwm._mcu,i_pins);
		this._port_no=p;
		
		this._ler_mask=0;
		this._pcr_mask=0;
		for(var i=0;i<this._pins.length;i++){
			this._ler_mask|=(0x1<<this._pins[i].ch);
			this._pcr_mask|=(0x101<<this._pins[i].ch);
		}		
		var opt=isUndef(i_opt)?{pin:{}}:
		{
			pin:isUndef(i_opt.pin)?{}:cloneAssoc(i_opt.pin),
			duty:i_opt.duty,
			enable:i_opt.enable
		};
		//デフォルト値のロード
		if(isUndef(opt.pin.sel)){opt.pin.sel=this._PINSEL_AUTO_DETECT;}
		if(isUndef(opt.duty)){opt.duty=0;}
		if(isUndef(opt.enable)){opt.enable=1;}
		this.setOpt(opt);
	}catch(e){
		throw new MiMicException(e);
	}	
}
DEV.PwmPort.prototype=
{
	_PINSEL_AUTO_DETECT:0x0fffffff,
	_pwm:null,
	_pins:null,
	_port_no:0,
	_port:null,
	_pcr_mask:0,
	_ler_mask:0,
	/**
	 * PWMポートにオプション値を設定する。
	 * 関数は、ポートを構成する全てのピンに、同じ値を設定する。
	 * 設定可能な値は、LPC1769.PwmPin#setOptと同じである。	 
	 * @name LPC1769.PwmPort#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * LPC1769.PwmPin#setOptを参照。
	 * @example
	 * var mcu=new LPC1769.Mcu("192.168.128.39",true);
	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
	 * var port=pwm.getPort([LPC1769.P2[0]]);
	 * port.setOpt({enable:0});
	 */
	setOpt:function setOpt(i_opt)
	{
		try{
			var db=new Array();
			//BCの生成
			var bc="";
			//i_optの展開
			if(!isUndef(i_opt.pin)){
				var optset=new Array();
				for(var i=0;i<this._pins.length;i++){
					//pinselが_PINSEL_AUTO_DETECTならばauto。そうでなければundefinedも含めて設定
					var s=(i_opt.pin.sel==this._PINSEL_AUTO_DETECT)?this._pins[i].pin_sel:i_opt.pin.sel;
					optset.push({sel:s,mode:i_opt.pin.mode,od:i_opt.pin.od});
				}
				//portの設定
				bc+=this._port.BCF_setOpts(optset,db);
			}
			//PCRに値設定
			if(!isUndef(i_opt.enable)){
				bc+=this._pwm.BCF_setPCRbits(this._pcr_mask,0,i_opt.enable,db);
			}
			//デューティ比を
			if(!isUndef(i_opt.duty)){
				//デューティ比を設定
				for(var i=0;i<this._pins.length;i++){
					bc+=this._pwm.BCF_setMRnByDuty(this._pins[i].ch,i_opt.duty,db);
				}
				//LERにセット
				bc+=this._pwm.BCF_setLERs(this._ler_mask,1,db);
			}
			this._pwm._mcu.callMiMicWithCheck(bc+BCF.END,db);
			return;
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * PWMポートのデューティ比をまとめて変更する。
	 * @name LPC1769.PwmPort#setDutys
	 * @function
	 * @param {array[double]} i_duty_array
	 * デューティ比の配列である。0.0<=n<=1.0のdouble値を指定する。
	 * ポートを構成するピンの数だけ指定する。変更しないピンには、undefinedを指定すること。
	 * @example
	 * varmcu=new LPC1769.Mcu("192.168.128.39",true);
	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
	 * var port=pwm.getPort([LPC1769.P2[0],LPC1769.P2[1]]);
	 * pwm.setDutys([0.5,0.0]);//PWM0=0.5,PWM1=0.0
	 * pwm.setDutys([undefined,0.0]);//PWM1=0.0
	 */	
	setDutys:function setDutys(i_duty_array)
	{
		try{
			if(i_duty_array.length!=this._pins.length){
				throw new MiMicException();
			}
			var bc="";
			var db=new Array();
			//デューティ比をまとめてセット
			for(var i=0;i<this._pins.length;i++){
				if(!isUndef(i_duty_array[i])){
					bc+=this._pwm.BCF_setMRnByDuty(this._pins[i].ch,i_duty_array[i],db);
				}
			}
			//LERにセット
			bc+=this._pwm.BCF_setLERs(this._ler_mask,1,db);
			this._pwm._mcu.callMiMicWithCheck(bc+BCF.END,db);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}
/**
 * PwmペリフェラルとPin識別子から、シングルエッジPwmピンを構成する。
 * Pwmペリフェラルオブジェクトにピン識別子で指定されたピンを関連付けて、PWM機能を持つピンを生成する。
 * 関数は、ピン識別子を元に、そのピンがPWM機能に接続できるかを調べる。ピンにPWM機能を割り当てられない場合、例外が発生する。どのピンにPWM機能が割り当てられるかは、MCUのスペックシートを参照すること。
 * ピンがPWM機能を持たない場合、例外が発生する。
 * @constructor
 * @name LPC1769.PwmPin
 * @param {object as LPC1769.Pwm} i_pwm
 * インスタンスを結びつけるAdcオブジェクト。
 * @param {object as pin識別子} i_pin
 * ピン識別子。指定できるのは、LPC1769.P?[?]である。
 * @param {object as associative array} i_opt
 * setOpt関数のi_optに渡すパラメタである。省略可能。省略時は{duty:100,enable:1,pin{sel:auto}}を設定する。
 * autoは、関数が自動的に決定するPINSELの値である。詳細はsetOpt関数を参照。 
 * @example
 * //create PWM1.0
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var pwm=new LPC1769.Pwm(mcu,{freq:100});
 * var pwmpin=new LPC1769.PwmPin(pwm,P2[0]); 
 */
DEV.PwmPin=function PwmPin(i_pwm,i_pin,i_opt)
{
	try{
		//1pinのポートとして実装
		this._pport=new DEV.PwmPort(i_pwm,[i_pin],i_opt);
	}catch(e){
		throw new MiMicException(e);
	}
}

DEV.PwmPin.prototype=
{
	_pport:null,

	/**
	 * PWMピンにオプション値を設定する。
	 * @name LPC1769.PwmPin#setOpt
	 * @function
	 * @param {object as associative array} i_opt
	 * PWMピンのコンフィグレーションパラメタである。必要な値を格納した連想配列で指定する。
	 * 全ての値を省略することは出来ない。連想配列のメンバは以下の通り。
	 * <pre>{pin:{associative array},enable:int,duty:double}</pre>
	 * <ul>
	 * <li>pin - LPC1769.Pin#setOpt関数のi_optに渡すパラメタである。</li>
	 * <li>enable - PWMの有効/無効を切り替える。1で有効。</li>
	 * <li>duty - デューティ比である。0.0<=n<=1.0のdouble値を指定する。</li>
	 * </ul>
	 * @example
	 * var mcu=new LPC1769.Mcu("192.168.128.39",true);
	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
	 * var pin=pwm.getPin(LPC1769.P2[0]);
	 * pin.setOpt({duty:0});
	 */
	setOpt:function setOpt(i_opt)
	{
		try{
			this._pport.setOpt(i_opt);
		}catch(e){
			throw new MiMicException(e);
		}
	},
	/**
	 * PWMのデューティ比を変更する。
	 * @name LPC1769.PwmPin#setDuty
	 * @function
	 * @param {double} i_duty
	 * デューティ比である。0.0<=n<=1.0のdouble値を指定する。
	 * @example
	 * varmcu=new LPC1769.Mcu("192.168.128.39",true);
	 * var pwm=mcu.getPeripheral("PWM",{freq:100});
	 * pwmpin=pwm.getPin(LPC1769.P2[0]);
	 * pwmpin.setDuty(0.5);
	 */
	setDuty:function setDuty(i_duty)
	{
		try{
			this._pport.setDutys([i_duty]);
		}catch(e){
			throw new MiMicException(e);
		}
	}
}
	


}());
/**
 * @fileOverview LPC1769における、ネイティブ関数コールインタフェイスを定義する。
  */
(function(){
var DEV=LPC1769;
var BCF=DEV._BCF;
var EE=DEV._EE;
var isUndef=MiMicLib.isUndef;



/**
 * LPC1769.Ni (NativeInterface)クラスのコンストラクタ。
 * MCUに関連付けしたネイティブインタフェイスを生成する。
 * クラスは、MiMicVMのCALL命令を使用した、ネイティブ関数コール機能を提供する。
 * @constructor
 * @name LPC1769.Ni
 * @param {object as LPC1769.Mcu} i_mcu
 * インスタンスを結びつけるMcuオブジェクト。
 * @example
 */
DEV.Ni=function Ni(i_mcu)
{
	try{
		this._mcu=i_mcu;
	}catch(e){
		throw new MiMicException(e);
	}

}
DEV.Ni.prototype=
{
	/**
	 * この関数は、CALLインストラクションを使ったネイティブファンクションコールを実行する。
	 * MiMicRemoteMCUに定義されているネイティブ関数から、ファンクションIDに一致するものを検索して、実行する。
	 * ネイティブ関数は、native_function.cのnaitive_function_tableに定義されている。
	 * 引き渡すパラメータは、SPUTによるストリーム値と、VMのレジスタ(WM)値である。得られる返却値は、ネイティブ関数実行後のVMレジスタ(WM)と、ストリームである。
	 * @name LPC1769.Ni#call
	 * @function
	 * @param {int} i_id
	 * ファンクションID。ファンクションIDは、呼び出す関数を識別するidである。
	 * @param {object as associative array} i_in
	 * 入力パラメータである。必要な値を格納した連想配列で指定する。省略が可能である。
	 * 連想配列のメンバは以下の通り。
	 * <pre>{wm?:int,stream:array[int]}</pre>
	 *
	 * <ul>
	 * <li>wm? - WMレジスタにセットする値である。wm0～wm7まで、最大8個の値を指定できる。</li>
	 * <li>stream - ストリームに出力する値である。長さに制限は無いが、100個程度が上限である。</li>
	 * </ul>
	 * @param {object as associative array} o_out
	 * 出力パラメータを受け取る変数である。戻り値として取得したい値を格納した連想配列を指定する。省略が可能である。
	 * 各メンバ変数は関数が割り当てるので、nullを設定しておくこと。
	 * 連想配列のメンバは以下の通り。
	 * <pre>{wm?:null,stream:null}</pre>
	 * <ul>
	 * <li>wm? - 取得するWMレジスタのプレースホルダ。戻り値としてwmレジスタの値を取得する時に指定する。取得したいWMを指定する。</li>
	 * <li>stream - 取得するストリームのプレースホルダ。戻り値としてネイティブ関数が出力したストリームを取得する時に指定する。純粋な返却streamから、wmの返却分を差し引いたint array値である。</li>
	 * </ul>
	 * @return {boolean}
	 * 関数コールが成功するとtrueである。
	 * @example
	 * var mcu=new LPC1769.Mcu("192.168.128.39",true);
	 * var ni=new LPC1769.Ni(mcu);
	 * //This function calls the function number 1. wm1=1,wm2=3 are set to WM before calling. And puts [12] to input stream.
	 * //Out values are consist of wm4,wm5 and output stream values.
	 * var r1={wm4:null,wm5:null};
	 * ni.call(0,{wm1:1,wm2:3,stream:[12]},r1);
	 *
	 * //sample2 no parameter, returns.
	 * ni.call(0);
	 * 
	 * //sample 3 stream only.
	 * var r2={stream:null};
	 * ni.call(0,{stream:[]},r2);
	 *
	 * //call sample echo back native function.
	 * var r3={stream:null};
	 * ni.call(0x39000000,{stream:[0x2525]},r3);
	 * alert(r3[0]);
	 *
	 * // set/get all work register and stream.
	 * var r4={stream:null,wm0:null,wm1:null,wm2:null,wm3:null,wm4:null,wm5:null,wm6:null,wm7:null};
	 * ni.call(0x39000000,{stream:[0x39],wm0:7,wm1:6,wm2:5,wm3:4,wm4:3,wm5:2,wm6:1,wm7:0},r4);
	 *
	 */
	call:function call(i_id,i_in,o_out)
	{
		/*
		 * .DBは、WM設定値(あれば),idx番号,stream値の順で格納。
		 * 命令は、
		 * WM初期化部(LD配列)
		 * LD #0;WM初期化(あれば)
		 * :
		 * SGET 
		 */
		var bc="";
		var db=new Array();
		//WM初期化命令
		if(!isUndef(i_in)){
			//wmがあれば、初期化命令を追加。
			//LD命令を直書き
			for(var i=0;i<8;i++){
				var hash="wm"+i;
				if(!isUndef(i_in[hash])){
					bc+="FB"+MiMicLib.hexout(i,2)+MiMicLib.hexout(i_in[hash],8);
				}
			}
			//streamをセット
			if(!isUndef(i_in.stream)){
				for(var i=0;i<i_in.stream.length;i++){
					db.push(i_in.stream[i]);
				}
			}
		}
		//CALL命令を直書き
		bc+="ZF"+MiMicLib.hexout(i_id,8);
		//
		var num_of_wm=0;
		if(!isUndef(o_out)){
			//o_out.wmxがあれば、回収用命令を追記
			//SGET命令を直書き
			for(var i=0;i<8;i++){
				if(!isUndef(o_out["wm"+i])){
					bc+="EE"+MiMicLib.hexout(i,2);
					num_of_wm++;
				}
			}
		}
		//実行
		var ret=this._mcu.callMiMic(bc+BCF.END,db);
		if(ret.result!=0x00){
			//失敗.理由はresultの内容。
			return false;
		}
		//streamから値を回収
		//streamは、関数の返したストリーム+WMの返却値
		if(!isUndef(o_out)){
			//WM回収のためにSGET命令を直書き
			var offset=ret.stream.length-num_of_wm;
			for(var i=0;i<8;i++){
				var hash="wm"+i;
				if(!isUndef(o_out[hash])){
					o_out[hash]=ret.stream[offset];
					offset++;
				}
			}
			//o_out.streamがあれば、値を回収。
			if(!isUndef(o_out.stream)){
				o_out.stream=ret.stream.slice(0,ret.stream.length-num_of_wm);
			}
		}
		return false;
	}
}




}());
/**
 * @fileOverview MbedM3ネームスペース、定数値を定義する。
 */

/**
 * MbedM3用の高レベルAPIのネームスペースである。LPC1769ネームスペースを継承して、MbedM3独自の拡張要素を追加する。
 * このネームスペースは、LPC1769ネームスペースの全てのクラス、関数、宣言を継承する。LPC1769.xxxは、MbedM3.xxxに置き換えることができる。
 * @namespace
 * <p>
 * 実装メモ
 * このネームスペースは、LPC1769を継承する。LPC1769の構築を完了させてから読み込むこと。
 * </p>
 *@example
 * var mcu=new MbedM3.Mcu(“192.168.0.39”);
 * var adpin=mcu.getPin(MbedM3.PINNAME.AIN0,"AD");//bind AIN0 with AD function
 * //This is same as the above fragment.
 * var mcu=new LPC1769.Mcu(“192.168.0.39”);
 * var adpin=mcu.getPin(LPC1769.P0[23],"AD");//bind AIN0 with AD function
 */
var MbedM3;

(function(){
	var isUndef=MiMicLib.isUndef;
	var DEV=LPC1769;
	//LPC1769を継承する。"構築済のLPC1769ネームスペース"をシャローコピーして、extensionをマージする方法で生成する。
	MbedM3=MiMicLib.cloneAssoc(DEV);

	if(!isUndef(MbedM3.PINNAME)){alert("invalid override[PINNAME]");}
	/**
	 * Mbedのピン名に対応するピン識別子である。
	 * 要素は、LPC1769のピン識別子を参照する。
	 * @name MbedM3#PINNAME
	 * @constant
	 * @field
	 * @example
	 * var mcu=new MbedM3.Mcu(“192.168.0.39”);
	 * var adpin=mcu.getPin(MbedM3.PINNAME.AIN0,"AD");//bind AIN0 with AD function
	 */
	MbedM3.PINNAME={
		//Left side
		SPI1MOSI:DEV.P0[9],
		SPI1MISO:DEV.P0[8],
		SPI1SCK :DEV.P0[7],
		GPIO    :DEV.P0[6],
		UART1TX :DEV.P0[0],I2C1SDA:DEV.P0[0],
		UART1RX :DEV.P0[1],I2C1SCL:DEV.P0[1],
		SPI2MODI:DEV.P0[18],
		SPI2MISO:DEV.P0[17],
		SPI2SCK :DEV.P0[15],UART2TX:DEV.P0[15],SPI2SCL :DEV.P0[15], //SPISCL->SPISCK?
		UART2RX :DEV.P0[16],
		AIN0:DEV.P0[23],
		AIN1:DEV.P0[24],
		AIN2:DEV.P0[25],
		AIN3:DEV.P0[26],AOUT:DEV.P0[26],
		AIN4:DEV.P0[30],
		AIN5:DEV.P0[31],
		//Right side
		USBDP:DEV.P0[29],
		USBDM:DEV.P0[30],
		CANRD:DEV.P0[4],
		CANTD:DEV.P0[5],
		UART3TX:DEV.P0[10],I2C2SDA:DEV.P0[10],
		UART3RX:DEV.P0[11],I2C2SCL:DEV.P0[10],
		PWMOUT0:DEV.P2[0],
		PWMOUT1:DEV.P2[1],
		PWMOUT2:DEV.P2[2],
		PWMOUT3:DEV.P2[3],
		PWMOUT4:DEV.P2[4],
		PWMOUT5:DEV.P2[5],
	};
	if(!isUndef(MbedM3.PIN)){alert("invalid override[PIN]");}
	/**
	 * Mbedのピン名に対応するピン識別子である。配列の番号は、Mbed付属のチートシートに一致する。
	 * 要素は、LPC1769のピン識別子を参照する。
	 * @name MbedM3#PIN
	 * @constant
	 * @field
	 * @example
	 * var mcu=new MbedM3.Mcu(“192.168.0.39”);
	 * var adpin=mcu.getPin(MbedM3.PINNAME.AIN0,"AD");//bind AIN0 with AD function
	 */
	MbedM3.PIN=[
		null,null,null,null,null,//0,1,2,3,4
		DEV.P0[9],//5
		DEV.P0[8],//6
		DEV.P0[7],//7
		DEV.P0[6],//8
		DEV.P0[0],//9
		DEV.P0[1],//10
		DEV.P0[18],//11
		DEV.P0[17],//12
		DEV.P0[15],//13
		DEV.P0[16],//14
		DEV.P0[23],//15
		DEV.P0[24],//16
		DEV.P0[25],//17
		DEV.P0[26],//18
		DEV.P1[30],//19
		DEV.P1[31],//20
		DEV.P2[5],//21
		DEV.P2[4],//22
		DEV.P2[3],//23
		DEV.P2[2],//24
		DEV.P2[1],//25
		DEV.P2[0],//26
		DEV.P0[11],//27
		DEV.P0[10],//28
		DEV.P0[5],//29
		DEV.P0[4]//30
	];
	if(!isUndef(MbedM3.LED)){alert("invalid override[LED]");}
	/**
	 * MbedのLEDに接続されたピン識別子である。
	 * 要素は、LPC1769のピン識別子を参照する。
	 * @name MbedM3#LED
	 * @constant
	 * @field
	 * @example
	 * var mcu=new MbedM3.Mcu(“192.168.0.39”);
	 * var pin=mcu.getPin(MbedM3.LED[0],"GPIO");//bind LEDPIN with gpio function
	 */
	MbedM3.LED=[
		DEV.P1[18],
		DEV.P1[20],
		DEV.P1[21],
		DEV.P1[23]
	]
}());