<?php

	class MiMic_LPC1769_Memory
	{
		private static function checkAlign($v)
		{
			if($v%4!=0){
				throw new MiMicException("An alignment is not 32bit unit.");
			}
		}
		private $_mcu;
		private $_base;
		public function __construct($i_mcu,$i_base=0)
		{
			$this->_base=$i_base;
			$this->_mcu=$i_mcu;
		}

		private function BCF_read32_1($i_addr,&$i_db)
		{
			self::checkAlign($i_addr);
			$bc=MiMic_LPC1769::_BCF_READMEM;
			array_push($i_db,$this->_base+$i_addr);
			return $bc;
		}			

		protected function read32_1($i_addr)
		{
			$db=array();
			$bc=$this->BCF_read32_1($i_addr,$db);
			$ret=$this->_mcu->callMiMicWithCheck($bc.MiMic_LPC1769::_BCF_END,$db);
			return $ret->stream;
		}

		private function BCF_read32_2($i_addr,&$i_db)
		{
			$bc="";
			for($i=0;$i<count($i_addr);$i++){
				self::checkAlign($i_addr[$i]);
				$bc.=MiMic_LPC1769::BCF_getMem($this->_base+$i_addr[$i],$i_db);
			}
			return $bc;
		}				
		protected function read32_2($i_addr)
		{
			$db=array();
			$bc=$this->BCF_read32_2($i_addr,$db);
			$ret=$this->_mcu->callMiMicWithCheck($bc.MiMic_LPC1769::_BCF_END,$db);
			return $ret->stream;
		}
		private function BCF_read32_3($i_addr,$i_bytes,&$i_db)
		{
			self::checkAlign($i_addr);
			self::checkAlign($i_bytes);
			$l=$i_bytes/4;
			$bc="";
			for($i=0;$i<$l;$i++){
				$bc.=MiMic_LPC1769::_BCF_READMEM;
				array_push($i_db,$this->_base+$i_addr+$i*4);
			}
			return $bc;
		}
		protected function read32_3($i_addr,$i_bytes)
		{
			$db=array();
			$bc=$this->BCF_read32_3($i_addr,$i_bytes,$db);
			$ret=$this->_mcu->callMiMicWithCheck($bc.MiMic_LPC1769::_BCF_END,$db);
			return $ret->stream;
		}
		public function read32($a1,$a2=null)
		{
			if(is_null($a2)){
				if(is_array($a1)){
					//read32_2($i_addr as array)
					return $this->read32_2($a1);
				}else{
					//read32_1($i_addr as int)
					return $this->read32_1($a1);
				}
			}else{
				return $this->read32_3($a1,$a2);
			}
		}

		//
		//write32(UInt32 i_addr,UInt32 i_value,List<UInt32> i_db)
		//

		 

		private function BCF_write32_1($i_addr,$i_value,&$i_db)
		{
			self::checkAlign($i_addr);
			$bc="";
			$bc.=MiMic_LPC1769::BCF_setMem($this->_base+$i_addr,$i_value,$i_db);
			return $bc;
		}

		public function write32_1($i_addr,$i_value)
		{
			$db=array();
			$bc=$this->BCF_write32_1($i_addr,$i_value,$db);
			$this->_mcu->callMiMicWithCheck($bc.MiMic_LPC1769::_BCF_END,$db);
		}
		//

		//write32(UInt32 i_addr,UInt32[] i_value,List<UInt32> i_db)

		//
		private function BCF_write32_2($i_addr,$i_value,&$i_db)
		{
			self::checkAlign($i_addr);
			$bc="";
			for($i=0;$i<count($i_value);$i++){
				$bc.=MiMic_LPC1769::BCF_setMem($this->_base+$i_addr+$i*4,$i_value[$i],$i_db);
			}
			return $bc;
		}
		public function write32_2($i_addr,$i_value)
		{
			$db=array();
			$bc=$this->BCF_write32_2($i_addr,$i_value,$db);
			$this->_mcu->callMiMicWithCheck($bc.MiMic_LPC1769::_BCF_END,$db);
		}

		//
		//write32(UInt32[] i_addr,UInt32[] i_value,List<UInt32> i_db)
		//		
		private function BCF_write32_3($i_addr,$i_value,&$i_db)
		{
			if(count($i_addr)!=count($i_value)){
				throw new MiMicException();
			}
			$bc="";
			for($i=0;$i<count($i_value);$i++){
				self::checkAlign($i_addr[$i]);
				$bc.=MiMic_LPC1769::BCF_setMem($this->_base+$i_addr[$i],$i_value[$i],$i_db);
			}
			return $bc;
		}

		public function write32_3($i_addr,$i_value)
		{
			$db=array();
			$bc=$this->BCF_write32_3($i_addr,$i_value,$db);
			$this->_mcu->callMiMicWithCheck($bc.MiMic_LPC1769::_BCF_END,$db);
		}
		public function write32($a1,$a2)
		{
			if(is_array($a1)){
				//write32_3($i_addr :array[int],$i_value:array[int])
				$this->write32_3($a1,$a2);
			}else{
				if(is_array($a2)){
					//write32_2($i_addr :int ,$i_value:arary[int])
					$this->write32_2($a1,$a2);
				}else{
					//write32_1($i_addr :int ,$i_value:int)
					$this->write32_1($a1,$a2);
				}
			}
		}
	}




