/*  dv-m68hc11spi.c -- Simulation of the 68HC11 SPI
    Copyright (C) 2000, 2002 Free Software Foundation, Inc.
    Written by Stephane Carrez (stcarrez@worldnet.fr)
    (From a driver model Contributed by Cygnus Solutions.)

    This file is part of the program GDB, the GNU debugger.
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    
    */


#include "sim-main.h"
#include "hw-main.h"
#include "dv-sockser.h"
#include "sim-assert.h"


/* DEVICE

        m68hc11spi - m68hc11 SPI interface

   
   DESCRIPTION

        Implements the m68hc11 Synchronous Serial Peripheral Interface
        described in the m68hc11 user guide (Chapter 8 in pink book).
        The SPI I/O controller is directly connected to the CPU
        interrupt.  The simulator implements:

            - SPI clock emulation
            - Data transfer
            - Write collision detection
    

   PROPERTIES

        None

   
   PORTS

   reset (input)

        Reset port. This port is only used to simulate a reset of the SPI
        I/O controller. It should be connected to the RESET output of the cpu.

   */



/* port ID's */

enum
{
  RESET_PORT
};


static const struct hw_port_descriptor m68hc11spi_ports[] = 
{
  { "reset", RESET_PORT, 0, input_port, },
  { NULL, },
};


/* SPI */
struct m68hc11spi 
{
  /* Information about next character to be transmited.  */
  unsigned char tx_char;
  int           tx_bit;
  unsigned char mode;
  
  unsigned char rx_char;
  unsigned char rx_clear_scsr;
  unsigned char clk_pin;
  
  /* SPI clock rate (twice the real clock).  */
  unsigned int clock;
  
  /* Periodic SPI event.  */
  struct hw_event* spi_event;
};



/* Finish off the partially created hw device.  Attach our local
   callbacks.  Wire up our port names etc */

static hw_io_read_buffer_method m68hc11spi_io_read_buffer;
static hw_io_write_buffer_method m68hc11spi_io_write_buffer;
static hw_port_event_method m68hc11spi_port_event;
static hw_ioctl_method m68hc11spi_ioctl;

#define M6811_SPI_FIRST_REG (M6811_SPCR)
#define M6811_SPI_LAST_REG  (M6811_SPDR)


static void
attach_m68hc11spi_regs (struct hw *me,
                        struct m68hc11spi *controller)
{
  hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,
                     M6811_SPI_FIRST_REG,
                     M6811_SPI_LAST_REG - M6811_SPI_FIRST_REG + 1,
		     me);
}

static void
m68hc11spi_finish (struct hw *me)
{
  struct m68hc11spi *controller;

  controller = HW_ZALLOC (me, struct m68hc11spi);
  set_hw_data (me, controller);
  set_hw_io_read_buffer (me, m68hc11spi_io_read_buffer);
  set_hw_io_write_buffer (me, m68hc11spi_io_write_buffer);
  set_hw_ports (me, m68hc11spi_ports);
  set_hw_port_event (me, m68hc11spi_port_event);
#ifdef set_hw_ioctl
  set_hw_ioctl (me, m68hc11spi_ioctl);
#else
  me->to_ioctl = m68hc11spi_ioctl;
#endif

  /* Attach ourself to our parent bus.  */
  attach_m68hc11spi_regs (me, controller);

  /* Initialize to reset state.  */
  controller->spi_event = NULL;
  controller->rx_clear_scsr = 0;
}



/* An event arrives on an interrupt port */

static void
m68hc11spi_port_event (struct hw *me,
                       int my_port,
                       struct hw *source,
                       int source_port,
                       int level)
{
  SIM_DESC sd;
  struct m68hc11spi *controller;
  sim_cpu* cpu;
  unsigned8 val;
  
  controller = hw_data (me);
  sd         = hw_system (me);
  cpu        = STATE_CPU (sd, 0);  
  switch (my_port)
    {
    case RESET_PORT:
      {
	HW_TRACE ((me, "SPI reset"));

        /* Reset the state of SPI registers.  */
        controller->rx_clear_scsr = 0;
        if (controller->spi_event)
          {
            hw_event_queue_deschedule (me, controller->spi_event);
            controller->spi_event = 0;
          }

        val = 0;
        m68hc11spi_io_write_buffer (me, &val, io_map,
                                    (unsigned_word) M6811_SPCR, 1);
        break;
      }

    default:
      hw_abort (me, "Event on unknown port %d", my_port);
      break;
    }
}

static void
set_bit_port (struct hw *me, sim_cpu *cpu, int port, int mask, int value)
{
  uint8 val;
  
  if (value)
    val = cpu->ios[port] | mask;
  else
    val = cpu->ios[port] & ~mask;

  /* Set the new value and post an event to inform other devices
     that pin 'port' changed.  */
  m68hc11cpu_set_port (me, cpu, port, val);
}


