Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
119 johboh 1
/*********************************************************************
2
 *
3
 *                  Main application
4
 *
5
 *********************************************************************
121 johboh 6
 * FileName:        $HeadURL: https://svn.auml.se/svn/HomeAutomation/trunk/EmbeddedSoftware/PIC/canIR/Source/Main.c $
7
 * Last changed:    $LastChangedDate: 2007-03-13 18:29:20 +0100 (Tue, 13 Mar 2007) $
8
 * By:              $LastChangedBy: johboh $
9
 * Revision:        $Revision: 363 $
119 johboh 10
 ********************************************************************/
11
 
12
 
363 johboh 13
#include <p18cxxx.h>
119 johboh 14
#include <compiler.h>
15
#include <stackTasks.h>
16
#include <Tick.h>
17
#include <funcdefs.h>
260 johboh 18
#include <CAN.h>
363 johboh 19
#include <EEAccess.h>
20
#include <crc16.h>
341 johboh 21
#include "..\canBoot\Include\boot.h"
119 johboh 22
 
23
 
363 johboh 24
typedef enum _EE_STATE {eesWAITING_START,eesSEND_ACK,eesWAIT_FIRST_DATA,eesWAIT_DATA_OR_CRC,eesWRITE_DATA,eesDONE} EE_STATE;
25
 
122 johboh 26
#ifdef USE_IREC
27
    #include <IRec.h>
28
#endif
29
 
119 johboh 30
static void mainInit(void);
363 johboh 31
static void loadIrCommands(void);
119 johboh 32
 
363 johboh 33
#define EE_PACKET_TIMOUT 5*TICK_100MS
34
#define IR_TIMOUT 2*TICK_100MS
119 johboh 35
 
363 johboh 36
static BOOL hasCtrlPacket = FALSE;
37
static CAN_PACKET ctrlPacket;
38
 
39
typedef struct _IR_COMMAND
40
{
41
    BYTE repeat;
42
    BYTE addr;
43
    BYTE data;
44
    BYTE pgm_class;
45
    WORD pgm_id;
46
    BYTE pgm_data[2];
47
} IR_COMMAND;
48
 
49
#define IR_COUNT 32
50
static BYTE irValids = 0;
51
static BYTE irCounts = 0;
52
static TICK tick_irTimout = 0;
53
static BYTE pgmData[56];
54
 
55
#pragma udata big_mem
56
static IR_COMMAND irCommands[IR_COUNT];
57
#pragma udata
58
 
