~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/gpsim/devices/p16f1503.cc

  • Committer: arcachofo
  • Date: 2021-01-01 14:23:42 UTC
  • Revision ID: arcachofo@simulide.com-20210101142342-ozfljnll44g5lbl3
Initial Commit 0.5.15-RC3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2013,2014,2017 Roy R. Rankin
 
3
 
 
4
This file is part of the libgpsim library of gpsim
 
5
 
 
6
This library is free software; you can redistribute it and/or
 
7
modify it under the terms of the GNU Lesser General Public
 
8
License as published by the Free Software Foundation; either
 
9
version 2.1 of the License, or (at your option) any later version.
 
10
 
 
11
This library is distributed in the hope that it will be useful,
 
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
Lesser General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU Lesser General Public
 
17
License along with this library; if not, see
 
18
<http://www.gnu.org/licenses/lgpl-2.1.html>.
 
19
*/
 
20
/****************************************************************
 
21
*                                                               *
 
22
*  Modified 2018 by Santiago Gonzalez    santigoro@gmail.com    *
 
23
*                                                               *
 
24
*****************************************************************/
 
25
 
 
26
 
 
27
// this  processors have extended 14bit instructions
 
28
 
 
29
#include <stdio.h>
 
30
#include <iostream>
 
31
#include <string>
 
32
 
 
33
#include "eeprom.h"
 
34
#include "p16f1503.h"
 
35
#include "pic-ioports.h"
 
36
#include "apfcon.h"
 
37
#include "pir.h"
 
38
 
 
39
//#define DEBUG
 
40
#if defined(DEBUG)
 
41
#include "config.h"
 
42
#define Dprintf(arg) {printf("%s:%d ",__FILE__,__LINE__); printf arg; }
 
43
#else
 
44
#define Dprintf(arg) {}
 
45
#endif
 
46
 
 
47
 
 
48
P16F1503::P16F1503(const char *_name)
 
49
  : _14bit_e_processor(_name ),
 
50
    comparator(this),
 
51
    pie1(this,"pie1" ),
 
52
    pie2(this,"pie2" ),
 
53
    pie3(this,"pie3" ),
 
54
    t2con(this, "t2con" ),
 
55
    pr2(this, "pr2" ),
 
56
    tmr2(this, "tmr2" ),
 
57
    t1con_g(this, "t1con" ),
 
58
    tmr1l(this, "tmr1l" ),
 
59
    tmr1h(this, "tmr1h" ),
 
60
    fvrcon(this, "fvrcon", 0xbf, 0x40),
 
61
    borcon(this, "borcon" ),
 
62
    ansela(this, "ansela" ),
 
63
    anselc(this, "anselc" ),
 
64
    adcon0(this,"adcon0" ),
 
65
    adcon1(this,"adcon1" ),
 
66
    adcon2(this,"adcon2" ),
 
67
    adresh(this,"adresh" ),
 
68
    adresl(this,"adresl" ),
 
69
    osccon(0),
 
70
    osctune(this, "osctune" ),
 
71
    oscstat(this, "oscstat" ),
 
72
    wdtcon(this, "wdtcon", 0x3f),
 
73
    ssp(this),
 
74
    apfcon1(this, "apfcon", 0x3b),
 
75
    pwm1con(this, "pwm1con", 0),
 
76
    pwm1dcl(this, "pwm1dcl" ),
 
77
    pwm1dch(this, "pwm1dch" ),
 
78
    pwm2con(this, "pwm2con", 1),
 
79
    pwm2dcl(this, "pwm2dcl" ),
 
80
    pwm2dch(this, "pwm2dch" ),
 
81
    pwm3con(this, "pwm3con", 2),
 
82
    pwm3dcl(this, "pwm3dcl" ),
 
83
    pwm3dch(this, "pwm3dch" ),
 
84
    pwm4con(this, "pwm4con", 3),
 
85
    pwm4dcl(this, "pwm4dcl" ),
 
86
    pwm4dch(this, "pwm4dch" ),
 
87
    cwg(this), nco(this), 
 
88
    clcdata(this, "clcdata" ),
 
89
    clc1(this, 0, &clcdata), clc2(this, 1, &clcdata),
 
90
        frc( 600000., CLC::FRC_IN, this ),
 
91
        lfintosc( 32000., CLC::LFINTOSC, this ),  // 32kHz is within tolerance or 31kHz
 
92
        hfintosc( 16e6, CLC::HFINTOSC, this ),
 
93
        vregcon( this, "vregcon" )
 
