Subversion Repositories HomeAutomation

Rev

Rev 597 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. #include <inttypes.h>
  2. #include <bios.h>
  3. #include <config.h>
  4. #include "channel.h"
  5.  
  6. Channel_Info_t channel_defs[ CHANNEL_COUNT ];
  7.  
  8. uint8_t Channel_Init( void ) {
  9.     Can_Message_t txMsg;
  10.  
  11.     uint8_t i;
  12.  
  13.     /* Reset channel_defs */
  14.     for(i=0;i<CHANNEL_COUNT;i++) {
  15.         channel_defs[i].channel = 0;
  16.         channel_defs[i].value = 0;
  17.     }
  18.  
  19.     /* CHANNEL_SUBCLASS_IDENTIFY */
  20.  
  21.     txMsg.Id    = (CAN_CHN                      << CAN_SHIFT_CLASS)
  22.                 | (CHANNEL_SUBCLASS_IDENTIFY    << CHANNEL_SHIFT_SUBCLASS)
  23.                 | (NODE_ID                      << CHANNEL_SHIFT_NODEID);
  24.     txMsg.ExtendedFlag = 1;
  25.     txMsg.RemoteFlag = 0;
  26.  
  27.     txMsg.DataLength = 1;
  28.     txMsg.Data.bytes[0] = CHANNEL_COUNT;
  29.  
  30.     BIOS_CanSend( &txMsg );
  31.  
  32.  
  33.  
  34.     return CHANNEL_OK;
  35. }
  36.  
  37. uint8_t Channel_HandleMsg(Can_Message_t *msg) {
  38.     uint8_t class;
  39.     uint8_t subclass;
  40.     uint8_t node_id;
  41.  
  42.     uint16_t channel;
  43.     uint16_t channel_mask;
  44.  
  45.     uint8_t i,j;
  46.  
  47.     if( msg->ExtendedFlag!=1) {
  48.         /* Channels only availible in Extended mode */
  49.         return CHANNEL_FAIL;
  50.     }
  51.     class = ( msg->Id & CAN_MASK_CLASS ) >> CAN_SHIFT_CLASS;
  52.     if( class != CAN_CHN ) {
  53.         /* Is not a channel-message */
  54.         return CHANNEL_FAIL;
  55.     }
  56.  
  57.     subclass    = ( msg->Id & CHANNEL_MASK_SUBCLASS ) >> CHANNEL_SHIFT_SUBCLASS;
  58.     channel     = ( msg->Id & CHANNEL_MASK_CHANNEL  ) >> CHANNEL_SHIFT_CHANNEL;
  59.     node_id     = ( msg->Id & CHANNEL_MASK_NODEID   ) >> CHANNEL_SHIFT_NODEID;
  60.  
  61.     switch( subclass ) {
  62.         case CHANNEL_SUBCLASS_DATA:
  63.             channel_mask = 0x0FFF & ~((msg->DataLength>>1)-1);
  64.             for( i=0; i<CHANNEL_COUNT; i++ ) {
  65.                 if( ( (channel_defs[i].channel) & channel_mask ) == channel ) {
  66.                     channel_defs[i].value = msg->Data.words[ channel_defs[i].channel - channel ];
  67.                     Channel_Callback_Value( i, channel_defs[i].value );
  68.                 }
  69.             }
  70.             return CHANNEL_OK;
  71.  
  72.  
  73.  
  74. /* Node-to-macro
  75.         case CHANNEL_SUBCLASS_IDENTIFY:
  76.             break;
  77. */
  78.  
  79.         case CHANNEL_SUBCLASS_CHN_BIND:
  80.             if( NODE_ID == node_id && msg->Data.bytes[0] < CHANNEL_COUNT ) {
  81.                 channel_defs[ msg->Data.bytes[0] ].channel = channel;
  82.                 return CHANNEL_OK;
  83.             }
  84.             return CHANNEL_FAIL;
  85.  
  86.  
  87.  
  88. #if CHANNEL_ENABLE_NAME
  89.         case CHANNEL_SUBCLASS_CHN_NAME:
  90.             for( i=0; i<CHANNEL_COUNT; i++ ) {
  91.                 if( channel_defs[i].channel == channel ) {
  92.                     for( j=0; j<msg->DataLength; j++) {
  93.                         channel_defs[i].name[j]=msg->Data.bytes[j];
  94.                     }
  95.                     channel_defs[i].name[j]='\0';
  96.                 }
  97.             }
  98.             return CHANNEL_OK;
  99. #endif
  100.  
  101. #if CHANNEL_ENABLE_TYPE
  102.         case CHANNEL_SUBCLASS_CHN_TYPE:
  103.             for( i=0; i<CHANNEL_COUNT; i++ ) {
  104.                 if( channel_defs[i].channel == channel ) {
  105.                     channel_defs[i].type_k = msg->Data.words[0];
  106.                     channel_defs[i].type_m = msg->Data.words[1];
  107. #if CHANNEL_ENABLE_TYPE_NAME
  108.                     for( j=0; j<msg->DataLength-4; j++) {
  109.                         channel_defs[i].type[j]=msg->Data.bytes[j+4];
  110.                     }
  111.                     channel_defs[i].type[j]='\0';
  112. #endif
  113.                 }
  114.             }
  115.             break;
  116. #endif
  117.     }
  118.  
  119.     return CHANNEL_FAIL;
  120. }
  121.  
  122. void Channel_Bind( uint8_t id, uint8_t channel ) {
  123.     channel_defs[id].channel = channel;
  124. }
  125.  
  126. uint16_t Channel_GetValue( uint8_t id ) {
  127.     return channel_defs[id].value;
  128. }
  129.  
  130. uint8_t Channel_SetValue( uint8_t id, uint16_t value ) {
  131.     uint16_t channel;
  132.     Can_Message_t txMsg;
  133.  
  134.     channel = channel_defs[id].channel;
  135.     if( channel == 0 ) return CHANNEL_FAIL;
  136.  
  137.     txMsg.Id    = (CAN_CHN                  << CAN_SHIFT_CLASS)
  138.                 | (CHANNEL_SUBCLASS_DATA    << CHANNEL_SHIFT_SUBCLASS)
  139.                 | (channel                  << CHANNEL_SHIFT_CHANNEL)
  140.                 | (NODE_ID                  << CHANNEL_SHIFT_NODEID);
  141.  
  142.     txMsg.ExtendedFlag = 1;
  143.     txMsg.RemoteFlag = 0;
  144.     txMsg.DataLength = 2;
  145.     txMsg.Data.words[0] = value;
  146.  
  147.     BIOS_CanSend( &txMsg );
  148.  
  149.     channel_defs[id].value = value;
  150.  
  151. #if CHANNEL_SET_SELF
  152.     Channel_Callback_Value( id, value );
  153. #endif
  154.  
  155.     return CHANNEL_OK;
  156. }
  157.  
  158. Channel_Info_t *Channel_GetStorage( uint8_t id ) {
  159.     return &channel_defs[id];
  160. }
  161.