119 johboh 59
void main()
60
{
363 johboh 61
    static EE_STATE ees = eesWAITING_START;
62
    static EE_STATE eesAckNext = eesWAITING_START;
63
    static BYTE ee_programmerId = 0;
64
    static BOOL ee_externalEE = FALSE;
65
    static DWORD ee_pgmAddress = 0;
66
    static DWORD ee_newPgmAddress = 0;
67
    static PGM_CTRL_TYPE ee_ackType = pctEE_ACK;
68
 
69
    static BYTE ee_lastLocalIndex = 0;
70
    CAN_PACKET outCp;
71
 
119 johboh 72
    // Inits
73
    mainInit();
363 johboh 74
 
75
    #ifdef USE_IREC
76
        loadIrCommands();
77
    #endif
78
 
79
 
260 johboh 80
    canInit();
119 johboh 81
 
122 johboh 82
    #ifdef USE_IREC
83
        irecInit();
84
    #endif
85
 
363 johboh 86
    for(ee_programmerId=0;ee_programmerId<56;ee_programmerId++) pgmData[ee_programmerId]=0xFF;
119 johboh 87
 
88
    while(1)
353 johboh 89
    {  
90
        TICK currentTick = tickGet();
119 johboh 91
 
353 johboh 92
        static TICK tick_led = 0;
363 johboh 93
        static TICK tick_ee = 0;
94
 
353 johboh 95
 
96
 
97
        if ((currentTick-tick_led)>(1*TICK_1S))
119 johboh 98
        {
363 johboh 99
            //LED0_IO=~LED0_IO;
353 johboh 100
            tick_led = currentTick;
119 johboh 101
        }
363 johboh 102
 
103
        if ((currentTick-tick_irTimout)>IR_TIMOUT)
104
        {
105
            irCounts = 0;
106
            tick_irTimout = currentTick;
107
        }
108
 
109
        switch(ees)
110
        {
111
            case eesWAITING_START:
112
 
113
                if (hasCtrlPacket == TRUE && ctrlPacket.pgm.id == pctEE_START && ctrlPacket.data[4] == myId())
114
                {
115
                    ee_programmerId = ctrlPacket.sid;
116
                    ee_externalEE = (ctrlPacket.data[3]==1?TRUE:FALSE);
117
                    ee_pgmAddress = (((DWORD)ctrlPacket.data[2])<<16)+(((DWORD)ctrlPacket.data[1])<<8)+((DWORD)ctrlPacket.data[0]);
118
                    tick_ee = currentTick;
119
                    ee_ackType = pctEE_ACK;
120
                    eesAckNext = eesWAIT_FIRST_DATA;
121
                    ees = eesSEND_ACK;
122
                }
123
                break;
124
 
125
            case eesSEND_ACK:
126
                // send ack
127
                outCp.type = ptPGM;
128
                outCp.pgm.class = pcCTRL;
129
                outCp.pgm.id = ee_ackType;
130
                outCp.length=0;
131
                tick_ee = currentTick;
132
                ees = eesAckNext;
133
                while(!canSendMessage(outCp,PRIO_HIGH));
134
                break;
135
 
136
            case eesWAIT_FIRST_DATA:
137
                // Wait for first pgm packet. use offset to determine data index.
138
                // When receiving crc from host, check crc for offsets bytes.
139
 
140
                if ((currentTick-tick_ee)>EE_PACKET_TIMOUT)
141
                {
142
                    // Timeout, resend ack/nack.
143
                    eesAckNext = eesWAIT_FIRST_DATA;
144
                    ees = eesSEND_ACK;
145
                }              
146
 
147
                if (hasCtrlPacket == TRUE && ctrlPacket.pgm.id==pctEE_PGM)
148
                {
149
                    BYTE localIndex = ctrlPacket.data[7];
150
                    ee_lastLocalIndex = localIndex;
151
                    pgmData[localIndex+0]=ctrlPacket.data[0]; pgmData[localIndex+1]=ctrlPacket.data[1]; pgmData[localIndex+2]=ctrlPacket.data[2]; pgmData[localIndex+3]=ctrlPacket.data[3];
152
                    pgmData[localIndex+4]=ctrlPacket.data[4]; pgmData[localIndex+5]=ctrlPacket.data[5]; pgmData[localIndex+6]=ctrlPacket.data[6];
153
                    ees = eesWAIT_DATA_OR_CRC;
154
                }
155
 
156
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_START)
157
                {
158
                    ees   = eesWAITING_START;
159
                }
160
 
161
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_CRC)
162
                {
163
                    ees   = eesWAIT_DATA_OR_CRC;
164
                }
165
 
166
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_DONE)
167
                {
168
                    ees = eesDONE;
169
                }
170
 
171
 
172
                break;
173
 
174
            case eesWAIT_DATA_OR_CRC:
175
                // Wait for pgm packet. use offset to determine data index.
176
                // When receiving crc from host, check crc for offsets bytes.
177
 
178
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_CRC)
179
                {
180
                    WORD crc16 = (((WORD)ctrlPacket.data[4])<<8)+((WORD)ctrlPacket.data[3]);
181
                    WORD crc16calc = calc_crc(pgmData,56);
182
 
183
                    // check CRC.
184
                    if (crc16calc==crc16)
185
                    {
186
                        ee_newPgmAddress = (((DWORD)ctrlPacket.data[2])<<16)+(((DWORD)ctrlPacket.data[1])<<8)+((DWORD)ctrlPacket.data[0]);
187
                        eesAckNext = eesWAIT_FIRST_DATA;
188
                        ees = eesWRITE_DATA;
189
                    }
190
                    else
191
                    {
192
                        tick_ee = currentTick;
193
                        ee_ackType = pctEE_NACK;
194
                        eesAckNext = eesWAIT_FIRST_DATA;
195
                        ees = eesSEND_ACK;
196
                    }
197
                }