94
{
 
95
  m_portc= new PicPortBRegister(this,"portc", intcon, 8,0x3f);
 
96
  m_trisc = new PicTrisRegister(this,"trisc", m_portc, false, 0x3f);
 
97
  m_latc  = new PicLatchRegister(this,"latc" ,m_portc, 0x3f);
 
98
 
 
99
 
 
100
  m_iocaf = new IOCxF(this, "iocaf", 0x3f);
 
101
  m_iocap = new IOC(this, "iocap", 0x3f);
 
102
  m_iocan = new IOC(this, "iocan", 0x3f);
 
103
  m_porta= new PicPortIOCRegister(this,"porta", intcon, m_iocap, m_iocan, m_iocaf, 8,0x3f);
 
104
  m_trisa = new PicTrisRegister(this,"trisa", m_porta, false, 0x37);
 
105
  m_lata  = new PicLatchRegister(this,"lata",m_porta, 0x37);
 
106
  m_wpua = new WPU(this, "wpua", m_porta, 0x3f);
 
107
  m_daccon0 = new DACCON0(this, "daccon0", 0xb4, 32);
 
108
  m_daccon1 = new DACCON1(this, "daccon1", 0xff, m_daccon0);
 
109
  m_cpu_temp = 30.0;
 
110
 
 
111
 
 
112
  tmr0.set_cpu(this, m_porta, 4, &option_reg);
 
113
  tmr0.start(0);
 
114
  tmr0.set_t1gcon(&t1con_g.t1gcon);
 
115
  set_mclr_pin(4);
 
116
 
 
117
  ((INTCON_14_PIR *)intcon)->write_mask = 0xfe;
 
118
 
 
119
 
 
120
  pir1 = new PIR1v1822(this,"pir1",intcon, &pie1);
 
121
  pir2 = new PIR2v1822(this,"pir2",intcon, &pie2);
 
122
  pir3 = new PIR3v178x(this,"pir3",intcon, &pie3);
 
123
 
 
124
  pir1->valid_bits = pir1->writable_bits = 0xcb;
 
125
  pir2->valid_bits = pir2->writable_bits = 0x6c;
 
126
  pir3->valid_bits = pir3->writable_bits = 0x03;
 
127
 
 
128
  comparator.cmxcon0[0] = new CMxCON0(this, "cm1con0", 0, &comparator);
 
129
  comparator.cmxcon1[0] = new CMxCON1(this, "cm1con1", 0, &comparator);
 
130
  comparator.cmout = new CMOUT(this, "cmout");
 
131
  comparator.cmxcon0[1] = new CMxCON0(this, "cm2con0", 1, &comparator);
 
132
  comparator.cmxcon1[1] = new CMxCON1(this, "cm2con1", 1, &comparator);
 
133
}
 
134
 
 
135
P16F1503::~P16F1503()
 
136
{
 
137
    unassignMCLRPin();
 
138
    delete_file_registers(0x20, 0x7f);
 
139
    delete_file_registers(0xa0, 0xbf);
 
140
 
 
141
    delete_SfrReg(m_iocap);
 
142
    delete_SfrReg(m_iocan);
 
143
    delete_SfrReg(m_iocaf);
 
144
    delete_SfrReg(m_daccon0);
 
145
    delete_SfrReg(m_daccon1);
 
146
 
 
147
    delete_SfrReg(m_trisa);
 
148
    delete_SfrReg(m_porta);
 
149
    delete_SfrReg(m_lata);
 
150
    delete_SfrReg(m_wpua);
 
151
    delete_SfrReg(m_portc);
 
152
    delete_SfrReg(m_trisc);
 
153
    delete_SfrReg(m_latc);
 
154
 
 
155
    remove_SfrReg(&clcdata);
 
156
    remove_SfrReg(&clc1.clcxcon);
 
157
    remove_SfrReg(&clc1.clcxpol);
 
158
    remove_SfrReg(&clc1.clcxsel0);
 
159
    remove_SfrReg(&clc1.clcxsel1);
 
160
    remove_SfrReg(&clc1.clcxgls0);
 
161
    remove_SfrReg(&clc1.clcxgls1);
 
162
    remove_SfrReg(&clc1.clcxgls2);
 
163
    remove_SfrReg(&clc1.clcxgls3);
 
164
    remove_SfrReg(&clc2.clcxcon);
 
165
    remove_SfrReg(&clc2.clcxpol);
 
166
    remove_SfrReg(&clc2.clcxsel0);
 
167
    remove_SfrReg(&clc2.clcxsel1);
 
168
    remove_SfrReg(&clc2.clcxgls0);
 
169
    remove_SfrReg(&clc2.clcxgls1);
 
170
    remove_SfrReg(&clc2.clcxgls2);
 
171
    remove_SfrReg(&clc2.clcxgls3);
 
172
    remove_SfrReg(&tmr0);
 
173
 
 
174
    remove_SfrReg(&tmr1l);
 
175
    remove_SfrReg(&tmr1h);
 
176
    remove_SfrReg(&t1con_g);
 
177
    remove_SfrReg(&t1con_g.t1gcon);
 
178
 
 
179
    remove_SfrReg(&tmr2);
 
180
    remove_SfrReg(&pr2);
 
181
    remove_SfrReg(&t2con);
 
182
    remove_SfrReg(&ssp.sspbuf);
 
183
    remove_SfrReg(&ssp.sspadd);
 
184
    remove_SfrReg(ssp.sspmsk);
 
185
    remove_SfrReg(&ssp.sspstat);
 
186
    remove_SfrReg(&ssp.sspcon);
 
187
    remove_SfrReg(&ssp.sspcon2);
 
188
    remove_SfrReg(&ssp.ssp1con3);
 
189
    remove_SfrReg(&pwm1con);
 
190
    remove_SfrReg(&pwm1dcl);
 
191
    remove_SfrReg(&pwm1dch);
 
192
    remove_SfrReg(&pwm2con);
 
193
    remove_SfrReg(&pwm2dcl);
 
194
    remove_SfrReg(&pwm2dch);
 
195
    remove_SfrReg(&pwm3con);
 
196
    remove_SfrReg(&pwm3dcl);
 
197
    remove_SfrReg(&pwm3dch);
 
198
    remove_SfrReg(&pwm4con);
 
199
    remove_SfrReg(&pwm4dcl);
 
200
    remove_SfrReg(&pwm4dch);
 
201
// RRR   remove_SfrReg(&pstr1con);
 
202
    remove_SfrReg(&pie1);
 
203
    remove_SfrReg(&pie2);
 
204
    remove_SfrReg(&pie3);
 
205
    remove_SfrReg(&adresl);
 
206
    remove_SfrReg(&adresh);
 
207
    remove_SfrReg(&adcon0);
 
208
    remove_SfrReg(&adcon1);
 
209
    remove_SfrReg(&adcon2);
 
210
    remove_SfrReg(&borcon);
 
211
    remove_SfrReg(&fvrcon);
 
212
    remove_SfrReg(&apfcon1);
 
213
    remove_SfrReg(&ansela);
 
214
    remove_SfrReg(&anselc);
 
215
    remove_SfrReg(&vregcon);
 
216
    remove_SfrReg(&ssp.sspbuf);
 
217
    remove_SfrReg(&ssp.sspadd);
 
218
    remove_SfrReg(ssp.sspmsk);
 
219
    remove_SfrReg(&ssp.sspstat);
 
220
    remove_SfrReg(&ssp.sspcon);
 
221
    remove_SfrReg(&ssp.sspcon2);
 
222
    remove_SfrReg(&ssp.ssp1con3);
 
223
    remove_SfrReg(&nco.nco1accl);
 
224
    remove_SfrReg(&nco.nco1acch);
 
225
    remove_SfrReg(&nco.nco1accu);
 
226
    remove_SfrReg(&nco.nco1incl);
 
227
    remove_SfrReg(&nco.nco1inch);
 
228
    remove_SfrReg(&nco.nco1con);
 
229
    remove_SfrReg(&nco.nco1clk);
 
230
    remove_SfrReg(&cwg.cwg1con0);
 
231
    remove_SfrReg(&cwg.cwg1con1);
 
232
    remove_SfrReg(&cwg.cwg1con2);
 
233
    remove_SfrReg(&cwg.cwg1dbr);
 
234
    remove_SfrReg(&cwg.cwg1dbf);
 
235
 
 
236
 
 
237
//RRR    remove_SfrReg(&pstr1con);
 
238
    remove_SfrReg(&option_reg);
 
239
    remove_SfrReg(osccon);
 
240
    remove_SfrReg(&oscstat);
 
241
 
 
242
    remove_SfrReg(comparator.cmxcon0[0]);
 
243
    remove_SfrReg(comparator.cmxcon1[0]);
 
244
    remove_SfrReg(comparator.cmout);
 
245
    remove_SfrReg(comparator.cmxcon0[1]);
 
246
    remove_SfrReg(comparator.cmxcon1[1]);
 
247
    delete_SfrReg(pir1);
 
248
    delete_SfrReg(pir2);
 
249
    delete_SfrReg(pir3);
 
250
    delete e;
 
251
}
 
