Subversion Repositories HomeAutomation

Rev

Rev 563 | Rev 577 | 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.  
  17. /*-----------------------------------------------------------------------------
  18.  * Includes
  19.  *---------------------------------------------------------------------------*/
  20. /* system files */
  21. #include <avr/io.h>
  22. #include <avr/interrupt.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. /* lib files */
  26. #include "../config.inc"
  27. #include <config.h>
  28. #include <bios.h>
  29. #include <drivers/timer/timebase.h>
  30. #include <drivers/sensor/tc1047/tc1047.h>
  31.  
  32.  
  33. /* defines */
  34. #define RELAY_OFF           0x01
  35. #define RELAY_ON            0x02
  36. #define FAILSAFE_MODE       0x0F
  37. #define FAILSAFE_TRESHOLD   0xFF  /* Degrees when nodeRelay goes into failsafe mode */
  38.  
  39. #define RELAY_CMD_ON        0x01
  40. #define RELAY_CMD_OFF       0x02
  41. #define RELAY_CMD_TOGGLE    0x03
  42. #define RELAY_CMD_STATUS    0x04
  43. #define RELAY_CMD_RESET     0x05
  44. #define STATUS_SEND_PERIOD  10000UL /* milliseconds */
  45. #define FAILSAFE_SEND_PERIOD    10000UL /* milliseconds */
  46. #define BOUNCE_TIME         10 /* milliseconds */
  47. #define BUTTON1             1
  48. #define BUTTON2             2
  49.  
  50. #define APP_TYPE    CAN_APPTYPES_RELAY
  51. #define APP_VERSION 0x0001
  52.  
  53. /*-------------------------------------------------------------------------
  54.  * Global variables
  55.  * -----------------------------------------------------------------------*/
  56. uint8_t relayStatus, failsafe_flag = 0;
  57. uint32_t boardTemperature = 0;
  58.  
  59. volatile Can_Message_t rxMsg; // Message storage
  60. volatile uint8_t rxMsgFull;   // Synchronization flag
  61.  
  62.  
  63. /*----------------------------------------------------------------------------
  64.  * Functions
  65.  * -------------------------------------------------------------------------*/
  66. uint8_t relayOff(void);
  67. uint8_t relayOn(void);
  68. void relayFailsafe(void);
  69. void sendStatus(void);
  70.  
  71. void can_receive(Can_Message_t *msg)
  72. { // CAN callback function
  73.     if (!rxMsgFull) {
  74.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  75.         rxMsgFull = 1;
  76.     }
  77. }
  78.  
  79. /*----------------------------------------------------------------------------
  80.  * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
  81.  * -------------------------------------------------------------------------*/
  82. #if TWO_BUTTON_MODE
  83. ISR( PCINT2_vect )
  84. {
  85.  
  86. }
  87. #endif
  88.  
  89. /*-----------------------------------------------------------------------------
  90.  * Main Program
  91.  *---------------------------------------------------------------------------*/
  92. int main(void) {
  93.  
  94.     uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
  95.  
  96.     adcTemperatureInit();
  97.  
  98.     // Set up callback for CAN messages
  99.     BIOS_CanCallback = &can_receive;
  100.  
  101.     sei();
  102.    
  103.     Timebase_Init();
  104.  
  105.     Can_Message_t txMsg;
  106.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  107.     txMsg.DataLength = 4;
  108.     txMsg.RemoteFlag = 0;
  109.     txMsg.ExtendedFlag = 1;
  110.     txMsg.Data.words[0] = APP_TYPE;
  111.     txMsg.Data.words[1] = APP_VERSION;
  112.     BIOS_CanSend(&txMsg);
  113.  
  114.     // Turn relay off
  115.     relayStatus = relayOff();
  116.  
  117.     // Main loop
  118.     while (1) {
  119.  
  120.         temp = Timebase_CurrentTime();
  121.         if( temp - timeStamp >= STATUS_SEND_PERIOD ){
  122.             timeStamp = temp;
  123.             // Send relay status to CAN
  124.             sendStatus();
  125.         }
  126.  
  127.         if (rxMsgFull) {
  128.             uint16_t acttype;
  129.             uint8_t relayid;
  130.        
  131.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
  132.                 // Actuator package
  133.                 acttype =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
  134.                 relayid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
  135.                
  136.                 if ((acttype == ACT_TYPE_RELAY) && (relayid == THISRELAYID)) {
  137.                     // This is a message for this relay
  138.                     if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
  139.                         // Return to normal operation
  140.                         failsafe_flag = 0;
  141.                     }
  142.                    
  143.                     if (!failsafe_flag) {
  144.                         if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
  145.                             // Turn relay on
  146.                             relayStatus = relayOn();
  147.            
  148.                         } else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
  149.                             // Turn relay off
  150.                             relayStatus = relayOff();
  151.            
  152.                         } else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
  153.                                 // Toggle relay
  154.                                 if(relayStatus == RELAY_OFF){
  155.                                     relayStatus = relayOn();
  156.                                 }else{
  157.                                     relayStatus = relayOff();
  158.                                 }
  159.            
  160.                         }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
  161.                             // Send relay status to CAN
  162.                             sendStatus();
  163.                         }
  164.                     }
  165.                 }
  166.             }
  167.             rxMsgFull = 0; //  
  168.  
  169.         }
  170.        
  171.     }
  172.     return 0;
  173. }
  174.  
  175. uint8_t relayOff()
  176. {
  177.     // Turn off relay
  178.     PORTC &= ~(1<<PC1);
  179.     DDRC |= (1<<DDC1);
  180.  
  181.     return RELAY_OFF;
  182. }
  183.  
  184. uint8_t relayOn()
  185. {
  186.     // Turn on relay
  187.     DDRC &= ~(1<<DDC1);
  188.     PORTC |= (1<<PC1);
  189.  
  190.     return RELAY_ON;
  191. }
  192.  
  193. void relayFailsafe()
  194. {
  195.     uint32_t failsafe_timeStamp, temp;
  196.     relayStatus = relayOff();
  197.     failsafe_flag = 1;
  198.  
  199.     while(1){
  200.  
  201.         if( !failsafe_flag ){
  202.             // Return from failsafe mode
  203.             return;
  204.         }
  205. // TODO skicka med period
  206.         sendStatus( );
  207.     }
  208. }
  209.  
  210. void sendStatus()
  211. {
  212.     uint32_t temperature;
  213.     Can_Message_t statusMsg;
  214.     statusMsg.RemoteFlag = 0;
  215.     statusMsg.ExtendedFlag = 1;
  216.     statusMsg.DataLength = 4;
  217.     statusMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_STATUS << CAN_SHIFT_SNS_TYPE) | (SNS_ID_RELAY_STATUS << CAN_SHIFT_SNS_ID) | (NODE_ID << CAN_SHIFT_SNS_SID));
  218.    
  219.     temperature = getTC1047temperature();
  220.     if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
  221.         // Goto failsafe mode
  222.         relayFailsafe();
  223.     }else{
  224.         // Transmitt node status
  225.         statusMsg.Data.bytes[0] = temperature & 0x00FF;
  226.         statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
  227.         statusMsg.Data.bytes[2] = relayStatus;
  228.         statusMsg.Data.bytes[3] = failsafe_flag;
  229.  
  230.         BIOS_CanSend( &statusMsg );
  231.     }
  232. }
  233.