simulavr  1.1.0
atmega128.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 "atmega128.h"
27 
28 #include "hardware.h"
29 #include "irqsystem.h"
30 #include "hwport.h"
31 #include "hwstack.h"
32 #include "hwspi.h"
33 #include "hweeprom.h"
34 #include "hwwado.h"
35 #include "hwsreg.h"
36 
37 #include "avrfactory.h"
38 
41 
43  delete acomp;
44  delete timer3;
45  delete timer2;
46  delete timer1;
47  delete timer0;
48  delete timer3irq;
49  delete timer012irq;
50  delete usart1;
51  delete usart0;
52  delete wado;
53  delete extirq;
54  delete eifr_reg;
55  delete eimsk_reg;
56  delete eicrb_reg;
57  delete eicra_reg;
58  delete spi;
59  delete ad;
60  delete aref;
61  delete admux;
62  if(rampz != NULL) delete rampz;
63  delete osccal_reg;
64  delete xdiv_reg;
65  delete stack;
66  delete eeprom;
67  delete irqSystem;
68  delete spmRegister;
69 }
70 
72  unsigned ee_bytes,
73  unsigned ext_bytes,
74  unsigned nrww_start):
75  AvrDevice(224, 4096, ext_bytes, flash_bytes),
76  porta(this, "A"),
77  portb(this, "B"),
78  portc(this, "C"),
79  portd(this, "D"),
80  porte(this, "E"),
81  portf(this, "F"),
82  portg(this, "G", false, 5),
83  assr_reg(&coreTraceGroup, "ASSR"),
84  sfior_reg(&coreTraceGroup, "SFIOR"),
85  prescaler0(this, "0", PinAtPort(&portg, 4), &assr_reg, 3, &sfior_reg, 1, 7),
86  prescaler123(this, "123", &sfior_reg, 0, 7),
87  premux0(&prescaler0),
88  premux1(&prescaler123, PinAtPort(&portd, 6)),
89  premux2(&prescaler123, PinAtPort(&portd, 7)),
90  premux3(&prescaler123, PinAtPort(&porte, 6)),
91  inputCapture1(PinAtPort(&portd, 4)),
92  inputCapture3(PinAtPort(&porte, 7))
93 {
94  // detect ATMega128 configuration
95  bool is_m128 = (flash_bytes == 128 * 1024);
96  if(is_m128)
97  flagELPMInstructions = true;
98  else
99  flagELPMInstructions = false;
100  fuses->SetFuseConfiguration(18, 0xfd99e1);
101  fuses->SetBootloaderConfig(nrww_start, 0x1000, 9, 8);
102  spmRegister = new FlashProgramming(this, 128, nrww_start, FlashProgramming::SPM_MEGA_MODE);
103  irqSystem = new HWIrqSystem(this, 4, 35); //4 bytes per vector, 35 vectors
104  eeprom = new HWEeprom( this, irqSystem, ee_bytes, 22);
105  stack = new HWStackSram(this, 16);
106  xdiv_reg = new XDIVRegister(this, &coreTraceGroup);
108 
109  if(is_m128)
110  rampz = new AddressExtensionRegister(this, "RAMPZ", 1);
111  else
112  rampz = NULL;
113 
114  admux = new HWAdmuxM16(this, &portf.GetPin(0), &portf.GetPin(1), &portf.GetPin(2),
115  &portf.GetPin(3), &portf.GetPin(4), &portf.GetPin(5),
116  &portf.GetPin(6), &portf.GetPin(7));
117  aref = new HWARef4(this, HWARef4::REFTYPE_NOBG);
118  // vector 21 ADConversion Complete
119  ad = new HWAd(this, (is_m128) ? HWAd::AD_M128 : HWAd::AD_M64, irqSystem, 21, admux, aref);
120 
121  spi = new HWSpi(this, irqSystem,
122  PinAtPort(&portb, 2), PinAtPort(&portb, 3), PinAtPort(&portb, 1),
123  PinAtPort(&portb, 0),/*irqvec*/ 17, true);
124 
125  eicra_reg = new IOSpecialReg(&coreTraceGroup, "EICRA");
126  eicrb_reg = new IOSpecialReg(&coreTraceGroup, "EICRB");
127  eimsk_reg = new IOSpecialReg(&coreTraceGroup, "EIMSK");
128  eifr_reg = new IOSpecialReg(&coreTraceGroup, "EIFR");
130  extirq->registerIrq(1, 0, new ExternalIRQSingle(eicra_reg, 0, 2, GetPin("D0")));
131  extirq->registerIrq(2, 1, new ExternalIRQSingle(eicra_reg, 2, 2, GetPin("D1")));
132  extirq->registerIrq(3, 2, new ExternalIRQSingle(eicra_reg, 4, 2, GetPin("D2")));
133  extirq->registerIrq(4, 3, new ExternalIRQSingle(eicra_reg, 6, 2, GetPin("D3")));
134  extirq->registerIrq(5, 4, new ExternalIRQSingle(eicrb_reg, 0, 2, GetPin("E4")));
135  extirq->registerIrq(6, 5, new ExternalIRQSingle(eicrb_reg, 2, 2, GetPin("E5")));
136  extirq->registerIrq(7, 6, new ExternalIRQSingle(eicrb_reg, 4, 2, GetPin("E6")));
137  extirq->registerIrq(8, 7, new ExternalIRQSingle(eicrb_reg, 6, 2, GetPin("E7")));
138 
139  wado = new HWWado(this);
140 
141  usart0 = new HWUsart(this, irqSystem,
142  PinAtPort(&porte,1), PinAtPort(&porte,0), PinAtPort(&porte, 2),
143  18, 19, 20, 0);
144  usart1 = new HWUsart(this, irqSystem,
145  PinAtPort(&portd,3), PinAtPort(&portd,2), PinAtPort(&portd, 5),
146  30, 31, 32, 1);
147 
149  timer012irq->registerLine(0, IRQLine("TOV0", 16));
150  timer012irq->registerLine(1, IRQLine("OCF0", 15));
151  timer012irq->registerLine(2, IRQLine("TOV1", 14));
152  timer012irq->registerLine(3, IRQLine("OCF1B", 13));
153  timer012irq->registerLine(4, IRQLine("OCF1A", 12));
154  timer012irq->registerLine(5, IRQLine("ICF1", 11));
155  timer012irq->registerLine(6, IRQLine("TOV2", 10));
156  timer012irq->registerLine(7, IRQLine("OCF2", 9));
157 
158  timer3irq = new TimerIRQRegister(this, irqSystem, -2);
159  timer3irq->registerLine(0, IRQLine("OCF1C", 24));
160  timer3irq->registerLine(1, IRQLine("OCF3C", 28));
161  timer3irq->registerLine(2, IRQLine("TOV3", 29));
162  timer3irq->registerLine(3, IRQLine("OCF3B", 27));
163  timer3irq->registerLine(4, IRQLine("OCF3A", 26));
164  timer3irq->registerLine(5, IRQLine("ICF3", 25));
165 
166  timer0 = new HWTimer8_1C(this,
167  &premux0,
168  0,
169  timer012irq->getLine("TOV0"),
170  timer012irq->getLine("OCF0"),
171  PinAtPort(&portb, 4));
172  timer1 = new HWTimer16_3C(this,
173  &premux1,
174  1,
175  timer012irq->getLine("TOV1"),
176  timer012irq->getLine("OCF1A"),
177  PinAtPort(&portb, 5),
178  timer012irq->getLine("OCF1B"),
179  PinAtPort(&portb, 6),
180  timer3irq->getLine("OCF1C"),
181  PinAtPort(&portb, 7),
182  timer012irq->getLine("ICF1"),
183  &inputCapture1);
184  timer2 = new HWTimer8_1C(this,
185  &premux2,
186  2,
187  timer012irq->getLine("TOV2"),
188  timer012irq->getLine("OCF2"),
189  PinAtPort(&portb, 7));
190  timer3 = new HWTimer16_3C(this,
191  &premux3,
192  3,
193  timer3irq->getLine("TOV3"),
194  timer3irq->getLine("OCF3A"),
195  PinAtPort(&porte, 3),
196  timer3irq->getLine("OCF3B"),
197  PinAtPort(&porte, 4),
198  timer3irq->getLine("OCF3C"),
199  PinAtPort(&porte, 5),
200  timer3irq->getLine("ICF3"),
201  &inputCapture3);
202 
203  acomp = new HWAcomp(this, irqSystem, PinAtPort(&porte, 2), PinAtPort(&porte, 3), 23, ad, timer1, &sfior_reg);
204 
205  rw[0x9d]= & usart1->ucsrc_reg;
206  rw[0x9c]= & usart1->udr_reg;
207  rw[0x9b]= & usart1->ucsra_reg;
208  rw[0x9a]= & usart1->ucsrb_reg;
209  rw[0x99]= & usart1->ubrr_reg;
210  rw[0x98]= & usart1->ubrrhi_reg;
211  // 0x97, 0x96 reserved
212  rw[0x95]= & usart0->ucsrc_reg;
213  // 0x94 - 0x91 reserved
214  rw[0x90]= & usart0->ubrrhi_reg;
215  // 0x8f reserved
216  if(!is_m128)
217  rw[0x8e]= & ad->adcsrb_reg;
218  // 0x8d reserved
219  rw[0x8c]= & timer3->tccrc_reg;
220  rw[0x8b]= & timer3->tccra_reg;
221  rw[0x8a]= & timer3->tccrb_reg;
222  rw[0x89]= & timer3->tcnt_h_reg;
223  rw[0x88]= & timer3->tcnt_l_reg;
224  rw[0x87]= & timer3->ocra_h_reg;
225  rw[0x86]= & timer3->ocra_l_reg;
226  rw[0x85]= & timer3->ocrb_h_reg;
227  rw[0x84]= & timer3->ocrb_l_reg;
228  rw[0x83]= & timer3->ocrc_h_reg;
229  rw[0x82]= & timer3->ocrc_l_reg;
230  rw[0x81]= & timer3->icr_h_reg;
231  rw[0x80]= & timer3->icr_l_reg;
232  // 0x7f, 0x7e reserved
233  rw[0x7d]= & timer3irq->timsk_reg;
234  rw[0x7c]= & timer3irq->tifr_reg;
235  // 0x7b reserved
236  rw[0x7a]= & timer1->tccrc_reg;
237  rw[0x79]= & timer1->ocrc_h_reg;
238  rw[0x78]= & timer1->ocrc_l_reg;
239 
240  rw[0x6f]= osccal_reg;
241 
242  rw[0x6a]= eicra_reg;
243  rw[0x68]= & spmRegister->spmcr_reg;
244 
245  rw[0x65]= & portg.port_reg;
246  rw[0x64]= & portg.ddr_reg;
247  rw[0x63]= & portg.pin_reg;
248  rw[0x62]= & portf.port_reg;
249  rw[0x61]= & portf.ddr_reg;
250 
251  rw[0x5f]= statusRegister;
252  rw[0x5e]= & ((HWStackSram *)stack)->sph_reg;
253  rw[0x5d]= & ((HWStackSram *)stack)->spl_reg;
254  rw[0x5c]= xdiv_reg;
255  if(is_m128)
256  rw[0x5b]= & rampz->ext_reg;
257  rw[0x5a]= eicrb_reg;
258  rw[0x59]= eimsk_reg;
259  rw[0x58]= eifr_reg;
260  rw[0x57]= & timer012irq->timsk_reg;
261  rw[0x56]= & timer012irq->tifr_reg;
262 
263  rw[0x53]= & timer0->tccr_reg;
264  rw[0x52]= & timer0->tcnt_reg;
265  rw[0x51]= & timer0->ocra_reg;
266  rw[0x50]= & assr_reg;
267  rw[0x4f]= & timer1->tccra_reg;
268  rw[0x4e]= & timer1->tccrb_reg;
269  rw[0x4d]= & timer1->tcnt_h_reg;
270  rw[0x4c]= & timer1->tcnt_l_reg;
271  rw[0x4b]= & timer1->ocra_h_reg;
272  rw[0x4a]= & timer1->ocra_l_reg;
273  rw[0x49]= & timer1->ocrb_h_reg;
274  rw[0x48]= & timer1->ocrb_l_reg;
275  rw[0x47]= & timer1->icr_h_reg;
276  rw[0x46]= & timer1->icr_l_reg;
277  rw[0x45]= & timer2->tccr_reg;
278  rw[0x44]= & timer2->tcnt_reg;
279  rw[0x43]= & timer2->ocra_reg;
280 
281  //0x42: on chip debug
282 
283  rw[0x40]= & sfior_reg;
284  rw[0x3f]= & eeprom->eearh_reg;
285  rw[0x3e]= & eeprom->eearl_reg;
286  rw[0x3d]= & eeprom->eedr_reg;
287  rw[0x3c]= & eeprom->eecr_reg;
288  rw[0x3b]= & porta.port_reg;
289  rw[0x3a]= & porta.ddr_reg;
290  rw[0x39]= & porta.pin_reg;
291  rw[0x38]= & portb.port_reg;
292  rw[0x37]= & portb.ddr_reg;
293  rw[0x36]= & portb.pin_reg;
294  rw[0x35]= & portc.port_reg;
295  rw[0x34]= & portc.ddr_reg;
296  rw[0x33]= & portc.pin_reg;
297  rw[0x32]= & portd.port_reg;
298  rw[0x31]= & portd.ddr_reg;
299  rw[0x30]= & portd.pin_reg;
300  rw[0x2f]= & spi->spdr_reg;
301  rw[0x2e]= & spi->spsr_reg;
302  rw[0x2d]= & spi->spcr_reg;
303  rw[0x2c]= & usart0->udr_reg;
304  rw[0x2b]= & usart0->ucsra_reg;
305  rw[0x2a]= & usart0->ucsrb_reg;
306  rw[0x29]= & usart0->ubrr_reg;
307  rw[0x28]= & acomp->acsr_reg;
308  rw[0x27]= & ad->admux_reg;
309  rw[0x26]= & ad->adcsra_reg;
310  rw[0x25]= & ad->adch_reg;
311  rw[0x24]= & ad->adcl_reg;
312  rw[0x23]= & porte.port_reg;
313  rw[0x22]= & porte.ddr_reg;
314  rw[0x21]= & porte.pin_reg;
315  rw[0x20]= & portf.pin_reg;
316 
317  Reset();
318 }
319 
oscillator version 3.x and older, 8bit, one range
Definition: rwmem.h:179
ADC reference is selected on 3 or 4 different sources: Vcc, aref pin, bandgap or 2.56V reference.
Definition: hwad.h:60
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
0:aref, 1:vcc, 2:-, 3:2.56V
Definition: hwad.h:67
AvrFuses * fuses
Definition: avrdevice.h:100
AddressExtensionRegister * rampz
RAMPZ address extension register.
Definition: avrdevice.h:105
AVR device class for ATMega64, see AvrDevice_atmega128base.
Definition: atmega128.h:93
PrescalerMultiplexerExt premux1
prescale multiplexer for timer1
Definition: atmega128.h:73
IOSpecialReg * eifr_reg
EIFR IO register.
Definition: atmega128.h:59
HWIrqSystem * irqSystem
Definition: avrdevice.h:104
PrescalerMultiplexer premux0
prescale multiplexer for timer0
Definition: atmega128.h:72
IOReg< HWAd > admux_reg
Definition: hwad.h:269
ExternalIRQHandler * extirq
external interrupt support
Definition: atmega128.h:55
Implements a stack with stack register using RAM as stackarea.
Definition: hwstack.h:131
IOReg< HWUart > ubrrhi_reg
IO register "UBRRxH" - baudrate.
Definition: hwuart.h:136
HWPort portd
port D
Definition: atmega128.h:51
IOReg< HWEeprom > eedr_reg
Definition: hweeprom.h:101
IOReg< HWTimer8_1C > tccr_reg
control register
Definition: hwtimer.h:388
HWPort portc
port C
Definition: atmega128.h:50
void registerIrq(int vector, int irqBit, ExternalIRQ *extirq)
Definition: externalirq.cpp:53
Pin & GetPin(unsigned char pinNo)
returns a pin reference of pin with pin number
Definition: hwport.cpp:87
HWTimer8_1C * timer2
timer 2 unit
Definition: atmega128.h:80
Timer unit with 8Bit counter and one output compare unit.
Definition: hwtimer.h:377
ICaptureSource inputCapture1
input capture source for timer1
Definition: atmega128.h:76
IOReg< HWTimer8 > tcnt_reg
counter register
Definition: hwtimer.h:229
Definition: hwwado.h:38
IOSpecialReg * eicra_reg
EICRA IO register.
Definition: atmega128.h:56
Handler for external IRQ&#39;s to communicate with IRQ system and mask/flag registers.
Definition: externalirq.h:41
Represents a timer interrupt line, Frontend for timer interrupts.
Definition: timerirq.h:42
TimerIRQRegister * timer3irq
timer interrupt unit for timer 3
Definition: atmega128.h:83
HWAd * ad
adc unit
Definition: atmega128.h:65
void SetFuseConfiguration(int size, unsigned long defvalue)
Configure fuses.
Definition: flashprog.cpp:246
IOReg< AddressExtensionRegister > ext_reg
Definition: ioregs.h:45
OSCCALRegister * osccal_reg
OSCCAL IO register.
Definition: atmega128.h:61
AVRDevice class for ATMega64 and ATMega128.
Definition: atmega128.h:45
HWTimer8_1C * timer0
timer 0 unit
Definition: atmega128.h:78
IOReg< HWUart > ubrr_reg
IO register "UBRRxL" - baudrate.
Definition: hwuart.h:136
ICaptureSource inputCapture3
input capture source for timer3
Definition: atmega128.h:77
IOSpecialReg tifr_reg
the TIFRx register
Definition: timerirq.h:74
IOReg< HWAd > adcsrb_reg
Definition: hwad.h:269
IOReg< HWSpi > spdr_reg
Definition: hwspi.h:121
AvrDevice_atmega128base(unsigned flash_bytes, unsigned ee_bytes, unsigned ext_bytes, unsigned nrww_start)
Definition: atmega128.cpp:71
Implements the I/O hardware necessary to do USART transfers.
Definition: hwuart.h:149
IOReg< HWPort > port_reg
Definition: hwport.h:84
IOReg< HWUart > ucsra_reg
Definition: hwuart.h:136
void Reset()
Definition: avrdevice.cpp:390
Implement XDIV register.
Definition: rwmem.h:156
IOReg< HWPort > pin_reg
Definition: hwport.h:84
IOSpecialReg sfior_reg
SFIOR IO register.
Definition: atmega128.h:69
IOReg< HWSpi > spcr_reg
Definition: hwspi.h:121
XDIVRegister * xdiv_reg
XDIV IO register.
Definition: atmega128.h:60
HWUsart * usart0
usart 0 unit
Definition: atmega128.h:85
PrescalerMultiplexerExt premux3
prescale multiplexer for timer3
Definition: atmega128.h:75
HWPort portf
port F
Definition: atmega128.h:53
TraceValueCoreRegister coreTraceGroup
Definition: avrdevice.h:108
IOReg< HWUart > ucsrb_reg
Definition: hwuart.h:136
ADC type M64: ADC on atmega64.
Definition: hwad.h:261
IOReg< HWAd > adcsra_reg
Definition: hwad.h:269
IOReg< HWEeprom > eearh_reg
Definition: hweeprom.h:101
HWARef * aref
adc reference unit
Definition: atmega128.h:64
IOSpecialReg * eimsk_reg
EIMSK IO register.
Definition: atmega128.h:58
Pin * GetPin(const char *name)
Definition: avrdevice.cpp:76
HWUsart * usart1
usart 1 unit
Definition: atmega128.h:86
Timer unit with 16Bit counter and 3 output compare units.
Definition: hwtimer.h:656
HWPort portb
port B
Definition: atmega128.h:49
Provices flag and mask register for timer interrupts and connects irq lines to irqsystem.
Definition: timerirq.h:61
HWPort porte
port E
Definition: atmega128.h:52
IOReg< HWEeprom > eecr_reg
Definition: hweeprom.h:101
HWEeprom * eeprom
Definition: avrdevice.h:102
AVR device class for ATMega128, see AvrDevice_atmega128base.
Definition: atmega128.h:100
Definition: hwspi.h:38
void registerLine(int idx, IRQLine *irq)
Definition: timerirq.cpp:88
PrescalerMultiplexerExt premux2
prescale multiplexer for timer2
Definition: atmega128.h:74
#define AVR_REGISTER(name, class)
Definition: avrfactory.h:69
RWMemoryMember ** rw
The whole memory: R0-R31, IO, Internal RAM.
Definition: avrdevice.h:129
TimerIRQRegister * timer012irq
timer interrupt unit for timer 0 to 2
Definition: atmega128.h:82
ADC type M128: ADC on atmega128.
Definition: hwad.h:262
Provides the programming engine for flash self programming.
Definition: flashprog.h:38
void SetBootloaderConfig(unsigned addr, int size, int bPosBOOTSZ, int bPosBOOTRST)
Set bootloader support configuration.
Definition: flashprog.cpp:274
IOReg< HWAd > adch_reg
Definition: hwad.h:269
HWPort portg
port G
Definition: atmega128.h:54
IOReg< HWSpi > spsr_reg
Definition: hwspi.h:121
IOReg< HWEeprom > eearl_reg
Definition: hweeprom.h:101
IOReg< HWAd > adcl_reg
Definition: hwad.h:269
HWTimer16_3C * timer1
timer 1 unit
Definition: atmega128.h:79
HWPort porta
port A
Definition: atmega128.h:48
IOReg< HWTimer8 > ocra_reg
output compare A register
Definition: hwtimer.h:230
HWStack * stack
Definition: avrdevice.h:131
RWSreg * statusRegister
the memory interface for status
Definition: avrdevice.h:133
IOReg< HWUart > udr_reg
Definition: hwuart.h:136
IOSpecialReg * eicrb_reg
EICRB IO register.
Definition: atmega128.h:57
IRQLine * getLine(const std::string &name)
Definition: timerirq.cpp:109
HWWado * wado
WDT timer.
Definition: avrdevice.h:134
Definition: hwad.h:204
FlashProgramming * spmRegister
Definition: avrdevice.h:99
IOSpecialReg assr_reg
ASSR IO register.
Definition: atmega128.h:68
HWSpi * spi
spi unit
Definition: atmega128.h:84
HWAdmux * admux
adc multiplexer unit
Definition: atmega128.h:63
IOReg< HWPort > ddr_reg
Definition: hwport.h:84
HWTimer16_3C * timer3
timer 3 unit
Definition: atmega128.h:81
IOReg< HWUsart > ucsrc_reg
Definition: hwuart.h:173
IOSpecialReg timsk_reg
the TIMSKx register
Definition: timerirq.h:73
Analog comparator peripheral.
Definition: hwacomp.h:42
IOReg< FlashProgramming > spmcr_reg
Definition: flashprog.h:95
Implement OSCCAL register.
Definition: rwmem.h:174
HWAcomp * acomp
analog compare unit
Definition: atmega128.h:66
External interrupt (INT0, INT1...) on a single pin, one and 2 bit configuration.
Definition: externalirq.h:110
bool flagELPMInstructions
ELPM instructions are available (only on devices with bigger flash)
Definition: avrdevice.h:120