252
 
 
253
void P16F1503::create_iopin_map()
 
254
{
 
255
  assign_pin(1, 0);        //Vdd
 
256
  assign_pin(2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5));
 
257
  assign_pin(3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4));
 
258
  assign_pin(4, m_porta->addPin(new IO_bi_directional_pu("porta3"),3));
 
259
  assign_pin(5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5));
 
260
  assign_pin(6, m_portc->addPin(new IO_bi_directional_pu("portc4"),4));
 
261
  assign_pin(7, m_portc->addPin(new IO_bi_directional_pu("portc3"),3));
 
262
 
 
263
  assign_pin(8, m_portc->addPin(new IO_bi_directional_pu("portc2"),2));
 
264
  assign_pin(9, m_portc->addPin(new IO_bi_directional_pu("portc1"),1));
 
265
  assign_pin(10, m_portc->addPin(new IO_bi_directional_pu("portc0"),0));
 
266
 
 
267
  assign_pin(11, m_porta->addPin(new IO_bi_directional_pu("porta2"),2));
 
268
  assign_pin(12, m_porta->addPin(new IO_bi_directional_pu("porta1"),1));
 
269
  assign_pin(13, m_porta->addPin(new IO_bi_directional_pu("porta0"),0));
 
270
  assign_pin(14, 0);        // Vss
 
271
}
 
272
 
 
273
void P16F1503::create_sfr_map()
 
274
{
 
275
    pir_set_2_def.set_pir1(pir1);
 
276
    pir_set_2_def.set_pir2(pir2);
 
277
    pir_set_2_def.set_pir3(pir3);
 
278
 
 
279
    add_file_registers(0x20, 0x7f, 0x00);
 
280
    add_file_registers(0xa0, 0xbf, 0x00);
 
281
 
 
282
    add_SfrReg(m_porta, 0x0c);
 
283
    add_SfrReg(m_portc, 0x0e);
 
284
    add_SfrRegR(pir1,    0x11, RegisterValue(0,0),"pir1");
 
285
    add_SfrRegR(pir2,    0x12, RegisterValue(0,0),"pir2");
 
286
    add_SfrRegR(pir3,    0x13, RegisterValue(0,0),"pir3");
 
287
    add_SfrReg(&tmr0,   0x15);
 
288
 
 
289
    add_SfrReg(&tmr1l,  0x16, RegisterValue(0,0),"tmr1l");
 
290
    add_SfrReg(&tmr1h,  0x17, RegisterValue(0,0),"tmr1h");
 
291
    add_SfrReg(&t1con_g,  0x18, RegisterValue(0,0));
 
292
    add_SfrReg(&t1con_g.t1gcon, 0x19, RegisterValue(0,0));
 
293
 
 
294
    add_SfrRegR(&tmr2,   0x1a, RegisterValue(0,0));
 
295
    add_SfrRegR(&pr2,    0x1b, RegisterValue(0,0));
 
296
    add_SfrRegR(&t2con,  0x1c, RegisterValue(0,0));
 
297
 
 
298
    add_SfrReg(m_trisa, 0x8c, RegisterValue(0x3f,0));
 
299
    add_SfrReg(m_trisc, 0x8e, RegisterValue(0x3f,0));
 
300
 
 
301
    pcon.valid_bits = 0xcf;
 
302
    add_SfrReg(&option_reg, 0x95, RegisterValue(0xff,0));
 
303
    add_SfrRegR(osccon,     0x99, RegisterValue(0x38,0));
 
304
    add_SfrReg(&oscstat,    0x9a, RegisterValue(0,0));
 
305
 
 
306
    intcon_reg.set_pir_set(get_pir_set());
 
307
 
 
308
    tmr1l.tmrh = &tmr1h;
 
309
    tmr1l.t1con = &t1con_g;
 
310
    tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v1::TMR1IF));
 
