Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "sns_ultrasonic.h"
  3. #include <util/delay.h>
  4.  
  5. uint8_t sns_ultrasonic_ReportInterval = (uint8_t)sns_ultrasonic_DEFAULT_REPORTINTERVAL;
  6. uint16_t sns_ultrasonic_BottomLevel = (uint16_t)sns_ultrasonic_DEFAULT_BOTTOMLEVEL;
  7. uint16_t sns_ultrasonic_TopLevel = (uint16_t)sns_ultrasonic_DEFAULT_TOPLEVEL;
  8. uint8_t sns_ultrasonic_Mode = (uint8_t)sns_ultrasonic_DEFAULT_MODE;
  9. uint16_t sns_ultrasonic_Measurement = 0u;
  10. uint8_t sns_ultrasonic_Measurement_flag = 0;
  11. uint8_t sns_ultrasonic_MeasurementState = 0;
  12. uint16_t lastCaptures[4];
  13.  
  14. #if sns_ultrasonic_USEEEPROM==1
  15. #include "sns_ultrasonic_eeprom.h"
  16. struct eeprom_sns_ultrasonic EEMEM eeprom_sns_ultrasonic =
  17. {
  18.     {
  19.         //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.         sns_ultrasonic_DEFAULT_REPORTINTERVAL,      // reportIntervall
  21.         sns_ultrasonic_DEFAULT_BOTTOMLEVEL,
  22.         sns_ultrasonic_DEFAULT_TOPLEVEL,
  23.         sns_ultrasonic_DEFAULT_MODE,
  24.     },
  25.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  26. };
  27. #endif
  28.  
  29. void StartMeasure_callback(uint8_t timer);
  30.  
  31. /*********************************************************************//**
  32. Function: ISR(TIMER1_CAPT_vect )
  33. Purpose:  Executed when pin change on Input capture pin.
  34. Input:    -
  35. Returns:  -
  36. **************************************************************************/
  37. ISR(TIMER1_CAPT_vect) {
  38.     static uint16_t last = 0;
  39.     static uint8_t index = 0;
  40.     if (sns_ultrasonic_MeasurementState == 1) {
  41.         last =  ICR1;
  42.         TCCR1B=0x83u;   //prescaler=64, input noice reduction and trigg on falling edge
  43.         sns_ultrasonic_MeasurementState = 2;
  44.     }  
  45.     else if (sns_ultrasonic_MeasurementState == 2){
  46.         TCCR1B=0xC3u;   //prescaler=64, input noice reduction and trigg on rising edge
  47.         lastCaptures[index] = ICR1 - last;
  48.         sns_ultrasonic_MeasurementState = 0;
  49.         Timer_SetTimeout(sns_ultrasonic_MEASURE_TIMER, 10 , TimerTypeOneShot, &StartMeasure_callback);
  50.         index++;
  51.         if (index >= 4) {
  52.             uint8_t flags_max = 0;
  53.             uint8_t flags_min = 0;
  54.             uint16_t temp;
  55.             index = 0;
  56.             temp = lastCaptures[0];
  57.             flags_max = 0x01;
  58.             if (lastCaptures[1] >= temp) {
  59.               flags_max = 0x02;
  60.               temp = lastCaptures[1];
  61.             }
  62.             if (lastCaptures[2] >= temp) {
  63.               flags_max = 0x04;
  64.               temp = lastCaptures[2];
  65.             }
  66.             if (lastCaptures[3] >= temp) {
  67.               flags_max = 0x08;
  68.             }
  69.            
  70.             temp = lastCaptures[0];
  71.             flags_min = 0x01;
  72.             if (lastCaptures[1] <= temp) {
  73.               flags_min = 0x02;
  74.               temp = lastCaptures[1];
  75.             }
  76.             if (lastCaptures[2] <= temp) {
  77.               flags_min = 0x04;
  78.               temp = lastCaptures[2];
  79.             }
  80.             if (lastCaptures[3] <= temp) {
  81.               flags_min = 0x08;
  82.             }
  83.             if (flags_max == flags_min)
  84.             {
  85.               temp = 2*temp;
  86.             } else {
  87.              
  88.               temp = 0;
  89.               if (((flags_max | flags_min) & 0x01u) == 0) {
  90.                 temp += lastCaptures[0];
  91.               }
  92.               if (((flags_max | flags_min) & 0x02u) == 0) {
  93.                 temp += lastCaptures[1];
  94.               }
  95.               if (((flags_max | flags_min) & 0x04u) == 0) {
  96.                 temp += lastCaptures[2];
  97.               }
  98.               if (((flags_max | flags_min) & 0x08u) == 0) {
  99.                 temp += lastCaptures[3];
  100.               }
  101.             }
  102.             sns_ultrasonic_Measurement = temp >> 1; //devide by 2 to the the average
  103.             sns_ultrasonic_Measurement_flag = 1;
  104.         }
  105.     }
  106. } /* ISR(TIMER1_CAPT_vect) */
  107.  
  108.  
  109. void StartMeasure_callback(uint8_t timer)
  110. {
  111.     gpio_clr_pin(sns_ultrasonic_Trigger_PIN);
  112.     sns_ultrasonic_MeasurementState = 1;
  113.     _delay_us(20);
  114.     gpio_set_pin(sns_ultrasonic_Trigger_PIN);
  115. }
  116.  
  117. void sns_ultrasonic_Init(void)
  118. {
  119. #if sns_ultrasonic_USEEEPROM==1
  120.     if (EEDATA_OK)
  121.     {
  122.         //Use stored data to set initial values for the module
  123.         sns_ultrasonic_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
  124.         sns_ultrasonic_BottomLevel = eeprom_read_word(EEDATA16.BottomLevel);
  125.         sns_ultrasonic_TopLevel = eeprom_read_word(EEDATA16.TopLevel);
  126.         sns_ultrasonic_Mode = eeprom_read_byte(EEDATA.mode);
  127.     } else
  128.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  129.         eeprom_write_byte_crc(EEDATA.reportInterval, sns_ultrasonic_DEFAULT_REPORTINTERVAL, WITHOUT_CRC);
  130.         eeprom_write_word_crc(EEDATA16.BottomLevel, sns_ultrasonic_BottomLevel, WITHOUT_CRC);
  131.         eeprom_write_word_crc(EEDATA16.TopLevel, sns_ultrasonic_TopLevel, WITHOUT_CRC);
  132.         eeprom_write_byte_crc(EEDATA.mode, sns_ultrasonic_Mode, WITHOUT_CRC);
  133.         EEDATA_UPDATE_CRC;
  134.     }
  135. #endif
  136.     gpio_set_pin(sns_ultrasonic_Trigger_PIN);
  137.     gpio_set_out(sns_ultrasonic_Trigger_PIN);
  138.     gpio_set_pin(sns_ultrasonic_Trigger_PIN);
  139.     gpio_set_in(EXP_D); //Set trigg input to input
  140.     Timer_SetTimeout(sns_ultrasonic_REPORT_TIMER, sns_ultrasonic_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  141.     Timer_SetTimeout(sns_ultrasonic_MEASURE_TIMER, 10 , TimerTypeOneShot, &StartMeasure_callback);
  142.     TCCR1B=0xC3u;   //prescaler=64, input noice reduction and trigg on rising edge
  143.     TIMSK1 |= 0x20u; //enable input capture interrupt
  144. }
  145.  
  146. void sns_ultrasonic_Process(void)
  147. {
  148.     static uint16_t lastvalue = 0;
  149.     ///TODO: Stuff that needs doing is done here
  150.     if (Timer_Expired(sns_ultrasonic_REPORT_TIMER)) {
  151.       uint16_t temp;
  152.         switch (sns_ultrasonic_Mode) {
  153.         case CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_LENGTH:
  154.            
  155.             temp = (uint16_t)((float)sns_ultrasonic_Measurement*1.36f);
  156.             //temp = lastCaptures[3];
  157.             StdCan_Msg_t txMsg;
  158.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  159.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  160.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  161.             txMsg.Header.ModuleId = sns_ultrasonic_ID;
  162.             txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_DISTANCE;
  163.             txMsg.Length = 3;
  164.             txMsg.Data[0] = 0;
  165.             txMsg.Data[1] = (temp>>8)&0xff;
  166.             txMsg.Data[2] = (temp)&0xff;
  167.             StdCan_Put(&txMsg);
  168.             break;
  169.         case CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_PERCENT:
  170.             temp = (uint16_t)((float)sns_ultrasonic_Measurement*1.36f);
  171.             if (temp > sns_ultrasonic_BottomLevel && temp < sns_ultrasonic_TopLevel) {
  172.                 temp = temp - sns_ultrasonic_BottomLevel;
  173.                 temp = (uint16_t)(((float)temp/(sns_ultrasonic_TopLevel-sns_ultrasonic_BottomLevel))*10000);
  174.                 StdCan_Msg_t txMsg;
  175.                 StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  176.                 StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  177.                 txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  178.                 txMsg.Header.ModuleId = sns_ultrasonic_ID;
  179.                 txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PERCENT;
  180.                 txMsg.Length = 3;
  181.                 txMsg.Data[0] = 0;
  182.                 txMsg.Data[1] = (temp>>8)&0xff;
  183.                 txMsg.Data[2] = (temp)&0xff;
  184.                 StdCan_Put(&txMsg);
  185.             }
  186.             break;
  187.         }  
  188.     }
  189.     if (sns_ultrasonic_Measurement_flag == 1) {
  190.         sns_ultrasonic_Measurement_flag = 0;
  191.         if (lastvalue > (sns_ultrasonic_Measurement + 5) || lastvalue < (sns_ultrasonic_Measurement - 5)) {
  192.             uint16_t temp;
  193.           lastvalue = sns_ultrasonic_Measurement;
  194.           switch (sns_ultrasonic_Mode) {
  195.         case CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_LENGTH:
  196.            
  197.             temp = (uint16_t)((float)sns_ultrasonic_Measurement*1.36f);
  198.             //temp = lastCaptures[3];
  199.             StdCan_Msg_t txMsg;
  200.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  201.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  202.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  203.             txMsg.Header.ModuleId = sns_ultrasonic_ID;
  204.             txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_DISTANCE;
  205.             txMsg.Length = 3;
  206.             txMsg.Data[0] = 0;
  207.             txMsg.Data[1] = (temp>>8)&0xff;
  208.             txMsg.Data[2] = (temp)&0xff;
  209.             StdCan_Put(&txMsg);
  210.             break;
  211.         case CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_PERCENT:
  212.             temp = (uint16_t)((float)sns_ultrasonic_Measurement*1.36f);
  213.             if (temp > sns_ultrasonic_BottomLevel && temp < sns_ultrasonic_TopLevel) {
  214.                 temp = temp - sns_ultrasonic_BottomLevel;
  215.                 temp = (uint16_t)(((float)temp/(sns_ultrasonic_TopLevel-sns_ultrasonic_BottomLevel))*10000);
  216.                 StdCan_Msg_t txMsg;
  217.                 StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  218.                 StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  219.                 txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  220.                 txMsg.Header.ModuleId = sns_ultrasonic_ID;
  221.                 txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PERCENT;
  222.                 txMsg.Length = 3;
  223.                 txMsg.Data[0] = 0;
  224.                 txMsg.Data[1] = (temp>>8)&0xff;
  225.                 txMsg.Data[2] = (temp)&0xff;
  226.                 StdCan_Put(&txMsg);
  227.             }
  228.             break;
  229.           }
  230.         }
  231.     }
  232. }
  233.  
  234. void sns_ultrasonic_HandleMessage(StdCan_Msg_t *rxMsg)
  235. {
  236.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_SNS &&
  237.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  238.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_SNS_ULTRASONIC &&
  239.         rxMsg->Header.ModuleId == sns_ultrasonic_ID)
  240.     {
  241.         StdCan_Msg_t txMsg;
  242.         switch (rxMsg->Header.Command)
  243.         {
  244.         case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
  245.             if (rxMsg->Length > 0)
  246.             {
  247.                 sns_ultrasonic_ReportInterval = rxMsg->Data[0];
  248.                 #if sns_ultrasonic_USEEEPROM==1
  249.                 eeprom_write_byte_crc(EEDATA.reportInterval, sns_ultrasonic_ReportInterval, WITHOUT_CRC);
  250.                 EEDATA_UPDATE_CRC;
  251.                 #endif
  252.                 Timer_SetTimeout(sns_ultrasonic_REPORT_TIMER, sns_ultrasonic_ReportInterval*1000 , TimerTypeFreeRunning, 0);
  253.             }
  254.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  255.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  256.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  257.             txMsg.Header.ModuleId = sns_ultrasonic_ID;
  258.             txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
  259.             txMsg.Length = 1;
  260.  
  261.             txMsg.Data[0] = sns_ultrasonic_ReportInterval;
  262.  
  263.             StdCan_Put(&txMsg);
  264.             break;
  265.         case CAN_MODULE_CMD_ULTRASONIC_ULTRASONICCONFIG:
  266.             if (rxMsg->Length > 5)
  267.             {
  268.                 sns_ultrasonic_BottomLevel = ((uint16_t)rxMsg->Data[1]<<8) + rxMsg->Data[2];
  269.                 sns_ultrasonic_TopLevel = ((uint16_t)rxMsg->Data[3]<<8) + rxMsg->Data[4];
  270.                 sns_ultrasonic_Mode = rxMsg->Data[5];
  271.                 if (sns_ultrasonic_Mode != CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_LENGTH && sns_ultrasonic_Mode != CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_PERCENT) {
  272.                     sns_ultrasonic_Mode = CAN_MODULE_ENUM_ULTRASONIC_ULTRASONICCONFIG_SENSORMODE_LENGTH;
  273.                 }
  274.                 #if sns_ultrasonic_USEEEPROM==1
  275.                 eeprom_write_word_crc(EEDATA16.BottomLevel, sns_ultrasonic_BottomLevel, WITHOUT_CRC);
  276.                 eeprom_write_word_crc(EEDATA16.TopLevel, sns_ultrasonic_TopLevel, WITHOUT_CRC);
  277.                 eeprom_write_byte_crc(EEDATA.mode, sns_ultrasonic_Mode, WITHOUT_CRC);
  278.                 EEDATA_UPDATE_CRC;
  279.                 #endif
  280.             }
  281.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  282.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  283.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  284.             txMsg.Header.ModuleId = sns_ultrasonic_ID;
  285.             txMsg.Header.Command = CAN_MODULE_CMD_ULTRASONIC_ULTRASONICCONFIG;
  286.             txMsg.Length = 6;
  287.  
  288.             txMsg.Data[0] = 0u;
  289.             txMsg.Data[1] = (uint8_t)((sns_ultrasonic_BottomLevel>>8)&0xff);
  290.             txMsg.Data[2] = (uint8_t)(sns_ultrasonic_BottomLevel&0xff);
  291.             txMsg.Data[3] = (uint8_t)((sns_ultrasonic_TopLevel>>8)&0xff);;
  292.             txMsg.Data[4] = (uint8_t)(sns_ultrasonic_TopLevel&0xff);
  293.             txMsg.Data[5] = sns_ultrasonic_Mode;
  294.             StdCan_Put(&txMsg);
  295.             break;
  296.         }
  297.     }
  298. }
  299.  
  300. void sns_ultrasonic_List(uint8_t ModuleSequenceNumber)
  301. {
  302.     StdCan_Msg_t txMsg;
  303.  
  304.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  305.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  306.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ULTRASONIC;
  307.     txMsg.Header.ModuleId = sns_ultrasonic_ID;
  308.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  309.     txMsg.Length = 6;
  310.  
  311.     uint32_t HwId=BIOS_GetHwId();
  312.     txMsg.Data[0] = HwId&0xff;
  313.     txMsg.Data[1] = (HwId>>8)&0xff;
  314.     txMsg.Data[2] = (HwId>>16)&0xff;
  315.     txMsg.Data[3] = (HwId>>24)&0xff;
  316.  
  317.     txMsg.Data[4] = NUMBER_OF_MODULES;
  318.     txMsg.Data[5] = ModuleSequenceNumber;
  319.  
  320.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  321. }
  322.