/* When a character is sent/received by the SPI, the PD2..PD5 line
   are driven by the following signals:

	      B7	B6
      -----+---------+--------+---/-+-------
 MOSI      |    |    |   |    |     |
 MISO	   +---------+--------+---/-+
		____      ___
 CLK	_______/    \____/   \__		CPOL=0, CPHA=0
	_______	     ____     __
	       \____/    \___/			CPOL=1, CPHA=0
	   ____	     ____     __
	__/    \____/    \___/			CPOL=0, CPHA=1
	__	____      ___
	  \____/    \____/   \__		CPOL=1, CPHA=1

 SS ___                                 ____
       \__________________________//___/

 MISO = PD2
 MOSI = PD3
 SCK  = PD4
 SS   = PD5

*/

#define SPI_START_BYTE 0
#define SPI_START_BIT  1
#define SPI_MIDDLE_BIT 2

void
m68hc11spi_clock (struct hw *me, void *data)
{
  SIM_DESC sd;
  struct m68hc11spi* controller;
  sim_cpu *cpu;
  int check_interrupt = 0;
  
  controller = hw_data (me);
  sd         = hw_system (me);
  cpu        = STATE_CPU (sd, 0);

  /* Cleanup current event.  */
  if (controller->spi_event)
    {
      hw_event_queue_deschedule (me, controller->spi_event);
      controller->spi_event = 0;
    }

  /* Change a bit of data at each two SPI event.  */
  if (controller->mode == SPI_START_BIT)
    {
      /* Reflect the bit value on bit 2 of port D.  */
      set_bit_port (me, cpu, M6811_PORTD, (1 << 2),
                    (controller->tx_char & (1 << controller->tx_bit)));
      controller->tx_bit--;
      controller->mode = SPI_MIDDLE_BIT;
    }
  else if (controller->mode == SPI_MIDDLE_BIT)
    {
      controller->mode = SPI_START_BIT;
    }

  if (controller->mode == SPI_START_BYTE)
    {
      /* Start a new SPI transfer.  */
      
      /* TBD: clear SS output.  */
      controller->mode = SPI_START_BIT;
      controller->tx_bit = 7;
      set_bit_port (me, cpu, M6811_PORTD, (1 << 4), ~controller->clk_pin);
    }
  else
    {
      /* Change the SPI clock at each event on bit 4 of port D.  */
      controller->clk_pin = ~controller->clk_pin;
      set_bit_port (me, cpu, M6811_PORTD, (1 << 4), controller->clk_pin);
    }
  
  /* Transmit is now complete for this byte.  */
  if (controller->mode == SPI_START_BIT && controller->tx_bit < 0)
    {
      controller->rx_clear_scsr = 0;
      cpu->ios[M6811_SPSR] |= M6811_SPIF;
      if (cpu->ios[M6811_SPCR] & M6811_SPIE)
        check_interrupt = 1;
    }
  else
    {
      controller->spi_event = hw_event_queue_schedule (me, controller->clock,
                                                       m68hc11spi_clock,
                                                       NULL);
    }

  if (check_interrupt)
    interrupts_update_pending (&cpu->cpu_interrupts);
}

/* Flags of the SPCR register.  */
io_reg_desc spcr_desc[] = {
  { M6811_SPIE, "SPIE ", "Serial Peripheral Interrupt Enable" },
  { M6811_SPE,  "SPE  ",  "Serial Peripheral System Enable" },
  { M6811_DWOM, "DWOM ", "Port D Wire-OR mode option" },
  { M6811_MSTR, "MSTR ", "Master Mode Select" },
  { M6811_CPOL, "CPOL ", "Clock Polarity" },
  { M6811_CPHA, "CPHA ", "Clock Phase" },
  { M6811_SPR1, "SPR1 ", "SPI Clock Rate Select" },
  { M6811_SPR0, "SPR0 ", "SPI Clock Rate Select" },
  { 0,  0, 0 }
};


/* Flags of the SPSR register.  */
io_reg_desc spsr_desc[] = {
  { M6811_SPIF,	"SPIF ", "SPI Transfer Complete flag" },
  { M6811_WCOL, "WCOL ", "Write Collision" },
  { M6811_MODF, "MODF ", "Mode Fault" },
  { 0,  0, 0 }
};