198
 
199
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_PGM)
200
                {
201
                    BYTE localIndex = ctrlPacket.data[7];
202
                    ee_lastLocalIndex = localIndex;
203
                    pgmData[localIndex+0]=ctrlPacket.data[0]; pgmData[localIndex+1]=ctrlPacket.data[1]; pgmData[localIndex+2]=ctrlPacket.data[2]; pgmData[localIndex+3]=ctrlPacket.data[3];
204
                    pgmData[localIndex+4]=ctrlPacket.data[4]; pgmData[localIndex+5]=ctrlPacket.data[5]; pgmData[localIndex+6]=ctrlPacket.data[6];
205
                }
206
 
207
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_START)
208
                {
209
                    ees   = eesWAITING_START;
210
                }
211
 
212
                if (hasCtrlPacket==TRUE && ctrlPacket.pgm.id==pctEE_DONE)
213
                {
214
                    ees = eesDONE;
215
                }
216
 
217
                break;
218
 
219
 
220
            case eesWRITE_DATA:
221
 
222
                ClrWdt();
223
 
224
                // Write EE and send ack.
225
 
226
                if (ee_externalEE == FALSE)
227
                {
228
                    BYTE i;
229
 
230
                    ee_pgmAddress = EE_IR_START+1+(WORD)((EE_INTERNAL_SIZE-1) & ee_pgmAddress);
231
 
232
                    for(i=0;i<56;i++)
233
                    {
234
                        EEWrite(ee_pgmAddress+i,pgmData[i]);
235
 
236
                        pgmData[i]=0xFF;
237
                    }  
238
 
239
 
240
                }
241
 
242
                ee_pgmAddress   = ee_newPgmAddress;
243
                ee_ackType      = pctEE_ACK;       
244
                ees             = eesSEND_ACK;
245
 
246
            break;
247
 
248
            case eesDONE:
249
                EEWrite(EE_IR_START,32);
250
                loadIrCommands();
251
 
252
                ees = eesWAITING_START;
253
            break;
254
 
255
 
256
            default:
257
                ees = eesWAITING_START;
258
            break;
259
 
260
        }
261
 
262
            hasCtrlPacket = FALSE;
263
 
119 johboh 264
    }
265
}
266
 
267
 
268
#pragma interrupt high_isr
269
void high_isr(void)
270
{
260 johboh 271
    canISR();
119 johboh 272
 
122 johboh 273
    #ifdef USE_IREC
274
        irecISR();
275
    #endif
276
 
119 johboh 277
}
278
 
279
 
280
#pragma interrupt low_isr
281
void low_isr(void)
282
{
283
 
284
}
285
 
