Subversion Repositories HomeAutomation

Rev

Rev 363 | Blame | 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-14 13:39:20 +0100 (Wed, 14 Mar 2007) $
  8.  * By:              $LastChangedBy: johboh $
  9.  * Revision:        $Revision: 365 $
  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. #define EE_ACK_MAX 7
  36.  
  37.  
  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.  
  61. void main()
  62. {
  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;
  70.     static BYTE ee_ackCount = 0;
  71.    
  72.     CAN_PACKET outCp;
  73.  
  74.     // Inits
  75.     mainInit();
  76.  
  77.     #ifdef USE_IREC
  78.         loadIrCommands();
  79.     #endif
  80.  
  81.  
  82.     canInit();
  83.  
  84.     #ifdef USE_IREC
  85.         irecInit();
  86.     #endif
  87.  
  88.     for(ee_programmerId=0;ee_programmerId<56;ee_programmerId++) pgmData[ee_programmerId]=0xFF;
  89.  
  90.     while(1)
  91.     {  
  92.         TICK currentTick = tickGet();
  93.  
  94.         static TICK tick_led = 0;
  95.         static TICK tick_ee = 0;
  96.  
  97.  
  98.         if ((currentTick-tick_led)>(1*TICK_1S))
  99.         {
  100.             //LED0_IO=~LED0_IO;
  101.             tick_led = currentTick;
  102.         }
  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;
  123.                     ee_ackCount = 0;
  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));
  136.  
  137.                 if (++ee_ackCount>EE_ACK_MAX) ees = eesWAITING_START;
  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.                 {
  171.                     irValids = (BYTE)((((WORD)ctrlPacket.data[1]<<8) + ctrlPacket.data[0]) >> 3);
  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;
  200.                         ee_ackCount = 0;
  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.                 {
  218.                     irValids = (BYTE)((((WORD)ctrlPacket.data[1]<<8) + ctrlPacket.data[0]) >> 3);
  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;
  249.                 ee_ackCount     = 0;
  250.  
  251.             break;
  252.  
  253.             case eesDONE:
  254.                 EEWrite(EE_IR_START,irValids);
  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.  
  269.     }
  270. }
  271.  
  272.  
  273. #pragma interrupt high_isr
  274. void high_isr(void)
  275. {
  276.     canISR();
  277.  
  278.     #ifdef USE_IREC
  279.         irecISR();
  280.     #endif
  281.  
  282. }
  283.  
  284.  
  285. #pragma interrupt low_isr
  286. void low_isr(void)
  287. {
  288.  
  289. }
  290.  
  291. void loadIrCommands()
  292. {
  293.  
  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];
  300.  
  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.  
  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. */
  345.  
  346. void canParse(CAN_PACKET cp)
  347. {
  348.     BYTE i;
  349.  
  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.  
  360. }
  361.  
  362.  
  363.  
  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. {
  376.     static BYTE lastToogle = 0;
  377.    
  378.     CAN_PACKET outCp;
  379.     BYTE i;
  380.     IR_COMMAND * buf_ptr = &irCommands[0];
  381.  
  382.     tick_irTimout = tickGet();
  383.  
  384.     irCounts++;
  385.  
  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));
  395.  
  396.     /*
  397.     // DUMP
  398.     if (addr==0x15 && data==0x00)
  399.     {
  400.         for(i=0;i<irValids;i++)
  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.     }
  417. */
  418.    
  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.  
  438. }
  439. #endif
  440.  
  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);
  446. #pragma code _RESET_INTERRUPT_VECTOR = RM_RESET_VECTOR
  447. void _reset (void)
  448. {
  449.     _asm goto _startup _endasm
  450. }
  451. #pragma code
  452. #endif
  453.  
  454. #pragma code _HIGH_INTERRUPT_VECTOR = RM_HIGH_INTERRUPT_VECTOR
  455. void _high_ISR (void)
  456. {
  457.     _asm GOTO high_isr _endasm
  458. }
  459. #pragma code
  460.  
  461. #pragma code _LOW_INTERRUPT_VECTOR = RM_LOW_INTERRUPT_VECTOR
  462. void _low_ISR (void)
  463. {
  464.     _asm GOTO low_isr _endasm
  465. }
  466. #pragma code
  467.