~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/gpsim/devices/p16f88x.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
 *
 
3
   Copyright (C) 2010,2015 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
 
 
23
//
 
24
// p16f88x
 
25
//
 
26
//  This file supports:
 
27
//    PIC16F882
 
28
//    PIC16F883
 
29
//    PIC16F884
 
30
//    PIC16F885
 
31
//    PIC16F886
 
32
//    PIC16F887
 
33
//
 
34
 
 
35
#include <stdio.h>
 
36
#include <iostream>
 
37
#include <string>
 
38
 
 
39
#include "p16f88x.h"
 
40
#include "pic-ioports.h"
 
41
 
 
42
//#define DEBUG
 
43
#if defined(DEBUG)
 
44
#define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__, __FUNCTION__); printf arg; }
 
45
#else
 
46
#define Dprintf(arg) {}
 
47
#endif
 
48
 
 
49
//========================================================================
 
50
//
 
51
// Configuration Memory for the 16F8X devices.
 
52
 
 
53
class Config188x : public ConfigWord
 
54
{
 
55
public:
 
56
    Config188x(P16F88x *pCpu)
 
57
        : ConfigWord("CONFIG188x", 0x3fff, pCpu, 0x2007)
 
58
    {
 
59
    }
 
60
    enum {
 
61
        FOSC0  = 1<<0,
 
62
        FOSC1  = 1<<1,
 
63
        FOSC2  = 1<<2,
 
64
        WDTEN  = 1<<3,
 
65
        PWRTEN = 1<<4,
 
66
        MCLRE  = 1<<5,
 
67
 
 
68
        BOREN  = 1<<8,
 
69
        BOREN1  = 1<<9,
 
70
        LVP    = 1<<12,
 
71
 
 
72
        CPD    = 1<<8,
 
73
        WRT0   = 1<<9,
 
74
        WRT1   = 1<<10,
 
75
        NOT_DEBUG  = 1<<11,
 
76
    };
 
77
 
 
78
    virtual void set(int64_t v)
 
79
    {
 
80
        Integer::set(v);
 
81
        Dprintf(("Config188x set %x\n", (int)v));
 
82
        if (m_pCpu)
 
83
        {
 
84
            m_pCpu->wdt.initialize((v & WDTEN) == WDTEN);
 
85
        }
 
86
    }
 
87
};
 
88
 
 
89
 
 
90
//========================================================================
 
91
 
 
92
P16F88x::P16F88x(const char *_name)
 
93
    : _14bit_processor(_name ),
 
94
      intcon_reg(this,"intcon" ),
 
95
      t1con(this, "t1con" ),
 
96
      pie1(this,"PIE1" ),
 
97
      pie2(this,"PIE2" ),
 
98
      t2con(this, "t2con" ),
 
99
      pr2(this, "pr2" ),
 
100
      tmr2(this, "tmr2" ),
 
101
      tmr1l(this, "tmr1l" ),
 
102
      tmr1h(this, "tmr1h" ),
 
103
      ccp1con(this, "ccp1con" ),
 
104
      ccpr1l(this, "ccpr1l" ),
 
105
      ccpr1h(this, "ccpr1h" ),
 
106
      ccp2con(this, "ccp2con" ),
 
107
      ccpr2l(this, "ccpr2l" ),
 
108
      ccpr2h(this, "ccpr2h" ),
 
109
      pcon(this, "pcon" ),
 
110
      ssp(this),
 
111
      osccon(0),
 
112
      osctune(this, "osctune" ),
 
113
      wdtcon(this, "wdtcon", 1),
 
114
      usart(this),
 
115
      comparator(this),
 
116
      vrcon(this, "vrcon" ),
 
117
      srcon(this, "srcon" ),
 
118
      ansel(this,"ansel" ),
 
119
      anselh(this,"anselh" ),
 
120
      adcon0(this,"adcon0" ),
 
121
      adcon1(this,"adcon1" ),
 
122
      eccpas(this, "eccpas" ),
 
123
      pwm1con(this, "pwm1con" ),
 
124
      pstrcon(this, "pstrcon" ),
 
125
      adresh(this,"adresh" ),
 
126
      adresl(this,"adresl" )
 
127
{
 
128
 
 
129
    m_porta = new PicPortRegister(this,"porta", 8,0x1f);
 
130
    m_trisa = new PicTrisRegister(this,"trisa", m_porta, false);
 
131
    m_ioc = new IOC(this, "iocb" );
 
132
    m_portb = new PicPortGRegister(this,"portb", &intcon_reg, m_ioc,8,0xff);
 
133
    m_trisb = new PicTrisRegister(this,"trisb", m_portb, false);
 
134
    m_portc = new PicPortRegister(this,"portc", 8,0xff);
 
135
    m_trisc = new PicTrisRegister(this,"trisc", m_portc, false);
 
136
    m_porte = new PicPortRegister(this,"porte", 8,0x0f);
 
137
    m_trise =  new PicPSP_TrisRegister(this,"trise", m_porte, false);
 
138
 
 
139
    pir1_2_reg = new PIR1v2(this,"pir1", &intcon_reg,&pie1);
 
140
    pir2_2_reg = new PIR2v3(this,"pir2", &intcon_reg,&pie2);
 
141
    pir1 = pir1_2_reg;
 
142
    pir2 = pir2_2_reg;
 
143
    m_wpu = new WPU(this, "wpub", m_portb, 0xff);
 
144
 
 
145
    tmr0.set_cpu(this, m_porta, 4, option_reg);
 
146
    tmr0.start(0);
 
147
    comparator.cmxcon0[0] = new CMxCON0_V2(this, "cm1con0", 0, &comparator);
 
148
    comparator.cmxcon0[1] = new CMxCON0_V2(this, "cm2con0", 1, &comparator);
 
149
    comparator.cmxcon1[0] = new CM2CON1_V3(this, "cm2con1", 0, &comparator);
 
150
    comparator.cmxcon1[1] = comparator.cmxcon1[0];
 
151
}
 
152
 
 
153
P16F88x::~P16F88x()
 
154
{
 
155
    unassignMCLRPin();
 
156
    delete_file_registers(0x20, 0x7f);
 
157
    delete_file_registers(0xa0, 0xbf);
 
158
 
 
159
    remove_SfrReg(&tmr0);
 
160
    remove_SfrReg(&intcon_reg);
 
161
    remove_SfrReg(&pie2);
 
162
    remove_SfrReg(&pie1);
 
163
    remove_SfrReg(&tmr1l);
 
164
    remove_SfrReg(&tmr1h);
 
165
    remove_SfrReg(&pcon);
 
166
    remove_SfrReg(&t1con);
 
167
    remove_SfrReg(&tmr2);
 
168
    remove_SfrReg(&t2con);
 
169
    remove_SfrReg(&pr2);
 
170
    remove_SfrReg(get_eeprom()->get_reg_eedata());
 
171
    remove_SfrReg(get_eeprom()->get_reg_eeadr());
 
172
    remove_SfrReg(get_eeprom()->get_reg_eedatah());
 
173
    remove_SfrReg(get_eeprom()->get_reg_eeadrh());
 
174
    remove_SfrReg(get_eeprom()->get_reg_eecon1());
 
175
    remove_SfrReg(get_eeprom()->get_reg_eecon2());
 
176
    delete get_eeprom();
 
177
 
 
178
    remove_SfrReg(&intcon_reg);
 
179
    remove_SfrReg(osccon);
 
180
    remove_SfrReg(&osctune);
 
181
    remove_SfrReg(&usart.rcsta);
 
182
    remove_SfrReg(&usart.txsta);
 
183
    remove_SfrReg(&usart.spbrg);
 
184
    remove_SfrReg(&usart.spbrgh);
 
185
    remove_SfrReg(&usart.baudcon);
 
186
    remove_SfrReg(&vrcon);
 
187
    remove_SfrReg(&srcon);
 
188
    remove_SfrReg(&wdtcon);
 
189
    remove_SfrReg(&ccpr2l);
 
190
    remove_SfrReg(&ccpr2h);
 
191
    remove_SfrReg(&ccp2con);
 
192
    remove_SfrReg(&adresl);
 
193
    remove_SfrReg(&adresh);
 
194
    remove_SfrReg(&ansel);
 
195
    remove_SfrReg(&anselh);
 
196
    remove_SfrReg(&adcon0);
 
197
    remove_SfrReg(&adcon1);
 
198
    remove_SfrReg(&ccpr1l);
 
199
    remove_SfrReg(&ccpr1h);
 
200
    remove_SfrReg(&ccp1con);
 
201
    remove_SfrReg(&ccpr2l);
 
202
    remove_SfrReg(&ccpr2h);
 
203
    remove_SfrReg(&ccp2con);
 
204
    remove_SfrReg(&pwm1con);
 
205
    remove_SfrReg(&pstrcon);
 
206
    remove_SfrReg(&eccpas);
 
207
    remove_SfrReg(&ssp.sspcon2);
 
208
    remove_SfrReg(&ssp.sspbuf);
 
209
    remove_SfrReg(&ssp.sspcon);
 
210
    remove_SfrReg(&ssp.sspadd);
 
211
    remove_SfrReg(&ssp.sspstat);
 
212
    delete_SfrReg(usart.txreg);
 
213
    delete_SfrReg(usart.rcreg);
 
214
    remove_SfrReg(comparator.cmxcon0[0]);
 
215
    remove_SfrReg(comparator.cmxcon0[1]);
 
216
    remove_SfrReg(comparator.cmxcon1[1]);
 
217
 
 
218
    delete_SfrReg(m_porta);
 
219
    delete_SfrReg(m_trisa);
 
220
    delete_SfrReg(m_portb);
 
221
    delete_SfrReg(m_trisb);
 
222
    delete_SfrReg(m_porte);
 
223
    delete_SfrReg(m_trise);
 
224
    delete_SfrReg(m_portc);
 
225
    delete_SfrReg(m_trisc);
 
226
 
 
227
    delete_SfrReg(pir1);
 
228
    delete_SfrReg(pir2);
 
229
    delete_SfrReg(m_wpu);
 
230
    delete_SfrReg(m_ioc);
 
231
}
 
232
 
 
233
void P16F88x::create_iopin_map()
 
234
{
 
235
    fprintf(stderr, "%s should be defined at a higer level\n", __FUNCTION__);
 
236
}
 
237
 
 
238
void P16F88x::create_sfr_map()
 
239
{
 
240
    add_SfrReg(indf,    0x00);
 
241
    alias_file_registers(0x00,0x00,0x80);
 
242
 
 
243
    add_SfrReg(&tmr0,   0x01);
 
244
    add_SfrReg(option_reg,  0x81, RegisterValue(0xff,0));
 
245
 
 
246
    add_SfrReg(pcl,     0x02, RegisterValue(0,0));
 
247
    add_SfrReg(status,  0x03, RegisterValue(0x18,0));
 
248
    add_SfrReg(fsr,     0x04);
 
249
    alias_file_registers(0x02,0x04,0x80);
 
250
 
 
251
    add_SfrReg(m_porta, 0x05);
 
252
    add_SfrReg(m_trisa, 0x85, RegisterValue(0x3f,0));
 
253
 
 
254
    add_SfrReg(m_portb, 0x06);
 
255
    add_SfrReg(m_trisb, 0x86, RegisterValue(0xff,0));
 
256
 
 
257
    add_SfrReg(pclath,  0x0a, RegisterValue(0,0));
 
258
 
 
259
    add_SfrReg(&intcon_reg, 0x0b, RegisterValue(0,0));
 
260
    //alias_file_registers(0x0a,0x0b,0x80); //Already donw
 
261
 
 
262
    intcon = &intcon_reg;
 
263
 
 
264
    pir_set_2_def.set_pir1(pir1);
 
265
    pir_set_2_def.set_pir2(pir2);
 
266
 
 
267
    add_SfrReg(m_porte, 0x09);
 
268
    add_SfrReg(m_trise, 0x89, RegisterValue(0xff,0));
 
269
    add_SfrReg(m_portc, 0x07);
 
270
    add_SfrReg(m_trisc, 0x87, RegisterValue(0xff,0));
 
271
 
 
272
    add_file_registers(0x20, 0x7f, 0);
 
273
    add_file_registers(0xa0, 0xbf, 0);
 
274
 
 
275
    alias_file_registers(0x70,0x7f,0x80);
 
276
    alias_file_registers(0x70,0x7f,0x100);
 
277
    alias_file_registers(0x70,0x7f,0x180);
 
278
 
 
279
    add_SfrReg(get_pir2(),   0x0d, RegisterValue(0,0),"pir2");
 
280
    add_SfrReg(&pie2,   0x8d, RegisterValue(0,0));
 
281
 
 
282
    pir_set_2_def.set_pir2(pir2);
 
283
 
 
284
    pie2.setPir(get_pir2());
 
285
    alias_file_registers(0x00,0x04,0x100);
 
286
    alias_file_registers(0x80,0x84,0x100);
 
287
    alias_file_registers(0x06,0x06,0x100);
 
288
    alias_file_registers(0x86,0x86,0x100);
 
289
 
 
290
    add_SfrReg(pir1,   0x0c, RegisterValue(0,0),"pir1");
 
291
    add_SfrReg(&pie1,   0x8c, RegisterValue(0,0));
 
292
 
 
293
    add_SfrReg(&tmr1l,  0x0e, RegisterValue(0,0),"tmr1l");
 
294
    add_SfrReg(&tmr1h,  0x0f, RegisterValue(0,0),"tmr1h");
 
295
 
 
296
    add_SfrReg(&pcon,   0x8e, RegisterValue(0,0),"pcon");
 
297
 
 
298
    add_SfrReg(&t1con,  0x10, RegisterValue(0,0));
 
299
    add_SfrReg(&tmr2,   0x11, RegisterValue(0,0));
 
300
    add_SfrReg(&t2con,  0x12, RegisterValue(0,0));
 
301
    add_SfrReg(&pr2,    0x92, RegisterValue(0xff,0));
 
302
 
 
303
    get_eeprom()->get_reg_eedata()->new_name("eedat");
 
304
    get_eeprom()->get_reg_eedatah()->new_name("eedath");
 
305
    add_SfrReg(get_eeprom()->get_reg_eedata(),  0x10c);
 
306
    add_SfrReg(get_eeprom()->get_reg_eeadr(),   0x10d);
 
307
    add_SfrReg(get_eeprom()->get_reg_eedatah(),  0x10e);
 
308
    add_SfrReg(get_eeprom()->get_reg_eeadrh(),   0x10f);
 
309
    add_SfrReg(get_eeprom()->get_reg_eecon1(),  0x18c, RegisterValue(0,0));
 
310
    get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD);
 