363 johboh 286
void loadIrCommands()
287
{
119 johboh 288
 
363 johboh 289
    // Load IRs
290
    BYTE i;
291
    irValids = EERead(EE_IR_START);
292
    for(i=0;(i<irValids && i<IR_COUNT);i++)
293
    {
294
        IR_COMMAND * buf_ptr = &irCommands[0];
119 johboh 295
 
363 johboh 296
 
297
        buf_ptr[i].repeat = EERead(EE_IR_START+1+(i<<3));
298
        buf_ptr[i].addr = EERead(EE_IR_START+2+(i<<3));
299
        buf_ptr[i].data = EERead(EE_IR_START+3+(i<<3));
300
        buf_ptr[i].pgm_class = EERead(EE_IR_START+4+(i<<3));
301
        buf_ptr[i].pgm_id = ((WORD)EERead(EE_IR_START+5+(i<<3)) << 8)+(WORD)EERead(EE_IR_START+6+(i<<3));
302
        buf_ptr[i].pgm_data[1] = EERead(EE_IR_START+7+(i<<3));
303
        buf_ptr[i].pgm_data[0] = EERead(EE_IR_START+8+(i<<3));
304
 
305
        /*
306
        buf_ptr[0].repeat = 5;
307
        buf_ptr[0].addr = 5;
308
        buf_ptr[0].data = 5;
309
        buf_ptr[0].pgm_class = 5;
310
        buf_ptr[0].pgm_id = 5;
311
        buf_ptr[0].pgm_data[1] = 5;
312
        buf_ptr[0].pgm_data[0] = 5;
313
 
314
        buf_ptr[1].repeat = 7;
315
        buf_ptr[1].addr = 7;
316
        buf_ptr[1].data = 7;
317
        buf_ptr[1].pgm_class = 7;
318
        buf_ptr[1].pgm_id = 7;
319
        buf_ptr[1].pgm_data[1] = 7;
320
        buf_ptr[1].pgm_data[0] = 7;
321
 
322
        buf_ptr[2].repeat = 9;
323
        buf_ptr[2].addr = 9;
324
        buf_ptr[2].data = 9;
325
        buf_ptr[2].pgm_class = 9;
326
        buf_ptr[2].pgm_id = 9;
327
        buf_ptr[2].pgm_data[1] = 9;
328
        buf_ptr[2].pgm_data[0] = 9;
329
        */
330
    }
331
}
332
 
333
 
119 johboh 334
/*
335
*   Function: mainInit
336
*
337
*   Input:  none
338
*   Output: none
339
*   Pre-conditions: none
340
*   Affects: Se code
341
*   Depends: none.
342
*/
343
void mainInit()
344
{
345
    LED0_TRIS=0;   
346
 
347
    // Enable Interrupts
348
    INTCONbits.GIEH = 1;
349
    INTCONbits.GIEL = 1;
350
 
351
    // Enable interrupt prirority
352
    RCONbits.IPEN=1;
353
 
354
 
355
}
356
 
357
/*
358
*   Function: canParse
359
*
360
*   Input:  Received can message
361
*   Output: none
362
*   Pre-conditions: canInit and received packet.
363
*   Affects: Sensors/actuators/etc. See code.
364
*   Depends: none.
365
*/
260 johboh 366
 
341 johboh 367
void canParse(CAN_PACKET cp)
119 johboh 368
{
363 johboh 369
    BYTE i;
119 johboh 370
 
363 johboh 371
 
372
    if (cp.pgm.class == pcCTRL)
373
    {
374
        hasCtrlPacket = TRUE;
375
        ctrlPacket.sid = cp.sid;
376
        for(i=0;i<8;i++) ctrlPacket.data[i]=cp.data[i];
377
        ctrlPacket.length = cp.length;
378
        ctrlPacket.pgm.id = cp.pgm.id;
379
    }
380
 
260 johboh 381
}
119 johboh 382
 
383
 
384
 
