Subversion Repositories HomeAutomation

Rev

Go to most recent revision | 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.  
  13.  
  14. #ifdef chn_ChnMaster_USEEEPROM
  15. #include "chn_ChnMaster_eeprom.h"
  16. struct eeprom_chn_ChnMaster EEMEM eeprom_chn_ChnMaster =
  17. {
  18.     {
  19.         ///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.
  20.         0xAB,    // x
  21.         0x1234    // y
  22.     },
  23.     0    // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  24. };
  25. #endif
  26.  
  27. void chn_ChnMaster_RegisterListener( uint16_t channel_id, void (*update_func)(uint16_t, uint16_t) ) {
  28.     chn_ChnMaster_listeners[ chn_ChnMaster_listenCount ].update_func = update_func;
  29.     chn_ChnMaster_listeners[ chn_ChnMaster_listenCount ].channel_id = channel_id;
  30.     chn_ChnMaster_listenCount++;
  31. }
  32.  
  33. void chn_ChnMaster_UpdateChannel( uint16_t channel_id, uint16_t value ) {
  34.     StdCan_Msg_t txMsg;
  35.     txMsg.Id = 0;
  36.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_CHN);
  37.  
  38.     txMsg.Id |= channel_id << 8;
  39.     txMsg.Id |= chn_ChnMaster_ID;
  40.  
  41.     txMsg.Length = 2;
  42.     txMsg.Data[0] = (value     >>8)&0xFF;
  43.     txMsg.Data[1] = (value        )&0xFF;
  44.  
  45.     while( StdCan_Put(&txMsg) != StdCan_Ret_OK );
  46. }
  47.  
  48.  
  49. void chn_ChnMaster_Init(void)
  50. {
  51. #ifdef chn_ChnMaster_USEEEPROM
  52.     if (EEDATA_OK)
  53.     {
  54.       ///TODO: Use stored data to set initial values for the module
  55.       blablaX = eeprom_read_byte(EEDATA.x);
  56.       blablaY = eeprom_read_word(EEDATA.y);
  57.     } else
  58.     {    //The CRC of the EEPROM is not correct, store default values and update CRC
  59.       eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
  60.       eeprom_write_word_crc(EEDATA.y, 0x1234, WITHOUT_CRC);
  61.       EEDATA_UPDATE_CRC;
  62.     }
  63. #endif  
  64.     ///TODO: Initialize hardware etc here
  65.  
  66.     // to use PCINt lib, call this function: (the callback function look as a timer callback function)
  67.     // Pcint_SetCallbackPin(chn_ChnMaster_PCINT, EXP_C , &chn_ChnMaster_pcint_callback);
  68.  
  69. }
  70.  
  71. void chn_ChnMaster_Process(void)
  72. {
  73.     ///TODO: Stuff that needs doing is done here
  74. }
  75.  
  76. void chn_ChnMaster_HandleMessage(StdCan_Msg_t *rxMsg)
  77. {
  78.     uint8_t i,j;
  79.     uint16_t channel_id;
  80.     uint16_t value;
  81.     if ( StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_CHN)
  82.     {
  83.         if( (rxMsg->Id & (1L<<24)) == 0 ) { /* Value */
  84.             channel_id = (rxMsg->Id >> 8) & 0xFFFF;
  85.  
  86.             for( j=0; j<(rxMsg->Length&~1); j+=2 ) {
  87.                 value      = (rxMsg->Data[j]<<8) | rxMsg->Data[j+1];
  88.                 for( i=0; i<chn_ChnMaster_listenCount; i++ ) {
  89.                     if( chn_ChnMaster_listeners[i].channel_id == channel_id ) {
  90.                         (*chn_ChnMaster_listeners[i].update_func)( channel_id, value );
  91.                     }
  92.                 }
  93.                 channel_id++;
  94.             }
  95.         } else { /* Metadata */
  96.         }
  97.     }
  98. }
  99.  
  100. void chn_ChnMaster_List(uint8_t ModuleSequenceNumber)
  101. {
  102.     StdCan_Msg_t txMsg;
  103.    
  104.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_CHN);
  105.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  106.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_CHN_CHNMASTER;
  107.     txMsg.Header.ModuleId = chn_ChnMaster_ID;
  108.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  109.     txMsg.Length = 6;
  110.  
  111.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  112.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  113.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  114.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  115.    
  116.     txMsg.Data[4] = NUMBER_OF_MODULES;
  117.     txMsg.Data[5] = ModuleSequenceNumber;
  118.    
  119.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  120. }
  121.