simulavr  1.1.0
hwport.cpp
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
5  * Copyright (C) 2001, 2002, 2003 Klaus Rudolph
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program 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
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  ****************************************************************************
22  *
23  * $Id$
24  */
25 
26 #include <iostream>
27 using namespace std; // used for string class
28 
29 #include "hwport.h"
30 #include "avrdevice.h"
31 #include "avrerror.h"
32 #include <assert.h>
33 
34 HWPort::HWPort(AvrDevice *core, const string &name, bool portToggle, int size):
35  Hardware(core),
36  TraceValueRegister(core, "PORT" + name),
37  myName(name),
38  portSize(size),
39  portToggleFeature(portToggle),
40  port_reg(this, "PORT",
41  this, &HWPort::GetPort, &HWPort::SetPort),
42  pin_reg(this, "PIN",
43  this,
44  &HWPort::GetPin, &HWPort::SetPin,
45  &HWPort::GetPinBit, &HWPort::SetPinBit
46  ),
47  ddr_reg(this, "DDR",
48  this, &HWPort::GetDdr, &HWPort::SetDdr)
49 {
50  assert((portSize >= 1) && (portSize <= sizeof(p)/sizeof(p[0])));
51  portMask = (unsigned char)((1 << portSize) - 1);
52 
53  for(unsigned int tt = 0; tt < portSize; tt++) {
54  // register pin to give access to pin by name
55  string dummy = name + (char)('0' + tt);
56  core->RegisterPin(dummy, &p[tt]);
57  // connect to output pin
58  p[tt].mask = 1 << tt;
59  p[tt].pinOfPort= &pin;
60  p[tt].pinRegOfPort= &pin_reg;
61  // register pin output trace
62  string tname = GetTraceValuePrefix() + name + (char)('0' + tt) + "-Out";
63  pintrace[tt] = new TraceValueOutput(tname);
64  pintrace[tt]->set_written(Pin::TRISTATE); // initial output driver state is tristate
66  }
67 
68  Reset();
69 }
70 
72  for(int tt = portSize - 1; tt >= 0; tt--) {
74  }
75 }
76 
77 void HWPort::Reset(void) {
78  port = 0;
79  pin = 0;
80  ddr = 0;
81 
82  for(int tt = portSize - 1; tt >= 0; tt--)
83  p[tt].ResetOverride();
84  CalcOutputs();
85 }
86 
87 Pin& HWPort::GetPin(unsigned char pinNo) {
88  assert(pinNo < sizeof(p)/sizeof(p[0]));
89  return p[pinNo];
90 }
91 
92 void HWPort::CalcOutputs(void) { // Calculate the new output value to be transmitted to the environment
93  unsigned char tmpPin = 0;
94 
95  for(unsigned int actualBitNo = 0; actualBitNo < portSize; actualBitNo++) {
96  unsigned char actualBit = 1 << actualBitNo;
97  bool regPort = (bool)(port & actualBit);
98  bool regDDR = (bool)(ddr & actualBit);
99 
100  if(p[actualBitNo].CalcPinOverride(regDDR, regPort, false))
101  tmpPin |= actualBit;
102  pintrace[actualBitNo]->change(p[actualBitNo].outState);
103  }
104  pin = tmpPin;
106 }
107 
108 string HWPort::GetPortString(void) {
109  string dummy;
110  dummy.resize(portSize);
111  for(unsigned int tt = 0; tt < portSize; tt++)
112  dummy[portSize - 1 - tt] = p[tt]; // calls Pin::operator char()
113 
114  return dummy;
115 }
116 
117 void HWPort::SetPort(unsigned char val) {
118  port = val & portMask;
119  CalcOutputs();
121 }
122 
123 void HWPort::SetDdr(unsigned char val) {
124  ddr = val & portMask;
125  CalcOutputs();
127 }
128 
129 void HWPort::SetPin(unsigned char val) {
130  if(portToggleFeature) {
131  port ^= val;
132  CalcOutputs();
134  } else
135  avr_warning("Writing of 'PORT%s.PIN' (with %d) is not supported.", myName.c_str(), val);
136 }
137 
138 // TODO: Please check and improve ! Untested and only copied from different sources here..
139 void HWPort::SetPinBit(bool val, unsigned int bitaddr) {
140  if(portToggleFeature) {
141  unsigned char tmpPin = pin;
142 
143  unsigned char actualBit = 1 << bitaddr;
144  tmpPin &= ~actualBit;
145  port ^= actualBit;
146 
147  // copied from CalcOutputs
148  bool regPort = (bool)(port & actualBit);
149  bool regDDR = (bool)(ddr & actualBit);
150 
151  if(p[bitaddr].CalcPinOverride(regDDR, regPort, false)) {
152  tmpPin |= actualBit;
153  pin=tmpPin;
154  }
155  pintrace[bitaddr]->change(p[bitaddr].outState);
156 
158  } else {
159  avr_warning("Writing of 'PORT%s.PIN' (with %d) is not supported.", myName.c_str(), val);
160  }
161 }
162 
163 /* EOF */
std::string myName
the "name" of the port
Definition: hwport.h:46
unsigned char GetPin()
getter method for PIN register
Definition: hwport.h:76
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
unsigned char * pinOfPort
points to HWPort::pin or nullptr
Definition: pin.h:101
TraceValue * pintrace[8]
trace channel to trace output driver state
Definition: hwport.h:53
Pin class, handles input and output to external parts.
Definition: pin.h:98
unsigned char pin
port input register
Definition: hwport.h:49
Defines a Port, e.g. a hardware device for GPIO.
Definition: hwport.h:43
STL namespace.
void RegisterPin(const std::string &name, Pin *p)
Definition: avrdevice.h:171
void Reset(void)
Definition: hwport.cpp:77
void CalcOutputs(void)
Calculate the new output value to be transmitted to the environment.
Definition: hwport.cpp:92
IOReg< HWPort > port_reg
Definition: hwport.h:84
IOReg< HWPort > pin_reg
Definition: hwport.h:84
void set_written()
Definition: traceval.cpp:99
HWPort(AvrDevice *core, const std::string &name, bool portToggle=false, int size=8)
Definition: hwport.cpp:34
unsigned char portMask
mask out unused bits, if necessary
Definition: hwport.h:55
unsigned char ddr
data direction register
Definition: hwport.h:50
unsigned char mask
byte mask for HWPort::pin
Definition: pin.h:103
Build a register for TraceValue&#39;s.
Definition: traceval.h:442
void RegisterTraceValue(TraceValue *t)
Registers a TraceValue for this register.
Definition: traceval.cpp:217
void SetPinBit(bool bit, unsigned int bitaddr)
Definition: hwport.cpp:139
std::string GetPortString(void)
returns a string representation of output states
Definition: hwport.cpp:108
unsigned char port
port output register
Definition: hwport.h:48
bool portToggleFeature
controls functionality of SetPin method (write to PIN toggles port register)
Definition: hwport.h:56
~HWPort()
Definition: hwport.cpp:71
void SetDdr(unsigned char val)
setter method for data direction register
Definition: hwport.cpp:123
#define avr_warning(...)
Definition: avrerror.h:133
void SetPort(unsigned char val)
setter method for port register
Definition: hwport.cpp:117
PortPin p[8]
the port pins, e.g. the final IO stages
Definition: hwport.h:52
void hardwareChange(unsigned char val)
Definition: rwmem.h:318
const std::string GetTraceValuePrefix(void)
Returns the scope prefix.
Definition: traceval.h:487
void SetPin(unsigned char val)
setter method for PIN register (for new devices with toggle port)
Definition: hwport.cpp:129
void UnregisterTraceValue(TraceValue *t)
Unregisters a TraceValue, remove it from register.
Definition: traceval.cpp:237
IOReg< HWPort > * pinRegOfPort
points to PIN io register of port or nullptr
Definition: pin.h:102
void change(unsigned val)
Log a change on this value.
Definition: traceval.cpp:68
IOReg< HWPort > ddr_reg
Definition: hwport.h:84
unsigned int portSize
how much bits does this port have [1..8]
Definition: hwport.h:54