122 johboh 385
/*
386
*   Function: irecParse
387
*
388
*   Input:  Received IR message
389
*   Output: none
390
*   Pre-conditions: irecInit
391
*   Affects: Sensors/actuators/etc. See code.
392
*   Depends: none.
393
*/
394
#ifdef USE_IREC
395
void irecParse(IR_TYPE type, BYTE toggle, BYTE addr, BYTE data)
396
{
363 johboh 397
    static BYTE lastToogle = 0;
398
 
341 johboh 399
    CAN_PACKET outCp;
363 johboh 400
    BYTE i;
401
    IR_COMMAND * buf_ptr = &irCommands[0];
122 johboh 402
 
363 johboh 403
    tick_irTimout = tickGet();
404
 
405
    irCounts++;
406
 
341 johboh 407
    outCp.type      = ptPGM;
408
    outCp.pgm.class = pcSENSOR;
409
    outCp.pgm.id    = pstIR;
410
    outCp.length    = 4;
411
    outCp.data[3]   = type;
412
    outCp.data[2]   = toggle;
413
    outCp.data[1]   = addr;
414
    outCp.data[0]   = data;
415
    while(!canSendMessage(outCp,PRIO_HIGH));
122 johboh 416
 
363 johboh 417
    // DUMP
418
    if (addr==0x15 && data>=0x00)
419
    {
420
        for(i=0;i<7;i++)
421
        {
422
            outCp.type      = ptPGM;
423
            outCp.pgm.class = 0x05;
424
            outCp.pgm.id    = 0x91;
425
            outCp.length    = 8;
426
            outCp.data[7] = buf_ptr[i].repeat;
427
            outCp.data[6]=buf_ptr[i].addr;
428
            outCp.data[5]=buf_ptr[i].data;
429
            outCp.data[4]=buf_ptr[i].pgm_class;
430
            outCp.data[3]=(BYTE)((buf_ptr[i].pgm_id & 0xFF00) >> 8);
431
            outCp.data[2]=(BYTE)buf_ptr[i].pgm_id;
432
            outCp.data[1]=buf_ptr[i].pgm_data[1];
433
            outCp.data[0]=buf_ptr[i].pgm_data[0];
434
            while(!canSendMessage(outCp,PRIO_HIGH));
435
        }      
436
    }
341 johboh 437
 
363 johboh 438
    /*
439
    if (addr==0x15 && data>=0x09)
440
    {
441
        for(i=0;i<7;i++)
442
        {
443
            outCp.type      = ptPGM;
444
            outCp.pgm.class = 0x05;
445
            outCp.pgm.id    = 0x91;
446
            outCp.length    = 8;
447
            outCp.data[7] = pgmData[i*8];
448
            outCp.data[6]=pgmData[i*8+1];
449
            outCp.data[5]=pgmData[i*8+2];
450
            outCp.data[4]=pgmData[i*8+3];
451
            outCp.data[3]=pgmData[i*8+4];
452
            outCp.data[2]=pgmData[i*8+5];
453
            outCp.data[1]=pgmData[i*8+6];
454
            outCp.data[0]=pgmData[i*8+7];
455
            while(!canSendMessage(outCp,PRIO_HIGH));
456
        }
457
    }
458
    */
459
 
460
    // slow? bad?
461
    for(i=0;(i<irValids && i<IR_COUNT);i++)
462
    {
463
        if (buf_ptr[i].addr==addr && buf_ptr[i].data==data && ((buf_ptr[i].repeat == 0 && (lastToogle != toggle || irCounts==1)) || (buf_ptr[i].repeat == irCounts)))
464
        {
465
            outCp.type      = ptPGM;
466
            outCp.pgm.class = buf_ptr[i].pgm_class;
467
            outCp.pgm.id    = buf_ptr[i].pgm_id;
468
            outCp.length    = 2;
469
            outCp.data[1]   = buf_ptr[i].pgm_data[1];
470
            outCp.data[0]   = buf_ptr[i].pgm_data[0];
471
            while(!canSendMessage(outCp,PRIO_HIGH));
472
 
473
            if (buf_ptr[i].repeat>0) irCounts = 0;
474
        }
475
    }
476
 
477
 
478
    lastToogle  = toggle;
479
 
122 johboh 480
}
481
#endif
482
 
119 johboh 483
// Below are mandantory when using bootloader
484
// define DEBUG_MODE to use without bootloader.
485
 
486
#ifndef DEBUG_MODE
487
extern void _startup (void);
341 johboh 488
#pragma code _RESET_INTERRUPT_VECTOR = RM_RESET_VECTOR
119 johboh 489
void _reset (void)
490
{
491
    _asm goto _startup _endasm
492
}
493
#pragma code
494
#endif
495
 
341 johboh 496
#pragma code _HIGH_INTERRUPT_VECTOR = RM_HIGH_INTERRUPT_VECTOR
119 johboh 497
void _high_ISR (void)
498
{
499
    _asm GOTO high_isr _endasm
500
}
501
#pragma code
502
 
341 johboh 503
#pragma code _LOW_INTERRUPT_VECTOR = RM_LOW_INTERRUPT_VECTOR
119 johboh 504
void _low_ISR (void)
505
{
506
    _asm GOTO low_isr _endasm
507
}
508
#pragma code