Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "sns_water.h"
  3.  
  4. static uint8_t volatile sns_water_status = LOW;
  5. static uint8_t sns_water_ReportInterval = (uint8_t)sns_water_SEND_PERIOD_S;
  6. static uint32_t volatile sns_water_TickCnt=0;
  7. static uint32_t volatile sns_water_TimePrevTick;
  8. static uint32_t volatile sns_water_Buffer[4]= {0x0000ffff,0x0000ffff,0x0000ffff,0x0000ffff};
  9. static uint8_t volatile sns_water_BufPointer=0;
  10. static uint32_t volatile sns_water_StoreCnt=0;
  11.  
  12. StdCan_Msg_t txMsg;
  13.  
  14. #if sns_water_USEEEPROM==1
  15. #include "sns_water_eeprom.h"
  16. struct eeprom_sns_water EEMEM eeprom_sns_water =
  17. {
  18.     {
  19.           (uint8_t)sns_water_SEND_PERIOD_S, // reportInterval
  20.           0,    // VolumeCounterUpper
  21.           0     // VolumeCounterLower
  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 sns_water_Init(void)
  28. {
  29. #if sns_water_USEEEPROM==1
  30.     if (EEDATA_OK)
  31.     {  // Use stored data to set initial values for the module
  32. printf("ok\n");
  33.       sns_water_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
  34.       sns_water_TickCnt = eeprom_read_word(EEDATA16.VolumeCounterLower);
  35.       sns_water_TickCnt += (((uint32_t)(eeprom_read_word(EEDATA16.VolumeCounterUpper)))<<16);
  36.     } else
  37.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  38. printf("nok;");
  39.       eeprom_write_byte_crc(EEDATA.reportInterval, sns_water_SEND_PERIOD_S, WITHOUT_CRC);
  40.       eeprom_write_word_crc(EEDATA16.VolumeCounterUpper, 0, WITHOUT_CRC);
  41.       eeprom_write_word_crc(EEDATA16.VolumeCounterLower, 0, WITHOUT_CRC);
  42.       EEDATA_UPDATE_CRC;
  43.     }
  44. #endif
  45.  
  46.     ADC_Init();
  47.     sns_water_TimePrevTick = Timer_GetTicks();
  48.     Timer_SetTimeout(sns_water_ADPOLL_TIMER, sns_water_ADPOLL_PERIOD_MS, TimerTypeFreeRunning, 0);
  49.     Timer_SetTimeout(sns_water_SEND_TIMER, sns_water_SEND_PERIOD_S*1000, TimerTypeFreeRunning, 0);
  50.  
  51.     uint16_t ADvalue = ADC_Get(sns_water_AD_CHANNEL);
  52.     if (ADvalue > (sns_water_HIGH_THRESHOLD_MV*1024UL/5000UL))
  53.     {
  54.         sns_water_status = HIGH;
  55.     }
  56.  
  57.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  58.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  59.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_WATER;
  60.     txMsg.Header.ModuleId = sns_water_ID;
  61.     txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_FLOW;
  62.     txMsg.Length = 6;
  63. }
  64.  
  65. void sns_water_Process(void)
  66. {
  67.     /*
  68.     Notes
  69.     maybe its better to skip the poll timer and always poll when in process
  70.     */
  71.     uint8_t oldstatus = sns_water_status;
  72.     if (Timer_Expired(sns_water_ADPOLL_TIMER))
  73.     {
  74.         uint16_t ADvalue = ADC_Get(sns_water_AD_CHANNEL);
  75.         if (sns_water_status == LOW && ADvalue > (sns_water_HIGH_THRESHOLD_MV*1024UL/5000UL))
  76.         {
  77.             sns_water_status = HIGH;
  78.         }
  79.         else if (sns_water_status == HIGH && ADvalue < (sns_water_LOW_THRESHOLD_MV*1024UL/5000UL))
  80.         {
  81.             sns_water_status = LOW;
  82.         }
  83.     }
  84.  
  85.     /* If status changed == one tick */
  86.     if (oldstatus != sns_water_status)
  87.     {
  88.         sns_water_TickCnt += 1;
  89.  
  90.         sns_water_Buffer[sns_water_BufPointer] = Timer_GetTicks() - sns_water_TimePrevTick;
  91.         if (sns_water_BufPointer++ == 4)
  92.         {
  93.             sns_water_BufPointer = 0;
  94.         }
  95.  
  96.         sns_water_TimePrevTick = Timer_GetTicks();
  97.  
  98. #if sns_water_USEEEPROM==1
  99.         if ((sns_water_TickCnt % 2048) == 0)
  100.         {
  101.             eeprom_write_word_crc(EEDATA16.VolumeCounterUpper, (uint16_t)((sns_water_TickCnt>>16) & 0xffff), WITHOUT_CRC);
  102.             eeprom_write_word_crc(EEDATA16.VolumeCounterLower, (uint16_t)(sns_water_TickCnt & 0xffff), WITH_CRC);
  103.         }
  104. #endif
  105.     }
  106.  
  107.     if (Timer_Expired(sns_water_SEND_TIMER))
  108.     {
  109.         uint32_t flow4 = 0;
  110.         for (uint8_t i = 0; i<4;i++) {
  111.              flow4 += sns_water_Buffer[i];
  112.         }
  113.         flow4 = flow4/4;
  114.         /* The flow is ml per tick / time between ticks */
  115.         flow4 = sns_water_UL_PER_TICK/flow4;
  116.  
  117.         txMsg.Data[0] = (uint8_t)((flow4>>8) & 0xff);
  118.         txMsg.Data[1] = (uint8_t)(flow4 & 0xff);
  119.         txMsg.Data[5] = (uint8_t)(sns_water_TickCnt*sns_water_UL_PER_TICK/1000) & 0xff;
  120.         txMsg.Data[4] = (uint8_t)((sns_water_TickCnt*sns_water_UL_PER_TICK/1000) >> 8) & 0xff;
  121.         txMsg.Data[3] = (uint8_t)((sns_water_TickCnt*sns_water_UL_PER_TICK/1000) >> 16) & 0xff;
  122.         txMsg.Data[2] = (uint8_t)((sns_water_TickCnt*sns_water_UL_PER_TICK/1000) >> 24) & 0xff;
  123. #if CAN_PRINTF==1
  124. //      txMsg.Data[5] = (uint8_t)sns_water_TickCnt & 0xff;
  125. //      txMsg.Data[4] = (uint8_t)(sns_water_TickCnt >> 8) & 0xff;
  126. //      txMsg.Data[3] = (uint8_t)(sns_water_TickCnt >> 16) & 0xff;
  127. //      txMsg.Data[2] = (uint8_t)(sns_water_TickCnt >> 24) & 0xff;
  128. #endif
  129.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  130.  
  131.         /* TODO How to handle no flow? (means no ticks, no new time-diffs) */
  132.         /* This solution starts to fill buffer with older values if ticks come in slower than we send out data */
  133.         if (Timer_GetTicks() - sns_water_TimePrevTick > sns_water_SEND_PERIOD_S*1000)
  134.         {
  135.             sns_water_Buffer[sns_water_BufPointer] = Timer_GetTicks() - sns_water_TimePrevTick;
  136.             if (sns_water_BufPointer++ == 4)
  137.             {
  138.                 sns_water_BufPointer = 0;
  139.             }
  140.         }
  141.     }
  142. }
  143.  
  144. void sns_water_HandleMessage(StdCan_Msg_t *rxMsg)
  145. {
  146. #if 0
  147.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  148.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  149.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_WATER &&
  150.         rxMsg->Header.ModuleId == sns_water_ID)
  151.     {
  152.         switch (rxMsg->Header.Command)
  153.         {
  154.         case CAN_CMD_MODULE_DUMMY:
  155.        
  156.         break;
  157.         }
  158.     }
  159. #endif
  160. }
  161.  
  162. void sns_water_List(uint8_t ModuleSequenceNumber)
  163. {
  164.     StdCan_Msg_t txMsg;
  165.  
  166.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  167.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  168.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_WATER;
  169.     txMsg.Header.ModuleId = sns_water_ID;
  170.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  171.     txMsg.Length = 6;
  172.  
  173.     uint32_t HwId=BIOS_GetHwId();
  174.     txMsg.Data[0] = HwId&0xff;
  175.     txMsg.Data[1] = (HwId>>8)&0xff;
  176.     txMsg.Data[2] = (HwId>>16)&0xff;
  177.     txMsg.Data[3] = (HwId>>24)&0xff;
  178.  
  179.     txMsg.Data[4] = NUMBER_OF_MODULES;
  180.     txMsg.Data[5] = ModuleSequenceNumber;
  181.  
  182.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  183. }
  184.