Subversion Repositories HomeAutomation

Rev

Rev 129 | Rev 260 | 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/canFreezer/Source/Main.c $
  7.  * Last changed:    $LastChangedDate: 2006-11-21 10:57:15 +0100 (Tue, 21 Nov 2006) $
  8.  * By:              $LastChangedBy: johboh $
  9.  * Revision:        $Revision: 141 $
  10.  ********************************************************************/
  11.  
  12.  
  13. #include <compiler.h>
  14. #include <stackTasks.h>
  15. #include <Tick.h>
  16. #include <funcdefs.h>
  17. #include <EEaccess.h>
  18.  
  19. #ifdef USE_CAN
  20.     #include <CAN.h>
  21. #endif
  22.  
  23. #ifdef USE_ADC
  24.     #include <adc.h>
  25. #endif
  26.  
  27. static void mainInit(void);
  28.  
  29.  
  30. static int MY_ID = DEFAULT_ID;
  31. static BYTE MY_NID = DEFAULT_NID;
  32.  
  33. void main()
  34. {
  35.     static TICK t = 0;
  36.     CAN_MESSAGE outCm;
  37.  
  38.     // Inits
  39.  
  40.     mainInit();
  41.  
  42.     #ifdef USE_CAN
  43.         canInit();
  44.     #endif
  45.  
  46.     #ifdef USE_ADC
  47.         adcInit(TRUE,0b1011);
  48.     #endif
  49.  
  50.     tickInit();
  51.  
  52.     // Read ID and NID if exist.
  53.     if (EERead(NODE_ID_EE)==NODE_HAS_ID)
  54.     {
  55.         MY_ID=(((WORD)EERead(NODE_ID_EE + 1))<<8)+EERead(NODE_ID_EE + 2);
  56.         MY_NID=EERead(NODE_ID_EE + 3);
  57.     }
  58.  
  59.     // Send user program startup heatbeat
  60.     outCm.funct                     = FUNCT_BOOTLOADER;
  61.     outCm.funcc                     = FUNCC_BOOT_HEARTBEAT;
  62.     outCm.nid                       = MY_NID;
  63.     outCm.sid                       = MY_ID;
  64.     outCm.data_length               = 1;
  65.     outCm.data[BOOT_DATA_HEARTBEAT_INDEX] = HEARTBEAT_USER_STARTUP;
  66.     while(!canSendMessage(outCm,PRIO_HIGH));
  67.  
  68.  
  69.     while(1)
  70.     {
  71.         static TICK t = 0;
  72.         static TICK heartbeat = 0;
  73.         static TICK temperature = 0;
  74.         static BYTE lastTemperature = TEMPERATURE_FREEZER;
  75.         static BYTE lastFreezerDoor = DOOR_CLOSED;
  76.         static BYTE lastRefrigeratorDoor = DOOR_CLOSED;
  77.  
  78.  
  79.         //Poll doors freezer door
  80.         if (lastFreezerDoor!=DOOR_FREEZER_IO)
  81.         {  
  82.             lastFreezerDoor=DOOR_FREEZER_IO;
  83.             // Send door status change
  84.             outCm.funct                     = FUNCT_SENSORS;
  85.             outCm.funcc                     = FUNCC_SENSORS_DOORS_FREEZER;
  86.             outCm.nid                       = MY_NID;
  87.             outCm.sid                       = MY_ID;
  88.             outCm.data_length               = 1;
  89.             outCm.data[0]                   = (lastFreezerDoor==DOOR_OPEN?0:1);
  90.             while(!canSendMessage(outCm,PRIO_HIGH));
  91.         }
  92.  
  93.         //Poll doors refrigerator door
  94.         if (lastRefrigeratorDoor!=DOOR_REFRIGERATOR_IO)
  95.         {  
  96.             lastRefrigeratorDoor=DOOR_REFRIGERATOR_IO;
  97.             // Send door status change
  98.             outCm.funct                     = FUNCT_SENSORS;
  99.             outCm.funcc                     = FUNCC_SENSORS_DOORS_REFRIGERATOR;
  100.             outCm.nid                       = MY_NID;
  101.             outCm.sid                       = MY_ID;
  102.             outCm.data_length               = 1;
  103.             outCm.data[0]                   = (lastRefrigeratorDoor==DOOR_OPEN?0:1);
  104.             while(!canSendMessage(outCm,PRIO_HIGH));
  105.         }
  106.  
  107.        
  108.         if ((tickGet()-heartbeat)>TICK_SECOND*5)
  109.         {
  110.             // Send alive heartbeat
  111.             outCm.funct                     = FUNCT_BOOTLOADER;
  112.             outCm.funcc                     = FUNCC_BOOT_HEARTBEAT;
  113.             outCm.nid                       = MY_NID;
  114.             outCm.sid                       = MY_ID;
  115.             outCm.data_length               = 1;
  116.             outCm.data[BOOT_DATA_HEARTBEAT_INDEX] = HEARTBEAT_ALIVE;
  117.             while(!canSendMessage(outCm,PRIO_HIGH));
  118.            
  119.             heartbeat = tickGet();
  120.         }
  121.  
  122.         if ((tickGet()-t)>TICK_SECOND)
  123.         {
  124.             LED0_IO=~LED0_IO;
  125.             t = tickGet();
  126.         }
  127.  
  128.         #ifdef USE_ADC
  129.         if ((tickGet()-temperature)>TICK_SECOND*2) // Each 2 second, read temperature.
  130.         {
  131.             if (lastTemperature==TEMPERATURE_FREEZER) lastTemperature=TEMPERATURE_REFRIGERATOR; else lastTemperature=TEMPERATURE_FREEZER;
  132.             adcConvert(lastTemperature);
  133.             temperature = tickGet();
  134.         }
  135.         #endif
  136.  
  137.  
  138.         #ifdef USE_ADC
  139.         if (adcDone()) // Has temperature, send it to the bus
  140.         {
  141.             BYTE decimal;
  142.             signed char tenth;
  143.             temperatureRead(&tenth,&decimal);
  144.  
  145.             outCm.funct                     = FUNCT_SENSORS;
  146.             outCm.funcc                     = (lastTemperature==TEMPERATURE_FREEZER?FUNCC_SENSORS_TEMPERATURE_FREEZER:FUNCC_SENSORS_TEMPERATURE_REFRIGERATOR);
  147.             outCm.nid                       = MY_NID;
  148.             outCm.sid                       = MY_ID;
  149.             outCm.data_length               = 2;
  150.             outCm.data[1]                   = tenth; //  signed 10 an 1 decimal.
  151.             outCm.data[0]                   = decimal; //  Decimal value, 0-9
  152.             while(!canSendMessage(outCm,PRIO_HIGH));
  153.         }
  154.         #endif
  155.  
  156.     }
  157. }
  158.  
  159.  
  160. #pragma interrupt high_isr
  161. void high_isr(void)
  162. {
  163.     ClrWdt();
  164.  
  165.     #ifdef USE_CAN
  166.         canISR();
  167.     #endif
  168.  
  169.     tickUpdate();
  170.  
  171. }
  172.  
  173.  
  174. #pragma interrupt low_isr
  175. void low_isr(void)
  176. {
  177.     #ifdef USE_ADC
  178.         adcISR();
  179.     #endif
  180. }
  181.  
  182.  
  183.  
  184. /*
  185. *   Function: mainInit
  186. *
  187. *   Input:  none
  188. *   Output: none
  189. *   Pre-conditions: none
  190. *   Affects: Se code
  191. *   Depends: none.
  192. */
  193. void mainInit()
  194. {
  195.     LED0_TRIS=0;   
  196.  
  197.     DOOR_FREEZER_TRIS=1;
  198.     DOOR_REFRIGERATOR_TRIS=1;
  199.  
  200.     // Enable Interrupts
  201.     INTCONbits.GIEH = 1;
  202.     INTCONbits.GIEL = 1;
  203.  
  204.     // Enable interrupt prirority
  205.     RCONbits.IPEN=1;
  206.    
  207.  
  208. }
  209.  
  210. /*
  211. *   Function: canParse
  212. *
  213. *   Input:  Received can message
  214. *   Output: none
  215. *   Pre-conditions: canInit and received packet.
  216. *   Affects: Sensors/actuators/etc. See code.
  217. *   Depends: none.
  218. */
  219. #ifdef USE_CAN
  220. void canParse(CAN_MESSAGE cm)
  221. {
  222.     CAN_MESSAGE outCm;
  223.  
  224.     ClrWdt();
  225.  
  226.     switch(cm.funct)
  227.     {
  228.         case FUNCT_BOOTLOADER:
  229.             if (cm.nid==MY_NID && ((((unsigned int)cm.data[BOOT_DATA_RID_HIGH_INDEX])<<8)+cm.data[BOOT_DATA_RID_LOW_INDEX])==MY_ID)
  230.             {
  231.                 switch(cm.funcc)
  232.                 {
  233.                     case FUNCC_BOOT_INIT: Reset(); break; //User whant to program me, reset me.
  234.                     case FUNCC_BOOT_SET_ID:
  235.                         // Change my ID and NID
  236.                         MY_ID=(((WORD)cm.data[BOOT_DATA_NEW_ID_HIGH_INDEX])<<8)+cm.data[BOOT_DATA_NEW_ID_LOW_INDEX];
  237.                         MY_NID=cm.data[BOOT_DATA_NEW_NID_INDEX];
  238.                         EEWrite(NODE_ID_EE+1,cm.data[BOOT_DATA_NEW_ID_HIGH_INDEX]);
  239.                         EEWrite(NODE_ID_EE+2,cm.data[BOOT_DATA_NEW_ID_LOW_INDEX]);
  240.                         EEWrite(NODE_ID_EE+3,cm.data[BOOT_DATA_NEW_NID_INDEX]);
  241.                         EEWrite(NODE_ID_EE,NODE_HAS_ID);
  242.                         // Send ack with new id.
  243.                         outCm.funct                     = FUNCT_BOOTLOADER;
  244.                         outCm.funcc                     = FUNCC_BOOT_ACK;
  245.                         outCm.nid                       = MY_NID;
  246.                         outCm.sid                       = MY_ID;
  247.                         outCm.data_length               = 8;
  248.                         outCm.data[BOOT_DATA_ERR_INDEX] = ACK_ERR_NO_ERROR;
  249.                         while(!canSendMessage(outCm,PRIO_HIGH));
  250.                     break;
  251.                 }
  252.             }
  253.  
  254.  
  255.         break;
  256.     }
  257. }
  258. #endif
  259.  
  260.  
  261.  
  262. // Below are mandantory when using bootloader
  263. // define DEBUG_MODE to use without bootloader.
  264.  
  265. #ifndef DEBUG_MODE
  266. extern void _startup (void);
  267. #pragma code _RESET_INTERRUPT_VECTOR = 0x001000
  268. void _reset (void)
  269. {
  270.     _asm goto _startup _endasm
  271. }
  272. #pragma code
  273. #endif
  274.  
  275. #pragma code _HIGH_INTERRUPT_VECTOR = 0x001008
  276. void _high_ISR (void)
  277. {
  278.     _asm GOTO high_isr _endasm
  279. }
  280. #pragma code
  281.  
  282. #pragma code _LOW_INTERRUPT_VECTOR = 0x001018
  283. void _low_ISR (void)
  284. {
  285.     _asm GOTO low_isr _endasm
  286. }
  287. #pragma code
  288.