OSDN Git Service

Copyright year update in most files of the GDB Project.
[pf3gnuchains/pf3gnuchains4x.git] / sim / m68hc11 / dv-m68hc11spi.c
1 /*  dv-m68hc11spi.c -- Simulation of the 68HC11 SPI
2     Copyright (C) 2000, 2002-2003, 2007-2012 Free Software Foundation,
3     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
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
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
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
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
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
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
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
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
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