


class OneWireMaster:

	R_CSR=0x0
	R_CDR=0x4

	CSR_DAT_MSK =(1<<0)
	CSR_RST_MSK =(1<<1)
	CSR_OVD_MSK =(1<<2)
	CSR_CYC_MSK =(1<<3)
	CSR_PWR_MSK =(1<<4)
	CSR_IRQ_MSK =(1<<6)
	CSR_IEN_MSK =(1<<7)
	CSR_SEL_OFS =8
	CSR_SEL_MSK =(0xF<<8)
	CSR_POWER_OFS =16
	CSR_POWER_MSK =(0xFFFF<<16)

	CDR_NOR_MSK =(0xFFFF<<0)
	CDR_OVD_OFS =16
	CDR_OVD_MSK =(0XFFFF<<16)


	def __init__(self, reg_rd, reg_wr, base=0x0):
		self._rd=reg_rd
		self._wr=reg_wr
		self.base = base
		
	def slot(self, bit):

		# request bit write
		self.write_reg( self.R_CSR, self.CSR_CYC_MSK | (bit & self.CSR_DAT_MSK) )

		# wait for completion
		while(1):
			stat = self.read_reg(self.R_CSR)
			if not (stat&self.CSR_CYC_MSK):
				break

		# return the data
		return (stat&self.CSR_DAT_MSK)

	def reset(self):

		# request bit write
		self.write_reg( self.R_CSR, self.CSR_CYC_MSK | self.CSR_RST_MSK )

		# wait for completion
		while(1):
			stat = self.read_reg(self.R_CSR)
			if not (stat&self.CSR_CYC_MSK):
				break

		if (stat&self.CSR_DAT_MSK):
			return False
		else:
			return True


	def read_reg(self, reg):
		return self._rd(self.base+reg)

	def write_reg(self, reg, dat):
		return self._wr(self.base+reg, dat)



	def read_bit(self):
		return self.slot(1)

	def write_bit(self, bit):
		written = self.slot(bit)
		
		if written != bit:
			print "Failed One wire write!"
			return -1
		else:
			return 0;

	def read_byte(self):
		ret = 0
		for i in xrange(8):
			ret |= (self.read_bit()<<i)

		return ret

	def write_byte(self, byte):
		ret = 0
		for i in xrange(8):
			ret  |= self.write_bit( byte&0x1 )
			byte = byte>>1

		return ret

	def read_block(self, bnr):
		if bnr > 160:
			print "Too long!"
			return

		ret = [0]*bnr
		for i in xrange(bnr):
			ret[i] = self.read_byte()

		return ret

	def write_block(self, dat):

		if len(dat)> 160:
			print "Too long!"
			return

		for d in dat:
			self.write_byte(d)

	def configure_dividers(self, clk_freq):
		cdr_n = int(clk_freq*(5e-6)-1)
		cdr_o = int(clk_freq*(1e-6)-1)

		reg = (cdr_n&self.CDR_NOR_MSK) | (( cdr_o<<self.CDR_OVD_OFS)&self.CDR_OVD_MSK )
		# print "Onewire divider values: CDR_N: %d, CDR_o:%d."% (cdr_n, cdr_o)
		# print "Writing to register: 0x%x" % reg
		self.write_reg(self.R_CDR, reg)
		