311
    add_SfrReg(get_eeprom()->get_reg_eecon2(),  0x18d);
 
312
 
 
313
    alias_file_registers(0x0a,0x0b,0x080);
 
314
    alias_file_registers(0x0a,0x0b,0x100);
 
315
    alias_file_registers(0x0a,0x0b,0x180);
 
316
 
 
317
    intcon_reg.set_pir_set(get_pir_set());
 
318
 
 
319
    add_SfrReg(osccon, 0x8f, RegisterValue(0x60,0),"osccon");
 
320
    add_SfrReg(&osctune, 0x90, RegisterValue(0,0),"osctune");
 
321
 
 
322
    osccon->set_osctune(&osctune);
 
323
    osctune.set_osccon(osccon);
 
324
 
 
325
    usart.initialize(pir1,&(*m_portc)[6], &(*m_portc)[7],
 
326
            new _TXREG(this,"txreg", &usart),
 
327
            new _RCREG(this,"rcreg", &usart));
 
328
 
 
329
    add_SfrReg(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta");
 
330
    add_SfrReg(&usart.txsta, 0x98, RegisterValue(2,0),"txsta");
 
331
    add_SfrReg(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg");
 
332
    add_SfrReg(&usart.spbrgh, 0x9a, RegisterValue(0,0),"spbrgh");
 
333
    add_SfrReg(&usart.baudcon,  0x187,RegisterValue(0x40,0),"baudctl");
 
334
    add_SfrReg(usart.txreg,  0x19, RegisterValue(0,0),"txreg");
 
335
    add_SfrReg(usart.rcreg,  0x1a, RegisterValue(0,0),"rcreg");
 
336
    usart.set_eusart(true);
 
337
    comparator.assign_tmr1l(&tmr1l);
 
338
    comparator.cmxcon1[1]->set_vrcon(&vrcon);
 
339
 
 
340
    add_SfrReg(comparator.cmxcon0[0], 0x107, RegisterValue(0,0), "cm1con0");
 
341
    add_SfrReg(comparator.cmxcon0[1], 0x108, RegisterValue(0,0), "cm2con0");
 
342
    add_SfrReg(comparator.cmxcon1[1], 0x109, RegisterValue(2,0), "cm2con1");
 
343
    add_SfrReg(&vrcon, 0x97, RegisterValue(0,0),"vrcon");
 
344
    add_SfrReg(&srcon, 0x185, RegisterValue(0,0),"srcon");
 
345
    add_SfrReg(&wdtcon, 0x105, RegisterValue(0x08,0),"wdtcon");
 
346
    add_SfrReg(&adresl,  0x9e, RegisterValue(0,0));
 
347
    add_SfrReg(&adresh,  0x1e, RegisterValue(0,0));
 
348
    add_SfrReg(&ansel, 0x188, RegisterValue(0xff,0));
 
349
    add_SfrReg(&anselh, 0x189, RegisterValue(0xff,0));
 
350
    add_SfrReg(&adcon0, 0x1f, RegisterValue(0,0));
 
351
    add_SfrReg(&adcon1, 0x9f, RegisterValue(0,0));
 
352
    add_SfrReg(m_wpu, 0x95, RegisterValue(0xff,0));
 
353
    add_SfrReg(m_ioc, 0x96, RegisterValue(0,0));
 
354
 
 
355
    ansel.setAdcon1(&adcon1);
 
356
    ansel.setAnselh(&anselh);
 
357
    anselh.setAdcon1(&adcon1);
 
358
    anselh.setAnsel(&ansel);
 
359
    adcon0.setAdresLow(&adresl);
 
360
    adcon0.setAdres(&adresh);
 
361
    adcon0.setAdcon1(&adcon1);
 
362
    adcon0.setIntcon(&intcon_reg);
 
363
    adcon0.setA2DBits(10);
 
364
    adcon0.setPir(pir1);
 
365
    adcon0.setChannel_Mask(0xf);
 
366
    adcon0.setChannel_shift(2);
 
367
    adcon0.setGo(1);
 
368
 
 
369
    adcon1.setValidBits(0xb0);
 
370
    adcon1.setNumberOfChannels(14);
 
371
    adcon1.setValidCfgBits(ADCON1::VCFG0 | ADCON1::VCFG1 , 4);
 
372
    adcon1.setIOPin(0, &(*m_porta)[0]);
 
373
    adcon1.setIOPin(1, &(*m_porta)[1]);
 
374
    adcon1.setIOPin(2, &(*m_porta)[2]);
 
375
    adcon1.setIOPin(3, &(*m_porta)[3]);
 
376
    adcon1.setIOPin(4, &(*m_porta)[4]);
 
377
    adcon1.setIOPin(8, &(*m_portb)[2]);
 
378
    adcon1.setIOPin(9, &(*m_portb)[3]);
 
379
    adcon1.setIOPin(10, &(*m_portb)[1]);
 
380
    adcon1.setIOPin(11, &(*m_portb)[4]);
 
381
    adcon1.setIOPin(12, &(*m_portb)[0]);
 
382
    adcon1.setIOPin(13, &(*m_portb)[5]);
 
383
 
 
384
    // set a2d modes where an3 is Vref+
 
385
    adcon1.setVrefHiConfiguration(1, 3);
 
386
    adcon1.setVrefHiConfiguration(3, 3);
 
387
 
 
388
    // set a2d modes where an2 is Vref-
 
389
    adcon1.setVrefLoConfiguration(2, 2);
 
390
    adcon1.setVrefLoConfiguration(3, 2);
 
391
 
 
392
    vrcon.setValidBits(0xff); // All bits settable
 
393
 
 
394
    add_SfrReg(&ccpr1l, 0x15, RegisterValue(0,0));
 
395
    add_SfrReg(&ccpr1h, 0x16, RegisterValue(0,0));
 
396
    add_SfrReg(&ccp1con, 0x17, RegisterValue(0,0));
 
397
    add_SfrReg(&ccpr2l, 0x1b, RegisterValue(0,0));
 
398
    add_SfrReg(&ccpr2h, 0x1c, RegisterValue(0,0));
 
399
    add_SfrReg(&ccp2con, 0x1d, RegisterValue(0,0));
 
400
    add_SfrReg(&pwm1con, 0x9b, RegisterValue(0,0));
 
401
    add_SfrReg(&pstrcon, 0x9d, RegisterValue(1,0));
 
402
    add_SfrReg(&eccpas, 0x9c, RegisterValue(0,0));
 
403
    eccpas.setIOpin(0, 0, &(*m_portb)[0]);
 
404
    eccpas.link_registers(&pwm1con, &ccp1con);
 
405
    ssp.sspmsk = new _SSPMSK(this, "ssp1msk");
 
406
    add_SfrReg(&ssp.sspbuf,  0x13, RegisterValue(0,0),"sspbuf");
 
407
    add_SfrReg(&ssp.sspcon,  0x14, RegisterValue(0,0),"sspcon");
 
408
    add_SfrReg(&ssp.sspcon2,  0x91, RegisterValue(0,0),"sspcon2");
 
409
    add_SfrReg(&ssp.sspadd,  0x93, RegisterValue(0,0),"sspadd");
 
410
    add_SfrReg(ssp.sspmsk,  0x93, RegisterValue(0xff,0), "sspmsk", false);
 
411
    add_SfrReg(&ssp.sspstat, 0x94, RegisterValue(0,0),"sspstat");
 
412
    tmr2.ssp_module[0] = &ssp;
 
413
 
 
414
    ssp.initialize(
 
415
                get_pir_set(),    // PIR
 
416
                &(*m_portc)[3],   // SCK
 
417
            &(*m_porta)[5],   // SS
 
418
            &(*m_portc)[5],   // SDO
 
419
            &(*m_portc)[4],    // SDI
 
420
            m_trisc,          // i2c tris port
 
421
            SSP_TYPE_SSP
 
422
            );
 
423
    tmr1l.tmrh = &tmr1h;
 
424
    tmr1l.t1con = &t1con;
 
425
    tmr1h.tmrl  = &tmr1l;
 
426
 
 
427
    t1con.tmrl  = &tmr1l;
 
428
 
 
429
    t2con.tmr2  = &tmr2;
 
430
    tmr2.pir_set   = get_pir_set();
 
431
    tmr2.pr2    = &pr2;
 
432
    tmr2.t2con  = &t2con;
 
433
    tmr2.add_ccp ( &ccp1con );
 
434
    tmr2.add_ccp ( &ccp2con );
 
435
    pr2.tmr2    = &tmr2;
 
436
 
 
437
    tmr1l.setIOpin(&(*m_portc)[0]);
 
438
    ccp1con.setBitMask(0xff);
 
439
    ccp1con.pstrcon = &pstrcon;
 
440
    ccp1con.pwm1con = &pwm1con;
 
441
    ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas);
 
442
    ccpr1l.ccprh  = &ccpr1h;
 
443
    ccpr1l.tmrl   = &tmr1l;
 
444
    ccpr1h.ccprl  = &ccpr1l;
 
445
 
 
446
    ccp2con.setIOpin(&(*m_portc)[1]);
 
447
    ccp2con.setCrosslinks(&ccpr2l, pir2, PIR2v3::CCP2IF, &tmr2);
 
448
    ccpr2l.ccprh  = &ccpr2h;
 
449
    ccpr2l.tmrl   = &tmr1l;
 
450
    ccpr2h.ccprl  = &ccpr2l;
 
451
 
 
452
    if (pir1) {
 
453
        pir1->set_intcon(&intcon_reg);
 
454
        pir1->set_pie(&pie1);
 
455
    }
 
456
    pie1.setPir(pir1);
 
457
 
 
458
    comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[4], &(*m_porta)[5]);
 
459
    comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[0], &(*m_porta)[1],
 
460
            &(*m_portb)[3],&(*m_portb)[1]);
 
461
    comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[3], &(*m_porta)[2]);
 
462
    comparator.cmxcon1[0]->setBitMask(0x33);
 
463
    comparator.cmxcon0[0]->setBitMask(0xb7);
 
464
    comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, PIR2v2::C1IF));
 
465
    comparator.cmxcon0[1]->setBitMask(0xb7);
 
466
    comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, PIR2v2::C2IF));
 
467
}
 
468
 
 
469
void P16F88x::option_new_bits_6_7(uint bits)
 
470
{
 
471
    Dprintf(("P18F88x::option_new_bits_6_7 bits=%x\n", bits));
 
472
    m_portb->setIntEdge ( (bits & OPTION_REG::BIT6) == OPTION_REG::BIT6);
 
473
    m_wpu->set_wpu_pu ( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7);
 
474
}
 
475
 
 
476
void P16F88x::set_out_of_range_pm(uint address, uint value)
 
477
{
 
478
    if( (address>= 0x2100) && (address < 0x2100 + get_eeprom()->get_rom_size()))
 
479
    {
 
480
        get_eeprom()->change_rom(address - 0x2100, value);
 
481
    }
 
482
}
 
483
 
 
484
bool P16F88x::set_config_word(uint address, uint cfg_word)
 