static void
m68hc11spi_info (struct hw *me)
{
  SIM_DESC sd;
  uint16 base = 0;
  sim_cpu *cpu;
  struct m68hc11spi *controller;
  uint8 val;
  
  sd = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);
  
  sim_io_printf (sd, "M68HC11 SPI:\n");

  base = cpu_get_io_base (cpu);

  val = cpu->ios[M6811_SPCR];
  print_io_byte (sd, "SPCR", spcr_desc, val, base + M6811_SPCR);
  sim_io_printf (sd, "\n");

  val = cpu->ios[M6811_SPSR];
  print_io_byte (sd, "SPSR", spsr_desc, val, base + M6811_SPSR);
  sim_io_printf (sd, "\n");

  if (controller->spi_event)
    {
      signed64 t;

      sim_io_printf (sd, "  SPI has %d bits to send\n",
                     controller->tx_bit + 1);
      t = hw_event_remain_time (me, controller->spi_event);
      sim_io_printf (sd, "  SPI current bit-cycle finished in %s\n",
		     cycle_to_string (cpu, t));

      t += (controller->tx_bit + 1) * 2 * controller->clock;
      sim_io_printf (sd, "  SPI operation finished in %s\n",
		     cycle_to_string (cpu, t));
    }
}

static int
m68hc11spi_ioctl (struct hw *me,
                  hw_ioctl_request request,
                  va_list ap)
{
  m68hc11spi_info (me);
  return 0;
}

/* generic read/write */

static unsigned
m68hc11spi_io_read_buffer (struct hw *me,
                           void *dest,
                           int space,
                           unsigned_word base,
                           unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11spi *controller;
  sim_cpu *cpu;
  unsigned8 val;
  
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));

  sd  = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);

  switch (base)
    {
    case M6811_SPSR:
      controller->rx_clear_scsr = cpu->ios[M6811_SCSR]
        & (M6811_SPIF | M6811_WCOL | M6811_MODF);
      
    case M6811_SPCR:
      val = cpu->ios[base];
      break;
      
    case M6811_SPDR:
      if (controller->rx_clear_scsr)
        {
          cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
          controller->rx_clear_scsr = 0;
          interrupts_update_pending (&cpu->cpu_interrupts);
        }
      val = controller->rx_char;
      break;
      
    default:
      return 0;
    }
  *((unsigned8*) dest) = val;
  return 1;
}

static unsigned
m68hc11spi_io_write_buffer (struct hw *me,
                            const void *source,
                            int space,
                            unsigned_word base,
                            unsigned nr_bytes)
{
  SIM_DESC sd;
  struct m68hc11spi *controller;
  sim_cpu *cpu;
  unsigned8 val;

  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));

  sd  = hw_system (me);
  cpu = STATE_CPU (sd, 0);
  controller = hw_data (me);
  
  val = *((const unsigned8*) source);
  switch (base)
    {
    case M6811_SPCR:
      cpu->ios[M6811_SPCR] = val;

      /* The SPI clock rate is 2, 4, 16, 32 of the internal CPU clock.
         We have to drive the clock pin and need a 2x faster clock.  */
      switch (val & (M6811_SPR1 | M6811_SPR0))
        {
        case 0:
          controller->clock = 1;
          break;

        case 1:
          controller->clock = 2;
          break;

        case 2:
          controller->clock = 8;
          break;

        default:
          controller->clock = 16;
          break;
        }

      /* Set the clock pin.  */
      if ((val & M6811_CPOL)
          && (controller->spi_event == 0
              || ((val & M6811_CPHA) && controller->mode == 1)))
        controller->clk_pin = 1;
      else
        controller->clk_pin = 0;

      set_bit_port (me, cpu, M6811_PORTD, (1 << 4), controller->clk_pin);
      break;
      
      /* Can't write to SPSR.  */
    case M6811_SPSR:
      break;
      
    case M6811_SPDR:
      if (!(cpu->ios[M6811_SPCR] & M6811_SPE))
        {
          return 0;
        }

      if (controller->rx_clear_scsr)
        {
          cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
          controller->rx_clear_scsr = 0;
          interrupts_update_pending (&cpu->cpu_interrupts);
        }

      /* If transfer is taking place, a write to SPDR
         generates a collision.  */
      if (controller->spi_event)
        {
          cpu->ios[M6811_SPSR] |= M6811_WCOL;
          break;
        }

      /* Refuse the write if there was no read of SPSR.  */
      /* ???? TBD. */

      /* Prepare to send a byte.  */
      controller->tx_char = val;
      controller->mode   = SPI_START_BYTE;

      /* Toggle clock pin internal value when CPHA is 0 so that
         it will really change in the middle of a bit.  */
      if (!(cpu->ios[M6811_SPCR] & M6811_CPHA))
        controller->clk_pin = ~controller->clk_pin;

      cpu->ios[M6811_SPDR] = val;

      /* Activate transmission.  */
      m68hc11spi_clock (me, NULL);
      break;

    default:
      return 0;
    }
  return nr_bytes;
}     


const struct hw_descriptor dv_m68hc11spi_descriptor[] = {
  { "m68hc11spi", m68hc11spi_finish },
  { "m68hc12spi", m68hc11spi_finish },
  { NULL },
};