311
 
 
312
    tmr1h.tmrl  = &tmr1l;
 
313
    t1con_g.tmrl  = &tmr1l;
 
314
    t1con_g.t1gcon.set_tmrl(&tmr1l);
 
315
    t1con_g.t1gcon.setInterruptSource(new InterruptSource(pir1, PIR1v1822::TMR1IF));
 
316
 
 
317
    tmr1l.setIOpin(&(*m_porta)[5]);
 
318
    t1con_g.t1gcon.setGatepin(&(*m_porta)[3]);
 
319
 
 
320
    add_SfrRegR(&pie1,   0x91, RegisterValue(0,0));
 
321
    add_SfrRegR(&pie2,   0x92, RegisterValue(0,0));
 
322
    add_SfrRegR(&pie3,   0x93, RegisterValue(0,0));
 
323
    add_SfrReg(&adresl, 0x9b);
 
324
    add_SfrReg(&adresh, 0x9c);
 
325
    add_SfrRegR(&adcon0, 0x9d, RegisterValue(0x00,0));
 
326
    add_SfrRegR(&adcon1, 0x9e, RegisterValue(0x00,0));
 
327
    add_SfrRegR(&adcon2, 0x9f, RegisterValue(0x00,0));
 
328
 
 
329
    add_SfrReg(m_lata,    0x10c);
 
330
    add_SfrReg(m_latc, 0x10e);
 
331
    add_SfrRegR(comparator.cmxcon0[0], 0x111, RegisterValue(0x04,0));
 
332
    add_SfrRegR(comparator.cmxcon1[0], 0x112, RegisterValue(0x00,0));
 
333
    add_SfrRegR(comparator.cmxcon0[1], 0x113, RegisterValue(0x04,0));
 
334
    add_SfrRegR(comparator.cmxcon1[1], 0x114, RegisterValue(0x00,0));
 
335
    add_SfrRegR(comparator.cmout,      0x115, RegisterValue(0x00,0));
 
336
    add_SfrReg(&borcon,   0x116, RegisterValue(0x80,0));
 
337
    add_SfrReg(&fvrcon,   0x117, RegisterValue(0x00,0));
 
338
    add_SfrRegR(m_daccon0, 0x118, RegisterValue(0x00,0));
 
339
    add_SfrRegR(m_daccon1, 0x119, RegisterValue(0x00,0));
 
340
    add_SfrRegR(&apfcon1 ,  0x11d, RegisterValue(0x00,0));
 
341
    add_SfrRegR(&ansela,   0x18c, RegisterValue(0x17,0));
 
342
    add_SfrRegR(&anselc,   0x18e, RegisterValue(0x0f,0));
 
343
    get_eeprom()->get_reg_eedata()->new_name("pmdatl");
 
344
    get_eeprom()->get_reg_eedatah()->new_name("pmdath");
 
345
    add_SfrRegR(get_eeprom()->get_reg_eeadr(), 0x191, RegisterValue(0,0), "pmadrl");
 
346
    add_SfrRegR(get_eeprom()->get_reg_eeadrh(), 0x192, RegisterValue(0,0), "pmadrh");
 
347
    add_SfrReg(get_eeprom()->get_reg_eedata(),  0x193);
 
348
    add_SfrReg(get_eeprom()->get_reg_eedatah(),  0x194);
 
349
    get_eeprom()->get_reg_eecon1()->set_always_on(1<<7);
 
350
    add_SfrRegR(get_eeprom()->get_reg_eecon1(),  0x195, RegisterValue(0x80,0), "pmcon1");
 
351
    add_SfrRegR(get_eeprom()->get_reg_eecon2(),  0x196, RegisterValue(0,0), "pmcon2");
 
352
    add_SfrRegR(&vregcon, 0x197, RegisterValue(1,0));
 
353
 
 
354
    add_SfrReg(m_wpua,     0x20c, RegisterValue(0xff,0),"wpua");
 
355
  
 
356
    add_SfrRegR(&ssp.sspbuf,  0x211, RegisterValue(0,0),"ssp1buf");
 
357
    add_SfrRegR(&ssp.sspadd,  0x212, RegisterValue(0,0),"ssp1add");
 
358
    add_SfrRegR(ssp.sspmsk, 0x213, RegisterValue(0xff,0),"ssp1msk");
 
359
    add_SfrRegR(&ssp.sspstat, 0x214, RegisterValue(0,0),"ssp1stat");
 
360
    add_SfrRegR(&ssp.sspcon,  0x215, RegisterValue(0,0),"ssp1con");
 
