Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "sns_counter.h"
  3.  
  4. #ifdef sns_counter_DEBOUNCE_TIME_MS
  5. static uint32_t volatile PreviousTimerValue = 0;
  6. #endif
  7. #ifdef sns_counter_USEEEPROM
  8. static uint8_t volatile StoreInEEPROM = 0;
  9. #endif
  10. static uint8_t sns_counter_ReportInterval = (uint8_t)sns_counter_SEND_PERIOD;
  11. static uint32_t volatile Count0 = 0;
  12.  
  13. #ifdef sns_counter_USEEEPROM
  14. #include "sns_counter_eeprom.h"
  15. struct eeprom_sns_counter EEMEM eeprom_sns_counter =
  16. {
  17.     {
  18.         (uint8_t)sns_counter_SEND_PERIOD,   // reportInterval
  19.         0                   // Count0
  20.     },
  21.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  22. };
  23. #endif
  24.  
  25. uint8_t sns_counter_save_data(void)
  26. {
  27. #ifdef sns_counter_USEEEPROM
  28.     eeprom_write_byte_crc(EEDATA.reportInterval, sns_counter_SEND_PERIOD, WITHOUT_CRC);
  29.     eeprom_write_dword_crc(EEDATA32.Count0, 0, WITHOUT_CRC);
  30.     EEDATA_UPDATE_CRC;
  31.     return 0;
  32. #else
  33.     return 2;
  34. #endif
  35. }
  36.  
  37. void sns_counter_send_counter(void)
  38. {
  39.     StdCan_Msg_t txMsg;
  40.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  41.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  42.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_COUNTER;
  43.     txMsg.Header.ModuleId = sns_counter_ID;
  44.     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_COUNTER;
  45.     txMsg.Length = 5;
  46.     txMsg.Data[0] = 0;  // CH0
  47.     txMsg.Data[4] = (uint8_t)Count0 & 0xff;
  48.     txMsg.Data[3] = (uint8_t)(Count0 >> 8) & 0xff;
  49.     txMsg.Data[2] = (uint8_t)(Count0 >> 16) & 0xff;
  50.     txMsg.Data[1] = (uint8_t)(Count0 >> 24) & 0xff;
  51.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  52. }
  53.  
  54. void sns_counter_pcint_callback(uint8_t id, uint8_t status)
  55. {
  56.     if (status == 0)
  57.     {
  58. #ifdef sns_counter_DEBOUNCE_TIME_MS
  59.         if (Timer_GetTicks() - PreviousTimerValue >= sns_counter_DEBOUNCE_TIME_MS)
  60.         {
  61.             PreviousTimerValue = Timer_GetTicks();
  62. #endif
  63.             Count0++;
  64.             sns_counter_send_counter();
  65. #if defined sns_counter_USEEEPROM && defined sns_counter_CH0_EEPROM_FREQ
  66.             if (Count0 %sns_counter_CH0_EEPROM_FREQ == 0)
  67.                 StoreInEEPROM = 1;
  68. #endif
  69. #ifdef sns_counter_DEBOUNCE_TIME_MS
  70.         }
  71. #endif
  72.     }
  73. }
  74.  
  75. void sns_counter_Init(void)
  76. {
  77. #ifdef sns_counter_USEEEPROM
  78.     if (EEDATA_OK)
  79.     {
  80.         //Use stored data to set initial values for the module
  81.         sns_counter_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
  82.         Count0 = eeprom_read_dword(EEDATA32.Count0);
  83.     } else
  84.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  85.         sns_counter_save_data();
  86.     }
  87. #endif
  88.     //Initialize hardware etc here
  89.     gpio_set_in(sns_counter_CH0);   // Set to input
  90.     gpio_set_pin(sns_counter_CH0);  // Enable pull-up
  91.  
  92.     Pcint_SetCallbackPin(sns_counter_PCINT_CH0, sns_counter_CH0 , &sns_counter_pcint_callback);
  93. #ifdef sns_counter_SEND_TIMER
  94.     Timer_SetTimeout(sns_counter_SEND_TIMER, sns_counter_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  95. #endif
  96. }
  97.  
  98. void sns_counter_Process(void)
  99. {
  100. #ifdef sns_counter_USEEEPROM
  101.     if (StoreInEEPROM == 1)
  102.     {
  103.         StoreInEEPROM = 0;
  104.         eeprom_write_dword_crc(EEDATA32.Count0, (uint32_t)(Count0), WITH_CRC);
  105.     }
  106. #endif
  107. #ifdef sns_counter_SEND_TIMER
  108.     if (Timer_Expired(sns_counter_SEND_TIMER))
  109.         sns_counter_send_counter();
  110. #endif
  111. }
  112.  
  113. void sns_counter_HandleMessage(StdCan_Msg_t *rxMsg)
  114. {
  115.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  116.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  117.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_COUNTER &&
  118.         rxMsg->Header.ModuleId == sns_counter_ID)
  119.     {
  120.         StdCan_Msg_t txMsg;
  121.  
  122.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  123.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  124.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_COUNTER;
  125.         txMsg.Header.ModuleId = sns_counter_ID;
  126.  
  127.         switch (rxMsg->Header.Command)
  128.         {
  129.         case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
  130.             if (rxMsg->Length > 0)
  131.             {
  132.                 sns_counter_ReportInterval = rxMsg->Data[0];
  133.                 Timer_SetTimeout(sns_counter_SEND_TIMER, sns_counter_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  134.             }
  135.             txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
  136.             txMsg.Length = 1;
  137.             txMsg.Data[0] = sns_counter_ReportInterval;
  138.             StdCan_Put(&txMsg);
  139.             break;
  140.         case CAN_MODULE_CMD_COUNTER_SETCOUNTER:
  141.             if (rxMsg->Length == 5 && rxMsg->Data[0] == 0)
  142.             {
  143.                 Count0 = rxMsg->Data[4];
  144.                 Count0 += ((uint32_t)rxMsg->Data[3])<<8;
  145.                 Count0 += ((uint32_t)rxMsg->Data[2])<<16;
  146.                 Count0 += ((uint32_t)rxMsg->Data[1])<<24;
  147.             }
  148.             txMsg.Header.Command = CAN_MODULE_CMD_COUNTER_SETCOUNTER;
  149.             txMsg.Length = 5;
  150.             txMsg.Data[0] = 0;  // CH0
  151.             txMsg.Data[4] = (uint8_t)Count0 & 0xff;
  152.             txMsg.Data[3] = (uint8_t)(Count0 >> 8) & 0xff;
  153.             txMsg.Data[2] = (uint8_t)(Count0 >> 16) & 0xff;
  154.             txMsg.Data[1] = (uint8_t)(Count0 >> 24) & 0xff;
  155.             StdCan_Put(&txMsg);
  156.             break;
  157.         }
  158.     }
  159. }
  160.  
  161. void sns_counter_List(uint8_t ModuleSequenceNumber)
  162. {
  163.     StdCan_Msg_t txMsg;
  164.  
  165.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  166.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  167.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_COUNTER;
  168.     txMsg.Header.ModuleId = sns_counter_ID;
  169.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  170.     txMsg.Length = 6;
  171.  
  172.     uint32_t HwId=BIOS_GetHwId();
  173.     txMsg.Data[0] = HwId&0xff;
  174.     txMsg.Data[1] = (HwId>>8)&0xff;
  175.     txMsg.Data[2] = (HwId>>16)&0xff;
  176.     txMsg.Data[3] = (HwId>>24)&0xff;
  177.  
  178.     txMsg.Data[4] = NUMBER_OF_MODULES;
  179.     txMsg.Data[5] = ModuleSequenceNumber;
  180.  
  181.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  182. }
  183.