Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_dimmer230.h"
  3. #include "act_dimmer230_eeprom.h"
  4.  
  5. #ifdef CHN_LOADED
  6. #include "../chn_ChnMaster/chn_ChnMaster.h"
  7. #endif
  8.  
  9. #ifdef CHN_LOADED
  10. void act_dimmer230_chn_update( uint16_t channel_id, uint16_t value );
  11. #endif
  12.  
  13. int8_t fadeSpeed = 0;
  14. uint8_t fadeSpeedFrac = 0;
  15. uint8_t fadeTarget = 0;
  16. uint8_t fadeSpeedCnt = 0;
  17.  
  18. uint8_t demoEndValue = 0;
  19. uint8_t demoHighValue = 0;
  20. uint8_t demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  21.  
  22. /*  This bool is set to make process routine send the NetInfo packet */
  23. uint8_t sendNetInfo = 0;
  24.  
  25. /*  netConnected stores the connection status, if connected to the net or not */
  26. uint8_t netConnected = CAN_MODULE_ENUM_DIMMER230_NETINFO_CONNECTION_DISCONNECTED;
  27.  
  28. /*  frequency stores the evaluated frequency, 50 or 60 Hz
  29.     don't calculate net frequency since the internal oscillator is not to be trusted, instead check if 50Hz or 60Hz system
  30.     should be used for switching powerStepTable depending on frequency */
  31. uint8_t frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_ERROR_UNKNOWN;
  32. /*  zero cross sync (time between pos flank of xc-detection and real zero cross) */
  33. uint16_t xcTimeDiff=0;
  34.  
  35. /*  dimmerValue is the current output
  36.     value of 0 is zero output, value of 255 is max output (ACT_DIMMMER230_MIN_DIM, ACT_DIMMMER230_MAX_DIM)
  37.     stored in eeprom, and restored at startup */
  38. uint8_t dimmerValue = ACT_DIMMMER230_MIN_DIM;
  39.  
  40. uint8_t state = ACT_DIMMMER230_STATE_IDLE;
  41.  
  42. /*  powerStepTable is used for stepping the output for constant increase/decrease in power, this should be a quater of a sin^2-wave (since the second quater can be calculated) */
  43. const uint16_t powerStepTable[] PROGMEM = {845, 1068, 1225, 1352, 1459, 1553, 1638, 1716, 1788, 1855, 1917, 1976, 2032, 2086, 2138, 2188, 2236, 2282, 2327, 2370, 2412, 2453, 2493, 2532, 2570, 2607, 2643, 2679, 2714, 2748, 2782, 2815, 2848, 2880, 2911, 2942, 2972, 3002, 3032, 3061, 3090, 3119, 3147, 3175, 3203, 3230, 3257, 3284, 3311, 3337, 3363, 3389, 3415, 3440, 3465, 3490, 3515, 3539, 3563, 3587, 3611, 3635, 3659, 3682, 3705, 3728, 3751, 3774, 3797, 3820, 3843, 3865, 3887, 3909, 3931, 3953, 3975, 3997, 4019, 4041, 4062, 4083, 4104, 4125, 4146, 4167, 4188, 4209, 4230, 4251, 4272, 4292, 4313, 4333, 4354, 4374, 4395, 4415, 4435, 4455, 4476, 4496, 4516, 4536, 4556, 4576, 4596, 4615, 4635, 4655, 4675, 4694, 4714, 4734, 4754, 4773, 4793, 4813, 4832, 4852, 4872, 4891, 4911, 4931, 4951, 4970, 4990};
  44.  
  45. #if act_dimmer230_SYNC>0
  46. uint8_t zeroCrossCnt = 0;
  47. #endif
  48.  
  49.  
  50. /*  Set the variable to "disconnected" if no zerocross have arrived for a while */
  51. void Net_Connection_callback(uint8_t timer)
  52. {
  53.     netConnected = CAN_MODULE_ENUM_DIMMER230_NETINFO_CONNECTION_DISCONNECTED;
  54. }
  55.  
  56. /*  This function will send the dimmer-status-packet containing connection status and frequency */
  57. void Send_Status_callback(uint8_t timer)
  58. {
  59.     sendNetInfo = 1;
  60. }
  61.  
  62. /*  When the timer reaches its compare value the triac should be trigged */
  63. ISR (TIMER1_COMPA_vect)
  64. {
  65.     gpio_set_pin(act_dimmer230_CHAN1_IO);
  66.     uint8_t dummycnt = 40;
  67.     while (dummycnt > 0)
  68.     {
  69.         dummycnt++;
  70.         asm("nop");
  71.         asm("nop");
  72.     }
  73.     gpio_clr_pin(act_dimmer230_CHAN1_IO);
  74.    
  75.     TIMSK1=0;                           //disable timer interrupt
  76.     state = ACT_DIMMMER230_STATE_IDLE;
  77. }
  78.  
  79. #ifdef CHN_LOADED
  80. void act_dimmer230_chn_update( uint16_t channel_id, uint16_t value ) {
  81.     fadeTarget = dimmerValue = value>>8;
  82. }
  83. #endif
  84.  
  85. /*  Interrupted at a pin change on zero-cross pin
  86.     The zero-cross pin will go high just before the real zero-cross and
  87.     low just after the real zero-cross. The time difference is measured
  88.     and adjusted for. */
  89. void act_dimmer230_pcint_callback(uint8_t id, uint8_t status) //ISR (act_dimmer230_ZC_PCINT_vect)
  90. {
  91.     /* only execute if zerocross pin is low (after real zerocross).
  92.     Calculate the diff from real zero-cross.
  93.     */
  94.     if (!status)
  95.     {
  96.         xcTimeDiff = TCNT1;
  97.         xcTimeDiff = xcTimeDiff >> 1; //divide by two
  98.         if (xcTimeDiff > 600) {
  99.             xcTimeDiff = 600;
  100.         }
  101.     }  
  102.     /* only execute if zerocross pin is high (before real zerocross) */
  103.     else
  104.     {
  105.         /* Reset the timer for checking net connection. If no zero-cross has come in 500ms then consider us disconnected */
  106.         Timer_SetTimeout(act_dimmer230_NET_CONNECT_TIMEOUT, 500, TimerTypeOneShot, &Net_Connection_callback);
  107.         /* Currently we are connected */
  108.         netConnected = CAN_MODULE_ENUM_DIMMER230_NETINFO_CONNECTION_CONNECTED;
  109.        
  110.         /* Check frequency by measure the time since last zero-cross */
  111.         uint16_t periodTime = TCNT1;
  112.         if (periodTime > ACT_DIMMMER230_50HZ_PERIOD_TIME-ACT_DIMMMER230_50HZ_PERIOD_TIME/10 && periodTime < ACT_DIMMMER230_50HZ_PERIOD_TIME+ACT_DIMMMER230_50HZ_PERIOD_TIME/10)
  113.         {
  114.             frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_50HZ;
  115.         }
  116.         else if (periodTime > ACT_DIMMMER230_60HZ_PERIOD_TIME-ACT_DIMMMER230_60HZ_PERIOD_TIME/10 && periodTime < ACT_DIMMMER230_60HZ_PERIOD_TIME+ACT_DIMMMER230_60HZ_PERIOD_TIME/10)
  117.         {
  118.             frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_60HZ;
  119.         }
  120.         else
  121.         {
  122.             frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_ERROR_UNKNOWN;
  123.         }
  124.        
  125.         /* Check demo states */
  126.         if (dimmerValue == fadeTarget) {
  127.             switch (demoState)
  128.             {
  129.             case ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING:
  130.             break;
  131.             case ACT_DIMMMER230_DEMO_STATE_DECREASE:
  132.                 demoState = ACT_DIMMMER230_DEMO_STATE_INCREASE;
  133.                 fadeTarget = demoHighValue;
  134.                 fadeSpeed = -fadeSpeed;
  135.             break;
  136.             case ACT_DIMMMER230_DEMO_STATE_INCREASE:
  137.                 demoState = ACT_DIMMMER230_DEMO_STATE_GOBACK;
  138.                 fadeTarget = demoEndValue;
  139.                 fadeSpeed = -fadeSpeed;
  140.             break;
  141.             case ACT_DIMMMER230_DEMO_STATE_GOBACK:
  142.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  143.             break;
  144.             }
  145.         }
  146.        
  147.         /* Calculate new time to triac triggering */
  148.         uint16_t newTimerVal = xcTimeDiff;      /* add the zerocross timediff */
  149.  
  150.         if (dimmerValue > 0 && dimmerValue <= 127)
  151.         {
  152.             newTimerVal += ACT_DIMMMER230_50HZ_PERIOD_TIME - pgm_read_word(&powerStepTable[dimmerValue-1]);
  153.         }
  154.         else if (dimmerValue < 255)
  155.         {
  156.             newTimerVal += pgm_read_word(&powerStepTable[254-dimmerValue]);
  157.         }
  158.         else if (dimmerValue == 255)
  159.         {
  160.             newTimerVal += 100; /* almost max, to make sure we don't fire before zerocross */
  161.             gpio_set_pin(act_dimmer230_CHAN1_IO);
  162.         }
  163.        
  164.         if (newTimerVal > ACT_DIMMMER230_50HZ_PERIOD_TIME)
  165.         {
  166.             newTimerVal -= ACT_DIMMMER230_50HZ_PERIOD_TIME;
  167.         }
  168.  
  169.         TCNT1 = 0;              /* reset timer1 count register */
  170.         if (dimmerValue > 0 && dimmerValue != 255 )     /* dont trigger the triac if dimmerValue is 0 */
  171.         {
  172.             OCR1A = newTimerVal;
  173.  
  174.             /* enable timer and timer interrupt */
  175.             TIFR1=(1<<OCF1A);       /* clear interrupt flag before enabling interrupt */
  176.             TIMSK1|=(1<<OCIE1A);
  177.  
  178.             state = ACT_DIMMMER230_STATE_TIMER_ON;
  179.         }
  180.        
  181.         /* Change the dimmerValue according to the current fading */
  182.         fadeSpeedCnt++;
  183.         if (fadeSpeedCnt == fadeSpeedFrac && dimmerValue != fadeTarget)
  184.         {
  185.             fadeSpeedCnt = 0;
  186.             uint8_t tempDimVal = dimmerValue;
  187.             dimmerValue += fadeSpeed;
  188.             if ((fadeSpeed > 0 && (dimmerValue < tempDimVal || dimmerValue >= fadeTarget)) ||
  189.                 (fadeSpeed < 0 && (dimmerValue > tempDimVal || dimmerValue <= fadeTarget)))
  190.             {
  191.                 dimmerValue = fadeTarget;
  192.             }
  193.            
  194.             /* if targetvalue was reached then send the netinfo packet */
  195.             if (dimmerValue == fadeTarget)
  196.             {
  197.                 sendNetInfo = 1;
  198.             }
  199.             /* 5 seconds after we have stopped fading we should store the current dimmerValue to eeprom */
  200.             Timer_SetTimeout(act_dimmer230_STORE_VALUE_TIMEOUT, 5000, TimerTypeOneShot, 0);
  201.         }
  202.        
  203. #if act_dimmer230_SYNC>0
  204.         /* Currently disabled, must add this packet to data.xml */
  205.         zeroCrossCnt++;
  206.         if (zeroCrossCnt >= act_dimmer230_SYNC)
  207.         {
  208.             zeroCrossCnt = 0;
  209.             //TODO: send sync-message on can
  210. #if 0
  211.             StdCan_Msg_t txMsg;
  212.             txMsg.Length = 6;
  213.             txMsg.Data[0] = (newTimerVal>>8)&0xff;
  214.             txMsg.Data[1] = newTimerVal&0xff;
  215.             txMsg.Data[2] = frequency;  //(periodTime>>8)&0xff;
  216.             //txMsg.Data[3] = periodTime&0xff;
  217.             txMsg.Data[4] = (xcTimeDiff>>8)&0xff;
  218.             txMsg.Data[5] = xcTimeDiff&0xff;
  219.             StdCan_Put(&txMsg);
  220. #endif
  221.         }
  222. #endif     
  223.     }
  224. }
  225.  
  226. #if act_dimmer230_USEEEPROM==1
  227. struct eeprom_act_dimmer230 EEMEM eeprom_act_dimmer230 =
  228. {
  229.     {
  230.         /* Define initialization values on the EEPROM variables here,
  231.         this will generate a *.eep file that can be used to store this values to the node,
  232.         can in future be done with a EEPROM module and the make-scrips.
  233.         Write the values in the exact same order as the struct is defined in the *.h file. */
  234.         0x00    /* eeDimmerValue */
  235.     },
  236.     0   /* crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts */
  237. };
  238. #endif
  239.  
  240. /*  Init function of dimmer-module, will init hardware such as timer and gpio and load
  241.     saved eeprom value */
  242. void act_dimmer230_Init(void)
  243. {
  244. #if act_dimmer230_USEEEPROM==1
  245.     if (EEDATA_OK)
  246.     {
  247.       /* Use stored data to set initial values for the module */
  248.       dimmerValue = eeprom_read_byte(EEDATA.eeDimmerValue);
  249.     } else
  250.     {   /* The CRC of the EEPROM is not correct, store default values and update CRC */
  251.       eeprom_write_byte_crc(EEDATA.eeDimmerValue, 0x00, WITHOUT_CRC);
  252.       EEDATA_UPDATE_CRC;
  253.     }
  254. #endif
  255.  
  256.     /* set dimmer port to output 0 */
  257.     gpio_clr_pin(act_dimmer230_CHAN1_IO);
  258.     gpio_set_out(act_dimmer230_CHAN1_IO);
  259.     /* set zero cross detection port to input, no pullup */
  260.     gpio_set_in(act_dimmer230_ZC_IO);
  261.     gpio_clr_pullup(act_dimmer230_ZC_IO);
  262.    
  263.     TIMSK1=0;                           /* disable timer interrupt */
  264.     TCCR1A=0;
  265.    
  266.     TCCR1B=(1<<CS11);                   /* enable timer, set to prescaler 8, must be changed if cpu freq is changed */
  267.  
  268. #ifdef CHN_LOADED
  269.     chn_ChnMaster_RegisterListener( act_dimmer230_CHN_CHANNEL, act_dimmer230_chn_update );
  270. #endif
  271.  
  272.     /* setup interrupt on zerocross, pcint */
  273.     //act_dimmer230_ZC_PCMSK=(1<<(act_dimmer230_ZC_PCINT_BIT));
  274.     //PCIFR=(1<<act_dimmer230_ZC_PCIF); /* clear any pending interrupt before enabling interrupts */
  275.     //PCICR=(1<<act_dimmer230_ZC_PCIE); /* enable interrupt for PCINT */
  276.     Pcint_SetCallbackPin(act_dimmer230_PCINT, act_dimmer230_ZC_IO, &act_dimmer230_pcint_callback);
  277.    
  278.     /* Setup timeout for sending the net status packet */
  279.     Timer_SetTimeout(act_dimmer230_SEND_STATUS_TIMEOUT, act_dimmer230_SEND_STATUS_INTERVAL*1000, TimerTypeFreeRunning, &Send_Status_callback);
  280. }
  281.  
  282.  
  283. /*  Process funtion of dimmer-module, currently everything is done interrupted */
  284. void act_dimmer230_Process(void)
  285. {
  286.     /* Send netinfo packet (if dimmervalue has changed, and periodically) */
  287.     if (sendNetInfo)
  288.     {
  289.         sendNetInfo = 0;
  290.         StdCan_Msg_t txMsg;
  291.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  292.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  293.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_DIMMER230;
  294.         txMsg.Header.ModuleId = act_dimmer230_ID;
  295.         txMsg.Header.Command = CAN_MODULE_CMD_DIMMER230_NETINFO;
  296.         txMsg.Length = 3;
  297.         txMsg.Data[0] = ((netConnected&0x1)<<7 | (frequency&0x3)<<5);
  298.         txMsg.Data[1] = dimmerValue;
  299.         txMsg.Data[2] = 0;  //Channel
  300.         StdCan_Put(&txMsg);
  301.     }
  302.    
  303.     /* If dimmervalue was changed over 5 seconds ago then store the new dimmervalue */
  304.     if (Timer_Expired(act_dimmer230_STORE_VALUE_TIMEOUT))
  305.     {
  306.         eeprom_write_byte_crc(EEDATA.eeDimmerValue, dimmerValue, WITH_CRC);
  307.     }
  308. }
  309.  
  310.  
  311. /*  Handle incoming message function of dimmer-module */
  312. void act_dimmer230_HandleMessage(StdCan_Msg_t *rxMsg)
  313. {
  314.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  315.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  316.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_DIMMER230 &&
  317.         rxMsg->Header.ModuleId == act_dimmer230_ID)
  318.     {
  319.         switch (rxMsg->Header.Command)
  320.         {
  321.         case CAN_MODULE_CMD_DIMMER230_DEMO:     /* Demo(channel, speed, steps) */
  322.             if (rxMsg->Length == 3) {
  323.                 uint8_t channel = rxMsg->Data[0];
  324.                 uint8_t speed = rxMsg->Data[1];
  325.                 uint8_t steps = rxMsg->Data[2];
  326.                
  327.                 fadeSpeedCnt = 0;
  328.                 fadeSpeed = 0;
  329.                 if (speed == 0) {
  330.                     /* do nothing */
  331.                 } else {
  332.                     uint8_t diffToMin = dimmerValue - ACT_DIMMMER230_MIN_DIM;
  333.                     uint8_t diffToMax = ACT_DIMMMER230_MAX_DIM - dimmerValue;
  334.                
  335.                     demoEndValue = dimmerValue;
  336.                     if (diffToMin >= steps && diffToMax >= steps)
  337.                     {
  338.                         /* not close to min or max */
  339.                         fadeTarget = dimmerValue - steps;
  340.                         demoHighValue = dimmerValue + steps;
  341.                     }
  342.                     else if (diffToMin >= steps)
  343.                     {
  344.                         /* close to max */
  345.                         fadeTarget = dimmerValue - steps - steps + diffToMax;
  346.                         demoHighValue = ACT_DIMMMER230_MAX_DIM;
  347.                     }
  348.                     else if (diffToMax >= steps)
  349.                     {
  350.                         /* close to min */
  351.                         fadeTarget = ACT_DIMMMER230_MIN_DIM;
  352.                         demoHighValue = dimmerValue + steps + steps - diffToMin;
  353.                     }
  354.                     demoState = ACT_DIMMMER230_DEMO_STATE_DECREASE;
  355.                
  356.                     if ((speed&0x80) == 0x80) {
  357.                         fadeSpeed = (speed&0x7f)+1;
  358.                         fadeSpeedFrac = 1;
  359.                     } else {
  360.                         fadeSpeed = 1;
  361.                         fadeSpeedFrac = 0x80-(speed&0x7f);
  362.                     }
  363.                     if (fadeTarget <= dimmerValue) {
  364.                         fadeSpeed = -fadeSpeed;
  365.                     }
  366.                 }
  367.             }
  368.         break;
  369.        
  370.         case CAN_MODULE_CMD_DIMMER230_START_FADE:   /* StartFade(channel, speed, direction) */
  371.             if (rxMsg->Length == 3) {
  372.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  373.                 uint8_t channel = rxMsg->Data[0];
  374.                 uint8_t speed = rxMsg->Data[1];
  375.                 uint8_t direction = rxMsg->Data[2];
  376.                
  377.                 fadeSpeedCnt = 0;
  378.                 fadeSpeed = 0;
  379.                 uint8_t endValue = 0;
  380.                 if (direction == CAN_MODULE_ENUM_DIMMER230_START_FADE_DIRECTION_INCREASE) {
  381.                     endValue = ACT_DIMMMER230_MAX_DIM;
  382.                 } else if (direction == CAN_MODULE_ENUM_DIMMER230_START_FADE_DIRECTION_DECREASE) {
  383.                     endValue = ACT_DIMMMER230_MIN_DIM;
  384.                 }
  385.                    
  386.                 if (speed == 0) {
  387.                     dimmerValue = endValue; /* set dimmer value immediately */
  388.                     sendNetInfo = 1;        /* send netinfo with the current dimmervalue*/
  389.                 } else {
  390.                     fadeTarget = endValue;
  391.                     if (fadeTarget != dimmerValue) {
  392.                         if ((speed&0x80) == 0x80) {
  393.                             fadeSpeed = (speed&0x7f)+1;
  394.                             fadeSpeedFrac = 1;
  395.                         } else {
  396.                             fadeSpeed = 1;
  397.                             fadeSpeedFrac = 0x80-(speed&0x7f);
  398.                         }
  399.                         if (fadeTarget < dimmerValue) {
  400.                             fadeSpeed = -fadeSpeed;
  401.                         }
  402.                     }
  403.                 }
  404.             }
  405.         break;
  406.  
  407.         case CAN_MODULE_CMD_DIMMER230_STOP_FADE:    /* StopFade(channel) */
  408.             if (rxMsg->Length == 1) {
  409.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  410.                 fadeSpeed = 0;
  411.                 sendNetInfo = 1;        /* send netinfo with the current dimmervalue*/
  412.             }
  413.         break;
  414.  
  415.         case CAN_MODULE_CMD_DIMMER230_ABS_FADE: /* AbsFade(channel, speed, endValue) */
  416.             if (rxMsg->Length == 3) {
  417.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  418.                 uint8_t channel = rxMsg->Data[0];
  419.                 uint8_t speed = rxMsg->Data[1];
  420.                 uint8_t endValue = rxMsg->Data[2];
  421.  
  422.                 fadeSpeedCnt = 0;
  423.                 fadeSpeed = 0;
  424.                 if (speed == 0) {
  425.                     dimmerValue = endValue; /* set dimmer value immediately */
  426.                     sendNetInfo = 1;        /* send netinfo with the current dimmervalue*/
  427.                 } else {
  428.                     fadeTarget = endValue;
  429.                     if (fadeTarget != dimmerValue) {
  430.                         if ((speed&0x80) == 0x80) {
  431.                             fadeSpeed = (speed&0x7f)+1;
  432.                             fadeSpeedFrac = 1;
  433.                         } else {
  434.                             fadeSpeed = 1;
  435.                             fadeSpeedFrac = 0x80-(speed&0x7f);
  436.                         }
  437.                         if (fadeTarget < dimmerValue) {
  438.                             fadeSpeed = -fadeSpeed;
  439.                         }
  440.                     }
  441.                 }
  442.             }
  443.         break;
  444.  
  445.         case CAN_MODULE_CMD_DIMMER230_REL_FADE: /* RelFade(channel, speed, direction, steps) */
  446.             if (rxMsg->Length == 4) {
  447.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  448.                 uint8_t channel = rxMsg->Data[0];
  449.                 uint8_t speed = rxMsg->Data[1];
  450.                 uint8_t direction = rxMsg->Data[2];
  451.                 uint8_t steps = rxMsg->Data[3];
  452.                
  453.                 fadeSpeedCnt = 0;
  454.                 fadeSpeed = 0;
  455.                 uint8_t tempDimVal = dimmerValue;
  456.                 uint8_t tempDimVal2 = dimmerValue;
  457.                 if (direction == CAN_MODULE_ENUM_DIMMER230_REL_FADE_DIRECTION_INCREASE) {                   /* if increase */
  458.                     tempDimVal2 += steps;               /* calculate new value */
  459.                     if (tempDimVal2 < tempDimVal) {     /* make overflow test */
  460.                         tempDimVal2 = ACT_DIMMMER230_MAX_DIM;
  461.                     }
  462.                 } else if (direction == CAN_MODULE_ENUM_DIMMER230_REL_FADE_DIRECTION_DECREASE) {            /* if decrease */
  463.                     tempDimVal2 -= steps;
  464.                     if (tempDimVal2 > tempDimVal) {
  465.                         tempDimVal2 = ACT_DIMMMER230_MIN_DIM;
  466.                     }
  467.                 }
  468.                 if (speed == 0) {
  469.                     dimmerValue = tempDimVal2;      /* set dimmer value immediately */
  470.                     sendNetInfo = 1;                /* send netinfo with the current dimmervalue*/
  471.                 } else {
  472.                     fadeTarget = tempDimVal2;       /* set the fade target */
  473.                    
  474.                     if (fadeTarget != dimmerValue) {
  475.                         if ((speed&0x80) == 0x80) {
  476.                             fadeSpeed = (speed&0x7f)+1;
  477.                             fadeSpeedFrac = 1;
  478.                         } else {
  479.                             fadeSpeed = 1;
  480.                             fadeSpeedFrac = 0x80-(speed&0x7f);
  481.                         }
  482.                         if (fadeTarget < dimmerValue) {
  483.                             fadeSpeed = -fadeSpeed;
  484.                         }
  485.                     }
  486.                 }
  487.             }
  488.         break;
  489.         }
  490.     }
  491. }
  492.  
  493. /* List function of dimmer-module */
  494. void act_dimmer230_List(uint8_t ModuleSequenceNumber)
  495. {
  496.     StdCan_Msg_t txMsg;
  497.    
  498.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  499.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  500.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_DIMMER230;
  501.     txMsg.Header.ModuleId = act_dimmer230_ID;
  502.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  503.     txMsg.Length = 6;
  504.  
  505.     uint32_t HwId=BIOS_GetHwId();
  506.     txMsg.Data[0] = HwId&0xff;
  507.     txMsg.Data[1] = (HwId>>8)&0xff;
  508.     txMsg.Data[2] = (HwId>>16)&0xff;
  509.     txMsg.Data[3] = (HwId>>24)&0xff;
  510.    
  511.     txMsg.Data[4] = NUMBER_OF_MODULES;
  512.     txMsg.Data[5] = ModuleSequenceNumber;
  513.    
  514.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  515. }
  516.  
  517.