361
    add_SfrRegR(&ssp.sspcon2, 0x216, RegisterValue(0,0),"ssp1con2");
 
362
    add_SfrRegR(&ssp.ssp1con3, 0x217, RegisterValue(0,0),"ssp1con3");
 
363
 
 
364
//  add_SfrReg(&pstr1con,    0x296, RegisterValue(1,0));
 
365
 
 
366
  add_SfrRegR(m_iocap, 0x391, RegisterValue(0,0),"iocap");
 
367
  add_SfrRegR(m_iocan, 0x392, RegisterValue(0,0),"iocan");
 
368
  add_SfrRegR(m_iocaf, 0x393, RegisterValue(0,0),"iocaf");
 
369
  m_iocaf->set_intcon(intcon);
 
370
 
 
371
  add_SfrRegR(&nco.nco1accl, 0x498, RegisterValue(0,0));
 
372
  add_SfrRegR(&nco.nco1acch, 0x499, RegisterValue(0,0));
 
373
  add_SfrRegR(&nco.nco1accu, 0x49a, RegisterValue(0,0));
 
374
  add_SfrRegR(&nco.nco1incl, 0x49b, RegisterValue(1,0));
 
375
  add_SfrRegR(&nco.nco1inch, 0x49c, RegisterValue(0,0));
 
376
  add_SfrRegR(&nco.nco1con,  0x49e, RegisterValue(0,0));
 
377
  add_SfrRegR(&nco.nco1clk,  0x49f, RegisterValue(0,0));
 
378
 
 
379
  nco.setIOpins(&(*m_porta)[5], &(*m_portc)[1]);
 
380
  nco.m_NCOif = new InterruptSource(pir2, 4);
 
381
  nco.set_clc(&clc1, 0);
 
382
  nco.set_clc(&clc2, 1);
 
383
  nco.set_cwg(&cwg);
 
384
 
 
385
  add_SfrRegR(&pwm1dcl,  0x611, RegisterValue(0,0));
 
386
  add_SfrReg(&pwm1dch,  0x612, RegisterValue(0,0));
 
387
  add_SfrRegR(&pwm1con,  0x613, RegisterValue(0,0));
 
388
  add_SfrRegR(&pwm2dcl,  0x614, RegisterValue(0,0));
 
389
  add_SfrReg(&pwm2dch,  0x615, RegisterValue(0,0));
 
390
  add_SfrRegR(&pwm2con,  0x616, RegisterValue(0,0));
 
391
  add_SfrRegR(&pwm3dcl,  0x617, RegisterValue(0,0));
 
392
  add_SfrReg(&pwm3dch,  0x618, RegisterValue(0,0));
 
393
  add_SfrRegR(&pwm3con,  0x619, RegisterValue(0,0));
 
394
  add_SfrRegR(&pwm4dcl,  0x61a, RegisterValue(0,0));
 
395
  add_SfrReg(&pwm4dch,  0x61b, RegisterValue(0,0));
 
396
  add_SfrRegR(&pwm4con,  0x61c, RegisterValue(0,0));
 
397
 
 
398
  add_SfrRegR(&cwg.cwg1dbr, 0x691);
 
399
  add_SfrReg(&cwg.cwg1dbf, 0x692);
 
400
  add_SfrRegR(&cwg.cwg1con0, 0x693, RegisterValue(0,0));
 
401
  add_SfrRegR(&cwg.cwg1con1, 0x694);
 
402
  add_SfrRegR(&cwg.cwg1con2, 0x695);
 
403
 
 
404
  add_SfrRegR(&clcdata, 0xf0f, RegisterValue(0,0));
 
405
  add_SfrRegR(&clc1.clcxcon, 0xf10, RegisterValue(0,0), "clc1con");
 
406
  add_SfrReg(&clc1.clcxpol, 0xf11, RegisterValue(0,0), "clc1pol");
 
407
  add_SfrReg(&clc1.clcxsel0, 0xf12, RegisterValue(0,0), "clc1sel0");
 
408
  add_SfrReg(&clc1.clcxsel1, 0xf13, RegisterValue(0,0), "clc1sel1");
 
409
  add_SfrReg(&clc1.clcxgls0, 0xf14, RegisterValue(0,0), "clc1gls0");
 
410
  add_SfrReg(&clc1.clcxgls1, 0xf15, RegisterValue(0,0), "clc1gls1");
 
411
  add_SfrReg(&clc1.clcxgls2, 0xf16, RegisterValue(0,0), "clc1gls2");
 
412
  add_SfrReg(&clc1.clcxgls3, 0xf17, RegisterValue(0,0), "clc1gls3");
 
413
  add_SfrRegR(&clc2.clcxcon, 0xf18, RegisterValue(0,0), "clc2con");
 
414
  add_SfrReg(&clc2.clcxpol, 0xf19, RegisterValue(0,0), "clc2pol");
 
415
  add_SfrReg(&clc2.clcxsel0, 0xf1a, RegisterValue(0,0), "clc2sel0");
 
416
  add_SfrReg(&clc2.clcxsel1, 0xf1b, RegisterValue(0,0), "clc2sel1");
 
417
  add_SfrReg(&clc2.clcxgls0, 0xf1c, RegisterValue(0,0), "clc2gls0");
 
418
  add_SfrReg(&clc2.clcxgls1, 0xf1d, RegisterValue(0,0), "clc2gls1");
 
419
  add_SfrReg(&clc2.clcxgls2, 0xf1e, RegisterValue(0,0), "clc2gls2");
 