485
{
 
486
    enum {
 
487
        CFG_FOSC0 = 1<<0,
 
488
        CFG_FOSC1 = 1<<1,
 
489
        CFG_FOSC2 = 1<<4,
 
490
        CFG_MCLRE = 1<<5,
 
491
        CFG_CCPMX = 1<<12
 
492
    };
 
493
    // Let the base class do most of the work:
 
494
    if (address == 0x2007)
 
495
    {
 
496
        pic_processor::set_config_word(address, cfg_word);
 
497
 
 
498
        uint valid_pins = m_porta->getEnableMask();
 
499
 
 
500
        set_int_osc(false);
 
501
        // Careful these bits not adjacent
 
502
        switch(cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2)) {
 
503
 
 
504
        case 0:  // LP oscillator: low power crystal is on RA6 and RA7
 
505
        case 1:     // XT oscillator: crystal/resonator is on RA6 and RA7
 
506
        case 2:     // HS oscillator: crystal/resonator is on RA6 and RA7
 
507
            break;
 
508
 
 
509
        case 0x13:  // ER oscillator: RA6 is CLKOUT, resistor (?) on RA7
 
510
            break;
 
511
 
 
512
        case 3:     // EC:  RA6 is an I/O, RA7 is a CLKIN
 
513
        case 0x12:  // ER oscillator: RA6 is an I/O, RA7 is a CLKIN
 
514
            valid_pins =  (valid_pins & 0x7f)|0x40;
 
515
            break;
 
516
 
 
517
        case 0x10:  // INTRC: Internal Oscillator, RA6 and RA7 are I/O's
 
518
            set_int_osc(true);
 
519
            valid_pins |= 0xc0;
 
520
            break;
 
521
 
 
522
        case 0x11:  // INTRC: Internal Oscillator, RA7 is an I/O, RA6 is CLKOUT
 
523
            set_int_osc(true);
 
524
            valid_pins = (valid_pins & 0xbf)|0x80;
 
525
            break;
 
526
 
 
527
        }
 
528
        // If the /MCLRE bit is set then RE3 is the MCLR pin, otherwise it's
 
529
        // a general purpose I/O pin.
 
530
 
 
531
        if ((cfg_word & CFG_MCLRE))
 
532
        {
 
533
            assignMCLRPin(1);
 
534
        }
 
535
        else
 
536
        {
 
537
            unassignMCLRPin();
 
538
        }
 
539
 
 
540
        if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO
 
541
        {
 
542
            m_porta->setEnableMask(valid_pins);
 
543
            m_porta->setTris(m_trisa);
 
544
        }
 
545
        return true;
 
546
    }
 
547
    else if (address == 0x2008 )
 
548
    {
 
549
        //cout << "p16f88x 0x" << hex << address << " config word2 0x" << cfg_word << '\n';
 
550
    }
 
551
    return false;
 
552
}
 
553
 
 
554
void P16F88x::create_config_memory()
 
555
{
 
556
    m_configMemory = new ConfigMemory(this,2);
 
557
    m_configMemory->addConfigWord(0,new Config188x(this));
 
558
    m_configMemory->addConfigWord(1,new ConfigWord("CONFIG2", 0, this,0x2008));
 
559
    wdt.initialize(true); // default WDT enabled
 
560
    wdt.set_timeout(0.000035);
 
561
    set_config_word(0x2007, 0x3fff);
 
562
 
 
563
}
 
564
 
 
565
void  P16F88x::create(int eesize)
 
566
{
 
567
    create_iopin_map();
 
568
 
 
569
    _14bit_processor::create();
 
570
    osccon = new OSCCON(this, "osccon" );
 
571
 
 
572
    EEPROM_WIDE *e;
 
573
    e = new EEPROM_WIDE(this,pir2);
 
574
    e->initialize(eesize);
 
575
    e->set_intcon(&intcon_reg);
 
576
    set_eeprom_wide(e);
 
577
 
 
578
    status->rp_mask = 0x60;  // rp0 and rp1 are valid.
 
579
    indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100
 
580
    indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100
 
581
 
 
582
    P16F88x::create_sfr_map();
 
583
}
 
584
 
 
585
//========================================================================
 
586
//
 
587
Processor * P16F882::construct(const char *name)
 
588
{
 
589
    P16F882 *p = new P16F882(name);
 
590
 
 
591
    p->P16F88x::create(128);
 
592
    p->P16F882::create_sfr_map();
 
593
    p->create_invalid_registers ();
 
594
 
 
595
    return p;
 
596
}
 
597
 
 
598
P16F882::P16F882(const char *_name )
 
599
    : P16F88x(_name )
 
600
{
 
601
    m_porta->setEnableMask(0xff);
 
602
}
 
603
 
 
604
void P16F882::create_iopin_map(void)
 
605
{
 
606
    assign_pin(1, m_porte->addPin(new IO_bi_directional("porte3"),3));
 
607
    assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0));
 
608
    assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1));
 
609
    assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2));
 
610
    assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3));
 
611
    assign_pin( 6, m_porta->addPin( new IOPIN("porta4", OPEN_COLLECTOR),4) );
 
612
    assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5));
 
613
    assign_pin(8, 0);
 
614
    assign_pin( 9, m_porta->addPin(new IO_bi_directional("porta7"),7));
 
615
    assign_pin( 10, m_porta->addPin(new IO_bi_directional("porta6"),6));
 
616
    assign_pin(11, m_portc->addPin(new IO_bi_directional("portc0"),0));
 
617
    assign_pin(12, m_portc->addPin(new IO_bi_directional("portc1"),1));
 
618
    assign_pin(13, m_portc->addPin(new IO_bi_directional("portc2"),2));
 
619
    assign_pin(14, m_portc->addPin(new IO_bi_directional("portc3"),3));
 
620
    assign_pin(15, m_portc->addPin(new IO_bi_directional("portc4"),4));
 
621
    assign_pin(16, m_portc->addPin(new IO_bi_directional("portc5"),5));
 
622
    assign_pin(17, m_portc->addPin(new IO_bi_directional("portc6"),6));
 
623
    assign_pin(18, m_portc->addPin(new IO_bi_directional("portc7"),7));
 
624
    assign_pin(19, 0);
 
625
    assign_pin(20, 0);
 
626
    assign_pin(21, m_portb->addPin(new IO_bi_directional_pu("portb0"),0));
 
627
    assign_pin(22, m_portb->addPin(new IO_bi_directional_pu("portb1"),1));
 
628
    assign_pin(23, m_portb->addPin(new IO_bi_directional_pu("portb2"),2));
 
629
    assign_pin(24, m_portb->addPin(new IO_bi_directional_pu("portb3"),3));
 
630
    assign_pin(25, m_portb->addPin(new IO_bi_directional_pu("portb4"),4));
 
631
    assign_pin(26, m_portb->addPin(new IO_bi_directional_pu("portb5"),5));
 
632
    assign_pin(27, m_portb->addPin(new IO_bi_directional_pu("portb6"),6));
 
633
    assign_pin(28, m_portb->addPin(new IO_bi_directional_pu("portb7"),7));
 
634
 
 
635
}
 
636
 
 
637
void P16F882::create_sfr_map()
 
638
{
 
639
    ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]);
 
640
}
 
641
//========================================================================
 
642
//
 
643
// Pic 16F883 
 
644
//
 
645
Processor * P16F883::construct(const char *name)
 
646
{
 
647
    P16F883 *p = new P16F883(name);
 
648
 
 
649
    p->P16F88x::create(256);
 
650
    p->P16F883::create_sfr_map();
 
651
    p->create_invalid_registers ();
 
652
 
 
653
    return p;
 
654
}
 
655
 
 
656
P16F883::P16F883(const char *_name )
 
657
    : P16F882(_name )
 
658
{
 
659
    m_porta->setEnableMask(0xff);
 
660
}
 
661
 
 
662
P16F883::~P16F883()
 
663
{
 
664
    delete_file_registers(0xc0,0xef);
 
665
    delete_file_registers(0x120,0x16f);
 
666
}
 
667
 
 
668
void P16F883::create_sfr_map()
 
669
{
 
670
    add_file_registers(0xc0,0xef,0);
 
671
    add_file_registers(0x120,0x16f,0);
 
672
    ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]);
 
673
}
 
674
//========================================================================
 
675
//
 
676
// Pic 16F886 
 
677
//
 
678
 
 
679
Processor * P16F886::construct(const char *name)
 
680
{
 
681
    P16F886 *p = new P16F886(name);
 
682
 
 
683
    p->P16F88x::create(256);
 
684
    p->P16F886::create_sfr_map();
 
685
    p->create_invalid_registers ();
 
686
 
 
687
    return p;
 
688
}
 
689
 
 
690
P16F886::P16F886(const char *_name )
 
691
    : P16F882(_name )
 
692
{
 
693
    m_porta->setEnableMask(0xff);
 
694
}
 
695
 
 
696
P16F886::~P16F886()
 
697
{
 
698
    delete_file_registers(0xc0,0xef);
 
699
    delete_file_registers(0x120,0x16f);
 
700
    delete_file_registers(0x190,0x1ef);
 
701
}
 
702
 
 
703
void P16F886::create_sfr_map()
 
704
{
 
705
    add_file_registers(0xc0,0xef,0);
 
706
    add_file_registers(0x120,0x16f,0);
 
707
    add_file_registers(0x190,0x1ef,0);
 
708
    ccp1con.setIOpin(&(*m_portc)[2], &(*m_portb)[2], &(*m_portb)[1], &(*m_portb)[4]);
 
709
}
 
710
//========================================================================
 
711
//
 
712
// Pic 16F887 
 
713
//
 
714
 
 
715
Processor * P16F887::construct(const char *name)
 
716
{
 
717
    P16F887 *p = new P16F887(name);
 
718
 
 
719
    p->P16F88x::create(256);
 
720
    p->P16F887::create_sfr_map();
 
721
    p->create_invalid_registers ();
 
722
 
 
723
    return p;
 
724
}
 
725
 
 
726
P16F887::P16F887(const char *_name )
 
727
    : P16F884(_name )
 
728
{
 
729
}
 
730
 
 
731
P16F887::~P16F887()
 
732
{
 
733
    delete_file_registers(0x110,0x11f);
 
734
    delete_file_registers(0x190,0x1ef);
 
735
}
 
736
 
 
737
void P16F887::create_sfr_map()
 
738
{
 
739
    add_file_registers(0xc0,0xef,0);
 
740
    add_file_registers(0x110,0x16f,0);
 
741
    //add_file_registers(0x110,0x11f,0);
 
742
    add_file_registers(0x190,0x1ef,0);
 
743
 
 
744
    add_SfrReg(m_portd, 0x08);
 
745
    add_SfrReg(m_trisd, 0x88, RegisterValue(0xff,0));
 
746
 
 
747
    ccp1con.setIOpin(&(*m_portc)[2], &(*m_portd)[5], &(*m_portd)[6], &(*m_portd)[7]);
 
748
    adcon1.setIOPin(5, &(*m_porte)[0]);
 
749
    adcon1.setIOPin(6, &(*m_porte)[1]);
 
750
    adcon1.setIOPin(7, &(*m_porte)[2]);
 
751
}
 
752
 
 
753
//========================================================================
 
754
//
 
755
Processor * P16F884::construct(const char *name)
 
756
{
 
757
    P16F884 *p = new P16F884(name);
 
758
 
 
759
    p->P16F88x::create(256);
 
760
    p->P16F884::create_sfr_map();
 
761
    p->create_invalid_registers ();
 
762
 
 
763
    return p;
 
764
}
 
765
 
 
766
P16F884::P16F884(const char *_name )
 
767
    : P16F88x(_name )
 
768
{
 
769
    m_porta->setEnableMask(0xff);
 
770
 
 
771
    // trisa5 is an input only pin
 
772
    m_trisa->setEnableMask(0xdf);
 
773
 
 
774
    m_portd = new PicPSP_PortRegister(this,"portd", 8,0xff);
 
775
    m_trisd = new PicTrisRegister(this,"trisd", (PicPortRegister *)m_portd, false);
 
776
}
 
777
 
 
778
P16F884::~P16F884()
 
779
{
 
780
    delete_file_registers(0xc0,0xef);
 
781
    delete_file_registers(0x120,0x16f);
 
782
 
 
783
    delete_SfrReg(m_portd);
 
784
    delete_SfrReg(m_trisd);
 
785
}
 
786
 
 
787
//------------------------------------------------------------------------
 
788
//
 
789
void P16F884::create_iopin_map(void)
 
790
{
 
791
    assign_pin(1, m_porte->addPin(new IO_bi_directional("porte3"),3));
 
792
    assign_pin( 2, m_porta->addPin(new IO_bi_directional("porta0"),0));
 
793
    assign_pin( 3, m_porta->addPin(new IO_bi_directional("porta1"),1));
 
794
    assign_pin( 4, m_porta->addPin(new IO_bi_directional("porta2"),2));
 
795
    assign_pin( 5, m_porta->addPin(new IO_bi_directional("porta3"),3));
 
796
    assign_pin( 6, m_porta->addPin( new IOPIN("porta4", OPEN_COLLECTOR),4) );
 
797
    assign_pin( 7, m_porta->addPin(new IO_bi_directional("porta5"),5));
 
798
    assign_pin( 8, m_porte->addPin(new IO_bi_directional("porte0"),0));
 
799
    assign_pin( 9, m_porte->addPin(new IO_bi_directional("porte1"),1));
 
800
    assign_pin(10, m_porte->addPin(new IO_bi_directional("porte2"),2));
 
801
    assign_pin(11, 0);
 
802
    assign_pin(12, 0);
 
803
    assign_pin( 13, m_porta->addPin(new IO_bi_directional("porta7"),7));
 
804
    assign_pin( 14, m_porta->addPin(new IO_bi_directional("porta6"),6));
 
805
    assign_pin(15, m_portc->addPin(new IO_bi_directional("portc0"),0));
 
806
    assign_pin(16, m_portc->addPin(new IO_bi_directional("portc1"),1));
 
807
    assign_pin(17, m_portc->addPin(new IO_bi_directional("portc2"),2));
 
808
    assign_pin(18, m_portc->addPin(new IO_bi_directional("portc3"),3));
 
809
    assign_pin(23, m_portc->addPin(new IO_bi_directional("portc4"),4));
 
810
    assign_pin(24, m_portc->addPin(new IO_bi_directional("portc5"),5));
 
811
    assign_pin(25, m_portc->addPin(new IO_bi_directional("portc6"),6));
 
812
    assign_pin(26, m_portc->addPin(new IO_bi_directional("portc7"),7));
 
813
    assign_pin(19, m_portd->addPin(new IO_bi_directional("portd0"),0));
 
814
    assign_pin(20, m_portd->addPin(new IO_bi_directional("portd1"),1));
 
815
    assign_pin(21, m_portd->addPin(new IO_bi_directional("portd2"),2));
 
816
    assign_pin(22, m_portd->addPin(new IO_bi_directional("portd3"),3));
 
817
    assign_pin(27, m_portd->addPin(new IO_bi_directional("portd4"),4));
 
818
    assign_pin(28, m_portd->addPin(new IO_bi_directional("portd5"),5));
 
819
    assign_pin(29, m_portd->addPin(new IO_bi_directional("portd6"),6));
 
820
    assign_pin(30, m_portd->addPin(new IO_bi_directional("portd7"),7));
 
821
    assign_pin(31, 0);
 
822
    assign_pin(32, 0);
 
823
    assign_pin(33, m_portb->addPin(new IO_bi_directional_pu("portb0"),0));
 
824
    assign_pin(34, m_portb->addPin(new IO_bi_directional_pu("portb1"),1));
 
825
    assign_pin(35, m_portb->addPin(new IO_bi_directional_pu("portb2"),2));
 
826
    assign_pin(36, m_portb->addPin(new IO_bi_directional_pu("portb3"),3));
 
827
    assign_pin(37, m_portb->addPin(new IO_bi_directional_pu("portb4"),4));
 
828
    assign_pin(38, m_portb->addPin(new IO_bi_directional_pu("portb5"),5));
 
829
    assign_pin(39, m_portb->addPin(new IO_bi_directional_pu("portb6"),6));
 
830
    assign_pin(40, m_portb->addPin(new IO_bi_directional_pu("portb7"),7));
 
831
}
 
