<?php


class MiMic_LPC1769_Port
{
	private static $_PINSEL=array(0x4002C000,0x4002C004,0x4002C008,0x4002C00C,0x4002C010,null,null,0x4002C0C0,null,0x4002C024,0x4002C028);
	private static $_PINMODE=array(0x4002C040,0x4002C044,0x4002C048,0x4002C04C,0x4002C050,0x4002C054,0x4002C058,0x4002C05C,null,0x4002C064);
	private static $_PINMODE_OD=array(0x4002C068,0x4002C06C,0x4002C070,0x4002C074,0x4002C078);

	public $_ref_mcu;
	protected $_pininfo;

	/**
	 * @param array[pinID] $i_pins
	 *
	 */
	public function __construct($i_mcu,$i_pins,$i_opts=null)
	{
		$this->_ref_mcu=$i_mcu;
		$this->_pininfo=array();
		//ピン情報に変換
		for($i=0;$i<count($i_pins);$i++){
			array_push($this->_pininfo,MiMic_LPC1769::getPinRegInfo($i_pins[$i]));
		}
		if(!is_null($i_opts)){
			this.setOpts($i_opts);
		}
	}
	public function BCF_setOpts($i_opts,&$i_db)
	{
		//10/5レジスタ分のワーク領域を作る。
		$selr=array(0,0,0,0,0,0,0,0,0,0);
		$selr_mask=array(0,0,0,0,0,0,0,0,0,0);
		$modr=array(0,0,0,0,0,0,0,0,0,0);
		$modr_mask=array(0,0,0,0,0,0,0,0,0,0);
		$odr=array(0,0,0,0,0);
		$odr_mask=array(0,0,0,0,0);



		//pinsとoptsの数は同じだよね？
		if(count($this->_pininfo)!=count($i_opts)){
			throw new MiMicException();
		}

		//レジスタ値、マスクの生成
		for($i=0;$i<count($i_opts);$i++)
		{
			//Exception will be thrown when casting failed.
			$pi=$this->_pininfo[$i];
			$opt=$i_opts[$i];
			if(isset($opt['sel']))
			{
				$idx=$pi['s'];
				$selr[$idx]|=(($opt['sel'])<<($pi['smb']));
				$selr_mask[$idx]|=(0x3<<($pi['smb']));
			}

			if(isset($opt['mode']))
			{
				$idx=$pi['m'];
				$modr[$idx]|=(($opt['mode'])<<$pi['smb']);
				$modr_mask[$idx]|=(0x3<<$pi['smb']);
			}

			if(isset($opt['od']))
			{
				$idx=$pi['o'];
				$odr[$idx]|=(($opt['od'])<<$pi['ob']);
				$odr_mask[$idx]|=(0x1<<$pi['ob']);
			}
		}

		//BCFを生成

		$bc="";

		for($i=0;$i<10;$i++){
			if($selr_mask[$i]!=0x0){
				$bc.=MiMic_LPC1769::BCF_setBit(self::$_PINSEL[$i],$selr_mask[$i],$selr[$i],0,$i_db);
			}
			if($modr_mask[$i]!=0x0){
				$bc.=MiMic_LPC1769::BCF_setBit(self::$_PINMODE[$i],$modr_mask[$i],$modr[$i],0,$i_db);
			}
		}

		for($i=0;$i<5;$i++){
			if($odr_mask[$i]!=0x0){
				$bc.=MiMic_LPC1769::BCF_setBit(self::$_PINMODE_OD[$i],$odr_mask[$i],$odr[$i],0,$i_db);
			}
		}
		return $bc;
	}

	public function setOpts($i_opts)
	{
		$db=array();
		$bc=$this->BCF_setOpts($i_opts,$db);
		if(count($bc)==0){
			throw new MiMicException("i_opt is empty or invalid.");
		}

		//MiMicBCを生成して実行
		$this->_ref_mcu->callMiMicWithCheck($bc.LPC1769::_BCF_END,$db);
		return;
	}

}


?>