420
  add_SfrReg(&clc2.clcxgls3, 0xf1f, RegisterValue(0,0), "clc2gls3");
 
421
 
 
422
  clc1.frc = &frc;
 
423
  clc2.frc = &frc;
 
424
  clc1.lfintosc = &lfintosc;
 
425
  clc2.lfintosc = &lfintosc;
 
426
  clc1.hfintosc = &hfintosc;
 
427
  clc2.hfintosc = &hfintosc;
 
428
  clc1.p_nco = &nco;
 
429
  clcdata.set_clc(&clc1, &clc2);
 
430
  frc.set_clc(&clc1, &clc2);
 
431
  lfintosc.set_clc(&clc1, &clc2);
 
432
  hfintosc.set_clc(&clc1, &clc2);
 
433
  tmr0.set_clc(&clc1, 0);
 
434
  tmr0.set_clc(&clc2, 1);
 
435
  t1con_g.tmrl->m_clc[0] = tmr2.m_clc[0] = &clc1;
 
436
  t1con_g.tmrl->m_clc[1] = tmr2.m_clc[1] = &clc2;
 
437
  comparator.m_clc[0] = &clc1;
 
438
  comparator.m_clc[1] = &clc2;
 
439
 
 
440
  clc1.set_clcPins(&(*m_porta)[3], &(*m_portc)[4], &(*m_porta)[2]);
 
441
  clc2.set_clcPins(&(*m_portc)[3], &(*m_porta)[5], &(*m_portc)[0]);
 
442
  clc1.setInterruptSource(new InterruptSource(pir3, 1));
 
443
  clc2.setInterruptSource(new InterruptSource(pir3, 2));
 
444
 
 
445
  tmr2.ssp_module[0] = &ssp;
 
446
 
 
447
    ssp.initialize(
 
448
        get_pir_set(),    // PIR
 
449
        &(*m_portc)[0],   // SCK
 
450
        &(*m_portc)[3],   // SS
 
451
        &(*m_portc)[2],   // SDO
 
452
        &(*m_portc)[1],    // SDI
 
453
          m_trisc,          // i2c tris port
 
454
        SSP_TYPE_MSSP1
 
455
    );
 
456
    apfcon1.set_ValidBits(0x3b);
 
457
    apfcon1.set_pins(0, &nco, NCO::NCOout_PIN, &(*m_portc)[1], &(*m_porta)[4]); //NCO
 
458
    apfcon1.set_pins(1, &clc1, CLC::CLCout_PIN, &(*m_porta)[2], &(*m_portc)[5]); //CLC
 
459
    apfcon1.set_pins(3, &t1con_g.t1gcon, 0, &(*m_porta)[4], &(*m_porta)[3]); //tmr1 gate
 
460
    apfcon1.set_pins(4, &ssp, SSP1_MODULE::SS_PIN, &(*m_portc)[3], &(*m_porta)[3]); //SSP SS
 
461
    apfcon1.set_pins(5, &ssp, SSP1_MODULE::SDO_PIN, &(*m_portc)[2], &(*m_porta)[4]); //SSP SDO
 
462
    
 
463
    if (pir1) 
 
464
    {
 
465
        pir1->set_intcon(intcon);
 
466
        pir1->set_pie(&pie1);
 
467
    }
 
468
    pie1.setPir(pir1);
 
469
    pie2.setPir(pir2);
 
470
    pie3.setPir(pir3);
 
471
    t2con.tmr2 = &tmr2;
 
472
    tmr2.pir_set   = get_pir_set();
 
473
    tmr2.pr2    = &pr2;
 
474
    tmr2.t2con  = &t2con;
 
475
    tmr2.add_ccp ( &pwm1con );
 
476
    tmr2.add_ccp ( &pwm2con );
 
477
    tmr2.add_ccp ( &pwm3con );
 
478
    tmr2.add_ccp ( &pwm4con );
 
479
 
 
480
    pr2.tmr2    = &tmr2;
 
481
 
 
482
    pwm1con.set_pwmdc(&pwm1dcl, &pwm1dch);
 
483
    pwm1con.setIOPin1(&(*m_portc)[5]);
 
484
    pwm1con.set_tmr2(&tmr2);
 
485
    pwm1con.set_cwg(&cwg);
 
486
    pwm1con.set_clc(&clc1, 0);
 
487
    pwm1con.set_clc(&clc2, 1);
 
488
    pwm2con.set_pwmdc(&pwm2dcl, &pwm2dch);
 
489
    pwm2con.setIOPin1(&(*m_portc)[3]);
 
490
    pwm2con.set_tmr2(&tmr2);
 
491
    pwm2con.set_cwg(&cwg);
 
492
    pwm2con.set_clc(&clc1, 0);
 
493
    pwm2con.set_clc(&clc2, 1);
 
494
    pwm3con.set_pwmdc(&pwm3dcl, &pwm3dch);
 
495
    pwm3con.setIOPin1(&(*m_porta)[2]);
 
496
    pwm3con.set_tmr2(&tmr2);
 
497
    pwm3con.set_cwg(&cwg);
 
498
    pwm3con.set_clc(&clc1, 0);
 
499
    pwm3con.set_clc(&clc2, 1);
 
500
    pwm4con.set_pwmdc(&pwm4dcl, &pwm4dch);
 
501
    pwm4con.setIOPin1(&(*m_portc)[1]);
 
502
    pwm4con.set_tmr2(&tmr2);
 