832
 
 
833
void P16F884::create_sfr_map()
 
834
{
 
835
    add_file_registers(0xc0,0xef,0);
 
836
    add_file_registers(0x120,0x16f,0);
 
837
 
 
838
    add_SfrReg(m_portd, 0x08);
 
839
    add_SfrReg(m_trisd, 0x88, RegisterValue(0xff,0));
 
840
 
 
841
    ccp1con.setIOpin(&(*m_portc)[2], &(*m_portd)[5], &(*m_portd)[6], &(*m_portd)[7]);
 
842
    adcon1.setIOPin(5, &(*m_porte)[0]);
 
843
    adcon1.setIOPin(6, &(*m_porte)[1]);
 
844
    adcon1.setIOPin(7, &(*m_porte)[2]);
 
845
}
 
846
//------------------------------------------------------------------------
 
847
//
 
848
//
 
849
 
 
850
class ConfigF631 : public ConfigWord
 
851
{
 
852
public:
 
853
    ConfigF631(P16F631 *pCpu)
 
854
        : ConfigWord("CONFIG", 0x3fff, pCpu, 0x2007)
 
855
    {
 
856
        Dprintf(("ConfigF631::ConfigF631 %p\n", m_pCpu));
 
857
    }
 
858
 
 
859
    enum {
 
860
        FOSC0  = 1<<0,
 
861
        FOSC1  = 1<<1,
 
862
        FOSC2  = 1<<2,
 
863
        WDTEN  = 1<<3,
 
864
        PWRTEN = 1<<4,
 
865
        MCLRE =  1<<5,
 
866
        BODEN =  1<<6,
 
867
        CP =     1<<7,
 
868
        CPD =    1<<8
 
869
    };
 
870
 
 
871
    string toString()
 
872
    {
 
873
        int64_t i64;
 
874
        get(i64);
 
875
        int i = i64 &0xfff;
 
876
 
 
877
        char buff[356];
 
878
 
 
879
        const char *OSCdesc[8] = {
 
880
            "LP oscillator",
 
881
            "XT oscillator",
 
882
            "HS oscillator",
 
883
            "EC oscillator w/ OSC2 configured as I/O",
 
884
            "INTOSC oscillator: I/O on RA4 pin, I/O on RA5",
 
885
            "INTOSC oscillator: CLKOUT on RA4 pin, I/O on RA5",
 
886
            "RC oscillator: I/O on RA4 pin, RC on RA5",
 
887
            "RC oscillator: CLKOUT on RA4 pin, RC on RA5"
 
888
        };
 
889
        snprintf(buff,sizeof(buff),
 
890
                 " $%04x\n"
 
891
                 " FOSC=%d - Clk source = %s\n"
 
892
                 " WDTEN=%d - WDT is %s\n"
 
893
                 " PWRTEN=%d - Power up timer is %s\n"
 
894
                 " MCLRE=%d - RA3 Pin %s\n"
 
895
                 " BODEN=%d -  Brown-out Detect %s\n"
 
896
                 " CP=%d - Code Protection %s\n"
 
897
                 " CPD=%d -  Data Code Protection %s\n",
 
898
                 i,
 
899
                 i&(FOSC0|FOSC1|FOSC2), OSCdesc[i&(FOSC0|FOSC1|FOSC2)],
 
900
                ((i&WDTE) ? 1 : 0), ((i&WDTE) ? "enabled" : "disabled"),
 
901
                ((i&PWRTEN) ? 1 : 0), ((i&PWRTEN) ? "disabled" : "enabled"),
 
902
                ((i&MCLRE) ? 1 : 0), ((i&MCLRE) ? "MCLR" : "Input"),
 
903
                ((i&BODEN) ? 1 : 0), ((i&BODEN) ? "enabled" : "disabled"),
 
904
                ((i&CP) ? 1 : 0), ((i&CP) ? "disabled" : "enabled"),
 
905
                ((i&CPD) ? 1 : 0), ((i&CPD) ? "disabled" : "enabled")
 
906
                );
 
907
        return string(buff);
 
908
    }
 
909
};
 
910
P16F631::P16F631(const char *_name )
 
911
    : _14bit_processor(_name ),
 
912
      t1con(this, "t1con" ),
 
913
      pie1(this,"pie1" ),
 
914
      pie2(this,"pie2" ),
 
915
      tmr1l(this, "tmr1l" ),
 
916
      tmr1h(this, "tmr1h" ),
 
917
      osctune(this, "osctune" ),
 
918
      pcon(this, "pcon" ),
 
919
      wdtcon(this, "wdtcon", 0x1f),
 
920
      osccon(0),
 
921
      vrcon(this, "vrcon" ),
 
922
      srcon(this, "srcon" ),
 
923
      ansel(this,"ansel" ),
 
924
      comparator(this),
 
925
      adcon0(this,"adcon0" ),
 
926
      adcon1(this,"adcon1" ),
 
927
 
 
928
      intcon_reg(this,"intcon" )
 
929
{
 
930
    pir1_2_reg = new PIR1v2(this,"pir1", &intcon_reg,&pie1);
 
931
    pir1 = pir1_2_reg;
 
932
    pir2_3_reg = new PIR2v3(this,"pir2", &intcon_reg,&pie2);
 
933
    pir2 = pir2_3_reg;
 
934
 
 
935
    m_ioca = new IOC(this, "ioca" );
 
936
    m_iocb = new IOC(this, "iocb" );
 
937
 
 
938
    m_porta = new PicPortGRegister(this,"porta", &intcon_reg, m_ioca, 8,0x3f);
 
939
    m_trisa = new PicTrisRegister(this,"trisa", m_porta, false, 0x37);
 
940
 
 
941
    m_portb = new PicPortGRegister(this,"portb", &intcon_reg, m_iocb, 8,0xf0);
 
942
    m_trisb = new PicTrisRegister(this,"trisb", m_portb, false);
 
943
 
 
944
    m_wpua = new WPU(this, "wpua", m_porta, 0x37);
 
945
    m_wpub = new WPU(this, "wpub", m_portb, 0xf0);
 
946
    tmr0.set_cpu(this, m_porta, 4, option_reg);
 
947
    tmr0.start(0);
 
948
 
 
949
    m_portc = new PicPortRegister(this,"portc", 8,0xff);
 
950
    m_trisc = new PicTrisRegister(this,"trisc", m_portc, false);
 
951
 
 
952
    comparator.cmxcon0[0] = new CMxCON0_V2(this, "cm1con0", 0, &comparator);
 
953
    comparator.cmxcon0[1] = new CMxCON0_V2(this, "cm2con0", 1, &comparator);
 
954
    comparator.cmxcon1[0] = new CM2CON1_V4(this, "cm2con1", 0, &comparator);
 
955
    comparator.cmxcon1[1] = comparator.cmxcon1[0];
 
956
}
 
957
 
 
958
P16F631::~P16F631()
 
959
{
 
960
    unassignMCLRPin();
 
961
    delete_file_registers(0x40, 0x7f);
 
962
    remove_SfrReg(comparator.cmxcon0[0]);
 
963
    remove_SfrReg(comparator.cmxcon0[1]);
 
964
    remove_SfrReg(comparator.cmxcon1[1]);
 
965
 
 
966
    remove_SfrReg(get_eeprom()->get_reg_eedata());
 
967
    remove_SfrReg(get_eeprom()->get_reg_eeadr());
 
968
    remove_SfrReg(get_eeprom()->get_reg_eecon1());
 
969
    remove_SfrReg(get_eeprom()->get_reg_eecon2());
 
970
    remove_SfrReg(&tmr0);
 
971
    remove_SfrReg(&vrcon);
 
972
    remove_SfrReg(&ansel);
 
973
    remove_SfrReg(&srcon);
 
974
    remove_SfrReg(&tmr1l);
 
975
    remove_SfrReg(&tmr1h);
 
976
    remove_SfrReg(&t1con);
 
977
    remove_SfrReg(&pcon);
 
978
    remove_SfrReg(&wdtcon);
 
979
    remove_SfrReg(osccon);
 
980
    remove_SfrReg(&pie1);
 
981
    remove_SfrReg(&pie2);
 
982
    remove_SfrReg(&intcon_reg);
 
983
    remove_SfrReg(&osctune);
 
984
    delete_SfrReg(pir2);
 
985
    delete_SfrReg(m_portc);
 
986
    delete_SfrReg(m_trisc);
 
987
 
 
988
    delete_SfrReg(m_portb);
 
989
    delete_SfrReg(m_trisb);
 
990
    delete_SfrReg(m_porta);
 
991
    delete_SfrReg(m_trisa);
 
992
    delete_SfrReg(m_ioca);
 
993
    delete_SfrReg(m_iocb);
 
994
    delete_SfrReg(m_wpua);
 
995
    delete_SfrReg(m_wpub);
 
996
    delete_SfrReg(pir1_2_reg);
 
997
    delete e;
 
998
}
 
999
void P16F631::create_iopin_map(void)
 
1000
{
 
1001
    assign_pin(1, 0);        // Vdd
 
1002
    assign_pin( 2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5));
 
1003
    assign_pin( 3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4));
 
1004
    assign_pin( 4, m_porta->addPin(new IOPIN("porta3"),3));
 
1005
    assign_pin( 5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5));
 
1006
    assign_pin( 6, m_portc->addPin(new IO_bi_directional("portc4"),4));
 
1007
    assign_pin( 7, m_portc->addPin(new IO_bi_directional("portc3"),3));
 
1008
    assign_pin( 8, m_portc->addPin(new IO_bi_directional("portc6"),6));
 
1009
    assign_pin( 9, m_portc->addPin(new IO_bi_directional("portc7"),7));
 
1010
    assign_pin(10, m_portb->addPin(new IO_bi_directional("portb7"),7));
 
1011
    assign_pin(11, m_portb->addPin(new IO_bi_directional_pu("portb6"),6));
 
1012
    assign_pin(12, m_portb->addPin(new IO_bi_directional_pu("portb5"),5));
 
1013
    assign_pin(13, m_portb->addPin(new IO_bi_directional_pu("portb4"),4));
 
1014
    assign_pin(14, m_portc->addPin(new IO_bi_directional_pu("portc2"),2));
 
1015
    assign_pin(15, m_portc->addPin(new IO_bi_directional_pu("portc1"),1));
 
1016
    assign_pin(16, m_portc->addPin(new IO_bi_directional_pu("portc0"),0));
 
1017
    assign_pin(17, m_porta->addPin(new IO_bi_directional_pu("porta2"),2));
 
1018
    assign_pin(18, m_porta->addPin(new IO_bi_directional_pu("porta1"),1));
 
1019
    assign_pin(19, m_porta->addPin(new IO_bi_directional_pu("porta0"),0));
 
1020
 
 
1021
    assign_pin(20, 0); //VSS
 
1022
 
 
1023
    tmr1l.setIOpin(&(*m_portc)[0]);
 
1024
}
 
1025
Processor * P16F631::construct(const char *name)
 
1026
{
 
1027
    P16F631 *p = new P16F631(name);
 
1028
 
 
1029
    p->create(128);
 
1030
    p->create_invalid_registers ();
 
1031
 
 
1032
    return p;
 
1033
}
 
1034
 
 
1035
void P16F631::create(int eesize)
 
