#!/usr/bin/env python3
#
# Copyright (c) 2019 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
# Author: Sathish Kuttan <sathish.k.kuttan@intel.com>

# This file defines device class that contains functions to
# setup/configure SPI master device and GPIO pins required
# to communicate with the target.
# Member functions are provided to send and receive messages
# over the SPI bus

import yaml
import time
import periphery
import sys
import os

class Device:
    """
    Device class containing the interface methods for communicating
    with the target using SPI bus and GPIOs
    """
    def __init__(self):
        """
        Read config file and determine the SPI device, speed, mode
        GPIO pin assignments, etc.
        Initialize data structures accordingly.
        """
        config_file = os.path.dirname(__file__)
        config_file += '/config.yml'
        with open(config_file, 'r') as ymlfile:
            config = yaml.safe_load(ymlfile)
        self.name = config['general']['name']
        self.spi_device = config['spi']['device']
        self.spi_speed = config['spi']['max_speed']
        self.spi_mode = None
        self.gpio_reset = config['gpio']['reset']
        self.gpio_wake = config['gpio']['wake']
        self.gpio_irq = config['gpio']['irq']
        self.spi = None
        self.reset_pin = None
        self.wake_pin = None
        self.irq_pin = None

    def print_config(self):
        """
        Print configuration information that was read from config file
        """
        print('%s Device on %s' %(self.name, self.spi_device))
        print('Max SPI Frequency: %2.1f MHz' % self.spi_speed)
        print('Reset GPIO: %d' % self.gpio_reset)
        print('Wake GPIO : %d' % self.gpio_wake)
        print('IRQ GPIO  : %d' % self.gpio_irq)

    def configure_device(self, spi_mode, order, bits):
        """
        Configure the SPI device and GPIOs for communication with target
        """
        self.reset_pin = periphery.GPIO(self.gpio_reset, 'out')
        self.wake_pin = periphery.GPIO(self.gpio_wake, 'out')
        self.irq_pin = periphery.GPIO(self.gpio_irq, 'in')
        self.spi = periphery.SPI(self.spi_device, spi_mode,
                self.spi_speed * 1e6)
        self.spi.bit_order = order
        self.spi.bits_per_word = bits
        print('Configured SPI %s for %s.' % (self.spi_device, self.name))
        print('Configured GPIO %d for %s Reset.' % (self.gpio_reset, self.name))
        print('Configured GPIO %d for %s Wake.' % (self.gpio_wake, self.name))
        print('Configured GPIO %d for %s IRQ.' % (self.gpio_irq, self.name))

    def check_device_ready(self):
        """
        Check whether the target is ready to accept a command as follows:
        Wait a minimum time and check whether IRQ is asserted by the target
        If IRQ is not asserted, wait maximum time and check again.
        Device is ready if IRQ is asserted
        """
        min_wait = 0.001 #   1 ms
        max_wait = 0.1 	 # 100 ms
        time.sleep(min_wait)
        ready = self.irq_pin.read()
        if not ready:
            time.sleep(max_wait)
            ready = self.irq_pin.read()
            if not ready:
                print('Error: Device not ready', file=sys.stderr)
        return ready

    def reset_device(self):
        """
        Assert the GPIO and deassert after a short duration to reset
        the target.
        """
        print('Resetting %s ...' % self.name)
        self.reset_pin.write(False)
        time.sleep(0.1)
        self.reset_pin.write(True)
        self.check_device_ready()

    def send_receive(self, data, wait=True):
        """
        Transmit and receive full duplex data over SPI
        If requested to wait, wait for device to become ready
        before return.
        """
        rx_data = self.spi.transfer(data)
        if wait:
            self.check_device_ready()
        return rx_data

    def send_bulk(self, data):
        """
        Send a byte stream of data without checking for device readiness.
        """
        self.spi.transfer(data)

    def close(self):
        """
        Close the device handle
        """
        self.spi.close()
