Subversion Repositories HomeAutomation

Rev

Rev 353 | Rev 365 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*********************************************************************
  2.  *
  3.  *                  Main application
  4.  *
  5.  *********************************************************************
  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 $
  10.  ********************************************************************/
  11.  
  12.  
  13. #include <p18cxxx.h>
  14. #include <compiler.h>
  15. #include <stackTasks.h>
  16. #include <Tick.h>
  17. #include <funcdefs.h>
  18. #include <CAN.h>
  19. #include <EEAccess.h>
  20. #include <crc16.h>
  21. #include "..\canBoot\Include\boot.h"
  22.  
  23.  
  24. typedef enum _EE_STATE {eesWAITING_START,eesSEND_ACK,eesWAIT_FIRST_DATA,eesWAIT_DATA_OR_CRC,eesWRITE_DATA,eesDONE} EE_STATE;
  25.  
  26. #ifdef USE_IREC
  27.     #include <IRec.h>
  28. #endif
  29.  
  30. static void mainInit(void);
  31. static void loadIrCommands(void);
  32.  
  33. #define EE_PACKET_TIMOUT 5*TICK_100MS
  34. #define IR_TIMOUT 2*TICK_100MS
  35.  
  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.  
  59. void main()
  60. {
  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.  
  72.     // Inits
  73.     mainInit();
  74.  
  75.     #ifdef USE_IREC
  76.         loadIrCommands();
  77.     #endif
  78.  
  79.  
  80.     canInit();
  81.  
  82.     #ifdef USE_IREC
  83.         irecInit();
  84.     #endif
  85.  
  86.     for(ee_programmerId=0;ee_programmerId<56;ee_programmerId++) pgmData[ee_programmerId]=0xFF;
  87.  
  88.     while(1)
  89.     {  
  90.         TICK currentTick = tickGet();
  91.  
  92.         static TICK tick_led = 0;
  93.         static TICK tick_ee = 0;
  94.        
  95.  
  96.  
  97.         if ((currentTick-tick_led)>(1*TICK_1S))
  98.         {
  99.             //LED0_IO=~LED0_IO;
  100.             tick_led = currentTick;
  101.         }
  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.  
  264.     }
  265. }
  266.  
  267.  
  268. #pragma interrupt high_isr
  269. void high_isr(void)
  270. {
  271.     canISR();
  272.  
  273.     #ifdef USE_IREC
  274.         irecISR();
  275.     #endif
  276.  
  277. }
  278.  
  279.  
  280. #pragma interrupt low_isr
  281. void low_isr(void)
  282. {
  283.  
  284. }
  285.  
  286. void loadIrCommands()
  287. {
  288.  
  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];
  295.  
  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.  
  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. */
  366.  
  367. void canParse(CAN_PACKET cp)
  368. {
  369.     BYTE i;
  370.  
  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.  
  381. }
  382.  
  383.  
  384.  
  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. {
  397.     static BYTE lastToogle = 0;
  398.    
  399.     CAN_PACKET outCp;
  400.     BYTE i;
  401.     IR_COMMAND * buf_ptr = &irCommands[0];
  402.  
  403.     tick_irTimout = tickGet();
  404.  
  405.     irCounts++;
  406.  
  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));
  416.  
  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.     }
  437.  
  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.  
  480. }
  481. #endif
  482.  
  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);
  488. #pragma code _RESET_INTERRUPT_VECTOR = RM_RESET_VECTOR
  489. void _reset (void)
  490. {
  491.     _asm goto _startup _endasm
  492. }
  493. #pragma code
  494. #endif
  495.  
  496. #pragma code _HIGH_INTERRUPT_VECTOR = RM_HIGH_INTERRUPT_VECTOR
  497. void _high_ISR (void)
  498. {
  499.     _asm GOTO high_isr _endasm
  500. }
  501. #pragma code
  502.  
  503. #pragma code _LOW_INTERRUPT_VECTOR = RM_LOW_INTERRUPT_VECTOR
  504. void _low_ISR (void)
  505. {
  506.     _asm GOTO low_isr _endasm
  507. }
  508. #pragma code
  509.