1 /*  dv-m68hc11spi.c -- Simulation of the 68HC11 SPI
2     Copyright (C) 2000, 2002, 2003, 2007, 2008, 2009, 2010, 2011
3     Free Software Foundation, Inc.
4     Written by Stephane Carrez (stcarrez@nerim.fr)
5     (From a driver model Contributed by Cygnus Solutions.)
6 
7     This file is part of the program GDB, the GNU debugger.
8 
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 3 of the License, or
12     (at your option) any later version.
13 
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 
22     */
23 
24 
25 #include "sim-main.h"
26 #include "hw-main.h"
27 #include "dv-sockser.h"
28 #include "sim-assert.h"
29 
30 
31 /* DEVICE
32 
33         m68hc11spi - m68hc11 SPI interface
34 
35 
36    DESCRIPTION
37 
38         Implements the m68hc11 Synchronous Serial Peripheral Interface
39         described in the m68hc11 user guide (Chapter 8 in pink book).
40         The SPI I/O controller is directly connected to the CPU
41         interrupt.  The simulator implements:
42 
43             - SPI clock emulation
44             - Data transfer
45             - Write collision detection
46 
47 
48    PROPERTIES
49 
50         None
51 
52 
53    PORTS
54 
55    reset (input)
56 
57         Reset port. This port is only used to simulate a reset of the SPI
58         I/O controller. It should be connected to the RESET output of the cpu.
59 
60    */
61 
62 
63 
64 /* port ID's */
65 
66 enum
67 {
68   RESET_PORT
69 };
70 
71 
72 static const struct hw_port_descriptor m68hc11spi_ports[] =
73 {
74   { "reset", RESET_PORT, 0, input_port, },
75   { NULL, },
76 };
77 
78 
79 /* SPI */
80 struct m68hc11spi
81 {
82   /* Information about next character to be transmited.  */
83   unsigned char tx_char;
84   int           tx_bit;
85   unsigned char mode;
86 
87   unsigned char rx_char;
88   unsigned char rx_clear_scsr;
89   unsigned char clk_pin;
90 
91   /* SPI clock rate (twice the real clock).  */
92   unsigned int clock;
93 
94   /* Periodic SPI event.  */
95   struct hw_event* spi_event;
96 };
97 
98 
99 
100 /* Finish off the partially created hw device.  Attach our local
101    callbacks.  Wire up our port names etc */
102 
103 static hw_io_read_buffer_method m68hc11spi_io_read_buffer;
104 static hw_io_write_buffer_method m68hc11spi_io_write_buffer;
105 static hw_port_event_method m68hc11spi_port_event;
106 static hw_ioctl_method m68hc11spi_ioctl;
107 
108 #define M6811_SPI_FIRST_REG (M6811_SPCR)
109 #define M6811_SPI_LAST_REG  (M6811_SPDR)
110 
111 
112 static void
attach_m68hc11spi_regs(struct hw * me,struct m68hc11spi * controller)113 attach_m68hc11spi_regs (struct hw *me,
114                         struct m68hc11spi *controller)
115 {
116   hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,
117                      M6811_SPI_FIRST_REG,
118                      M6811_SPI_LAST_REG - M6811_SPI_FIRST_REG + 1,
119 		     me);
120 }
121 
122 static void
m68hc11spi_finish(struct hw * me)123 m68hc11spi_finish (struct hw *me)
124 {
125   struct m68hc11spi *controller;
126 
127   controller = HW_ZALLOC (me, struct m68hc11spi);
128   set_hw_data (me, controller);
129   set_hw_io_read_buffer (me, m68hc11spi_io_read_buffer);
130   set_hw_io_write_buffer (me, m68hc11spi_io_write_buffer);
131   set_hw_ports (me, m68hc11spi_ports);
132   set_hw_port_event (me, m68hc11spi_port_event);
133 #ifdef set_hw_ioctl
134   set_hw_ioctl (me, m68hc11spi_ioctl);
135 #else
136   me->to_ioctl = m68hc11spi_ioctl;
137 #endif
138 
139   /* Attach ourself to our parent bus.  */
140   attach_m68hc11spi_regs (me, controller);
141 
142   /* Initialize to reset state.  */
143   controller->spi_event = NULL;
144   controller->rx_clear_scsr = 0;
145 }
146 
147 
148 
149 /* An event arrives on an interrupt port */
150 
151 static void
m68hc11spi_port_event(struct hw * me,int my_port,struct hw * source,int source_port,int level)152 m68hc11spi_port_event (struct hw *me,
153                        int my_port,
154                        struct hw *source,
155                        int source_port,
156                        int level)
157 {
158   SIM_DESC sd;
159   struct m68hc11spi *controller;
160   sim_cpu* cpu;
161   unsigned8 val;
162 
163   controller = hw_data (me);
164   sd         = hw_system (me);
165   cpu        = STATE_CPU (sd, 0);
166   switch (my_port)
167     {
168     case RESET_PORT:
169       {
170 	HW_TRACE ((me, "SPI reset"));
171 
172         /* Reset the state of SPI registers.  */
173         controller->rx_clear_scsr = 0;
174         if (controller->spi_event)
175           {
176             hw_event_queue_deschedule (me, controller->spi_event);
177             controller->spi_event = 0;
178           }
179 
180         val = 0;
181         m68hc11spi_io_write_buffer (me, &val, io_map,
182                                     (unsigned_word) M6811_SPCR, 1);
183         break;
184       }
185 
186     default:
187       hw_abort (me, "Event on unknown port %d", my_port);
188       break;
189     }
190 }
191 
192 static void
set_bit_port(struct hw * me,sim_cpu * cpu,int port,int mask,int value)193 set_bit_port (struct hw *me, sim_cpu *cpu, int port, int mask, int value)
194 {
195   uint8 val;
196 
197   if (value)
198     val = cpu->ios[port] | mask;
199   else
200     val = cpu->ios[port] & ~mask;
201 
202   /* Set the new value and post an event to inform other devices
203      that pin 'port' changed.  */
204   m68hc11cpu_set_port (me, cpu, port, val);
205 }
206 
207 
208 /* When a character is sent/received by the SPI, the PD2..PD5 line
209    are driven by the following signals:
210 
211 	      B7	B6
212       -----+---------+--------+---/-+-------
213  MOSI      |    |    |   |    |     |
214  MISO	   +---------+--------+---/-+
215 		____      ___
216  CLK	_______/    \____/   \__		CPOL=0, CPHA=0
217 	_______	     ____     __
218 	       \____/    \___/			CPOL=1, CPHA=0
219 	   ____	     ____     __
220 	__/    \____/    \___/			CPOL=0, CPHA=1
221 	__	____      ___
222 	  \____/    \____/   \__		CPOL=1, CPHA=1
223 
224  SS ___                                 ____
225        \__________________________//___/
226 
227  MISO = PD2
228  MOSI = PD3
229  SCK  = PD4
230  SS   = PD5
231 
232 */
233 
234 #define SPI_START_BYTE 0
235 #define SPI_START_BIT  1
236 #define SPI_MIDDLE_BIT 2
237 
238 void
m68hc11spi_clock(struct hw * me,void * data)239 m68hc11spi_clock (struct hw *me, void *data)
240 {
241   SIM_DESC sd;
242   struct m68hc11spi* controller;
243   sim_cpu *cpu;
244   int check_interrupt = 0;
245 
246   controller = hw_data (me);
247   sd         = hw_system (me);
248   cpu        = STATE_CPU (sd, 0);
249 
250   /* Cleanup current event.  */
251   if (controller->spi_event)
252     {
253       hw_event_queue_deschedule (me, controller->spi_event);
254       controller->spi_event = 0;
255     }
256 
257   /* Change a bit of data at each two SPI event.  */
258   if (controller->mode == SPI_START_BIT)
259     {
260       /* Reflect the bit value on bit 2 of port D.  */
261       set_bit_port (me, cpu, M6811_PORTD, (1 << 2),
262                     (controller->tx_char & (1 << controller->tx_bit)));
263       controller->tx_bit--;
264       controller->mode = SPI_MIDDLE_BIT;
265     }
266   else if (controller->mode == SPI_MIDDLE_BIT)
267     {
268       controller->mode = SPI_START_BIT;
269     }
270 
271   if (controller->mode == SPI_START_BYTE)
272     {
273       /* Start a new SPI transfer.  */
274 
275       /* TBD: clear SS output.  */
276       controller->mode = SPI_START_BIT;
277       controller->tx_bit = 7;
278       set_bit_port (me, cpu, M6811_PORTD, (1 << 4), ~controller->clk_pin);
279     }
280   else
281     {
282       /* Change the SPI clock at each event on bit 4 of port D.  */
283       controller->clk_pin = ~controller->clk_pin;
284       set_bit_port (me, cpu, M6811_PORTD, (1 << 4), controller->clk_pin);
285     }
286 
287   /* Transmit is now complete for this byte.  */
288   if (controller->mode == SPI_START_BIT && controller->tx_bit < 0)
289     {
290       controller->rx_clear_scsr = 0;
291       cpu->ios[M6811_SPSR] |= M6811_SPIF;
292       if (cpu->ios[M6811_SPCR] & M6811_SPIE)
293         check_interrupt = 1;
294     }
295   else
296     {
297       controller->spi_event = hw_event_queue_schedule (me, controller->clock,
298                                                        m68hc11spi_clock,
299                                                        NULL);
300     }
301 
302   if (check_interrupt)
303     interrupts_update_pending (&cpu->cpu_interrupts);
304 }
305 
306 /* Flags of the SPCR register.  */
307 io_reg_desc spcr_desc[] = {
308   { M6811_SPIE, "SPIE ", "Serial Peripheral Interrupt Enable" },
309   { M6811_SPE,  "SPE  ",  "Serial Peripheral System Enable" },
310   { M6811_DWOM, "DWOM ", "Port D Wire-OR mode option" },
311   { M6811_MSTR, "MSTR ", "Master Mode Select" },
312   { M6811_CPOL, "CPOL ", "Clock Polarity" },
313   { M6811_CPHA, "CPHA ", "Clock Phase" },
314   { M6811_SPR1, "SPR1 ", "SPI Clock Rate Select" },
315   { M6811_SPR0, "SPR0 ", "SPI Clock Rate Select" },
316   { 0,  0, 0 }
317 };
318 
319 
320 /* Flags of the SPSR register.  */
321 io_reg_desc spsr_desc[] = {
322   { M6811_SPIF,	"SPIF ", "SPI Transfer Complete flag" },
323   { M6811_WCOL, "WCOL ", "Write Collision" },
324   { M6811_MODF, "MODF ", "Mode Fault" },
325   { 0,  0, 0 }
326 };
327 
328 static void
m68hc11spi_info(struct hw * me)329 m68hc11spi_info (struct hw *me)
330 {
331   SIM_DESC sd;
332   uint16 base = 0;
333   sim_cpu *cpu;
334   struct m68hc11spi *controller;
335   uint8 val;
336 
337   sd = hw_system (me);
338   cpu = STATE_CPU (sd, 0);
339   controller = hw_data (me);
340 
341   sim_io_printf (sd, "M68HC11 SPI:\n");
342 
343   base = cpu_get_io_base (cpu);
344 
345   val = cpu->ios[M6811_SPCR];
346   print_io_byte (sd, "SPCR", spcr_desc, val, base + M6811_SPCR);
347   sim_io_printf (sd, "\n");
348 
349   val = cpu->ios[M6811_SPSR];
350   print_io_byte (sd, "SPSR", spsr_desc, val, base + M6811_SPSR);
351   sim_io_printf (sd, "\n");
352 
353   if (controller->spi_event)
354     {
355       signed64 t;
356 
357       sim_io_printf (sd, "  SPI has %d bits to send\n",
358                      controller->tx_bit + 1);
359       t = hw_event_remain_time (me, controller->spi_event);
360       sim_io_printf (sd, "  SPI current bit-cycle finished in %s\n",
361 		     cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE));
362 
363       t += (controller->tx_bit + 1) * 2 * controller->clock;
364       sim_io_printf (sd, "  SPI operation finished in %s\n",
365 		     cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE));
366     }
367 }
368 
369 static int
m68hc11spi_ioctl(struct hw * me,hw_ioctl_request request,va_list ap)370 m68hc11spi_ioctl (struct hw *me,
371                   hw_ioctl_request request,
372                   va_list ap)
373 {
374   m68hc11spi_info (me);
375   return 0;
376 }
377 
378 /* generic read/write */
379 
380 static unsigned
m68hc11spi_io_read_buffer(struct hw * me,void * dest,int space,unsigned_word base,unsigned nr_bytes)381 m68hc11spi_io_read_buffer (struct hw *me,
382                            void *dest,
383                            int space,
384                            unsigned_word base,
385                            unsigned nr_bytes)
386 {
387   SIM_DESC sd;
388   struct m68hc11spi *controller;
389   sim_cpu *cpu;
390   unsigned8 val;
391 
392   HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
393 
394   sd  = hw_system (me);
395   cpu = STATE_CPU (sd, 0);
396   controller = hw_data (me);
397 
398   switch (base)
399     {
400     case M6811_SPSR:
401       controller->rx_clear_scsr = cpu->ios[M6811_SCSR]
402         & (M6811_SPIF | M6811_WCOL | M6811_MODF);
403 
404     case M6811_SPCR:
405       val = cpu->ios[base];
406       break;
407 
408     case M6811_SPDR:
409       if (controller->rx_clear_scsr)
410         {
411           cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
412           controller->rx_clear_scsr = 0;
413           interrupts_update_pending (&cpu->cpu_interrupts);
414         }
415       val = controller->rx_char;
416       break;
417 
418     default:
419       return 0;
420     }
421   *((unsigned8*) dest) = val;
422   return 1;
423 }
424 
425 static unsigned
m68hc11spi_io_write_buffer(struct hw * me,const void * source,int space,unsigned_word base,unsigned nr_bytes)426 m68hc11spi_io_write_buffer (struct hw *me,
427                             const void *source,
428                             int space,
429                             unsigned_word base,
430                             unsigned nr_bytes)
431 {
432   SIM_DESC sd;
433   struct m68hc11spi *controller;
434   sim_cpu *cpu;
435   unsigned8 val;
436 
437   HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
438 
439   sd  = hw_system (me);
440   cpu = STATE_CPU (sd, 0);
441   controller = hw_data (me);
442 
443   val = *((const unsigned8*) source);
444   switch (base)
445     {
446     case M6811_SPCR:
447       cpu->ios[M6811_SPCR] = val;
448 
449       /* The SPI clock rate is 2, 4, 16, 32 of the internal CPU clock.
450          We have to drive the clock pin and need a 2x faster clock.  */
451       switch (val & (M6811_SPR1 | M6811_SPR0))
452         {
453         case 0:
454           controller->clock = 1;
455           break;
456 
457         case 1:
458           controller->clock = 2;
459           break;
460 
461         case 2:
462           controller->clock = 8;
463           break;
464 
465         default:
466           controller->clock = 16;
467           break;
468         }
469 
470       /* Set the clock pin.  */
471       if ((val & M6811_CPOL)
472           && (controller->spi_event == 0
473               || ((val & M6811_CPHA) && controller->mode == 1)))
474         controller->clk_pin = 1;
475       else
476         controller->clk_pin = 0;
477 
478       set_bit_port (me, cpu, M6811_PORTD, (1 << 4), controller->clk_pin);
479       break;
480 
481       /* Can't write to SPSR.  */
482     case M6811_SPSR:
483       break;
484 
485     case M6811_SPDR:
486       if (!(cpu->ios[M6811_SPCR] & M6811_SPE))
487         {
488           return 0;
489         }
490 
491       if (controller->rx_clear_scsr)
492         {
493           cpu->ios[M6811_SPSR] &= ~controller->rx_clear_scsr;
494           controller->rx_clear_scsr = 0;
495           interrupts_update_pending (&cpu->cpu_interrupts);
496         }
497 
498       /* If transfer is taking place, a write to SPDR
499          generates a collision.  */
500       if (controller->spi_event)
501         {
502           cpu->ios[M6811_SPSR] |= M6811_WCOL;
503           break;
504         }
505 
506       /* Refuse the write if there was no read of SPSR.  */
507       /* ???? TBD. */
508 
509       /* Prepare to send a byte.  */
510       controller->tx_char = val;
511       controller->mode   = SPI_START_BYTE;
512 
513       /* Toggle clock pin internal value when CPHA is 0 so that
514          it will really change in the middle of a bit.  */
515       if (!(cpu->ios[M6811_SPCR] & M6811_CPHA))
516         controller->clk_pin = ~controller->clk_pin;
517 
518       cpu->ios[M6811_SPDR] = val;
519 
520       /* Activate transmission.  */
521       m68hc11spi_clock (me, NULL);
522       break;
523 
524     default:
525       return 0;
526     }
527   return nr_bytes;
528 }
529 
530 
531 const struct hw_descriptor dv_m68hc11spi_descriptor[] = {
532   { "m68hc11spi", m68hc11spi_finish },
533   { "m68hc12spi", m68hc11spi_finish },
534   { NULL },
535 };
536 
537