503
    pwm4con.set_cwg(&cwg);
 
504
    pwm4con.set_clc(&clc1, 0);
 
505
    pwm4con.set_clc(&clc2, 1);
 
506
  
 
507
    cwg.set_IOpins(&(*m_portc)[5], &(*m_portc)[4], &(*m_porta)[2]);
 
508
  
 
509
    ansela.config(0x17, 0);
 
510
    ansela.setValidBits(0x17);
 
511
    ansela.setAdcon1(&adcon1);
 
512
  
 
513
    anselc.config(0x0f, 4);
 
514
    anselc.setValidBits(0x0f);
 
515
    anselc.setAdcon1(&adcon1);
 
516
    ansela.setAnsel(&anselc);
 
517
    anselc.setAnsel(&ansela);
 
518
  
 
519
    adcon0.setAdresLow(&adresl);
 
520
    adcon0.setAdres(&adresh);
 
521
    adcon0.setAdcon1(&adcon1);
 
522
    //  adcon0.setAdcon2(&adcon2);
 
523
    adcon0.setIntcon(intcon);
 
524
    adcon0.setA2DBits(10);
 
525
    adcon0.setPir(pir1);
 
526
    adcon0.setChannel_Mask(0x1f);
 
527
    adcon0.setChannel_shift(2);
 
528
    adcon0.setGo(1);
 
529
    adcon2.setAdcon0(&adcon0);
 
530
  
 
531
    tmr0.set_adcon2(&adcon2);
 
532
  
 
533
    adcon1.setAdcon0(&adcon0);
 
534
    adcon1.setNumberOfChannels(32); // not all channels are used
 
535
    adcon1.setIOPin(0, &(*m_porta)[0]);
 
536
    adcon1.setIOPin(1, &(*m_porta)[1]);
 
537
    adcon1.setIOPin(2, &(*m_porta)[2]);
 
538
    adcon1.setIOPin(3, &(*m_porta)[4]);
 
539
    adcon1.setIOPin(4, &(*m_portc)[0]);
 
540
    adcon1.setIOPin(5, &(*m_portc)[1]);
 
541
    adcon1.setIOPin(6, &(*m_portc)[2]);
 
542
    adcon1.setIOPin(7, &(*m_portc)[3]);
 
543
    adcon1.setValidBits(0xf7);
 
544
    adcon1.setVrefHiConfiguration(0, 0);
 
545
  //RRR    adcon1.setVrefLoConfiguration(0, 2);
 
546
    adcon1.set_FVR_chan(0x1f);
 
547
  
 
548
    comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[0], &(*m_portc)[1],  &(*m_portc)[2],  &(*m_portc)[3]);
 
549
    comparator.cmxcon1[1]->set_INpinNeg(&(*m_porta)[0], &(*m_portc)[1],  &(*m_portc)[2],  &(*m_portc)[3]);
 
550
    comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[0]);
 
551
    comparator.cmxcon1[1]->set_INpinPos(&(*m_portc)[0]);
 
552
  
 
553
    comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[2]);
 
554
    comparator.cmxcon1[1]->set_OUTpin(&(*m_portc)[4]);
 
555
    comparator.cmxcon0[0]->setBitMask(0xbf);
 
556
    comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, (1<<5)));
 
557
    comparator.cmxcon0[1]->setBitMask(0xbf);
 
558
    comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, (1<<6)));
 
559
    comparator.cmxcon1[0]->setBitMask(0xff);
 
560
    comparator.cmxcon1[1]->setBitMask(0xff);
 
561
 
 
562
    comparator.assign_pir_set(get_pir_set());
 
563
    comparator.assign_t1gcon(&t1con_g.t1gcon);
 
564
    fvrcon.set_adcon1(&adcon1);
 
565
    fvrcon.set_daccon0(m_daccon0);
 
566
    fvrcon.set_cmModule(&comparator);
 
567
    fvrcon.set_VTemp_AD_chan(0x1d);
 
568
    fvrcon.set_FVRAD_AD_chan(0x1f);
 
569
 
 
570
    m_daccon0->set_adcon1(&adcon1);
 
571
    m_daccon0->set_cmModule(&comparator);
 
572
    m_daccon0->set_FVRCDA_AD_chan(0x1e);
 
573
    m_daccon0->setDACOUT(&(*m_porta)[0], &(*m_porta)[2]);
 
574
 
 
575
 
 
576
 
 
577
    osccon->set_osctune(&osctune);
 
578
    osccon->set_oscstat(&oscstat);
 
579
    osctune.set_osccon((OSCCON *)osccon);
 
580
    osccon->write_mask = 0xfb;
 
581
}
 
582
 
 
583
void P16F1503::set_out_of_range_pm(uint address, uint value)
 
584
{
 
585
 
 
586
  if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size()))
 
587
      get_eeprom()->change_rom(address - 0x2100, value);
 
588
}
 
589
 
 
590
void  P16F1503::create(int ram_top, int dev_id)
 
591
{
 
592
 
 
593
  create_iopin_map();
 
594
 
 
595
  osccon = new OSCCON_2(this, "osccon" );
 
596
 
 
597
  e = new EEPROM_EXTND(this, pir2);
 
598
  set_eeprom(e);
 
599
  e->initialize(0, 16, 16, 0x8000, true);
 
600
  e->set_intcon(intcon);
 
601
  e->get_reg_eecon1()->set_valid_bits(0x7f);
 
602
 
 
603
 
 
604
  pic_processor::create();
 
605
 
 
606
  P16F1503::create_sfr_map();
 
607
  _14bit_e_processor::create_sfr_map();
 
608
  // Set DeviceID
 
609
  if (m_configMemory && m_configMemory->getConfigWord(6))
 
610
      m_configMemory->getConfigWord(6)->set(dev_id);
 
611
}
 
