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