1036
{
 
1037
    create_iopin_map();
 
1038
 
 
1039
    _14bit_processor::create();
 
1040
    osccon = new OSCCON(this, "osccon" );
 
1041
 
 
1042
    e = new EEPROM_WIDE(this,pir2);
 
1043
    e->initialize(eesize);
 
1044
    e->set_intcon(&intcon_reg);
 
1045
    set_eeprom_wide(e);
 
1046
 
 
1047
    status->rp_mask = 0x60;  // rp0 and rp1 are valid.
 
1048
    indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100
 
1049
    indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100
 
1050
 
 
1051
    P16F631::create_sfr_map();
 
1052
}
 
1053
 
 
1054
//-------------------------------------------------------------------
 
1055
void P16F631::create_sfr_map()
 
1056
{
 
1057
    pir_set_2_def.set_pir1(pir1);
 
1058
    pir_set_2_def.set_pir2(pir2);
 
1059
 
 
1060
    add_file_registers(0x40, 0x7f, 0);
 
1061
    alias_file_registers(0x70, 0x7f, 0x80);
 
1062
    alias_file_registers(0x70, 0x7f, 0x100);
 
1063
    alias_file_registers(0x70, 0x7f, 0x180);
 
1064
 
 
1065
    add_SfrReg(indf,    0x00);
 
1066
    alias_file_registers(0x00,0x00,0x80);
 
1067
    alias_file_registers(0x00,0x00,0x100);
 
1068
    alias_file_registers(0x00,0x00,0x180);
 
1069
 
 
1070
    add_SfrReg(&tmr0,   0x01);
 
1071
    alias_file_registers(0x01,0x01,0x100);
 
1072
    add_SfrReg(option_reg,  0x81, RegisterValue(0xff,0));
 
1073
    alias_file_registers(0x81,0x81,0x100);
 
1074
 
 
1075
    add_SfrReg(pcl,     0x02, RegisterValue(0,0));
 
1076
    add_SfrReg(status,  0x03, RegisterValue(0x18,0));
 
1077
    add_SfrReg(fsr,     0x04);
 
1078
    alias_file_registers(0x02,0x04,0x80);
 
1079
    alias_file_registers(0x02,0x04,0x100);
 
1080
    alias_file_registers(0x02,0x04,0x180);
 
1081
 
 
1082
    add_SfrReg(m_porta, 0x05);
 
1083
    add_SfrReg(m_trisa, 0x85, RegisterValue(0x3f,0));
 
1084
 
 
1085
    add_SfrReg(m_portb, 0x06);
 
1086
    add_SfrReg(m_trisb, 0x86, RegisterValue(0xf0,0));
 
1087
 
 
1088
    add_SfrReg(m_portc, 0x07);
 
1089
    add_SfrReg(m_trisc, 0x87, RegisterValue(0xff,0));
 
1090
    alias_file_registers(0x05,0x07,0x100);
 
1091
    alias_file_registers(0x85,0x87,0x100);
 
1092
 
 
1093
    add_SfrReg(pclath,  0x0a, RegisterValue(0,0));
 
1094
    add_SfrReg(&intcon_reg, 0x00b, RegisterValue(0,0));
 
1095
 
 
1096
    alias_file_registers(0x0a,0x0b,0x80);
 
1097
    alias_file_registers(0x0a,0x0b,0x100);
 
1098
    alias_file_registers(0x0a,0x0b,0x180);
 
1099
    add_SfrReg(pir1, 0x0c, RegisterValue(0,0));
 
1100
    add_SfrReg(pir2, 0x0d, RegisterValue(0,0));
 
1101
    add_SfrReg(&tmr1l, 0x0e, RegisterValue(0,0), "tmr1l");
 
1102
    add_SfrReg(&tmr1h, 0x0f, RegisterValue(0,0), "tmr1h");
 
1103
    add_SfrReg(&t1con, 0x10, RegisterValue(0,0));
 
1104
    add_SfrReg(&pcon, 0x8e, RegisterValue(0,0));
 
1105
    add_SfrReg(&wdtcon, 0x97, RegisterValue(0x08,0));
 
1106
    add_SfrReg(osccon, 0x8f, RegisterValue(0x60,0));
 
1107
 
 
1108
    add_SfrReg(&vrcon, 0x118, RegisterValue(0,0),"vrcon");
 
1109
    add_SfrReg(comparator.cmxcon0[0], 0x119, RegisterValue(0,0), "cm1con0");
 
1110
    add_SfrReg(comparator.cmxcon0[1], 0x11a, RegisterValue(0,0), "cm2con0");
 
1111
    add_SfrReg(comparator.cmxcon1[1], 0x11b, RegisterValue(2,0), "cm2con1");
 
1112
    comparator.cmxcon1[0]->set_OUTpin(&(*m_porta)[2], &(*m_portc)[4]);
 
1113
    comparator.cmxcon1[0]->set_INpinNeg(&(*m_porta)[1], &(*m_portc)[1],
 
1114
            &(*m_portc)[2], &(*m_portc)[3]);
 
1115
    comparator.cmxcon1[0]->set_INpinPos(&(*m_porta)[0], &(*m_portc)[0]);
 
1116
    comparator.cmxcon1[0]->setBitMask(0x03);
 
1117
    comparator.cmxcon0[0]->setBitMask(0xb7);
 
1118
    comparator.cmxcon0[0]->setIntSrc(new InterruptSource(pir2, PIR2v2::C1IF));
 
1119
    comparator.cmxcon0[1]->setBitMask(0xb7);
 
1120
    comparator.cmxcon0[1]->setIntSrc(new InterruptSource(pir2, PIR2v2::C2IF));
 
1121
    comparator.cmxcon1[0]->set_vrcon(&vrcon);
 
1122
    comparator.cmxcon1[1] = comparator.cmxcon1[0];
 
1123
    comparator.assign_tmr1l(&tmr1l);
 
1124
 
 
1125
    add_SfrReg(&ansel, 0x11e, RegisterValue(0xff,0));
 
1126
    add_SfrReg(&srcon, 0x19e, RegisterValue(0,0),"srcon");
 
1127
 
 
1128
    ansel.setAdcon1(&adcon1);
 
1129
    ansel.setValidBits(0xff);
 
1130
 
 
1131
    adcon1.setNumberOfChannels(12);
 
1132
    adcon1.setIOPin(0, &(*m_porta)[0]);
 
1133
    adcon1.setIOPin(1, &(*m_porta)[1]);
 
1134
    adcon1.setIOPin(4, &(*m_portc)[0]);
 
1135
 
 
1136
    adcon1.setIOPin(5, &(*m_portc)[1]);
 
1137
    adcon1.setIOPin(6, &(*m_portc)[2]);
 
1138
    adcon1.setIOPin(7, &(*m_portc)[3]);
 
1139
    intcon = &intcon_reg;
 
1140
    intcon_reg.set_pir_set(get_pir_set());
 
1141
 
 
1142
    tmr1l.tmrh = &tmr1h;
 
1143
    tmr1l.t1con = &t1con;
 
1144
    // FIXME -- can't delete this new'd item
 
1145
    tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v3::TMR1IF));
 
1146
    tmr1h.tmrl  = &tmr1l;
 
1147
    t1con.tmrl  = &tmr1l;
 
1148
 
 
1149
    tmr1l.setIOpin(&(*m_porta)[5]);
 
1150
    tmr1l.setGatepin(&(*m_porta)[4]);
 
1151
 
 
1152
    add_SfrReg(&pie1,   0x8c, RegisterValue(0,0));
 
1153
    add_SfrReg(&pie2,   0x8d, RegisterValue(0,0));
 
1154
    if (pir1) {
 
1155
        pir1->set_intcon(&intcon_reg);
 
1156
        pir1->set_pie(&pie1);
 
1157
    }
 
1158
    pie1.setPir(pir1);
 
1159
    pie2.setPir(pir2);
 
1160
 
 
1161
    get_eeprom()->get_reg_eedata()->new_name("eedat");
 
1162
    add_SfrReg(get_eeprom()->get_reg_eedata(),  0x10c);
 
1163
    add_SfrReg(get_eeprom()->get_reg_eeadr(),   0x10d);
 
1164
    add_SfrReg(get_eeprom()->get_reg_eecon1(),  0x18c, RegisterValue(0,0));
 
1165
    add_SfrReg(get_eeprom()->get_reg_eecon2(),  0x18d);
 
1166
    add_SfrReg(m_wpua, 0x95, RegisterValue(0x37,0),"wpua");
 
1167
    add_SfrReg(m_wpub, 0x115, RegisterValue(0xf0,0),"wpub");
 
1168
    add_SfrReg(m_ioca, 0x96, RegisterValue(0,0),"ioca");
 
1169
    add_SfrReg(m_iocb, 0x116, RegisterValue(0,0),"iocb");
 
1170
    add_SfrReg(&osctune, 0x90, RegisterValue(0,0),"osctune");
 
1171
 
 
1172
    osccon->set_osctune(&osctune);
 
1173
    osctune.set_osccon(osccon);
 
1174
}
 
1175
//-------------------------------------------------------------------
 
1176
void P16F631::option_new_bits_6_7(uint bits)
 
1177
{
 
1178
    m_wpua->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7);
 
1179
    m_wpub->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7);
 
1180
    m_porta->setIntEdge((bits & OPTION_REG::BIT6) == OPTION_REG::BIT6);
 
1181
}
 
1182
//-------------------------------------------------------------------
 
1183
void P16F631::create_config_memory()
 
1184
{
 
1185
    m_configMemory = new ConfigMemory(this,1);
 
1186
    m_configMemory->addConfigWord(0,new ConfigF631(this));
 
1187
    wdt.initialize(true); // default WDT enabled
 
1188
    wdt.set_timeout(0.000035);
 
1189
    set_config_word(0x2007, 0x3fff);
 
1190
 
 
1191
};
 
1192
 
 
1193
//-------------------------------------------------------------------
 
1194
bool P16F631::set_config_word(uint address, uint cfg_word)
 