612
 
 
613
void P16F1503::enter_sleep()
 
614
{
 
615
    if (wdt_flag == 2)          // WDT is suspended during sleep
 
616
        wdt.initialize(false);
 
617
    else if (get_pir_set()->interrupt_status() )
 
618
    {
 
619
        pc->increment();
 
620
          return;
 
621
    }
 
622
 
 
623
    tmr1l.sleep();
 
624
    osccon->sleep();
 
625
    tmr0.sleep();
 
626
    nco.sleep(true);
 
627
    pic_processor::enter_sleep();
 
628
}
 
629
 
 
630
void P16F1503::exit_sleep()
 
631
{
 
632
    if (m_ActivityState == ePASleeping)
 
633
    {
 
634
        tmr1l.wake();
 
635
        osccon->wake();
 
636
        nco.sleep(false);
 
637
        _14bit_e_processor::exit_sleep();
 
638
    }
 
639
}
 
640
 
 
641
void P16F1503::option_new_bits_6_7(uint bits)
 
642
{
 
643
        Dprintf(("P16F1503::option_new_bits_6_7 bits=%x\n", bits));
 
644
    m_porta->setIntEdge ( (bits & OPTION_REG::BIT6) == OPTION_REG::BIT6);
 
645
    m_wpua->set_wpu_pu ( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7);
 
646
}
 
647
 
 
648
void P16F1503::oscillator_select(uint cfg_word1, bool clkout)
 
649
{
 
650
    uint mask = 0x1f;
 
651
 
 
652
    uint fosc = cfg_word1 & (FOSC0|FOSC1|FOSC2);
 
653
 
 
654
    osccon->set_config_irc(fosc == 4);
 
655
    osccon->set_config_xosc(fosc < 3);
 
656
    osccon->set_config_ieso(cfg_word1 & IESO);
 
657
    set_int_osc(false);
 
658
    switch(fosc)
 
659
    {
 
660
    case 0:        //LP oscillator: low power crystal
 
661
    case 1:        //XT oscillator: Crystal/resonator
 
662
    case 2:        //HS oscillator: High-speed crystal/resonator
 
663
        mask = 0x0f;
 
664
        break;
 
665
 
 
666
    case 3:        //EXTRC oscillator External RC circuit connected to CLKIN pin
 
667
        mask = 0x1f;
 
668
        if(clkout) mask = 0x0f;
 
669
        break;
 
670
 
 
671
    case 4:        //INTOSC oscillator: I/O function on CLKIN pin
 
672
        set_int_osc(true);
 
673
        mask = 0x3f;
 
674
        if(clkout) mask = 0x2f;
 
675
 
 
676
        break;
 
677
 
 
678
    case 5:        //ECL: External Clock, Low-Power mode (0-0.5 MHz): on CLKIN pin
 
679
        mask = 0x1f;
 
680
        if(clkout) mask = 0x0f;
 
681
        break;
 
682
 
 
683
    case 6:        //ECM: External Clock, Medium-Power mode (0.5-4 MHz): on CLKIN pin
 
684
        mask = 0x1f;
 
685
        if(clkout) mask = 0x0f;
 
686
        break;
 
687
 
 
688
    case 7:        //ECH: External Clock, High-Power mode (4-32 MHz): on CLKIN pin
 
689
        mask = 0x1f;
 
690
        if(clkout) mask = 0x0f;
 
691
        break;
 
692
    };
 
693
    ansela.setValidBits(0x17 & mask);
 
694
    m_porta->setEnableMask(mask);
 
695
}
 
696
 
 
697
void P16F1503::program_memory_wp(uint mode)
 
698
{
 
699
        switch(mode)
 
700
        {
 
701
        case 3:        // no write protect
 
702
            get_eeprom()->set_prog_wp(0x0);
 
703
            break;
 
704
 
 
705
        case 2: // write protect 0000-01ff
 
706
            get_eeprom()->set_prog_wp(0x0200);
 
707
            break;
 
708
 
 
709
        case 1: // write protect 0000-03ff
 
710
            get_eeprom()->set_prog_wp(0x0400);
 
711
            break;
 
712
 
 
713
        case 0: // write protect 0000-07ff
 
714
            get_eeprom()->set_prog_wp(0x0800);
 
715
            break;
 
716
 
 
717
        default:
 
718
            printf("%s unexpected mode %u\n", __FUNCTION__, mode);
 
719
            break;
 
720
        }
 
721
}
 
722
 
 
723
Processor * P16F1503::construct(const char *name)
 
724
{
 
725
  P16F1503 *p = new P16F1503(name);
 
726
 
 
727
  p->create(2048, 0x2ce0);
 
728
  p->create_invalid_registers ();
 
729
 
 
730
  return p;
 
731
}
 
732
 
 
733
//========================================================================
 
734
 
 
735
P16LF1503::P16LF1503(const char *_name )
 
736
  : P16F1503(_name )
 
737
{
 
738
}
 
739
 
 
740
Processor * P16LF1503::construct(const char *name)
 
741
{
 
742
  P16LF1503 *p = new P16LF1503(name);
 
743
 
 
744
  p->create(2048, 0x2da0);
 
745
  p->create_invalid_registers ();
 
746
 
 
747
  return p;
 
748
}