1 /*
2 Copyright (C) 1998,1999 Scott Dattalo
3 Copyright (C) 2014 Roy R. Rankin
4
5 This file is part of the libgpsim library of gpsim
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, see
19 <http://www.gnu.org/licenses/lgpl-2.1.html>.
20 */
21
22 #include <stdio.h>
23 #include <iostream>
24
25 #include "../config.h"
26
27 #include "uart.h"
28 #include <assert.h> // for assert
29 #include "pir.h" // for PIR
30 #include "processor.h" // for Processor
31 #include "stimuli.h" // for IOPIN, SignalSink
32 #include "trace.h" // for Trace, trace
33
34 #define p_cpu ((Processor *)cpu)
35
36
37 // defining EUSART_PIN causes TX pin direction to be set for EUSART devices
38 #define EUSART_PIN
39 //#define DEBUG
40 #if defined(DEBUG)
41 #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; }
42 #else
43 #define Dprintf(arg) {}
44 #endif
45
46 //--------------------------------------------------
47 //
48 //--------------------------------------------------
49 // Drive output for TX pin
50 class TXSignalSource : public SignalControl
51 {
52 public:
TXSignalSource(_TXSTA * _txsta)53 explicit TXSignalSource(_TXSTA *_txsta)
54 : m_txsta(_txsta)
55 {
56 assert(m_txsta);
57 }
~TXSignalSource()58 ~TXSignalSource() { }
getState()59 virtual char getState()
60 {
61 return m_txsta->getState();
62 }
release()63 virtual void release()
64 {
65 m_txsta->releasePin();
66 }
67 private:
68 _TXSTA *m_txsta;
69 };
70
71 // Set TX pin to output
72 class TXSignalControl : public SignalControl
73 {
74 public:
TXSignalControl(_TXSTA * _txsta)75 explicit TXSignalControl(_TXSTA *_txsta)
76 : m_txsta(_txsta)
77 { }
~TXSignalControl()78 ~TXSignalControl() { }
getState()79 virtual char getState() { return '0'; }
release()80 virtual void release()
81 {
82 m_txsta->releasePin();
83 }
84 private:
85 _TXSTA *m_txsta;
86 };
87
88 // set Synchronous DT pin direction
89 class RCSignalControl : public SignalControl
90 {
91 public:
RCSignalControl(_RCSTA * _rcsta)92 explicit RCSignalControl(_RCSTA *_rcsta)
93 : m_rcsta(_rcsta)
94 { }
~RCSignalControl()95 ~RCSignalControl() { }
getState()96 virtual char getState() { return '0'; }
97 //virtual char getState() { return m_rcsta->getDir(); }
release()98 virtual void release()
99 {
100 m_rcsta->releasePin();
101 }
102 private:
103 _RCSTA *m_rcsta;
104 };
105
106 // Drive date of DT pin when transmitting
107 class RCSignalSource : public SignalControl
108 {
109 public:
RCSignalSource(_RCSTA * _rcsta)110 explicit RCSignalSource(_RCSTA *_rcsta)
111 : m_rcsta(_rcsta)
112 {
113 assert(m_rcsta);
114 }
~RCSignalSource()115 ~RCSignalSource() { }
getState()116 virtual char getState()
117 {
118 return m_rcsta->getState();
119 }
release()120 virtual void release()
121 {
122 m_rcsta->releasePin();
123 }
124 private:
125 _RCSTA *m_rcsta;
126 };
127
128 //--------------------------------------------------
129 //
130 //--------------------------------------------------
131
132 // Report state changes on incoming RX pin
133 class RXSignalSink : public SignalSink
134 {
135 public:
RXSignalSink(_RCSTA * _rcsta)136 explicit RXSignalSink(_RCSTA *_rcsta)
137 : m_rcsta(_rcsta)
138 {
139 assert(_rcsta);
140 }
141
setSinkState(char new3State)142 virtual void setSinkState(char new3State) { m_rcsta->setState(new3State); }
release()143 virtual void release() {delete this; }
144 private:
145 _RCSTA *m_rcsta;
146 };
147
148 //--------------------------------------------------
149 //
150 //--------------------------------------------------
151
152 // Report state changes on incoming Clock pin for Synchronous slave mode
153 class CLKSignalSink : public SignalSink
154 {
155 public:
CLKSignalSink(_RCSTA * _rcsta)156 explicit CLKSignalSink(_RCSTA *_rcsta)
157 : m_rcsta(_rcsta)
158 {
159 assert(_rcsta);
160 }
161
setSinkState(char new3State)162 virtual void setSinkState(char new3State) { m_rcsta->clock_edge(new3State); }
163 // virtual void release() { delete this; }
release()164 virtual void release() {delete this; }
165 private:
166 _RCSTA *m_rcsta;
167 };
168
169 //-----------------------------------------------------------
_RCSTA(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)170 _RCSTA::_RCSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
171 : sfr_register(pCpu, pName, pDesc),
172 rcreg(0), spbrg(0),
173 txsta(0), txreg(nullptr), sync_next_clock_edge_high(false),
174 rsr(0), bit_count(0), rx_bit(0), sample(0),
175 state(_RCSTA::RCSTA_DISABLED), sample_state(0),
176 future_cycle(0), last_cycle(0),
177 mUSART(pUSART),
178 m_PinModule(0), m_sink(0), m_cRxState('?'),
179 SourceActive(false), m_control(0), m_source(0), m_cTxState('\0'),
180 m_DTdirection('0'), bInvertPin(false),
181 old_clock_state(true)
182 {
183 assert(mUSART);
184 }
185
~_RCSTA()186 _RCSTA::~_RCSTA()
187 {
188 if (SourceActive && m_PinModule)
189 {
190 m_PinModule->setSource(0);
191 m_PinModule->setControl(0);
192 }
193
194 delete m_source;
195 delete m_control;
196 }
197
198 //-----------------------------------------------------------
_TXSTA(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)199 _TXSTA::_TXSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
200 : sfr_register(pCpu, pName, pDesc), txreg(0), spbrg(0),
201 rcsta(nullptr), tsr(0), bit_count(0),
202 mUSART(pUSART),
203 m_PinModule(0),
204 m_source(0),
205 m_control(0),
206 m_clkSink(0),
207 SourceActive(false),
208 m_cTxState('?'),
209 bInvertPin(false)
210 {
211 assert(mUSART);
212 }
213
~_TXSTA()214 _TXSTA::~_TXSTA()
215 {
216 if (SourceActive && m_PinModule)
217 {
218 m_PinModule->setSource(0);
219 m_PinModule->setControl(0);
220 }
221
222 delete m_source;
223 delete m_control;
224 }
225
226 //-----------------------------------------------------------
_RCREG(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)227 _RCREG::_RCREG(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
228 : sfr_register(pCpu, pName, pDesc),
229 oldest_value(0), fifo_sp(0), mUSART(pUSART), m_rcsta(0)
230 {
231 assert(mUSART);
232 }
233
_TXREG(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)234 _TXREG::_TXREG(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
235 : sfr_register(pCpu, pName, pDesc), m_txsta(0), m_rcsta(nullptr),
236 mUSART(pUSART), full(false)
237 {
238 assert(mUSART);
239 }
240
241
_BAUDCON(Processor * pCpu,const char * pName,const char * pDesc)242 _BAUDCON::_BAUDCON(Processor *pCpu, const char *pName, const char *pDesc)
243 : sfr_register(pCpu, pName, pDesc),
244 txsta(nullptr), rcsta(nullptr)
245 {
246 }
247
_SPBRG(Processor * pCpu,const char * pName,const char * pDesc)248 _SPBRG::_SPBRG(Processor *pCpu, const char *pName, const char *pDesc)
249 : sfr_register(pCpu, pName, pDesc),
250 txsta(0), rcsta(0), brgh(0), baudcon(0), start_cycle(0), last_cycle(0),
251 future_cycle(0), running(false), skip(0)
252 {
253 }
254
255
_SPBRGH(Processor * pCpu,const char * pName,const char * pDesc)256 _SPBRGH::_SPBRGH(Processor *pCpu, const char *pName, const char *pDesc)
257 : sfr_register(pCpu, pName, pDesc), m_spbrg(0)
258 {
259 }
260
261 //-----------------------------------------------------------
262 // TXREG - USART Transmit Register
263 //
264 // writing to this register causes the PIR1::TXIF bit to clear.
265 // my reading of the spec is this happens at the end of the next pic
266 // instruction. If the shift register is empty the bit will then be set
267 // one pic instruction later. Otherwise the bit is set when the shift
268 // register empties. RRR 10/2014
269
270
put(unsigned int new_value)271 void _TXREG::put(unsigned int new_value)
272 {
273
274 trace.raw(write_trace.get() | value.get());
275 value.put(new_value & 0xff);
276
277 Dprintf(("txreg just got a new value:0x%x\n",new_value));
278 assert(m_txsta);
279 assert(m_rcsta);
280
281 // The transmit register has data,
282 // so clear the TXIF flag
283
284 full = true;
285 get_cycles().set_break(get_cycles().get() + 1, this);
286
287 if(m_txsta->bTRMT() && m_txsta->bTXEN())
288 {
289 // If the transmit buffer is empty and the transmitter is enabled
290 // then transmit this new data now...
291
292 get_cycles().set_break(get_cycles().get() + 2, this);
293 if (m_txsta->bSYNC())
294 m_rcsta->sync_start_transmitting();
295 else
296 m_txsta->start_transmitting();
297 }
298 else if(m_txsta->bTRMT() && m_txsta->bSYNC())
299 {
300 m_txsta->value.put(m_txsta->value.get() & ~ _TXSTA::TRMT);
301 }
302
303 }
304
put_value(unsigned int new_value)305 void _TXREG::put_value(unsigned int new_value)
306 {
307 put(new_value);
308
309 update();
310 }
311
callback()312 void _TXREG::callback()
313 {
314 Dprintf(("TXREG callback - time:%" PRINTF_GINT64_MODIFIER "x full %d\n",get_cycles().get(), full));
315 if (full)
316 {
317 mUSART->full();
318 full = false;
319 }
320 else
321 {
322 mUSART->emptyTX();
323 }
324 }
callback_print()325 void _TXREG::callback_print()
326 {
327 std::cout << "TXREG " << name() << " CallBack ID " << CallBackID << '\n';
328 }
329 //-----------------------------------------------------------
330 // TXSTA - setIOpin - assign the I/O pin associated with the
331 // the transmitter.
332
333
setIOpin(PinModule * newPinModule)334 void _TXSTA::setIOpin(PinModule *newPinModule)
335 {
336 if (!m_source)
337 {
338 m_source = new TXSignalSource(this);
339 m_control = new TXSignalControl(this);
340 }
341 else if (m_PinModule) // disconnect old pin
342 {
343 disableTXPin();
344 }
345
346 m_PinModule = newPinModule;
347 if (bTXEN() && rcsta->bSPEN())
348 {
349 enableTXPin();
350 }
351 }
352
disableTXPin()353 void _TXSTA::disableTXPin()
354 {
355 if (m_PinModule)
356 {
357 m_PinModule->setSource(0);
358 m_PinModule->setControl(0);
359 SourceActive = false;
360 m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
361 if (m_clkSink)
362 {
363 m_PinModule->removeSink(m_clkSink);
364 m_clkSink->release();
365 m_clkSink = 0;
366 }
367 m_PinModule->updatePinModule();
368 }
369 }
370
setCKpin(PinModule * ck_pin)371 void _TXSTA::setCKpin(PinModule *ck_pin)
372 {
373
374 if (!SourceActive)
375 m_PinModule = ck_pin;
376 }
enableTXPin()377 void _TXSTA::enableTXPin()
378 {
379 assert(m_PinModule);
380
381 if (m_PinModule && !SourceActive)
382 {
383 char out;
384 char reg_no = *(name().c_str() + 5);
385 if (bSYNC())
386 {
387 char ck[4] = "CK";
388 if (reg_no)
389 {
390 ck[2] = reg_no;
391 ck[3] = 0;
392 }
393 m_PinModule->getPin().newGUIname(ck);
394 out = '0';
395 if (!bCSRC()) // slave clock
396 {
397 if (!m_clkSink)
398 {
399 m_clkSink = new CLKSignalSink(rcsta);
400 m_PinModule->addSink(m_clkSink);
401 rcsta->set_old_clock_state(m_PinModule->getPin().getState());
402 }
403 mUSART->emptyTX();
404 return;
405 }
406 }
407 else
408 {
409 char tx[4] = "TX";
410 if (reg_no)
411 {
412 tx[2] = reg_no;
413 tx[3] = 0;
414 }
415 m_PinModule->getPin().newGUIname(tx);
416 out = '1';
417 }
418 m_PinModule->setSource(m_source);
419 #ifdef EUSART_PIN
420 if (mUSART->IsEUSART())
421 m_PinModule->setControl(m_control);
422 #else
423 m_PinModule->setControl(m_control);
424 #endif
425 putTXState(out);
426 SourceActive = true;
427 }
428
429 mUSART->emptyTX();
430 }
431
releasePin()432 void _TXSTA::releasePin()
433 {
434 if (m_PinModule && SourceActive)
435 {
436 m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
437 m_PinModule->setControl(0);
438 SourceActive = false;
439 }
440 }
441
442 //-----------------------------------------------------------
443 // TXSTA - putTXState - update the state of the TX output pin
444 //
445
putTXState(char newTXState)446 void _TXSTA::putTXState(char newTXState)
447 {
448 m_cTxState = bInvertPin ? newTXState ^ 1 : newTXState;
449
450 if (m_PinModule)
451 m_PinModule->updatePinModule();
452 }
453
454 //-----------------------------------------------------------
455 // TXSTA - Transmit Register Status and Control
456
put_value(unsigned int new_value)457 void _TXSTA::put_value(unsigned int new_value)
458 {
459 put(new_value);
460
461 update();
462 }
463
put(unsigned int new_value)464 void _TXSTA::put(unsigned int new_value)
465 {
466 unsigned int old_value = value.get();
467
468 trace.raw(write_trace.get() | value.get());
469
470 if (! mUSART->IsEUSART() )
471 new_value &= ~SENDB; // send break only supported on EUSART
472
473 // The TRMT bit is controlled entirely by hardware.
474 // It is high if the TSR has any data.
475
476 //RRRvalue.put((new_value & ~TRMT) | ( (bit_count) ? 0 : TRMT));
477 value.put((new_value & ~TRMT) | (old_value & TRMT));
478
479 Dprintf(("%s TXSTA value=0x%x\n",name().c_str(), value.get()));
480
481 if ((old_value ^ value.get()) & TXEN)
482 {
483
484 // The TXEN bit has changed states.
485 //
486 // If transmitter is being enabled and the transmit register
487 // has some data that needs to be sent, then start a
488 // transmission.
489 // If the transmitter is being disabled, then abort any
490 // transmission.
491
492 if (value.get() & TXEN)
493 {
494 Dprintf(("TXSTA - enabling transmitter\n"));
495 if (rcsta->bSPEN())
496 {
497
498 if (bSYNC() && ! bTRMT() && !rcsta->bSREN() && !rcsta->bCREN())
499 {
500 // need to check bTRMT before calling enableTXPin
501 enableTXPin();
502 rcsta->sync_start_transmitting();
503 }
504 else
505 enableTXPin();
506 }
507 }
508 else
509 {
510 stop_transmitting();
511 mUSART->full(); // Turn off TXIF
512 disableTXPin();
513
514 }
515 }
516 }
517 //------------------------------------------------------------
518 //
getState()519 char _TXSTA::getState()
520 {
521 return m_cTxState;
522 }
523
524
525 // _TXSTA::stop_transmitting()
526 //
stop_transmitting()527 void _TXSTA::stop_transmitting()
528 {
529 Dprintf(("stopping a USART transmission\n"));
530
531 bit_count = 0;
532 value.put(value.get() | TRMT);
533
534 // It's not clear from the documentation as to what happens
535 // to the TXIF when we are aborting a transmission. According
536 // to the documentation, the TXIF is set when the TXEN bit
537 // is set. In other words, when the Transmitter is enabled
538 // the txreg is emptied (and hence TXIF set). But what happens
539 // when TXEN is cleared? Should we clear TXIF too?
540 //
541 // There is one sentence that says when the transmitter is
542 // disabled that the whole transmitter is reset. So I interpret
543 // this to mean that the TXIF gets cleared. I could be wrong
544 // (and I don't have a way to test it on a real device).
545 //
546 // Another interpretation is that TXIF retains it state
547 // through changing TXEN. However, when SPEN (serial port) is
548 // set then the whole usart is reinitialized and TXIF will
549 // get set.
550 //
551 // txreg->full(); // Clear TXIF
552
553 }
554
start_transmitting()555 void _TXSTA::start_transmitting()
556 {
557 Dprintf(("starting a USART transmission\n"));
558
559 // Build the serial byte that's about to be transmitted.
560 // I doubt the pic really does this way, but gpsim builds
561 // the entire bit stream including the start bit, 8 data
562 // bits, optional 9th data bit and the stop, and places
563 // this into the tsr register. But since the contents of
564 // the tsr are inaccessible, I guess we'll never know.
565 //
566 // (BTW, if you look carefully you may puzzle over why
567 // there appear to be 2 stop bits in the packet built
568 // below. Well, it's because the way gpsim implements
569 // the transmit logic. The second stop bit doesn't
570 // actually get transmitted - it merely causes the first
571 // stop bit to get transmitted before the TRMT bit is set.
572 //
573 // RRR I believe the above paragraph is a mis-understanding
574 // The tsr register becomes empty, and the TRMT flag goes high,
575 // when we start to transmit the stop bit. Note that transmision
576 // is synchronous with the baud clock, so the start of transmision
577 // of a new character waits for the next callback. This delay maybe,
578 // in fact, the stop bit of the previous transmision,
579 //
580 // [Recall that the TRMT bit indicates when the tsr
581 // {transmit shift register} is empty. It's not tied to
582 // an interrupt pin, so the pic application software
583 // most poll this bit.
584 //
585 // RRR Also The following is wrong:
586 // This bit is set after the STOP
587 // bit is transmitted.] This is a cheap trick that saves
588 // one comparison in the callback code.)
589
590 // The start bit, which is always low, occupies bit position
591 // zero. The next 8 bits come from the txreg.
592 assert(txreg);
593 if (!txreg)
594 return;
595 if (value.get() & SENDB)
596 {
597 transmit_break();
598 return;
599 }
600 tsr = txreg->value.get() << 1;
601
602 // Is this a 9-bit data transmission?
603 if (value.get() & TX9)
604 {
605 // Copy the stop bit and the 9th data bit to the tsr.
606 // (See note above for the reason why two stop bits
607 // are appended to the packet.)
608
609 tsr |= ( (value.get() & TX9D) ? (3 << 9) : (2 << 9));
610 bit_count = 11; // 1 start, 9 data, 1 stop
611 }
612 else
613 {
614 // The stop bit is always high. (See note above
615 // for the reason why two stop bits are appended to
616 // the packet.)
617 tsr |= (1 << 9);
618 bit_count = 10; // 1 start, 8 data, 1 stop
619 }
620
621
622 // Set a callback breakpoint at the next SPBRG edge
623 if(cpu)
624 get_cycles().set_break(spbrg->get_cpu_cycle(1), this);
625
626
627 // The TSR now has data, so clear the Transmit Shift
628 // Register Status bit.
629
630 trace.raw(write_trace.get() | value.get());
631 value.put(value.get() & ~TRMT);
632
633 }
634
transmit_break()635 void _TXSTA::transmit_break()
636 {
637 Dprintf(("starting a USART sync-break transmission\n"));
638
639 // A sync-break is 13 consecutive low bits and one stop bit. Use the
640 // standard transmit logic to achieve this
641
642 if (!txreg)
643 return;
644
645 tsr = 1 << 13;
646
647 bit_count = 14; // 13 break, 1 stop
648
649 // The TSR now has data, so clear the Transmit Shift
650 // Register Status bit.
651
652 trace.raw(write_trace.get() | value.get());
653 value.put(value.get() & ~TRMT);
654
655 callback();
656 }
657
transmit_a_bit()658 void _TXSTA::transmit_a_bit()
659 {
660 if (bit_count)
661 {
662 Dprintf(("Transmit bit #%x: bit val:%u time:0x%" PRINTF_GINT64_MODIFIER "x\n",
663 bit_count, (tsr & 1), get_cycles().get()));
664
665 putTXState((tsr & 1) ? '1' : '0');
666
667 tsr >>= 1;
668
669 --bit_count;
670 }
671 }
672
673
674
callback()675 void _TXSTA::callback()
676 {
677 Dprintf(("TXSTA callback - time:%" PRINTF_GINT64_MODIFIER "x\n", get_cycles().get()));
678
679 transmit_a_bit();
680
681 if (!bit_count)
682 {
683
684 value.put(value.get() & ~SENDB);
685
686 // tsr is empty.
687 // If there is any more data in the TXREG, then move it to
688 // the tsr and continue transmitting other wise set the TRMT bit
689
690 // (See the note above about the 'extra' stop bit that was stuffed
691 // into the tsr register.
692
693 if (mUSART->bIsTXempty())
694 value.put(value.get() | TRMT);
695 else
696 {
697 start_transmitting();
698 mUSART->emptyTX();
699 }
700
701 }
702 else
703 {
704 // bit_count is non zero which means there is still
705 // data in the tsr that needs to be sent.
706
707 if (cpu)
708 {
709 get_cycles().set_break(spbrg->get_cpu_cycle(1), this);
710 }
711 }
712
713 }
714
callback_print()715 void _TXSTA::callback_print()
716 {
717 std::cout << "TXSTA " << name() << " CallBack ID " << CallBackID << '\n';
718 }
719
720 //-----------------------------------------------------------
721 // Receiver portion of the USART
722 //-----------------------------------------------------------
723 //
724 // First RCSTA -- Receiver Control and Status
725 // The RCSTA class controls the usart reception. The PIC usarts have
726 // two modes: synchronous and asynchronous.
727 // Asynchronous reception:
728 // Asynchronous reception means that there is no external clock
729 // available for telling the usart when to sample the data. Sampling
730 // timing is all based upon the PIC's oscillator. The SPBRG divides
731 // this clock down to a frequency that's appropriate to the data
732 // being received. (e.g. 9600 baud defines the rate at which data
733 // will be sent to the pic - 9600 bits per second.) The start bit,
734 // which is a high to low transition on the receive line, defines
735 // when the usart should start sampling the incoming data.
736 // The pic usarts sample asynchronous data three times in "approximately
737 // the middle" of each bit. The data sheet is not exactly specific
738 // on what's the middle. Consequently, gpsim takes a stab/ educated
739 // guess on when these three samples are to be taken. Once the
740 // three samples are taken, then simple majority summing determines
741 // the sample e.g. if two out of three of the samples are high, then
742 // then the data bit is considered high.
743 //
744 //-----------------------------------------------------------
745 // RCSTA::put
746 //
put(unsigned int new_value)747 void _RCSTA::put(unsigned int new_value)
748 {
749 unsigned int diff;
750 unsigned int readonly = value.get() & (RX9D | OERR | FERR);
751
752 diff = new_value ^ value.get();
753 trace.raw(write_trace.get() | value.get());
754 assert(txsta);
755 assert(txsta->txreg);
756 assert(rcreg);
757 // If SPEN being turned off, clear all readonly bits
758 if (diff & SPEN && !(new_value & SPEN))
759 {
760 readonly = 0;
761 // clear receive stack (and rxif)
762 rcreg->pop();
763 rcreg->pop();
764 }
765 // if CREN is being cleared, make sure OERR is clear
766 else if (diff & CREN && !(new_value & CREN))
767 readonly &= (RX9D | FERR);
768 value.put( readonly | (new_value & ~(RX9D | OERR | FERR)));
769
770 if (!txsta->bSYNC()) // Asynchronous case
771 {
772 if (diff & (SPEN | CREN)) // RX status change
773 {
774 if ((value.get() & (SPEN | CREN)) == SPEN )
775 {
776 if (txsta->bTXEN()) txsta->enableTXPin();
777 spbrg->start();
778 }
779 else if ((value.get() & (SPEN | CREN)) == (SPEN | CREN))
780 {
781 enableRCPin();
782 if (txsta->bTXEN()) txsta->enableTXPin();
783 spbrg->start();
784 start_receiving();
785 // If the rx line is low, then go ahead and start receiving now.
786 if (m_cRxState == '0' || m_cRxState == 'w')
787 receive_start_bit();
788 // Clear overrun error when turning on RX
789 value.put( value.get() & (~OERR) );
790 }
791 else // RX off, check TX
792 {
793 if (m_PinModule)
794 m_PinModule->getPin().newGUIname(
795 m_PinModule->getPin().name().c_str());
796 stop_receiving();
797 state = RCSTA_DISABLED;
798
799 if (bSPEN()) // RX off but TX may still be active
800 {
801 if (txsta->bTXEN()) //TX output active
802 txsta->enableTXPin();
803 else // TX off
804 txsta->disableTXPin();
805 }
806 return;
807 }
808 }
809 }
810 else // synchronous case
811 {
812
813 if (diff & RX9)
814 {
815 if (bRX9())
816 bit_count = 9;
817 else
818 bit_count = 8;
819 }
820 if (diff & (SPEN | CREN | SREN )) // RX status change
821 {
822 // Synchronous transmit (SREN & CREN == 0)
823 if ((value.get() & (SPEN | SREN | CREN)) == SPEN)
824 {
825 enableRCPin(DIR_OUT);
826 if (txsta->bTXEN()) txsta->enableTXPin();
827 return;
828 }
829 // Synchronous receive (SREN | CREN != 0)
830 else if (value.get() & (SPEN))
831 {
832 enableRCPin(DIR_IN);
833 txsta->enableTXPin();
834 rsr = 0;
835 if (bRX9())
836 bit_count = 9;
837 else
838 bit_count = 8;
839 if (txsta->bCSRC()) // Master mode
840 {
841 sync_next_clock_edge_high = true;
842 txsta->putTXState('0'); // clock low
843 callback();
844 }
845
846 return;
847 }
848 else // turn off UART
849 {
850 if (m_PinModule)
851 {
852 m_PinModule->getPin().newGUIname(
853 m_PinModule->getPin().name().c_str());
854 if (m_sink)
855 {
856 m_PinModule->removeSink(m_sink);
857 m_sink->release();
858 m_sink = 0;
859 }
860 }
861 txsta->disableTXPin();
862 }
863 }
864 }
865
866 }
867
enableRCPin(char direction)868 void _RCSTA::enableRCPin(char direction)
869 {
870 if (m_PinModule)
871 {
872 char reg_no = *(name().c_str() + 5);
873 if (txsta->bSYNC()) // Synchronous case
874 {
875 if (!m_source)
876 {
877 m_source = new RCSignalSource(this);
878 m_control = new RCSignalControl(this);
879 }
880 if (direction == DIR_OUT)
881 {
882 m_DTdirection = '0';
883 if (SourceActive == false)
884 {
885 m_PinModule->setSource(m_source);
886 m_PinModule->setControl(m_control);
887 SourceActive = true;
888 }
889 putRCState('0');
890 }
891 else
892 {
893 m_DTdirection = '1';
894 if (SourceActive == true)
895 {
896 m_PinModule->setSource(0);
897 m_PinModule->setControl(0);
898 m_PinModule->updatePinModule();
899 }
900 }
901 char dt[4] = "DT";
902 dt[2] = reg_no;
903 dt[3] = 0;
904 m_PinModule->getPin().newGUIname(dt);
905
906 }
907 else // Asynchronous case
908 {
909 char rx[4] = "RX";
910 rx[2] = reg_no;
911 rx[3] = 0;
912 m_PinModule->getPin().newGUIname(rx);
913 }
914
915 }
916
917 }
918
disableRCPin()919 void _RCSTA::disableRCPin()
920 {
921 }
922
releasePin()923 void _RCSTA::releasePin()
924 {
925 if (m_PinModule && SourceActive)
926 {
927 m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
928 m_PinModule->setControl(0);
929 SourceActive = false;
930 }
931 }
932
put_value(unsigned int new_value)933 void _RCSTA::put_value(unsigned int new_value)
934 {
935 put(new_value);
936
937 update();
938 }
939
940 //-----------------------------------------------------------
941 // RCSTA - putRCState - update the state of the DTx output pin
942 // only used for Synchronous mode
943 //
944
putRCState(char newRCState)945 void _RCSTA::putRCState(char newRCState)
946 {
947 bInvertPin = mUSART->baudcon.rxdtp();
948 m_cTxState = bInvertPin ? newRCState ^ 1 : newRCState;
949
950 if (m_PinModule)
951 m_PinModule->updatePinModule();
952 }
953
954 //-----------------------------------------------------------
955 // RCSTA - setIOpin - assign the I/O pin associated with the
956 // the receiver.
957
setIOpin(PinModule * newPinModule)958 void _RCSTA::setIOpin(PinModule *newPinModule)
959 {
960 if (m_sink)
961 {
962 if (m_PinModule)
963 {
964 m_PinModule->removeSink(m_sink);
965 if (value.get() & SPEN)
966 m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
967 }
968 }
969 else
970 m_sink = new RXSignalSink(this);
971
972 m_PinModule = newPinModule;
973 if (m_PinModule)
974 {
975 m_PinModule->addSink(m_sink);
976 old_clock_state = m_PinModule->getPin().getState();
977 if (value.get() & SPEN)
978 m_PinModule->getPin().newGUIname("RX/DT");
979 }
980
981 }
982
983 //-----------------------------------------------------------
984 // RCSTA - setState
985 // This gets called whenever there's a change detected on the RX pin.
986 // The usart is only interested in those changes when it is waiting
987 // for the start bit. Otherwise, the rcsta callback function will sample
988 // the rx pin (if we're receiving).
989
990
setState(char new_RxState)991 void _RCSTA::setState(char new_RxState)
992 {
993 Dprintf((" %s setState:%c\n",name().c_str(), new_RxState));
994
995 m_cRxState = new_RxState;
996
997 if ((state == RCSTA_WAITING_FOR_START) && (m_cRxState == '0' || m_cRxState == 'w'))
998 receive_start_bit();
999 }
1000
1001 // Transmit in synchronous mode
1002 //
sync_start_transmitting()1003 void _RCSTA::sync_start_transmitting()
1004 {
1005 assert(txreg);
1006
1007 rsr = txreg->value.get();
1008 if (txsta->bTX9())
1009 {
1010 rsr |= (txsta->bTX9D() << 8);
1011 bit_count = 9;
1012 }
1013 else
1014 bit_count = 8;
1015 txsta->value.put(txsta->value.get() & ~ _TXSTA::TRMT);
1016 if (txsta->bCSRC())
1017 {
1018 sync_next_clock_edge_high = true;
1019 txsta->putTXState('0'); // clock low
1020 callback();
1021 }
1022 }
1023
set_old_clock_state(char new3State)1024 void _RCSTA::set_old_clock_state(char new3State)
1025 {
1026 bool state = (new3State == '1' || new3State == 'W');
1027 state = mUSART->baudcon.txckp() ? !state : state;
1028 old_clock_state = state;
1029 }
1030
clock_edge(char new3State)1031 void _RCSTA::clock_edge(char new3State)
1032 {
1033 bool state = (new3State == '1' || new3State == 'W');
1034
1035 // invert clock, if requested
1036 state = mUSART->baudcon.txckp() ? !state : state;
1037 if (old_clock_state == state) return;
1038 old_clock_state = state;
1039 if (value.get() & SPEN)
1040 {
1041 // Transmitting ?
1042 if ((value.get() & ( CREN | SREN)) == 0)
1043 {
1044 if (state) // clock high, output data
1045 {
1046 if (bit_count)
1047 {
1048 putRCState((rsr & 1) ? '1' : '0');
1049 rsr >>= 1;
1050 bit_count--;
1051 }
1052 }
1053 else
1054 {
1055 if(mUSART->bIsTXempty())
1056 {
1057 txsta->value.put(txsta->value.get() | _TXSTA::TRMT);
1058 }
1059 else
1060 {
1061 sync_start_transmitting();
1062 mUSART->emptyTX();
1063 }
1064 }
1065 }
1066 else // receiving
1067 {
1068 if (!state) // read data as clock goes low
1069 {
1070 bool data = m_PinModule->getPin().getState();
1071 data = mUSART->baudcon.rxdtp() ? !data : data;
1072
1073 if (bRX9())
1074 rsr |= data << 9;
1075 else
1076 rsr |= data << 8;
1077
1078 rsr >>= 1;
1079 if (--bit_count == 0)
1080 {
1081 rcreg->push(rsr);
1082 if (bRX9())
1083 bit_count = 9;
1084 else
1085 bit_count = 8;
1086 rsr = 0;
1087 }
1088 }
1089 }
1090 }
1091
1092 }
1093
1094 //-----------------------------------------------------------
1095 // RCSTA::receive_a_bit(unsigned int bit)
1096 //
1097 // A new bit needs to be copied to the the Receive Shift Register.
1098 // If the receiver is receiving data, then this routine will copy
1099 // the incoming bit to the rsr. If this is the last bit, then a
1100 // check will be made to see if we need to set up for the next
1101 // serial byte.
1102 // If this is not the last bit, then the receive state machine.
1103
receive_a_bit(unsigned int bit)1104 void _RCSTA::receive_a_bit(unsigned int bit)
1105 {
1106 // If we're waiting for the start bit and this isn't it then
1107 // we don't need to look any further
1108 Dprintf(("%s receive_a_bit state:%u bit:%u time:0x%" PRINTF_GINT64_MODIFIER "x\n",
1109 name().c_str(), state, bit, get_cycles().get()));
1110
1111 if( state == RCSTA_MAYBE_START)
1112 {
1113 if (bit)
1114 state = RCSTA_WAITING_FOR_START;
1115 else
1116 state = RCSTA_RECEIVING;
1117 return;
1118 }
1119 if (bit_count == 0)
1120 {
1121 // we should now have the stop bit
1122 if (bit)
1123 {
1124 // got the stop bit
1125 // If the rxreg has data from a previous reception then
1126 // we have a receiver overrun error.
1127 // cout << "rcsta.rsr is full\n";
1128
1129 if((value.get() & RX9) == 0)
1130 rsr >>= 1;
1131
1132 // Clear any framing error
1133 value.put(value.get() & (~FERR) );
1134
1135 // copy the rsr to the fifo
1136 if(rcreg)
1137 rcreg->push( rsr & 0x1ff);
1138
1139 Dprintf(("%s _RCSTA::receive_a_bit received 0x%02X\n",name().c_str(), rsr & 0x1ff));
1140
1141 }
1142 else
1143 {
1144 //no stop bit; framing error
1145 value.put(value.get() | FERR);
1146
1147 // copy the rsr to the fifo
1148 if(rcreg)
1149 rcreg->push( rsr & 0x1ff);
1150 }
1151 // If we're continuously receiving, then set up for the next byte.
1152 // FIXME -- may want to set a half bit delay before re-starting...
1153 if(value.get() & CREN)
1154 start_receiving();
1155 else
1156 state = RCSTA_DISABLED;
1157 return;
1158 }
1159
1160
1161 // Copy the bit into the Receive Shift Register
1162 if (bit)
1163 rsr |= 1 << 9;
1164
1165 //cout << "Receive bit #" << bit_count << ": " << (rsr&(1<<9)) << '\n';
1166
1167 rsr >>= 1;
1168 bit_count--;
1169
1170 }
1171
stop_receiving()1172 void _RCSTA::stop_receiving()
1173 {
1174 rsr = 0;
1175 bit_count = 0;
1176 state = RCSTA_DISABLED;
1177 }
1178
start_receiving()1179 void _RCSTA::start_receiving()
1180 {
1181 Dprintf(("%s The USART is starting to receive data\n", name().c_str()));
1182
1183 rsr = 0;
1184 sample = 0;
1185
1186 // Is this a 9-bit data reception?
1187 bit_count = (value.get() & RX9) ? 9 : 8;
1188
1189 state = RCSTA_WAITING_FOR_START;
1190 }
1191
overrun()1192 void _RCSTA::overrun()
1193 {
1194 value.put(value.get() | _RCSTA::OERR);
1195 }
1196
set_callback_break(unsigned int spbrg_edge)1197 void _RCSTA::set_callback_break(unsigned int spbrg_edge)
1198 {
1199 if (cpu && spbrg)
1200 {
1201 unsigned int time_to_event
1202 = ( spbrg->get_cycles_per_tick() * spbrg_edge ) / TOTAL_SAMPLE_STATES;
1203 get_cycles().set_break(get_cycles().get() + time_to_event, this);
1204 }
1205 }
1206
receive_start_bit()1207 void _RCSTA::receive_start_bit()
1208 {
1209 Dprintf(("%s USART received a start bit\n", name().c_str()));
1210
1211 if ((value.get() & (CREN | SREN)) == 0)
1212 {
1213 Dprintf((" but not enabled\n"));
1214 return;
1215 }
1216
1217 if (txsta && (txsta->value.get() & _TXSTA::BRGH))
1218 set_callback_break(BRGH_FIRST_MID_SAMPLE);
1219 else
1220 set_callback_break(BRGL_FIRST_MID_SAMPLE);
1221
1222 sample = 0;
1223 sample_state = RCSTA_WAITING_MID1;
1224 state = RCSTA_MAYBE_START;
1225 }
1226
1227 //------------------------------------------------------------
callback()1228 void _RCSTA::callback()
1229 {
1230 Dprintf(("RCSTA callback. %s time:0x%" PRINTF_GINT64_MODIFIER "x\n", name().c_str(), get_cycles().get()));
1231
1232 if (txsta->bSYNC()) // Synchronous mode RX/DT is data, TX/CK is clock
1233 {
1234 if (sync_next_clock_edge_high) // + edge of clock
1235 {
1236 sync_next_clock_edge_high = false;
1237 txsta->putTXState('1'); // Clock high
1238 // Transmit
1239 if ((value.get() & (SPEN | SREN | CREN)) == SPEN)
1240 {
1241 if (bit_count)
1242 {
1243 putRCState((rsr & 1) ? '1' : '0');
1244 rsr >>= 1;
1245 bit_count--;
1246 }
1247 }
1248 }
1249 else // - clock edge
1250 {
1251 sync_next_clock_edge_high = true;
1252 txsta->putTXState('0'); //clock low
1253 // Receive Master mode
1254 if ((value.get() & (SPEN | SREN | CREN)) != SPEN)
1255 {
1256
1257 if (value.get() & OERR)
1258 return;
1259 bool data = m_PinModule->getPin().getState();
1260 data = mUSART->baudcon.rxdtp() ? !data : data;
1261 if (bRX9())
1262 rsr |= data << 9;
1263 else
1264 rsr |= data << 8;
1265 rsr >>= 1;
1266 if (--bit_count == 0)
1267 {
1268 rcreg->push(rsr);
1269 if (bRX9())
1270 bit_count = 9;
1271 else
1272 bit_count = 8;
1273 rsr = 0;
1274 value.put(value.get() & ~SREN);
1275 if ((value.get() & (SPEN | SREN | CREN)) == SPEN )
1276 {
1277 enableRCPin(DIR_OUT);
1278 return;
1279 }
1280 }
1281 }
1282 else // Transmit, clock low
1283 {
1284 if (bit_count == 0 && !mUSART->bIsTXempty())
1285 {
1286 sync_start_transmitting();
1287 mUSART->emptyTX();
1288 return;
1289 }
1290 else if(bit_count == 0 && mUSART->bIsTXempty())
1291 {
1292 txsta->value.put(txsta->value.get() | _TXSTA::TRMT);
1293 putRCState('0');
1294 return;
1295 }
1296 }
1297 }
1298 if (cpu && (value.get() & SPEN))
1299 {
1300 future_cycle = get_cycles().get() + spbrg->get_cycles_per_tick();
1301 get_cycles().set_break(future_cycle, this);
1302 }
1303 }
1304 else
1305 {
1306 // A bit is sampled 3 times.
1307 switch (sample_state)
1308 {
1309 case RCSTA_WAITING_MID1:
1310 if (m_cRxState == '1' || m_cRxState == 'W')
1311 sample++;
1312
1313 if(txsta && (txsta->value.get() & _TXSTA::BRGH))
1314 set_callback_break(BRGH_SECOND_MID_SAMPLE - BRGH_FIRST_MID_SAMPLE);
1315 else
1316 set_callback_break(BRGL_SECOND_MID_SAMPLE - BRGL_FIRST_MID_SAMPLE);
1317
1318 sample_state = RCSTA_WAITING_MID2;
1319
1320 break;
1321
1322 case RCSTA_WAITING_MID2:
1323 if (m_cRxState == '1' || m_cRxState == 'W')
1324 sample++;
1325
1326 if(txsta && (txsta->value.get() & _TXSTA::BRGH))
1327 set_callback_break(BRGH_THIRD_MID_SAMPLE - BRGH_SECOND_MID_SAMPLE);
1328 else
1329 set_callback_break(BRGL_THIRD_MID_SAMPLE - BRGL_SECOND_MID_SAMPLE);
1330
1331 sample_state = RCSTA_WAITING_MID3;
1332
1333 break;
1334
1335 case RCSTA_WAITING_MID3:
1336 if (m_cRxState == '1' || m_cRxState == 'W')
1337 sample++;
1338
1339 receive_a_bit( (sample >= 2));
1340 sample = 0;
1341
1342 // If this wasn't the last bit then go ahead and set a break for the next bit.
1343 if(state==RCSTA_RECEIVING)
1344 {
1345 if(txsta && (txsta->value.get() & _TXSTA::BRGH))
1346 set_callback_break(TOTAL_SAMPLE_STATES - (BRGH_THIRD_MID_SAMPLE - BRGH_FIRST_MID_SAMPLE));
1347 else
1348 set_callback_break(TOTAL_SAMPLE_STATES - (BRGL_THIRD_MID_SAMPLE - BRGL_FIRST_MID_SAMPLE));
1349
1350 sample_state = RCSTA_WAITING_MID1;
1351 }
1352
1353 break;
1354
1355 default:
1356 //cout << "Error RCSTA callback with bad state\n";
1357 // The receiver was probably disabled in the middle of a reception.
1358 ;
1359 }
1360 }
1361
1362 }
1363
1364 //-----------------------------------------------------------
callback_print()1365 void _RCSTA::callback_print()
1366 {
1367 std::cout << "RCSTA " << name() << " CallBack ID " << CallBackID << '\n';
1368 }
1369
1370 //-----------------------------------------------------------
1371 // RCREG
1372 //
push(unsigned int new_value)1373 void _RCREG::push(unsigned int new_value)
1374 {
1375 trace.raw(write_trace.get() | value.get());
1376
1377 if (fifo_sp >= 2)
1378 {
1379
1380 if (m_rcsta)
1381 m_rcsta->overrun();
1382
1383 Dprintf(("%s receive overrun\n", name().c_str()));
1384
1385 }
1386 else
1387 {
1388
1389 Dprintf(("%s pushing uart reception onto rcreg stack, value received=0x%x\n",name().c_str(), new_value));
1390 fifo_sp++;
1391 oldest_value = value.get();
1392 value.put(new_value & 0xff);
1393 if (m_rcsta)
1394 {
1395 unsigned int rcsta = m_rcsta->value.get();
1396 if (new_value & 0x100)
1397 rcsta |= _RCSTA::RX9D;
1398 else
1399 rcsta &= ~ _RCSTA::RX9D;
1400 m_rcsta->value.put(rcsta);
1401 }
1402 }
1403
1404 mUSART->set_rcif();
1405 }
1406
pop()1407 void _RCREG::pop()
1408 {
1409 if (fifo_sp == 0)
1410 return;
1411
1412 if (--fifo_sp == 1)
1413 {
1414 value.put(oldest_value & 0xff);
1415 if (m_rcsta)
1416 {
1417 unsigned int rcsta = m_rcsta->value.get();
1418 if (oldest_value & 0x100)
1419 rcsta |= _RCSTA::RX9D;
1420 else
1421 rcsta &= ~ _RCSTA::RX9D;
1422 m_rcsta->value.put(rcsta);
1423 }
1424 }
1425
1426 if (fifo_sp == 0)
1427 mUSART->clear_rcif();
1428 }
1429
get_value()1430 unsigned int _RCREG::get_value()
1431 {
1432 return value.get();
1433 }
1434
get()1435 unsigned int _RCREG::get()
1436 {
1437 pop();
1438 trace.raw(read_trace.get() | value.get());
1439 return value.get();
1440 }
1441
1442
1443
1444
1445 //-----------------------------------------------------------
1446 // SPBRG - Serial Port Baud Rate Generator
1447 //
1448 // The SPBRG is essentially a continuously running programmable
1449 // clock. (Note that this will slow the simulation down if the
1450 // serial port is not used. Perhaps gpsim needs some kind of
1451 // pragma type thing to disable cpu intensive peripherals...)
1452
get_next_cycle_break()1453 void _SPBRG::get_next_cycle_break()
1454 {
1455 future_cycle = last_cycle + get_cycles_per_tick();
1456
1457 if (cpu)
1458 {
1459 if (future_cycle <= get_cycles().get())
1460 {
1461 Dprintf(("%s future %" PRINTF_GINT64_MODIFIER "d <= now %" PRINTF_GINT64_MODIFIER "d\n", name().c_str(), future_cycle, get_cycles().get()));
1462 last_cycle = get_cycles().get();
1463 future_cycle = last_cycle + get_cycles_per_tick();
1464 }
1465 get_cycles().set_break(future_cycle, this);
1466 }
1467
1468 //Dprintf(("SPBRG::callback next break at 0x%" PRINTF_GINT64_MODIFIER "x\n",future_cycle));
1469 }
1470
get_cycles_per_tick()1471 unsigned int _SPBRG::get_cycles_per_tick()
1472 {
1473 unsigned int cpi = (cpu) ? p_cpu->get_ClockCycles_per_Instruction() : 4;
1474 unsigned int brgval, cpt, ret;
1475
1476 if ( baudcon && baudcon->brg16() )
1477 {
1478 brgval = ( brgh ? brgh->value.get() * 256 : 0 ) + value.get();
1479 cpt = 4; // hi-speed divisor in 16-bit mode is 4
1480 }
1481 else
1482 {
1483 brgval = value.get();
1484 cpt = 16; // hi-speed divisor in 8-bit mode is 16
1485 }
1486
1487 if ( txsta && (txsta->value.get() & _TXSTA::SYNC) )
1488 {
1489 // Synchronous mode - divisor is always 4
1490 // However, code wants two transitions per bit
1491 // to generate clock for master mode, so use 2
1492 cpt = 2;
1493 }
1494 else
1495 {
1496 // Asynchronous mode
1497 if(txsta && !(txsta->value.get() & _TXSTA::BRGH))
1498 {
1499 cpt *= 4; // lo-speed divisor is 4 times hi-speed
1500 }
1501 }
1502
1503 ret = ((brgval + 1) * cpt) / cpi;
1504 ret = ret ? ret : 1;
1505 return ret;
1506 }
1507
start()1508 void _SPBRG::start()
1509 {
1510 if (running)
1511 return;
1512
1513 if (! skip || get_cycles().get() >= skip)
1514 {
1515 if (cpu)
1516 last_cycle = get_cycles().get();
1517 skip = 0;
1518 }
1519 running = true;
1520
1521 start_cycle = last_cycle;
1522
1523 get_next_cycle_break();
1524
1525 Dprintf((" SPBRG::start last_cycle:0x%" PRINTF_GINT64_MODIFIER "x: future_cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle,future_cycle));
1526 }
1527
put(unsigned int new_value)1528 void _SPBRG::put(unsigned int new_value)
1529 {
1530 trace.raw(write_trace.get() | value.get());
1531 value.put(new_value);
1532
1533 Dprintf((" SPBRG value=0x%x\n",value.get()));
1534 //Prevent updating last_cycle until all current breakpoints have expired
1535 //Otherwise we see that rx/tx periods get screwed up from now until future_cycle
1536 future_cycle = last_cycle + get_cycles_per_tick();
1537 skip = future_cycle;
1538 Dprintf((" SPBRG value=0x%x skip=0x%" PRINTF_GINT64_MODIFIER "x last=0x%" PRINTF_GINT64_MODIFIER "x cycles/tick=0x%x\n",value.get(), skip, last_cycle, get_cycles_per_tick()));
1539 }
1540
put_value(unsigned int new_value)1541 void _SPBRG::put_value(unsigned int new_value)
1542 {
1543 put(new_value);
1544
1545 update();
1546 }
1547
put(unsigned int new_value)1548 void _SPBRGH::put(unsigned int new_value)
1549 {
1550 trace.raw(write_trace.get() | value.get());
1551 value.put(new_value);
1552
1553 if (m_spbrg)
1554 m_spbrg->set_start_cycle();
1555 }
1556
set_start_cycle()1557 void _SPBRG::set_start_cycle()
1558 {
1559 //Prevent updating last_cycle until all current breakpoints have expired
1560 //Otherwise we see that rx/tx persiods get screwed up from now until future_cycle
1561 future_cycle = last_cycle + get_cycles_per_tick();
1562 skip = future_cycle;
1563 }
1564
put_value(unsigned int new_value)1565 void _SPBRGH::put_value(unsigned int new_value)
1566 {
1567 put(new_value);
1568
1569 update();
1570 }
1571
1572 //--------------------------
1573 //guint64 _SPBRG::get_last_cycle()
1574 //
1575 // Get the cpu cycle corresponding to the last edge of the SPBRG
1576 //
1577
get_last_cycle()1578 guint64 _SPBRG::get_last_cycle()
1579 {
1580 // There's a chance that a SPBRG break point exists on the current
1581 // cpu cycle, but has not yet been serviced.
1582 if (cpu)
1583 return (get_cycles().get() == future_cycle) ? future_cycle : last_cycle;
1584 else
1585 return 0;
1586 }
1587
1588 //--------------------------
1589 //guint64 _SPBRG::get_cpu_cycle(unsigned int edges_from_now)
1590 //
1591 // When the SPBRG is enabled, it becomes a free running counter
1592 // that's synchronous with the cpu clock. The frequency of the
1593 // counter depends on the mode of the usart:
1594 //
1595 // Synchronous mode:
1596 // baud = cpu frequency / 4 / (spbrg.value + 1)
1597 //
1598 // Asynchronous mode:
1599 // high frequency:
1600 // baud = cpu frequency / 16 / (spbrg.value + 1)
1601 // low frequency:
1602 // baud = cpu frequency / 64 / (spbrg.value + 1)
1603 //
1604 // What this routine will do is return the cpu cycle corresponding
1605 // to a (rising) edge of the spbrg clock.
1606
get_cpu_cycle(unsigned int edges_from_now)1607 guint64 _SPBRG::get_cpu_cycle(unsigned int edges_from_now)
1608 {
1609 // There's a chance that a SPBRG break point exists on the current
1610 // cpu cycle, but has not yet been serviced.
1611 guint64 cycle = (get_cycles().get() == future_cycle) ? future_cycle : last_cycle;
1612
1613 return edges_from_now * get_cycles_per_tick() + cycle;
1614 }
1615
callback()1616 void _SPBRG::callback()
1617 {
1618 if (skip)
1619 {
1620 Dprintf((" SPBRG skip=0x%" PRINTF_GINT64_MODIFIER "x, cycle=0x%" PRINTF_GINT64_MODIFIER "x\n", skip, get_cycles().get()));
1621 }
1622 if (! skip || get_cycles().get() >= skip)
1623 {
1624 last_cycle = get_cycles().get();
1625 skip = 0;
1626 }
1627
1628 //Dprintf(("SPBRG rollover at cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle));
1629
1630 if ((rcsta && rcsta->bSPEN()) || (txsta && txsta->bTXEN()))
1631 {
1632 // If the serial port is enabled, then set another
1633 // break point for the next clock edge.
1634 get_next_cycle_break();
1635
1636 }
1637 else
1638 {
1639 running = false;
1640 }
1641 }
1642
1643 //-----------------------------------------------------------
1644 // TXSTA - Transmit Register Status and Control
1645
put_value(unsigned int new_value)1646 void _BAUDCON::put_value(unsigned int new_value)
1647 {
1648 put(new_value);
1649
1650 update();
1651 }
1652
put(unsigned int new_value)1653 void _BAUDCON::put(unsigned int new_value)
1654 {
1655 unsigned int old_value = value.get();
1656
1657 trace.raw(write_trace.get() | value.get());
1658
1659 // The RCIDL bit is controlled entirely by hardware.
1660 new_value &= ~RCIDL;
1661 if ( rcsta->rc_is_idle() ) new_value |= RCIDL;
1662
1663 value.put(new_value);
1664
1665 Dprintf(("%s BAUDCON value=0x%x\n",name().c_str(), value.get()));
1666
1667
1668 if ( (old_value ^ value.get()) & TXCKP)
1669 {
1670
1671 // The TXCKP bit has changed states.
1672 //
1673 txsta->set_pin_pol ((value.get() & TXCKP) ? true : false);
1674 }
1675 }
1676
1677 //--------------------------------------------------
1678 // member functions for the USART
1679 //--------------------------------------------------
initialize(PIR * _pir,PinModule * tx_pin,PinModule * rx_pin,_TXREG * _txreg,_RCREG * _rcreg)1680 void USART_MODULE::initialize(PIR *_pir,
1681 PinModule *tx_pin, PinModule *rx_pin,
1682 _TXREG *_txreg, _RCREG *_rcreg)
1683 {
1684 assert(_txreg && _rcreg);
1685
1686 pir = _pir;
1687
1688 spbrg.txsta = &txsta;
1689 spbrg.rcsta = &rcsta;
1690
1691 txreg = _txreg;
1692
1693 txreg->assign_rcsta(&rcsta);
1694 txreg->assign_txsta(&txsta);
1695
1696 rcreg = _rcreg;
1697 rcreg->assign_rcsta(&rcsta);
1698
1699 txsta.txreg = txreg;
1700 txsta.rcsta = &rcsta;
1701 txsta.spbrg = &spbrg;
1702 txsta.bit_count = 0;
1703 txsta.setIOpin(tx_pin);
1704
1705 rcsta.rcreg = rcreg;
1706 rcsta.spbrg = &spbrg;
1707 rcsta.txsta = &txsta;
1708 rcsta.txreg = txreg;
1709 rcsta.setIOpin(rx_pin);
1710 }
1711
setIOpin(PinModule * pin,int data)1712 void USART_MODULE::setIOpin(PinModule *pin, int data)
1713 {
1714
1715 switch (data)
1716 {
1717 case TX_PIN:
1718 txsta.setIOpin(pin);
1719 break;
1720
1721 case RX_PIN:
1722 rcsta.setIOpin(pin);
1723 break;
1724
1725 case CK_PIN:
1726 txsta.setCKpin(pin);
1727 break;
1728
1729 }
1730 }
1731
bIsTXempty()1732 bool USART_MODULE::bIsTXempty()
1733 {
1734 if (m_txif)
1735 return m_txif->Get();
1736 return pir ? pir->get_txif() : true;
1737 }
1738
emptyTX()1739 void USART_MODULE::emptyTX()
1740 {
1741 Dprintf(("usart::empty - setting TXIF %s\n", txsta.name().c_str()));
1742
1743 if (txsta.bTXEN())
1744 {
1745 if (m_txif)
1746 m_txif->Trigger();
1747 else if (pir)
1748 pir->set_txif();
1749 else
1750 assert(pir);
1751 }
1752 }
1753
full()1754 void USART_MODULE::full()
1755 {
1756 Dprintf((" txreg::full - clearing TXIF\n"));
1757 if (m_txif)
1758 m_txif->Clear();
1759 else if(pir)
1760 pir->clear_txif();
1761 else
1762 assert(pir);
1763 }
1764
set_rcif()1765 void USART_MODULE::set_rcif()
1766 {
1767 Dprintf((" - setting RCIF\n"));
1768 if (m_rcif)
1769 m_rcif->Trigger();
1770 else if(pir)
1771 pir->set_rcif();
1772 }
1773
clear_rcif()1774 void USART_MODULE::clear_rcif()
1775 {
1776 Dprintf((" - clearing RCIF\n"));
1777 if (m_rcif)
1778 m_rcif->Clear();
1779 else if(pir)
1780 pir->clear_rcif();
1781 }
1782
1783 //--------------------------------------------------
USART_MODULE(Processor * pCpu)1784 USART_MODULE::USART_MODULE(Processor *pCpu)
1785 : txsta(pCpu,"","USART Transmit Status",this), // Don't set names incase there are two UARTS
1786 rcsta(pCpu,"","USART Receive Status",this),
1787 spbrg(pCpu,"","Serial Port Baud Rate Generator"),
1788 txreg(nullptr), rcreg(nullptr), pir(nullptr),
1789 spbrgh(pCpu,"spbrgh","Serial Port Baud Rate high byte"),
1790 baudcon(pCpu,"baudcon","Serial Port Baud Rate Control"),
1791 is_eusart(false)
1792 {
1793 baudcon.txsta = &txsta;
1794 baudcon.rcsta = &rcsta;
1795 }
1796
~USART_MODULE()1797 USART_MODULE::~USART_MODULE()
1798 {
1799 }
1800
mk_rcif_int(PIR * reg,unsigned int bit)1801 void USART_MODULE::mk_rcif_int(PIR *reg, unsigned int bit)
1802 {
1803 m_rcif = std::unique_ptr<InterruptSource>(new InterruptSource(reg, bit));
1804 }
1805
mk_txif_int(PIR * reg,unsigned int bit)1806 void USART_MODULE::mk_txif_int(PIR *reg, unsigned int bit)
1807 {
1808 m_txif = std::unique_ptr<InterruptSource>(new InterruptSource(reg, bit));
1809 }
1810
1811 //--------------------------------------------------
set_eusart(bool is_it)1812 void USART_MODULE::set_eusart(bool is_it )
1813 {
1814 if (is_it)
1815 {
1816 spbrgh.assign_spbrg ( &spbrg );
1817 spbrg.baudcon = &baudcon;
1818 spbrg.brgh = &spbrgh;
1819 is_eusart = true;
1820 }
1821 else
1822 {
1823 spbrgh.assign_spbrg ( 0 );
1824 spbrg.baudcon = 0;
1825 spbrg.brgh = 0;
1826 is_eusart = false;
1827 }
1828 }
1829
1830