1195
{
 
1196
    enum {
 
1197
        CFG_FOSC0 = 1<<0,
 
1198
        CFG_FOSC1 = 1<<1,
 
1199
        CFG_FOSC2 = 1<<2,
 
1200
        CFG_WDTE  = 1<<3,
 
1201
        CFG_MCLRE = 1<<5,
 
1202
        CFG_IESO  = 1<<10,
 
1203
    };
 
1204
 
 
1205
    if(address == config_word_address())
 
1206
    {
 
1207
        uint valid_pins = m_porta->getEnableMask();
 
1208
 
 
1209
        if ((cfg_word & CFG_MCLRE) == CFG_MCLRE)
 
1210
        {
 
1211
            assignMCLRPin(4);
 
1212
        }
 
1213
        else
 
1214
        {
 
1215
            unassignMCLRPin();
 
1216
        }
 
1217
 
 
1218
        wdt.initialize((cfg_word & CFG_WDTE) == CFG_WDTE);
 
1219
 
 
1220
        set_int_osc(false);
 
1221
 
 
1222
        // AnalogReq is used so ADC does not change clock names
 
1223
        // set_config_word is first called with default and then
 
1224
        // often called a second time. the following call is to
 
1225
        // reset porta so next call to AnalogReq sill set the pin name
 
1226
        //
 
1227
        (&(*m_porta)[4])->AnalogReq((Register *)this, false, "porta4");
 
1228
        valid_pins |= 0x20;
 
1229
 
 
1230
        uint fosc = cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2);
 
1231
        if (osccon)
 
1232
        {
 
1233
            osccon->set_config_xosc(fosc < 3);
 
1234
            osccon->set_config_irc(fosc == 4 || fosc == 5);
 
1235
            osccon->set_config_ieso(cfg_word & CFG_IESO);
 
1236
        }
 
1237
 
 
1238
        switch(fosc)
 
1239
        {
 
1240
        case 0:  // LP oscillator: low power crystal is on RA4 and RA5
 
1241
        case 1:     // XT oscillator: crystal/resonator is on RA4 and RA5
 
1242
        case 2:     // HS oscillator: crystal/resonator is on RA4 and RA5
 
1243
            (&(*m_porta)[4])->AnalogReq((Register *)this, true, "OSC2");
 
1244
 
 
1245
            valid_pins &= 0xcf;
 
1246
            break;
 
1247
 
 
1248
        case 3:        // EC I/O on RA4 pin, CLKIN on RA5
 
1249
            valid_pins &= 0xef;
 
1250
            break;
 
1251
            
 
1252
        case 5: // INTOSC CLKOUT on RA4 pin
 
1253
            (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT");
 
1254
        case 4: // INTOSC
 
1255
            set_int_osc(true);
 
1256
            osccon->set_rc_frequency();
 
1257
            break;
 
1258
 
 
1259
        case 6: //RC oscillator: I/O on RA4 pin, RC on RA5
 
1260
            valid_pins &= 0xdf;
 
1261
            break;
 
1262
 
 
1263
        case 7: // RC oscillator: CLKOUT on RA4 pin, RC on RA5
 
1264
            (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT");
 
1265
 
 
1266
            valid_pins &= 0xdf;
 
1267
            break;
 
1268
        };
 
1269
 
 
1270
        if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO
 
1271
        {
 
1272
            m_porta->setEnableMask(valid_pins);
 
1273
            m_trisa->setEnableMask(valid_pins & 0xf7);
 
1274
        }
 
1275
        return(true);
 
1276
    }
 
1277
    return false;
 
1278
}
 
1279
 
 
1280
//========================================================================
 
1281
//
 
1282
// Pic 16F684
 
1283
//
 
1284
P16F684::P16F684(const char *_name )
 
1285
    : _14bit_processor(_name ),
 
1286
      comparator(this),
 
1287
      t1con(this, "t1con" ),
 
1288
      t2con(this, "t2con" ),
 
1289
      pie1(this,"pie1" ),
 
1290
      pr2(this, "pr2" ),
 
1291
      tmr2(this, "tmr2" ),
 
1292
      tmr1l(this, "tmr1l" ),
 
1293
      tmr1h(this, "tmr1h" ),
 
1294
      osctune(this, "osctune" ),
 
1295
      pcon(this, "pcon" ),
 
1296
      wdtcon(this, "wdtcon", 0x1f),
 
1297
      osccon(0),
 
1298
      ansel(this, "ansel" ),
 
1299
      adcon0(this, "adcon0" ),
 
1300
      adcon1(this, "adcon1" ),
 
1301
      adresh(this, "adresh" ),
 
1302
      adresl(this, "adresl" ),
 
1303
      ccp1con(this, "ccp1con" ),
 
1304
      ccpr1l(this, "ccpr1l" ),
 
1305
      ccpr1h(this, "ccpr1h" ),
 
1306
      eccpas(this, "eccpas" ),
 
1307
      pwm1con(this, "pwm1con" ),
 
1308
      pstrcon(this, "pstrcon" ),
 
1309
      intcon_reg(this,"intcon" )
 
1310
{
 
1311
    pir1_3_reg = new PIR1v3(this,"pir1", &intcon_reg,&pie1);
 
1312
    pir1 = pir1_3_reg;
 
1313
    pir1->valid_bits = pir1->writable_bits = 0xff;
 
1314
 
 
1315
    m_ioca = new IOC(this, "ioca" );
 
1316
 
 
1317
    m_porta = new PicPortGRegister(this,"porta", &intcon_reg, m_ioca, 8,0x3f);
 
1318
    m_trisa = new PicTrisRegister(this,"trisa", m_porta, false);
 
1319
 
 
1320
    m_wpua = new WPU(this, "wpua", m_porta, 0x37);
 
1321
    tmr0.set_cpu(this, m_porta, 4, option_reg);
 
1322
    tmr0.start(0);
 
1323
 
 
1324
    m_portc = new PicPortRegister(this,"portc", 8,0x3f);
 
1325
    m_trisc = new PicTrisRegister(this,"trisc", m_portc, false);
 
1326
}
 
1327
 
 
1328
P16F684::~P16F684()
 
1329
{
 
1330
    unassignMCLRPin();
 
1331
 
 
1332
    delete_file_registers(0x20, 0x7f);
 
1333
    delete_file_registers(0xa0, 0xbf);
 
1334
 
 
1335
    remove_SfrReg(&tmr0);
 
1336
    remove_SfrReg(&intcon_reg);
 
1337
    remove_SfrReg(pir1);
 
1338
    remove_SfrReg(&tmr1l);
 
1339
    remove_SfrReg(&tmr1h);
 
1340
    remove_SfrReg(&t1con);
 
1341
    remove_SfrReg(&tmr2);
 
1342
    remove_SfrReg(&t2con);
 
1343
    remove_SfrReg(&ccpr1l);
 
1344
    remove_SfrReg(&ccpr1h);
 
1345
    remove_SfrReg(&ccp1con);
 
1346
    remove_SfrReg(&pwm1con);
 
1347
    remove_SfrReg(&eccpas);
 
1348
    remove_SfrReg(&wdtcon);
 
1349
    remove_SfrReg(&comparator.cmcon);
 
1350
    remove_SfrReg(&comparator.cmcon1);
 
1351
    remove_SfrReg(&adresh);
 
1352
    remove_SfrReg(&adcon0);
 
1353
    remove_SfrReg(&pie1);
 
1354
    remove_SfrReg(&pcon);
 
1355
    remove_SfrReg(osccon);
 
1356
    remove_SfrReg(&osctune);
 
1357
    remove_SfrReg(&ansel);
 
1358
    remove_SfrReg(&pr2);
 
1359
    remove_SfrReg(&comparator.vrcon);
 
1360
    remove_SfrReg(get_eeprom()->get_reg_eedata());
 
1361
    remove_SfrReg(get_eeprom()->get_reg_eeadr());
 
1362
    remove_SfrReg(get_eeprom()->get_reg_eecon1());
 
1363
    remove_SfrReg(get_eeprom()->get_reg_eecon2());
 
1364
    remove_SfrReg(&adresl);
 
1365
    remove_SfrReg(&adcon1);
 
1366
 
 
1367
    delete_SfrReg(m_portc);
 
1368
    delete_SfrReg(m_trisc);
 
1369
 
 
1370
    delete_SfrReg(m_porta);
 
1371
    delete_SfrReg(m_trisa);
 
1372
    delete_SfrReg(m_ioca);
 
1373
    delete_SfrReg(m_wpua);
 
1374
    delete_SfrReg(pir1_3_reg);
 
1375
    delete e;
 
1376
}
 
1377
 
 
1378
void P16F684::create_iopin_map(void)
 
1379
{
 
1380
    assign_pin(1, 0);        // Vdd
 
1381
 
 
1382
    assign_pin( 2, m_porta->addPin(new IO_bi_directional_pu("porta5"),5));
 
1383
    assign_pin( 3, m_porta->addPin(new IO_bi_directional_pu("porta4"),4));
 
1384
    assign_pin( 4, m_porta->addPin(new IOPIN("porta3"),3));
 
1385
    assign_pin( 5, m_portc->addPin(new IO_bi_directional_pu("portc5"),5));
 
1386
    assign_pin( 6, m_portc->addPin(new IO_bi_directional("portc4"),4));
 
1387
    assign_pin( 7, m_portc->addPin(new IO_bi_directional("portc3"),3));
 
1388
 
 
1389
    assign_pin( 8, m_portc->addPin(new IO_bi_directional("portc2"),2));
 
1390
    assign_pin( 9, m_portc->addPin(new IO_bi_directional("portc1"),1));
 
1391
    assign_pin(10, m_portc->addPin(new IO_bi_directional("portc0"),0));
 
1392
 
 
1393
    assign_pin(11, m_porta->addPin(new IO_bi_directional_pu("porta2"),2));
 
1394
    assign_pin(12, m_porta->addPin(new IO_bi_directional_pu("porta1"),1));
 
1395
    assign_pin(13, m_porta->addPin(new IO_bi_directional_pu("porta0"),0));
 
1396
 
 
1397
    assign_pin(14, 0); //VSS
 
1398
 
 
1399
    tmr1l.setIOpin(&(*m_portc)[0]);
 
1400
}
 
1401
 
 
1402
Processor * P16F684::construct(const char *name)
 
1403
{
 
1404
    P16F684 *p = new P16F684(name);
 
1405
 
 
1406
    p->create(256);
 
1407
    p->create_invalid_registers ();
 
1408
 
 
1409
    return p;
 
1410
}
 
1411
 
 
1412
void P16F684::create(int eesize)
 
1413
{
 
1414
    create_iopin_map();
 
1415
 
 
1416
    _14bit_processor::create();
 
1417
 
 
1418
    osccon = new OSCCON(this, "osccon" );
 
1419
 
 
1420
    e = new EEPROM_WIDE(this,pir1);
 
1421
    e->initialize(eesize);
 
1422
    e->set_intcon(&intcon_reg);
 
1423
    set_eeprom_wide(e);
 
1424
 
 
1425
    status->rp_mask = 0x60;  // rp0 and rp1 are valid.
 
1426
    indf->base_address_mask1 = 0x80; // used for indirect accesses above 0x100
 
1427
    indf->base_address_mask2 = 0x1ff; // used for indirect accesses above 0x100
 
1428
 
 
1429
    P16F684::create_sfr_map();
 
1430
}
 
1431
 
 
1432
void P16F684::create_sfr_map()
 
1433
{
 
1434
    pir_set_def.set_pir1(pir1);
 
1435
 
 
1436
    add_file_registers(0x20, 0x7f, 0);
 
1437
    add_file_registers(0xa0, 0xbf, 0);
 
1438
    alias_file_registers(0x70, 0x7f, 0x80);
 
1439
 
 
1440
    add_SfrReg(indf,    0x00);
 
1441
    alias_file_registers(0x00,0x00,0x80);
 
1442
 
 
1443
    add_SfrReg(&tmr0,   0x01);
 
1444
    add_SfrReg(option_reg,  0x81, RegisterValue(0xff,0));
 
1445
 
 
1446
    add_SfrReg(pcl,     0x02, RegisterValue(0,0));
 
1447
    add_SfrReg(status,  0x03, RegisterValue(0x18,0));
 
1448
    add_SfrReg(fsr,     0x04);
 
1449
    alias_file_registers(0x02,0x04,0x80);
 
1450
 
 
1451
    add_SfrReg(m_porta, 0x05);
 
1452
    add_SfrReg(m_trisa, 0x85, RegisterValue(0x3f,0));
 
1453
 
 
1454
    add_SfrReg(m_portc, 0x07);
 
1455
    add_SfrReg(m_trisc, 0x87, RegisterValue(0xff,0));
 
1456
 
 
1457
    add_SfrReg(pclath,  0x0a, RegisterValue(0,0));
 
1458
    add_SfrReg(&intcon_reg, 0x00b, RegisterValue(0,0));
 
1459
 
 
1460
    alias_file_registers(0x0a,0x0b,0x80);
 
1461
    add_SfrReg(pir1, 0x0c, RegisterValue(0,0));
 
1462
    add_SfrReg(&tmr1l, 0x0e, RegisterValue(0,0), "tmr1l");
 
1463
    add_SfrReg(&tmr1h, 0x0f, RegisterValue(0,0), "tmr1h");
 
1464
    add_SfrReg(&t1con, 0x10, RegisterValue(0,0));
 
1465
    add_SfrReg(&tmr2, 0x11, RegisterValue(0,0));
 
1466
    add_SfrReg(&t2con, 0x12, RegisterValue(0,0));
 
1467
    add_SfrReg(&ccpr1l, 0x13, RegisterValue(0,0));
 
1468
    add_SfrReg(&ccpr1h, 0x14, RegisterValue(0,0));
 
1469
    add_SfrReg(&ccp1con, 0x15, RegisterValue(0,0));
 
1470
    add_SfrReg(&pwm1con, 0x16, RegisterValue(0,0));
 
1471
    add_SfrReg(&eccpas, 0x17, RegisterValue(0,0));
 
1472
    add_SfrReg(&wdtcon, 0x18, RegisterValue(0x08,0));
 
1473
    add_SfrReg(&comparator.cmcon, 0x19, RegisterValue(0,0), "cmcon0");
 
1474
    add_SfrReg(&comparator.cmcon1, 0x1a, RegisterValue(0,0), "cmcon1");
 
1475
    add_SfrReg(&adresh,  0x1e, RegisterValue(0,0));
 
1476
    add_SfrReg(&adcon0, 0x1f, RegisterValue(0,0));
 
1477
 
 
1478
    add_SfrReg(&pie1,   0x8c, RegisterValue(0,0));
 
1479
    add_SfrReg(&pcon, 0x8e, RegisterValue(0,0));
 
1480
    add_SfrReg(osccon, 0x8f, RegisterValue(0x60,0));
 
1481
 
 
1482
    add_SfrReg(&osctune, 0x90, RegisterValue(0,0),"osctune");
 
1483
    add_SfrReg(&ansel, 0x91, RegisterValue(0xff,0));
 
1484
    add_SfrReg(&pr2,    0x92, RegisterValue(0xff,0));
 
1485
    add_SfrReg(m_wpua, 0x95, RegisterValue(0x37,0),"wpua");
 
1486
    add_SfrReg(m_ioca, 0x96, RegisterValue(0,0),"ioca");
 
1487
    add_SfrReg(&comparator.vrcon, 0x99, RegisterValue(0,0),"vrcon");
 
1488
    add_SfrReg(get_eeprom()->get_reg_eedata(),  0x9a);
 
1489
    add_SfrReg(get_eeprom()->get_reg_eeadr(),   0x9b);
 
1490
    add_SfrReg(get_eeprom()->get_reg_eecon1(),  0x9c, RegisterValue(0,0));
 
1491
    add_SfrReg(get_eeprom()->get_reg_eecon2(),  0x9d);
 
1492
    add_SfrReg(&adresl,  0x9e, RegisterValue(0,0));
 
1493
    add_SfrReg(&adcon1, 0x9f, RegisterValue(0,0));
 
1494
 
 
1495
    ansel.setAdcon1(&adcon1);
 
1496
    ansel.setValidBits(0xff);
 
1497
 
 
1498
    // Link the comparator and voltage ref to porta
 
1499
    comparator.initialize(&pir_set_def, NULL,
 
1500
                          &(*m_porta)[0], &(*m_porta)[1],          // AN0 AN1
 
1501
            0, 0,
 
1502
            &(*m_porta)[2], &(*m_portc)[4]);        //OUT0 OUT1
 
1503
 
 
1504
    comparator.cmcon.setINpin(2, &(*m_portc)[0], "an4"); //AN4
 
1505
    comparator.cmcon.setINpin(3, &(*m_portc)[1], "an5"); //AN5
 
1506
 
 
1507
    comparator.cmcon.set_tmrl(&tmr1l);
 
1508
    comparator.cmcon1.set_tmrl(&tmr1l);
 
1509
 
 
1510
    comparator.cmcon.set_configuration(1, 0, AN0, AN1, AN0, AN1, ZERO);
 
1511
    comparator.cmcon.set_configuration(2, 0, AN2, AN3, AN2, AN3, ZERO);
 
1512
    comparator.cmcon.set_configuration(1, 1, AN1, AN2, AN0, AN2, NO_OUT);
 
1513
    comparator.cmcon.set_configuration(2, 1, AN3, AN2, AN3, AN2, NO_OUT);
 
1514
    comparator.cmcon.set_configuration(1, 2, AN1, VREF, AN0, VREF, NO_OUT);
 
1515
    comparator.cmcon.set_configuration(2, 2, AN3, VREF, AN2, VREF, NO_OUT);
 
1516
    comparator.cmcon.set_configuration(1, 3, AN1, AN2, AN1, AN2, NO_OUT);
 
1517
    comparator.cmcon.set_configuration(2, 3, AN3, AN2, AN3, AN2, NO_OUT);
 
1518
    comparator.cmcon.set_configuration(1, 4, AN1, AN0, AN1, AN0, NO_OUT);
 
1519
    comparator.cmcon.set_configuration(2, 4, AN3, AN2, AN3, AN2, NO_OUT);
 
1520
    comparator.cmcon.set_configuration(1, 5, NO_IN, NO_IN, NO_IN, NO_IN, ZERO);
 
1521
    comparator.cmcon.set_configuration(2, 5, AN3, AN2, AN3, AN2, NO_OUT);
 
1522
    comparator.cmcon.set_configuration(1, 6, AN1, AN2, AN1, AN2, OUT0);
 
1523
    comparator.cmcon.set_configuration(2, 6, AN3, AN2, AN3, AN2, OUT1);
 
1524
    comparator.cmcon.set_configuration(1, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO);
 
1525
    comparator.cmcon.set_configuration(2, 7, NO_IN, NO_IN, NO_IN, NO_IN, ZERO);
 
1526
    comparator.vrcon.setValidBits(0xaf);
 
1527
 
 
1528
    adcon0.setAdresLow(&adresl);
 
1529
    adcon0.setAdres(&adresh);
 
1530
    adcon0.setAdcon1(&adcon1);
 
1531
    adcon0.setIntcon(&intcon_reg);
 
1532
    adcon0.setA2DBits(10);
 
1533
    adcon0.setPir(pir1);
 
1534
    adcon0.setChannel_Mask(7);
 
1535
    adcon0.setChannel_shift(2);
 
1536
 
 
1537
    adcon1.setAdcon0(&adcon0);        // VCFG0, VCFG1 in adcon0
 
1538
    adcon1.setNumberOfChannels(8);
 
1539
    adcon1.setIOPin(0, &(*m_porta)[0]);
 
1540
    adcon1.setIOPin(1, &(*m_porta)[1]);
 
1541
    adcon1.setIOPin(2, &(*m_porta)[2]);
 
1542
    adcon1.setIOPin(3, &(*m_porta)[4]);
 
1543
    adcon1.setIOPin(4, &(*m_portc)[0]);
 
1544
    adcon1.setIOPin(5, &(*m_portc)[1]);
 
1545
    adcon1.setIOPin(6, &(*m_portc)[2]);
 
1546
    adcon1.setIOPin(7, &(*m_portc)[3]);
 
1547
    adcon1.setVrefHiConfiguration(2, 1);
 
1548
    intcon = &intcon_reg;
 
1549
    intcon_reg.set_pir_set(get_pir_set());
 
1550
 
 
1551
    tmr1l.tmrh = &tmr1h;
 
1552
    tmr1l.t1con = &t1con;
 
1553
    // FIXME -- can't delete this new'd item
 
1554
    tmr1l.setInterruptSource(new InterruptSource(pir1, PIR1v3::TMR1IF));
 
1555
    tmr1h.tmrl  = &tmr1l;
 
1556
    t1con.tmrl  = &tmr1l;
 
1557
 
 
1558
    tmr1l.setIOpin(&(*m_porta)[5]);
 
1559
    tmr1l.setGatepin(&(*m_porta)[4]);
 
1560
 
 
1561
    if (pir1)
 
1562
    {
 
1563
        pir1->set_intcon(&intcon_reg);
 
1564
        pir1->set_pie(&pie1);
 
1565
    }
 
1566
    pie1.setPir(pir1);
 
1567
 
 
1568
    t2con.tmr2  = &tmr2;
 
1569
    tmr2.pir_set   = get_pir_set();
 
1570
    tmr2.pr2    = &pr2;
 
1571
    tmr2.t2con  = &t2con;
 
1572
    tmr2.add_ccp ( &ccp1con );
 
1573
    pr2.tmr2    = &tmr2;
 
1574
 
 
1575
    eccpas.setIOpin(0, 0, &(*m_portc)[5]);
 
1576
    eccpas.link_registers(&pwm1con, &ccp1con);
 
1577
 
 
1578
    ccp1con.setIOpin(&(*m_portc)[5], &(*m_portc)[4], &(*m_portc)[3], &(*m_portc)[2]);
 
1579
    ccp1con.setBitMask(0xff);
 
1580
    ccp1con.pstrcon = &pstrcon;
 
1581
    ccp1con.pwm1con = &pwm1con;
 
1582
    ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas);
 
1583
    ccpr1l.ccprh  = &ccpr1h;
 
1584
    ccpr1l.tmrl   = &tmr1l;
 
1585
    ccpr1h.ccprl  = &ccpr1l;
 
1586
 
 
1587
    osccon->set_osctune(&osctune);
 
1588
    osctune.set_osccon(osccon);
 
1589
}
 
