'''
Copyright 2021 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
ASTRON Netherlands Institute for Radio Astronomy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

I2C_serial_Pi
Started by Gijs

Class for using the I2C bus of the I2C. This class is used for the
basic I2C scripts to read and write the RCU2, PCC etc.

'''
import smbus2
import sys
from time import *

DEBUG = False #True
SLOW = False


class I2C:

    def __init__(self, ADDRESS='040',BUSNR=3):
        self.I2C_Address = ADDRESS
        self.bus_nr = BUSNR

    def close(self):
        bus = smbus2.SMBus(self.bus_nr)
        bus.close()
        return True

    def open(self):
        bus = smbus2.SMBus(self.bus_nr)
        bus.open(self.bus_nr)
        return True

    def read_bytes(self, register, bytes_to_read=2):
        bus = smbus2.SMBus(self.bus_nr)
        try:
            rd_value = bus.read_i2c_block_data(self.I2C_Address, register, bytes_to_read)
            ret_value = ''
            for cnt in range(bytes_to_read):
                ret_value += (hex(rd_value[cnt])[2:])
            ret_ack = 1
            if SLOW:
                sleep(0.2)
        except IOError:
            ret_ack = 0
            ret_value = 'ffff'
            if DEBUG:
                print("Reading IO-error")
        return ret_ack, ret_value

    
    def read_last_reg(self, bytes_to_read):
        bus = smbus2.SMBus(self.bus_nr)
        rd_value = []
        ret_value = ''
        for cnt in range(bytes_to_read):
            try:
                rd_value.append(bus.read_byte(self.I2C_Address))
                ret_ack = 1
                if SLOW:
                    sleep(0.2)
            except IOError:
                ret_ack = 0
                rd_value.append(0)
                if DEBUG:
                    print("IO-Reading error")
        for cnt in range(bytes_to_read):
            ret_value += (hex(rd_value[cnt])[2:])
        return ret_ack,ret_value
  
    def write_bytes(self, register, data):
        bus = smbus2.SMBus(self.bus_nr)
        if type(data) is not list:
            data = [data]
        try:
            bus.write_i2c_block_data(self.I2C_Address, register, data)
            ret_ack = 1
            if SLOW:
                sleep(0.3)
        except IOError:
            ret_ack = 0
            ret_value = 0
            if DEBUG:
                print("Write IO-error")
        return ret_ack

    def write_register(self, register):
        bus = smbus2.SMBus(self.bus_nr)
        try:
            bus.write_byte(self.I2C_Address, register)
#            print(f"Wrote {register:x}")
            ret_ack = 1
            if SLOW:
                sleep(0.3)
        except IOError:
            ret_ack = 0
            ret_value = 0
#            if DEBUG:
            print("Write IO-error")
        return ret_ack

    def write_pointer(self, register):
        bus = smbus2.SMBus(self.bus_nr)
        try:
            ret_value = bus.read_i2c_block_data(self.I2C_Address, register, 1)
            ret_ack = 1
            if SLOW:
                sleep(0.3)
        except IOError:
            ret_ack = 0
            ret_value = 0
            if DEBUG:
                print("Write IO-error")
        return ret_ack

    def ack_check(self):
        bus = smbus2.SMBus(self.bus_nr)
        try:
            print("check ACK")
            ret_value = bus.write_quick(self.I2C_Address)
            ret_ack = 1
            if SLOW:
                sleep(0.3)
        except IOError:
            ret_ack = 0
            ret_value = 0
            if DEBUG:
                print("No ACK IO-Error")
        return ret_ack

if __name__ == "__main__":
    I2C_Device = I2C(0x40)
    I2C_Device.write_bytes(0x00, 0x00)
    ret_ack, ret_value = I2C_Device.read_bytes(0x8C, 2)
    print(ret_value)