Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CAN Relay.
  3.  *
  4.  *
  5.  * @date    2006-12-17
  6.  * @author  Erik Larsson
  7.  *
  8.  *   ADC=Vin*1024/Vref
  9.  *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
  10.  *
  11.  *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
  12.  *
  13.  *
  14.  */
  15.  
  16. #define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
  17.  
  18. /*-----------------------------------------------------------------------------
  19.  * Includes
  20.  *---------------------------------------------------------------------------*/
  21. /* system files */
  22. #include <avr/io.h>
  23. #include <avr/interrupt.h>
  24. #include <stdio.h>
  25. /* lib files */
  26. #include <bios.h>
  27. #include <config.h>
  28. #include <drivers/timer/timebase.h>
  29. #include <tc1047.h>
  30. #include <funcdefs.h>
  31.  
  32. /* defines */
  33. #define GROUP_ID        0x01UL
  34.  
  35. #define RELAY_OFF           0x01
  36. #define RELAY_ON            0x02
  37. #define FAILSAFE_MODE       0x0F
  38. #define FAILSAFE_TRESHOLD   0xFF  /* Degrees when nodeRelay goes into failsafe mode */
  39.  
  40. #define RELAY_CMD_ON        0x01
  41. #define RELAY_CMD_OFF       0x02
  42. #define RELAY_CMD_TOGGLE    0x03
  43. #define RELAY_CMD_STATUS    0x04
  44. #define RELAY_CMD_RESET     0x05
  45. #define STATUS_SEND_PERIOD  10000UL /* milliseconds */
  46. #define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
  47. #define BOUNCE_TIME         10 /* milliseconds */
  48. #define BUTTON1             1
  49. #define BUTTON2             2
  50.  
  51. /*-------------------------------------------------------------------------
  52.  * Global variables
  53.  * -----------------------------------------------------------------------*/
  54. uint8_t relayStatus, failsafe_flag = 0, rxMsg_Data_bytes[8], msg_received = 0;
  55. uint32_t boardTemperature = 0;
  56.  
  57.  
  58. /*----------------------------------------------------------------------------
  59.  * Functions
  60.  * -------------------------------------------------------------------------*/
  61. uint8_t relayOff();
  62. uint8_t relayOn();
  63. void relayFailsafe();
  64. void sendStatus();
  65.  
  66. void can_receive(Can_Message_t *msg)
  67. { // CAN callback function
  68.     uint32_t act;
  69.     uint8_t m, act_type, group, node;
  70.  
  71.     if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
  72.         // Actuator package
  73.         act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
  74.         act_type =(uint8_t)((act & ACT_TYPE_MASK) >> ACT_TYPE_BITS);
  75.         group = (uint8_t)((act & ACT_GROUP_MASK) >> ACT_GROUP_BITS);
  76.         node = (uint8_t)((act & ACT_NODE_MASK) >> ACT_NODE_BITS);
  77.  
  78.         if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
  79.             // This is a message for this node
  80.  
  81.             if(rxMsg_Data_bytes[0] == RELAY_CMD_RESET){
  82.                 // Return to normal operation
  83.                 failsafe_flag = 0;
  84.             }
  85.  
  86.             for(m=0;m<(msg->DataLength);m++){
  87.                 rxMsg_Data_bytes[m] = msg->Data.bytes[m];
  88.             }
  89.             msg_received = 1; // Tell application that message has arrived
  90.         }
  91.     }
  92. }
  93.  
  94. /*----------------------------------------------------------------------------
  95.  * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
  96.  * -------------------------------------------------------------------------*/
  97. #if TWO_BUTTON_MODE
  98. ISR( PCINT2_vect )
  99. {
  100.  
  101. }
  102. #endif
  103.  
  104. /*-----------------------------------------------------------------------------
  105.  * Main Program
  106.  *---------------------------------------------------------------------------*/
  107. int main(void) {
  108.  
  109.     uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
  110.  
  111.     Can_Message_t txMsg;
  112.     txMsg.RemoteFlag = 0;
  113.     txMsg.ExtendedFlag = 1;
  114.     txMsg.DataLength = 4;
  115.  
  116.     adcTemperatureInit();
  117.  
  118.     // Set up callback for CAN messages
  119.     BIOS_CanCallback = &can_receive;
  120.  
  121.     sei();
  122.    
  123.     Timebase_Init();
  124.  
  125.     // Turn relay off
  126.     relayStatus = relayOff();
  127. //  txMsg.Id = 0x8000110; // FIXME
  128. //  bios->can_send(&txMsg);
  129.  
  130.     // Main loop
  131.     while (1) {
  132.  
  133.         if(msg_received && !failsafe_flag ){
  134.  
  135.             if( rxMsg_Data_bytes[0] == RELAY_CMD_ON ){
  136.                 // Turn relay on
  137.                 relayStatus = relayOn();
  138.  
  139.             }else if(rxMsg_Data_bytes[0] == RELAY_CMD_OFF ){
  140.                 // Turn relay off
  141.                 relayStatus = relayOff();
  142.  
  143.             }else if(rxMsg_Data_bytes[0] == RELAY_CMD_TOGGLE ){
  144.                     // Toggle relay
  145.                     if(relayStatus == RELAY_OFF){
  146.                         relayStatus = relayOn();
  147.                     }else{
  148.                         relayStatus = relayOff();
  149.                     }
  150.  
  151.             }else if(rxMsg_Data_bytes[0] == RELAY_CMD_STATUS ){
  152.                 // Send relay status to CAN
  153.                 sendStatus();
  154.             }
  155.             msg_received = 0;
  156.         }
  157.  
  158.         temp = Timebase_CurrentTime();
  159.         if( temp - timeStamp >= STATUS_SEND_PERIOD ){
  160.             timeStamp = temp;
  161. /*          txMsg.Id = 0x8000111;
  162.             txMsg.Data.bytes[0] = timeStamp & 0x000000FF;
  163.             txMsg.Data.bytes[0] = (timeStamp & 0x0000FF00)>>8;
  164.             txMsg.Data.bytes[0] = (timeStamp & 0x00FF0000)>>16;
  165.             txMsg.Data.bytes[0] = (timeStamp & 0xFF000000)>>24;
  166.             bios->can_send(&txMsg);
  167. */          // Send relay status to CAN
  168.             sendStatus();
  169.         }
  170.     }
  171.     return 0;
  172. }
  173.  
  174. uint8_t relayOff()
  175. {
  176.     // Turn off relay
  177.     PORTC &= ~(1<<PC1);
  178.     DDRC |= (1<<DDC1);
  179.  
  180.     return RELAY_OFF;
  181. }
  182.  
  183. uint8_t relayOn()
  184. {
  185.     // Turn on relay
  186.     DDRC &= ~(1<<DDC1);
  187.     PORTC |= (1<<PC1);
  188.  
  189.     return RELAY_ON;
  190. }
  191.  
  192. void relayFailsafe()
  193. {
  194.     uint32_t failsafe_timeStamp, temp;
  195.     relayStatus = relayOff();
  196.     failsafe_flag = 1;
  197.  
  198.     while(1){
  199.  
  200.         if( !failsafe_flag ){
  201.             // Return from failsafe mode
  202.             return;
  203.         }
  204. // TODO skicka med period
  205.         sendStatus( );
  206.     }
  207. }
  208.  
  209. void sendStatus()
  210. {
  211.     uint32_t temperature;
  212.     Can_Message_t statusMsg;
  213.     statusMsg.RemoteFlag = 0;
  214.     statusMsg.ExtendedFlag = 1;
  215.     statusMsg.DataLength = 4;
  216.     statusMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
  217.  
  218.     temperature = getTC1047temperature();
  219.     if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
  220.         // Goto failsafe mode
  221.         relayFailsafe();
  222.     }else{
  223.         // Transmitt node status
  224.         statusMsg.Data.bytes[0] = temperature & 0x00FF;
  225.         statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
  226.         statusMsg.Data.bytes[2] = relayStatus;
  227.         statusMsg.Data.bytes[3] = failsafe_flag;
  228.  
  229.         BIOS_CanSend( &statusMsg );
  230.     }
  231. }
  232.