Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "chn_ChnMaster.h"
  3.  
  4. struct chn_ChnMaster_listener_t {
  5.     uint16_t channel_id;
  6.     void (*update_func)(uint16_t, uint16_t); /* channel, value */
  7. };
  8.  
  9. struct chn_ChnMaster_listener_t chn_ChnMaster_listeners[ chn_ChnMaster_MAX_LISTENERS ];
  10. uint8_t chn_ChnMaster_listenCount = 0;
  11.  
  12. struct chn_ChnMaster_buffer_t {
  13.     uint16_t channel_id;
  14.     uint16_t value;
  15. } chn_ChnMaster_buffer[ chn_ChnMaster_BUFFER_SIZE ];
  16.  
  17. volatile uint8_t chn_ChnMaster_buf_in_pos = 0; // next to write
  18. volatile uint8_t chn_ChnMaster_buf_out_pos = 0; // next to read
  19.  
  20. #if chn_ChnMaster_USEEEPROM==1
  21. #include "chn_ChnMaster_eeprom.h"
  22. struct eeprom_chn_ChnMaster EEMEM eeprom_chn_ChnMaster =
  23. {
  24.     {
  25.         ///TODO: Define initialization values on the EEPROM variables here, this will generate a *.eep file that can be used to store this values to the node, can in future be done with a EEPROM module and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file.
  26.         0xAB,    // x
  27.         0x1234    // y
  28.     },
  29.     0    // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  30. };
  31. #endif
  32.  
  33. void chn_ChnMaster_RegisterListener( uint16_t channel_id, void (*update_func)(uint16_t, uint16_t) ) {
  34.     chn_ChnMaster_listeners[ chn_ChnMaster_listenCount ].update_func = update_func;
  35.     chn_ChnMaster_listeners[ chn_ChnMaster_listenCount ].channel_id = channel_id;
  36.     chn_ChnMaster_listenCount++;
  37. }
  38.  
  39. void chn_ChnMaster_UpdateChannel( uint16_t channel_id, uint16_t value ) {
  40.     StdCan_Msg_t txMsg;
  41.     txMsg.Id = 0;
  42.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_CHN);
  43.  
  44.     txMsg.Id |= ((uint32_t)channel_id) << 8;
  45.     txMsg.Id |= chn_ChnMaster_ID;
  46.  
  47.     txMsg.Length = 2;
  48.     txMsg.Data[0] = (value     >>8)&0xFF;
  49.     txMsg.Data[1] = (value        )&0xFF;
  50.  
  51.     while( StdCan_Put(&txMsg) != StdCan_Ret_OK );
  52. }
  53.  
  54.  
  55. void chn_ChnMaster_Init(void) {
  56. }
  57.  
  58. void chn_ChnMaster_Process(void)
  59. {
  60.     uint16_t value;
  61.     uint16_t channel_id;
  62.     uint8_t i;
  63.     while( chn_ChnMaster_buf_out_pos != chn_ChnMaster_buf_in_pos ) {
  64.         value      = chn_ChnMaster_buffer[chn_ChnMaster_buf_out_pos].value;
  65.         channel_id = chn_ChnMaster_buffer[chn_ChnMaster_buf_out_pos].channel_id;
  66.  
  67.         for( i=0; i<chn_ChnMaster_listenCount; i++ ) {
  68.             if( chn_ChnMaster_listeners[i].channel_id == channel_id ) {
  69.                 (*chn_ChnMaster_listeners[i].update_func)( channel_id, value );
  70.             }
  71.         }
  72.  
  73.         chn_ChnMaster_buf_out_pos = (chn_ChnMaster_buf_out_pos+1)%chn_ChnMaster_BUFFER_SIZE;
  74.     }
  75.     ///TODO: Stuff that needs doing is done here
  76. }
  77.  
  78. void chn_ChnMaster_HandleMessage(StdCan_Msg_t *rxMsg)
  79. {
  80.     uint8_t j;
  81.     uint16_t channel_id;
  82.     uint16_t value;
  83.     if ( StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_CHN)
  84.     {
  85.         channel_id = (rxMsg->Id >> 8) & 0xFFFF;
  86.         if( (rxMsg->Id & (1L<<24)) == 0 ) { /* Value */
  87.             for( j=0; j<(rxMsg->Length&~1); j+=2 ) {
  88.                 value      = (rxMsg->Data[j]<<8) | rxMsg->Data[j+1];
  89. /*
  90.                 for( i=0; i<chn_ChnMaster_listenCount; i++ ) {
  91.                     if( chn_ChnMaster_listeners[i].channel_id == channel_id ) {
  92.                         (*chn_ChnMaster_listeners[i].update_func)( channel_id, value );
  93.                     }
  94.                 }
  95.                 */
  96.                 chn_ChnMaster_buffer[chn_ChnMaster_buf_in_pos].channel_id = channel_id;
  97.                 chn_ChnMaster_buffer[chn_ChnMaster_buf_in_pos].value = value;
  98.                 chn_ChnMaster_buf_in_pos = (chn_ChnMaster_buf_in_pos+1)%chn_ChnMaster_BUFFER_SIZE;
  99.                 channel_id++;
  100.             }
  101.         } else { /* Metadata */
  102.         }
  103.     }
  104. }
  105.  
  106. void chn_ChnMaster_List(uint8_t ModuleSequenceNumber)
  107. {
  108.     StdCan_Msg_t txMsg;
  109.    
  110.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_CHN);
  111.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  112.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_CHN_CHNMASTER;
  113.     txMsg.Header.ModuleId = chn_ChnMaster_ID;
  114.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  115.     txMsg.Length = 6;
  116.  
  117.     uint32_t HwId=BIOS_GetHwId();
  118.     txMsg.Data[0] = HwId&0xff;
  119.     txMsg.Data[1] = (HwId>>8)&0xff;
  120.     txMsg.Data[2] = (HwId>>16)&0xff;
  121.     txMsg.Data[3] = (HwId>>24)&0xff;
  122.    
  123.     txMsg.Data[4] = NUMBER_OF_MODULES;
  124.     txMsg.Data[5] = ModuleSequenceNumber;
  125.    
  126.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  127. }
  128.