#!   /usr/bin/env   python
#    coding: utf8

# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org

import sys
import rr
import time
import os
import re
from ctypes import *

from ptsexcept import *

from cp210x import usb, valuefile, cp210x
from cp210x.eeprom import EEPROM


"""
cp210x_eeprom: Access to USB-UART bridge CP2103 EEPROM

Note: The EEPROM is used to store calibration data (reference voltage output for
      the three ranges). The data are stores as a string in the "Product String".
      Format: "4.09551500 0.40967800 0.04096060"

"""


CALIBR_RANGES = ['10V', '1V', '100mV']

class CP210xEepromOperationError(Exception):
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return ("CP210x EEPROM: %s" %(self.msg))

class CCP210x_Eeprom:

    def __init__(self, vid, pid):
        usb.init()
        usb_patterns = []
        vid = int(vid, 16)
        pid = int(pid, 16)
        usb_patterns.append(dict(idVendor=vid, idProduct=pid))
        self.dev = [item for item in cp210x.Cp210xProgrammer.list_devices(usb_patterns)]
        self.dev = self.dev[0]


    def get_calibr_data(self):
        self.dev.open()
        try:
            eeprom = EEPROM(self.dev)
        except:
            raise CP210xEepromOperationError('Cannot open device.')
        finally:
            self.dev.close()
        eeprom_value = eeprom.get_values()
        product_string = eeprom_value['product_string']
        #print "Product string: \"%s\"" % product_string
        calibr_string_list = product_string.split(' ')
        if len(calibr_string_list) != 3:
            raise CP210xEepromOperationError('Product string has the wrong format.')
        calibr_data = {}
        for i in range(len(calibr_string_list)):
            pattern = r'\b[0-9]\.[0-9]{8}\b'
            if re.search(pattern, calibr_string_list[i]):
                calibr_data[CALIBR_RANGES[i]] = calibr_string_list[i]
            else:
                raise CP210xEepromOperationError('Product string has the wrong format.')

        return calibr_data


    def set_calibr_data(self, data):
        self.dev.open()
        product_string = data[CALIBR_RANGES[0]] + ' ' + data[CALIBR_RANGES[1]] + ' ' + data[CALIBR_RANGES[2]]
        #print "New product string value: \"%s\"" % product_string
        try:
            self.dev.set_product_string(product_string)
            print "Calibration data written to cp210x EEPROM."
        finally:
            self.dev.close()