1590
 
 
1591
void P16F684::option_new_bits_6_7(uint bits)
 
1592
{
 
1593
    m_wpua->set_wpu_pu( (bits & OPTION_REG::BIT7) != OPTION_REG::BIT7);
 
1594
    m_porta->setIntEdge((bits & OPTION_REG::BIT6) == OPTION_REG::BIT6);
 
1595
}
 
1596
 
 
1597
void P16F684::create_config_memory()
 
1598
{
 
1599
    m_configMemory = new ConfigMemory(this,1);
 
1600
    m_configMemory->addConfigWord(0,new ConfigF631((P16F631*)this));
 
1601
    wdt.initialize(true); // default WDT enabled
 
1602
    wdt.set_timeout(0.000035);
 
1603
    set_config_word(0x2007, 0x3fff);
 
1604
}
 
1605
 
 
1606
bool P16F684::set_config_word(uint address, uint cfg_word)
 
1607
{
 
1608
    enum {
 
1609
        CFG_FOSC0 = 1<<0,
 
1610
        CFG_FOSC1 = 1<<1,
 
1611
        CFG_FOSC2 = 1<<2,
 
1612
        CFG_WDTE  = 1<<3,
 
1613
        CFG_MCLRE = 1<<5,
 
1614
        CFG_IESO  = 1<<11,
 
1615
    };
 
1616
 
 
1617
    if(address == config_word_address())
 
1618
    {
 
1619
        config_clock_mode = (cfg_word & (CFG_FOSC0 | CFG_FOSC1 | CFG_FOSC2));
 
1620
        if (osccon)
 
1621
        {
 
1622
            osccon->set_config_xosc(config_clock_mode < 3);
 
1623
            osccon->set_config_irc(config_clock_mode == 4 || config_clock_mode == 5);
 
1624
            osccon->set_config_ieso(cfg_word & CFG_IESO);
 
1625
        }
 
1626
        uint valid_pins = m_porta->getEnableMask();
 
1627
 
 
1628
        if ((cfg_word & CFG_MCLRE) == CFG_MCLRE) assignMCLRPin(4);
 
1629
        else                                     unassignMCLRPin();
 
1630
 
 
1631
        wdt.initialize((cfg_word & CFG_WDTE) == CFG_WDTE);
 
1632
 
 
1633
        set_int_osc(false);
 
1634
 
 
1635
        // AnalogReq is used so ADC does not change clock names
 
1636
        // set_config_word is first called with default and then
 
1637
        // often called a second time. the following call is to
 
1638
        // reset porta so next call to AnalogReq sill set the pin name
 
1639
        //
 
1640
        (&(*m_porta)[4])->AnalogReq((Register *)this, false, "porta4");
 
1641
        valid_pins |= 0x20;
 
1642
        switch(config_clock_mode)
 
1643
        {
 
1644
 
 
1645
        case 0:  // LP oscillator: low power crystal is on RA4 and RA5
 
1646
        case 1:     // XT oscillator: crystal/resonator is on RA4 and RA5
 
1647
        case 2:     // HS oscillator: crystal/resonator is on RA4 and RA5
 
1648
            (&(*m_porta)[4])->AnalogReq((Register *)this, true, "OSC2");
 
1649
            valid_pins &= 0xcf;
 
1650
            break;
 
1651
 
 
1652
        case 3:        // EC I/O on RA4 pin, CLKIN on RA5
 
1653
            valid_pins &= 0xef;
 
1654
            break;
 
1655
 
 
1656
            
 
1657
        case 5: // INTOSC CLKOUT on RA4 pin
 
1658
            (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT");
 
1659
        case 4: // INTOSC
 
1660
            set_int_osc(true);
 
1661
            osccon->set_rc_frequency();
 
1662
            break;
 
1663
 
 
1664
        case 6: //RC oscillator: I/O on RA4 pin, RC on RA5
 
1665
            valid_pins &= 0xdf;
 
1666
            break;
 
1667
 
 
1668
        case 7: // RC oscillator: CLKOUT on RA4 pin, RC on RA5
 
1669
            (&(*m_porta)[4])->AnalogReq((Register *)this, true, "CLKOUT");
 
1670
            valid_pins &= 0xdf;
 
1671
            break;
 
1672
        };
 
1673
 
 
1674
        if (valid_pins != m_porta->getEnableMask()) // enable new pins for IO
 
1675
        {
 
1676
            m_porta->setEnableMask(valid_pins);
 
1677
            m_trisa->setEnableMask(valid_pins);
 
1678
        }
 
1679
        return(true);
 
1680
    }
 
1681
    return false;
 
1682
}
 
1683
//======================================================================== 
 
1684
 
 
1685
Processor* P16F677::construct( const char *name )
 
1686
{
 
1687
    P16F677* p = new P16F677( name );
 
1688
 
 
1689
    p->create(256);
 
1690
    p->set_hasSSP();
 
1691
    p->create_sfr_map();
 
1692
    p->create_invalid_registers ();
 
1693
 
 
1694
    return p;
 
1695
}
 
1696
 
 
1697
P16F677::P16F677(const char *_name )
 
1698
    : P16F631(_name ),
 
1699
      ssp(this),
 
1700
      anselh(this,"anselh" ),
 
1701
      adresh(this,"adresh" ),
 
1702
      adresl(this,"adresl" )
 
1703
{
 
1704
}
 
1705
 
 
1706
P16F677::~P16F677()
 
1707
{
 
1708
    delete_file_registers(0x20,0x3f);
 
1709
    delete_file_registers(0xa0,0xbf);
 
1710
 
 
1711
    remove_SfrReg(&anselh);
 
1712
 
 
1713
    if (hasSSP())
 
1714
    {
 
1715
        remove_SfrReg(&ssp.sspbuf);
 
1716
        remove_SfrReg(&ssp.sspcon);
 
1717
        remove_SfrReg(&ssp.sspadd);
 
1718
        remove_SfrReg(&ssp.sspstat);
 
1719
    }
 
1720
    remove_SfrReg(&adresl);
 
1721
    remove_SfrReg(&adresh);
 
1722
    remove_SfrReg(&adcon0);
 
1723
    remove_SfrReg(&adcon1);
 
1724
    //delete m_cvref;
 
1725
    //delete m_v06ref;
 
1726
}
 
1727
 
 
1728
void P16F677::create_sfr_map()
 
1729
{
 
1730
    ansel.setAdcon1(&adcon1);
 
1731
    ansel.setAnselh(&anselh);
 
1732
    anselh.setAdcon1(&adcon1);
 
1733
    anselh.setAnsel(&ansel);
 
1734
    anselh.setValidBits(0x0f);
 
1735
    ansel.setValidBits(0xff);
 
1736
    adcon0.setAdresLow(&adresl);
 
1737
    adcon0.setAdres(&adresh);
 
1738
    adcon0.setAdcon1(&adcon1);
 
1739
    adcon0.setIntcon(&intcon_reg);
 
1740
    adcon0.setA2DBits(10);
 
1741
    adcon0.setPir(pir1);
 
1742
    adcon0.setChannel_Mask(0xf);
 
1743
    adcon0.setChannel_shift(2);
 
1744
    adcon0.setGo(1);
 
1745
    adcon0.setValidBits(0xff);
 
1746
 
 
1747
    adcon1.setValidBits(0xb0);
 
1748
    adcon1.setAdcon0(&adcon0);
 
1749
    adcon1.setNumberOfChannels(14);
 
1750
    adcon1.setValidCfgBits(ADCON1::VCFG0 , 6);
 
1751
    adcon1.setIOPin(2, &(*m_porta)[2]);
 
1752
    adcon1.setIOPin(3, &(*m_porta)[4]);
 
1753
 
 
1754
    adcon1.setIOPin(8, &(*m_portc)[6]);
 
1755
    adcon1.setIOPin(9, &(*m_portc)[7]);
 
1756
    adcon1.setIOPin(10, &(*m_portb)[4]);
 
1757
    adcon1.setIOPin(11, &(*m_portb)[5]);
 
1758
    adcon1.setVoltRef(12, 0.0);
 
1759
    adcon1.setVoltRef(13, 0.0);
 
1760
    adcon1.setVrefHiConfiguration(2, 1); // set a2d modes where an1 is Vref+
 
1761
 
 
1762
    add_SfrReg(&anselh, 0x11f, RegisterValue(0x0f,0));
 
1763
    add_file_registers(0x20,0x3f,0);
 
1764
    add_file_registers(0xa0,0xbf,0);
 
1765
 
 
1766
    if( hasSSP() )
 
1767
    {
 
1768
        add_SfrReg(&ssp.sspbuf,  0x13, RegisterValue(0,0),"sspbuf");
 
1769
        add_SfrReg(&ssp.sspcon,  0x14, RegisterValue(0,0),"sspcon");
 
1770
        add_SfrReg(&ssp.sspadd,  0x93, RegisterValue(0,0),"sspadd");
 
1771
        add_SfrReg(&ssp.sspstat, 0x94, RegisterValue(0,0),"sspstat");
 
1772
 
 
1773
        ssp.initialize(
 
1774
                    get_pir_set(),    // PIR
 
1775
                    &(*m_portb)[6],   // SCK
 
1776
                &(*m_portc)[6],   // SS
 
1777
                &(*m_portc)[7],   // SDO
 
1778
                &(*m_portb)[4],    // SDI
 
1779
                m_trisb,          // i2c tris port
 
1780
                SSP_TYPE_SSP
 
1781
                );
 
1782
    }
 
1783
    add_SfrReg(&adresl, 0x9e, RegisterValue(0,0));
 
1784
    add_SfrReg(&adresh, 0x1e, RegisterValue(0,0));
 
1785
    add_SfrReg(&adcon0, 0x1f, RegisterValue(0,0));
 
1786
    add_SfrReg(&adcon1, 0x9f, RegisterValue(0,0));
 
1787
}
 
1788
//========================================================================
 
1789
//
 
1790
// Pic 16F685 
 
1791
//
 
1792
 
 
1793
Processor* P16F685::construct(const char *name)
 
1794
{
 
1795
    P16F685 *p = new P16F685(name);
 
1796
 
 
1797
    p->create(256);
 
1798
    p->create_sfr_map();
 
1799
    p->create_invalid_registers ();
 
1800
 
 
1801
    return p;
 
1802
}
 
1803
 
 
1804
P16F685::P16F685(const char *_name )
 
1805
    : P16F677(_name ),
 
1806
      t2con(this, "t2con" ),
 
1807
      pr2(this, "pr2" ),
 
1808
      tmr2(this, "tmr2" ),
 
1809
      tmr1l(this, "tmr1l" ),
 
1810
      tmr1h(this, "tmr1h" ),
 
1811
      ccp1con(this, "ccp1con" ),
 
1812
      ccpr1l(this, "ccpr1l" ),
 
1813
      ccpr1h(this, "ccpr1h" ),
 
1814
      pcon(this, "pcon" ),
 
1815
      eccpas(this, "eccpas" ),
 
1816
      pwm1con(this, "pwm1con" ),
 
1817
      pstrcon(this, "pstrcon" )
 
1818
{
 
1819
    set_hasSSP();
 
1820
}
 
1821
 
 
1822
P16F685::~P16F685()
 
1823
{
 
1824
    delete_file_registers(0xc0,0xef);
 
1825
    delete_file_registers(0x120,0x16f);
 
1826
    remove_SfrReg(&pstrcon);
 
1827
    remove_SfrReg(&tmr2);
 
1828
    remove_SfrReg(&t2con);
 
1829
    remove_SfrReg(&pr2);
 
1830
    remove_SfrReg(&ccpr1l);
 
1831
    remove_SfrReg(&ccpr1h);
 
1832
    remove_SfrReg(&ccp1con);
 
1833
    remove_SfrReg(&pwm1con);
 
1834
    remove_SfrReg(&eccpas);
 
1835
}
 
1836
 
 
1837
void P16F685::create_sfr_map()
 
1838
{
 
1839
    P16F677::create_sfr_map();
 
1840
 
 
1841
    add_SfrReg(get_eeprom()->get_reg_eedatah(),  0x10e );
 
1842
    add_SfrReg(get_eeprom()->get_reg_eeadrh(),   0x10f);
 
1843
 
 
1844
    // Enable program memory reads and writes.
 
1845
    get_eeprom()->get_reg_eecon1()->set_bits(EECON1::EEPGD);
 
1846
 
 
1847
 
 
1848
    add_SfrReg(&tmr2,   0x11, RegisterValue(0,0));
 
1849
    add_SfrReg(&t2con,  0x12, RegisterValue(0,0));
 
1850
    add_SfrReg(&pr2,    0x92, RegisterValue(0xff,0));
 
1851
    t2con.tmr2  = &tmr2;
 
1852
    tmr2.pir_set   = get_pir_set();
 
1853
    tmr2.pr2    = &pr2;
 
1854
    tmr2.t2con  = &t2con;
 
1855
    tmr2.add_ccp ( &ccp1con );
 
1856
    pr2.tmr2    = &tmr2;
 
1857
 
 
1858
    eccpas.setIOpin(0, 0, &(*m_portb)[0]);
 
1859
    eccpas.link_registers(&pwm1con, &ccp1con);
 
1860
    add_SfrReg(&pstrcon, 0x19d, RegisterValue(1,0));
 
1861
 
 
1862
    ccp1con.setIOpin(&(*m_portc)[5], &(*m_portc)[4], &(*m_portc)[3], &(*m_portc)[2]);
 
1863
    ccp1con.setBitMask(0xff);
 
1864
    ccp1con.pstrcon = &pstrcon;
 
1865
    ccp1con.pwm1con = &pwm1con;
 
1866
    ccp1con.setCrosslinks(&ccpr1l, pir1, PIR1v2::CCP1IF, &tmr2, &eccpas);
 
1867
    ccpr1l.ccprh  = &ccpr1h;
 
1868
    ccpr1l.tmrl   = &tmr1l;
 
1869
    ccpr1h.ccprl  = &ccpr1l;
 
1870
 
 
1871
    add_SfrReg(&ccpr1l, 0x15, RegisterValue(0,0));
 
1872
    add_SfrReg(&ccpr1h, 0x16, RegisterValue(0,0));
 
1873
    add_SfrReg(&ccp1con, 0x17, RegisterValue(0,0));
 
1874
 
 
1875
    add_SfrReg(&pwm1con, 0x1c, RegisterValue(0,0));
 
1876
    add_SfrReg(&eccpas, 0x1d, RegisterValue(0,0));
 
1877
    //  add_file_registers(0x20,0x3f,0);
 
1878
    //  add_file_registers(0xa0,0xef,0);
 
1879
    add_file_registers(0xc0,0xef,0);
 
1880
    add_file_registers(0x120,0x16f,0);
 
1881
 
 
1882
 
 
1883
}
 
1884
//========================================================================
 
1885
//
 
1886
// Pic 16F687 
 
1887
//
 
1888
 
 
1889
Processor * P16F687::construct(const char *name)
 
1890
{
 
1891
    P16F687 *p = new P16F687(name);
 
1892
 
 
1893
    p->create(256);
 
1894
    p->create_sfr_map();
 
1895
    p->create_invalid_registers ();
 
1896
 
 
1897
    return p;
 
1898
}
 
1899
 
 
1900
P16F687::P16F687(const char *_name )
 
1901
    : P16F677(_name ),
 
1902
      tmr1l(this, "tmr1l" ),
 
1903
      tmr1h(this, "tmr1h" ),
 
1904
      pcon(this, "pcon" ),
 
1905
      usart(this)
 
1906
{
 
1907
    set_hasSSP();
 
1908
}
 
1909
 
 
1910
P16F687::~P16F687()
 
1911
{
 
1912
    remove_SfrReg(&usart.rcsta);
 
1913
    remove_SfrReg(&usart.txsta);
 
1914
    remove_SfrReg(&usart.spbrg);
 
1915
    remove_SfrReg(&usart.spbrgh);
 
1916
    remove_SfrReg(&usart.baudcon);
 
1917
    delete_SfrReg(usart.txreg);
 
1918
    delete_SfrReg(usart.rcreg);
 
1919
}
 
1920
 
 
1921
void P16F687::create_sfr_map()
 
1922
{
 
1923
    P16F677::create_sfr_map();
 
1924
 
 
1925
    add_SfrReg(get_eeprom()->get_reg_eedatah(),  0x10e);
 
1926
    add_SfrReg(get_eeprom()->get_reg_eeadrh(),   0x10f);
 
1927
 
 
1928
    //  add_file_registers(0x20,0x3f,0);
 
1929
    //  add_file_registers(0xa0,0xbf,0);
 
1930
 
 
1931
    usart.initialize(pir1,&(*m_portb)[7], &(*m_portb)[5],
 
1932
            new _TXREG(this,"txreg", &usart),
 
1933
            new _RCREG(this,"rcreg", &usart));
 
1934
 
 
1935
    add_SfrReg(&usart.rcsta, 0x18, RegisterValue(0,0),"rcsta");
 
1936
    add_SfrReg(&usart.txsta, 0x98, RegisterValue(2,0),"txsta");
 
1937
    add_SfrReg(&usart.spbrg, 0x99, RegisterValue(0,0),"spbrg");
 
1938
    add_SfrReg(&usart.spbrgh, 0x9a, RegisterValue(0,0),"spbrgh");
 
1939
    add_SfrReg(&usart.baudcon,  0x9b,RegisterValue(0x40,0),"baudctl");
 
1940
    add_SfrReg(usart.txreg,  0x19, RegisterValue(0,0),"txreg");
 
1941
    add_SfrReg(usart.rcreg,  0x1a, RegisterValue(0,0),"rcreg");
 
1942
    usart.set_eusart(true);
 
1943
 
 
1944
}
 
1945
//========================================================================
 
1946
//
 
1947
// Pic 16F689 
 
1948
//
 
1949
 
 
1950
Processor * P16F689::construct(const char *name)
 
1951
{
 
1952
    P16F689 *p = new P16F689(name);
 
1953
 
 
1954
    p->create(256);
 
1955
    p->create_sfr_map();
 
1956
    p->create_invalid_registers ();
 
1957
 
 
1958
    return p;
 
1959
}
 
1960
 
 
1961
P16F689::P16F689(const char *_name )
 
1962
    : P16F687(_name )
 
1963
{
 
1964
    set_hasSSP();
 
1965
}
 
1966
 
 
1967
//========================================================================
 
1968
//
 
1969
Processor * P16F690::construct(const char *name)
 
1970
{
 
1971
    P16F690 *p = new P16F690(name);
 
1972
 
 
1973
    p->create(256);
 
1974
    p->create_sfr_map();
 
1975
    p->create_invalid_registers ();
 
1976
 
 
1977
    return p;
 
1978
}
 
1979
 
 
1980
P16F690::P16F690(const char *_name )
 
1981
    : P16F685(_name ),
 
1982
      ccp2con(this, "ccp2con" ),
 
1983
      ccpr2l(this, "ccpr2l" ),
 
1984
      ccpr2h(this, "ccpr2h" ),
 
1985
      usart(this)
 
1986
{
 
1987
    set_hasSSP();
 
1988
}
 
1989
 
 
1990
P16F690::~P16F690()
 
1991
{
 
1992
    remove_SfrReg(&usart.rcsta);
 
1993
    remove_SfrReg(&usart.txsta);
 
1994
    remove_SfrReg(&usart.spbrg);
 
1995
    remove_SfrReg(&usart.spbrgh);
 
1996
    remove_SfrReg(&usart.baudcon);
 
1997
    delete_SfrReg(usart.txreg);
 
1998
    delete_SfrReg(usart.rcreg);
 
1999
}
 
2000
 
 
2001
void P16F690::create_sfr_map()
 
2002
{
 
2003
    P16F685::create_sfr_map();
 
2004
 
 
2005
    tmr2.ssp_module[0] = &ssp;
 
2006
    eccpas.setIOpin(0, 0, &(*m_portb)[0]);
 
2007
    eccpas.link_registers( &pwm1con, &ccp1con );
 
2008
 
 
2009
    usart.initialize( pir1,&(*m_portb)[7], &(*m_portb)[5],
 
2010
            new _TXREG( this,"txreg", &usart ),
 
2011
            new _RCREG( this,"rcreg", &usart ));
 
2012
 
 
2013
    add_SfrReg( &usart.rcsta, 0x18, RegisterValue(0,0),"rcsta");
 
2014
    add_SfrReg( &usart.txsta, 0x98, RegisterValue(2,0),"txsta");
 
2015
    add_SfrReg( &usart.spbrg, 0x99, RegisterValue(0,0),"spbrg");
 
2016
    add_SfrReg( &usart.spbrgh, 0x9a, RegisterValue(0,0),"spbrgh");
 
2017
    add_SfrReg( &usart.baudcon,  0x9b,RegisterValue(0x40,0),"baudctl");
 
2018
    add_SfrReg( usart.txreg,  0x19, RegisterValue(0,0),"txreg");
 
2019
    add_SfrReg( usart.rcreg,  0x1a, RegisterValue(0,0),"rcreg");
 
2020
    usart.set_eusart(true);
 
2021
}