Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_hwPWM.h"
  3.  
  4. uint16_t pwmValue[4];
  5. uint8_t sendInfo[4] = {0,0,0,0};
  6.  
  7. int8_t fadeSpeed[4] = {0,0,0,0};
  8. uint8_t fadeSpeedFrac[4] = {0,0,0,0};
  9. uint16_t fadeTarget[4] = {0,0,0,0};
  10. uint8_t fadeSpeedCnt[4] = {0,0,0,0};
  11.  
  12. uint16_t demoEndValue[4] = {0,0,0,0};
  13. uint16_t demoHighValue[4] = {0,0,0,0};
  14. uint8_t demoState[4] = {ACT_HWPWM_DEMO_STATE_NOT_RUNNING, ACT_HWPWM_DEMO_STATE_NOT_RUNNING, ACT_HWPWM_DEMO_STATE_NOT_RUNNING,                   ACT_HWPWM_DEMO_STATE_NOT_RUNNING};
  15.  
  16. #ifdef act_hwPWM_USEEEPROM
  17. #include "act_hwPWM_eeprom.h"
  18. struct eeprom_act_hwPWM EEMEM eeprom_act_hwPWM =
  19. {
  20.     {
  21.         ///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.
  22.         0x0000, // ch 1
  23.         0x0000, // ch 2
  24.         0x0000, // ch 3
  25.         0x0000  // ch 4
  26.     },
  27.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  28. };
  29. #endif
  30.  
  31. #if act_hwPWM_ENABLE_FADE == 1
  32. void act_hwPWM_timer_callback(uint8_t timer)
  33. {
  34.     uint8_t channel = 0;
  35.     for (channel = 0; channel < 4; channel++) {
  36.         /* Check demo states */
  37.         if (pwmValue[channel] == fadeTarget[channel]) {
  38.             switch (demoState[channel])
  39.             {
  40.             case ACT_HWPWM_DEMO_STATE_NOT_RUNNING:
  41.             break;
  42.             case ACT_HWPWM_DEMO_STATE_DECREASE:
  43.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_INCREASE;
  44.                 fadeTarget[channel] = demoHighValue[channel];
  45.                 fadeSpeed[channel] = -fadeSpeed[channel];
  46.             break;
  47.             case ACT_HWPWM_DEMO_STATE_INCREASE:
  48.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_GOBACK;
  49.                 fadeTarget[channel] = demoEndValue[channel];
  50.                 fadeSpeed[channel] = -fadeSpeed[channel];
  51.             break;
  52.             case ACT_HWPWM_DEMO_STATE_GOBACK:
  53.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  54.             break;
  55.             }
  56.         }
  57.        
  58.         /* Change the dimmerValue according to the current fading */
  59.         fadeSpeedCnt[channel]++;
  60.         if (fadeSpeedCnt[channel] == fadeSpeedFrac[channel] && pwmValue[channel] != (fadeTarget[channel]))
  61.         {
  62.             fadeSpeedCnt[channel] = 0;
  63.             uint16_t tempDimVal = pwmValue[channel];
  64.             pwmValue[channel] += (fadeSpeed[channel]*39);
  65.             if ((fadeSpeed[channel] > 0 && (pwmValue[channel] < tempDimVal || pwmValue[channel] >= (fadeTarget[channel]))) ||
  66.                 (fadeSpeed[channel] < 0 && (pwmValue[channel] > tempDimVal || pwmValue[channel] <= (fadeTarget[channel]))))
  67.             {
  68.                 pwmValue[channel] = (fadeTarget[channel]);
  69.             }
  70.             if (pwmValue[channel] > 10000) {
  71.                 pwmValue[channel] = 10000;
  72.             }
  73.             /* if targetvalue was reached then send the netinfo packet */
  74.             if (pwmValue[channel] == fadeTarget[channel])
  75.             {
  76.                 sendInfo[channel] = 1;
  77.             }
  78.         }
  79.     }
  80.  
  81. }
  82. #endif
  83.  
  84.  
  85. void act_hwPWM_Init(void)
  86. {
  87. #ifdef act_hwPWM_USEEEPROM
  88.     if (EEDATA_OK)
  89.     {
  90.       ///TODO: Use stored data to set initial values for the module
  91.       pwmValue[0] = eeprom_read_word(EEDATA16.ch1);
  92.       pwmValue[1] = eeprom_read_word(EEDATA16.ch2);
  93.       pwmValue[2] = eeprom_read_word(EEDATA16.ch3);
  94.       pwmValue[3] = eeprom_read_word(EEDATA16.ch4);
  95.     } else
  96.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  97.       eeprom_write_word_crc(EEDATA16.ch1, 0x0000, WITHOUT_CRC);
  98.       eeprom_write_word_crc(EEDATA16.ch2, 0x0000, WITHOUT_CRC);
  99.       eeprom_write_word_crc(EEDATA16.ch3, 0x0000, WITHOUT_CRC);
  100.       eeprom_write_word_crc(EEDATA16.ch4, 0x0000, WITHOUT_CRC);
  101.       EEDATA_UPDATE_CRC;
  102.     }
  103. #endif
  104.     TCCR1A = 0;
  105.     TCCR1B = 0;
  106.     TCCR0A = 0;
  107.     TCCR0B = 0;
  108.  
  109.     /* set up pwm values */
  110.     cli();
  111.     #if act_hwPWM_CH1_COM>0
  112.     OCR_1=(uint16_t)(pwmValue[0]*act_hwPWM_CH1_FACT)>>8;
  113.     #endif
  114.     #if act_hwPWM_CH2_COM>0
  115.     OCR_2=(uint16_t)(pwmValue[1]*act_hwPWM_CH2_FACT)>>8;
  116.     #endif
  117.     #if act_hwPWM_CH3_COM>0
  118.     OCR_3=(uint16_t)(pwmValue[2]*act_hwPWM_CH3_FACT)>>8;
  119.     #endif
  120.     #if act_hwPWM_CH4_COM>0
  121.     OCR_4=(uint16_t)(pwmValue[3]*act_hwPWM_CH4_FACT)>>8;
  122.     #endif
  123.     sei();
  124.  
  125.     /* set up waveform generation mode for timer 1 */
  126.     #if act_hwPWM_CH1_COM>0
  127.     TCCR1A=((act_hwPWM_CH1_WGM&0x03)<<WGM00);
  128.     TCCR1B=(((act_hwPWM_CH1_WGM>>2)&0x03)<<WGM12);
  129.     #elif act_hwPWM_CH2_COM>0
  130.     TCCR1A=((act_hwPWM_CH2_WGM&0x03)<<WGM00);
  131.     TCCR1B=(((act_hwPWM_CH2_WGM>>2)&0x03)<<WGM12);
  132.     #endif
  133.  
  134.     /* enable outputs for timer 1 */
  135.     #if act_hwPWM_CH1_COM>0
  136.     gpio_set_out(EXP_B);
  137.     #endif
  138.     #if act_hwPWM_CH2_COM>0
  139.     gpio_set_out(EXP_C);
  140.     #endif
  141.  
  142.     /* set up counter mode for timer 1 */
  143.     #if act_hwPWM_CH1_COM>0 || act_hwPWM_CH2_COM>0
  144.     if (pwmValue[0]>0)
  145.     {
  146.         TCCR1A|=(act_hwPWM_CH1_COM<<COM1B0);
  147.     }
  148.     if (pwmValue[1]>0)
  149.     {
  150.         TCCR1A|=(act_hwPWM_CH2_COM<<COM1A0);
  151.     }
  152.     ICR1 = 0xffff;
  153.     #endif
  154.  
  155.     /* enable timer 1 */
  156.     #if act_hwPWM_CH1_COM>0
  157.     TCCR1B|=(act_hwPWM_CH1_CS<<CS10);
  158.     #elif act_hwPWM_CH2_COM>0
  159.     TCCR1B|=(act_hwPWM_CH2_CS<<CS10);
  160.     #endif
  161.  
  162.  
  163.     /* set up waveform generation mode for timer 0 */
  164.     #if act_hwPWM_CH3_COM>0
  165.     TCCR0A=((act_hwPWM_CH3_WGM&0x03)<<WGM00);
  166.     TCCR0B=(((act_hwPWM_CH3_WGM>>2)&0x01)<<WGM02);
  167.     #elif act_hwPWM_CH4_COM>0
  168.     TCCR0A=((act_hwPWM_CH4_WGM&0x03)<<WGM00);
  169.     TCCR0B=(((act_hwPWM_CH4_WGM>>2)&0x01)<<WGM02);
  170.     #endif
  171.  
  172.     /* enable outputs for timer 0 */
  173.     #if act_hwPWM_CH3_COM>0
  174.     gpio_set_out(EXP_F);
  175.     #endif
  176.     #if act_hwPWM_CH4_COM>0
  177.     gpio_set_out(EXP_G);
  178.     #endif
  179.  
  180.     /* set up counter mode for timer 0 */
  181.     #if act_hwPWM_CH3_COM>0 || act_hwPWM_CH4_COM>0
  182.     if (pwmValue[2]>0)
  183.     {
  184.         TCCR0A|=(act_hwPWM_CH3_COM<<COM0A0);
  185.     }
  186.     if (pwmValue[3]>0)
  187.     {
  188.         TCCR0A|=(act_hwPWM_CH4_COM<<COM0B0);
  189.     }
  190.     #endif
  191.  
  192.     /* enable timer 0 */
  193.     #if act_hwPWM_CH3_COM>0
  194.     TCCR0B|=(act_hwPWM_CH3_CS<<CS00);
  195.     #elif act_hwPWM_CH4_COM>0
  196.     TCCR0B|=(act_hwPWM_CH4_CS<<CS00);
  197.     #endif
  198.     //printf("1A %x, 1B %x, 0A %x, 0B %x\n", TCCR1A, TCCR1B, TCCR0A, TCCR0B);
  199.    
  200. #if act_hwPWM_ENABLE_FADE == 1
  201.     Timer_SetTimeout(act_hwPWM_FADE_TIMER, 10, TimerTypeFreeRunning, &act_hwPWM_timer_callback);
  202. #endif
  203.    
  204.     /* Setup timeout for sending the status packet */
  205.     Timer_SetTimeout(act_hwPWM_SEND_STATUS_TIMEOUT, act_hwPWM_SEND_STATUS_INTERVAL_S*1000, TimerTypeFreeRunning, 0);
  206.     //printf("Hello world!\n");
  207. }
  208. uint8_t channel_to_send = 1;
  209. void act_hwPWM_Process(void)
  210. {
  211.     if (Timer_Expired(act_hwPWM_SEND_STATUS_TIMEOUT))
  212.     {
  213.         if (channel_to_send >4) {
  214.           #if act_hwPWM_CH1_COM==0
  215.           channel_to_send = 2;
  216.               #if act_hwPWM_CH2_COM==0
  217.               channel_to_send = 3;
  218.               #if act_hwPWM_CH3_COM==0
  219.                   channel_to_send = 4;
  220.               #else
  221.                   channel_to_send=3;
  222.                 #endif 
  223.               #else
  224.                   channel_to_send=2;
  225.             #endif     
  226.              
  227.           #else
  228.             channel_to_send=1;
  229.           #endif       
  230.        
  231.         }
  232.         sendInfo[channel_to_send-1] = 1;
  233.         channel_to_send++;
  234. #if act_hwPWM_CH1_COM==0
  235.           if (channel_to_send == 1)
  236.             channel_to_send++;
  237. #endif     
  238. #if act_hwPWM_CH2_COM==0
  239.           if (channel_to_send == 2)
  240.             channel_to_send++;
  241. #endif 
  242. #if act_hwPWM_CH3_COM==0
  243.           if (channel_to_send == 3)
  244.             channel_to_send++;
  245. #endif 
  246. #if act_hwPWM_CH4_COM==0
  247.           if (channel_to_send == 4)
  248.             channel_to_send++;
  249. #endif 
  250.        
  251.        
  252.     }
  253.     /* Send netinfo packet (if pwmvalue has changed, and periodically) */
  254.     uint8_t index;
  255.     for(index =0;index < 4; index++){
  256.         if (pwmValue[index] > 10000) {
  257.             pwmValue[index] = 10000;
  258.         }
  259.         if (sendInfo[index])
  260.         {
  261.             sendInfo[index] = 0;
  262.             StdCan_Msg_t txMsg;
  263.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  264.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  265.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_HWPWM;
  266.             txMsg.Header.ModuleId = act_hwPWM_ID;
  267.             txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PWM;
  268.             txMsg.Length = 3;
  269.             txMsg.Data[0] = index+1;
  270.             txMsg.Data[1] = (0xff&(pwmValue[index]>>8));
  271.             txMsg.Data[2] = (0xff&(pwmValue[index]));
  272.             StdCan_Put(&txMsg);
  273.         }
  274.     }
  275.    
  276.     if (Timer_Expired(act_hwPWM_STORE_VALUE_TIMEOUT))
  277.     {
  278.         if (pwmValue[0] != eeprom_read_word(EEDATA16.ch1))
  279.         {
  280.             eeprom_write_word_crc(EEDATA16.ch1, pwmValue[0], WITH_CRC);
  281.         }
  282.         if (pwmValue[1] != eeprom_read_word(EEDATA16.ch2))
  283.         {
  284.             eeprom_write_word_crc(EEDATA16.ch2, pwmValue[1], WITH_CRC);
  285.         }
  286.         if (pwmValue[2] != eeprom_read_word(EEDATA16.ch3))
  287.         {
  288.             eeprom_write_word_crc(EEDATA16.ch3, pwmValue[2], WITH_CRC);
  289.         }
  290.         if (pwmValue[3] != eeprom_read_word(EEDATA16.ch4))
  291.         {
  292.             eeprom_write_word_crc(EEDATA16.ch4, pwmValue[3], WITH_CRC);
  293.         }
  294.     }
  295.                    
  296. #if act_hwPWM_CH1_COM>0
  297.     if (OCR_1 != (uint16_t)(pwmValue[0]*act_hwPWM_CH1_FACT)>>8) {
  298.         cli(); 
  299.         OCR_1=(uint16_t)(pwmValue[0]*act_hwPWM_CH1_FACT)>>8;
  300.         if (OCR_1==0)
  301.         {
  302.             TCCR1A&=~((1<<COM1B0)|(1<<COM1B1));
  303.         }
  304.         else
  305.         {
  306.             TCCR1A|=(act_hwPWM_CH1_COM<<COM1B0);
  307.         }
  308.         sei();
  309.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  310.     }
  311. #endif
  312. #if act_hwPWM_CH2_COM>0
  313.     if (OCR_2 != (uint16_t)((uint32_t)pwmValue[1]*act_hwPWM_CH2_FACT)>>8) {
  314.         cli(); 
  315.         OCR_2=(uint16_t)(((uint32_t)pwmValue[1]*act_hwPWM_CH2_FACT)>>8);
  316.         if (OCR_2==0)
  317.         {
  318.             TCCR1A&=~((1<<COM1A0)|(1<<COM1A1));
  319.         }
  320.         else
  321.         {
  322.             TCCR1A|=(act_hwPWM_CH2_COM<<COM1A0);
  323.         }
  324.         sei();
  325.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  326.     }
  327. #endif
  328. #if act_hwPWM_CH3_COM>0
  329.     if (OCR_3 != (uint16_t)(pwmValue[2]*act_hwPWM_CH3_FACT)>>8) {
  330.         cli(); 
  331.         OCR_3=(uint16_t)(pwmValue[2]*act_hwPWM_CH3_FACT)>>8;
  332.         if (OCR_3==0)
  333.         {
  334.             TCCR0A &= ~((1<<COM0A0)|(1<<COM0A1));
  335.         }
  336.         else
  337.         {
  338.             TCCR0A|=(act_hwPWM_CH3_COM<<COM0A0);
  339.         }
  340.         sei();
  341.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  342.     }
  343. #endif
  344. #if act_hwPWM_CH4_COM>0
  345.     if (OCR_4 != (uint16_t)(pwmValue[3]*act_hwPWM_CH4_FACT)>>8) {
  346.         cli(); 
  347.         OCR_4=(uint16_t)(pwmValue[3]*act_hwPWM_CH4_FACT)>>8;
  348.         if (OCR_4==0)
  349.         {
  350.             TCCR0A &= ~((1<<COM0B0)|(1<<COM0B1));
  351.         }
  352.         else
  353.         {
  354.             TCCR0A|=(act_hwPWM_CH4_COM<<COM0B0);
  355.         }
  356.         sei();
  357.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  358.     }
  359. #endif
  360. }
  361.  
  362. void act_hwPWM_HandleMessage(StdCan_Msg_t *rxMsg)
  363. {
  364.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  365.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  366.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_HWPWM &&
  367.         rxMsg->Header.ModuleId == act_hwPWM_ID)
  368.     {
  369.         uint8_t channel = 0;
  370.         switch (rxMsg->Header.Command)
  371.         {
  372.         case CAN_MODULE_CMD_PHYSICAL_PWM:
  373.             if (rxMsg->Length == 3) {
  374.                 channel = rxMsg->Data[0];
  375.                 pwmValue[channel-1] = (rxMsg->Data[1]<<8)+(rxMsg->Data[2]);
  376.             }
  377.            
  378.         break;
  379. #if act_hwPWM_ENABLE_FADE == 1
  380.         case CAN_MODULE_CMD_HWPWM_DEMO:     /* Demo(channel, speed, steps) */
  381.             if (rxMsg->Length == 4) {
  382.                 channel = rxMsg->Data[0]-1;
  383.                 uint8_t speed = rxMsg->Data[1];
  384.                 uint16_t steps = (rxMsg->Data[2]<<8)+(rxMsg->Data[3]);
  385.                
  386.                 fadeSpeedCnt[channel] = 0;
  387.                 fadeSpeed[channel] = 0;
  388.                 if (speed == 0) {
  389.                     /* do nothing */
  390.                 } else {
  391.                     uint16_t diffToMin = pwmValue[channel] - ACT_HWPWM_MIN_DIM;
  392.                     uint16_t diffToMax = ACT_HWPWM_MAX_DIM - pwmValue[channel];
  393.                
  394.                     demoEndValue[channel] = pwmValue[channel];
  395.                     if (diffToMin >= steps && diffToMax >= steps)
  396.                     {
  397.                         /* not close to min or max */
  398.                         fadeTarget[channel] = pwmValue[channel] - steps;
  399.                         demoHighValue[channel] = pwmValue[channel] + steps;
  400.                     }
  401.                     else if (diffToMin >= steps)
  402.                     {
  403.                         /* close to max */
  404.                         fadeTarget[channel] = pwmValue[channel] - steps - steps + diffToMax;
  405.                         demoHighValue[channel] = ACT_HWPWM_MAX_DIM;
  406.                     }
  407.                     else if (diffToMax >= steps)
  408.                     {
  409.                         /* close to min */
  410.                         fadeTarget[channel] = ACT_HWPWM_MIN_DIM;
  411.                         demoHighValue[channel] = pwmValue[channel] + steps + steps - diffToMin;
  412.                     }
  413.                     demoState[channel] = ACT_HWPWM_DEMO_STATE_DECREASE;
  414.                
  415.                     if ((speed&0x80) == 0x80) {
  416.                         fadeSpeed[channel] = (speed&0x7f)+1;
  417.                         fadeSpeedFrac[channel] = 1;
  418.                     } else {
  419.                         fadeSpeed[channel] = 1;
  420.                         fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  421.                     }
  422.                     if (fadeTarget[channel] <= pwmValue[channel]) {
  423.                         fadeSpeed[channel] = -fadeSpeed[channel];
  424.                     }
  425.                 }
  426.             }
  427.         break;
  428.        
  429.         case CAN_MODULE_CMD_HWPWM_START_FADE:   /* StartFade(channel, speed, direction) */
  430.             if (rxMsg->Length == 3) {
  431.                
  432.                 channel = rxMsg->Data[0]-1;
  433.                 uint8_t speed = rxMsg->Data[1];
  434.                 uint8_t direction = rxMsg->Data[2];
  435.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  436.                 fadeSpeedCnt[channel] = 0;
  437.                 fadeSpeed[channel] = 0;
  438.                 uint16_t endValue = 0;
  439.                 if (direction == CAN_MODULE_ENUM_HWPWM_START_FADE_DIRECTION_INCREASE) {
  440.                     endValue = ACT_HWPWM_MAX_DIM;
  441.                 } else if (direction == CAN_MODULE_ENUM_HWPWM_START_FADE_DIRECTION_DECREASE) {
  442.                     endValue = ACT_HWPWM_MIN_DIM;
  443.                 }
  444.                    
  445.                 if (speed == 0) {
  446.                     pwmValue[channel] = endValue;   /* set dimmer value immediately */
  447.                     sendInfo[channel] = 1;      /* send netinfo with the current dimmervalue*/
  448.                 } else {
  449.                     fadeTarget[channel] = endValue;
  450.                     if (fadeTarget[channel] != pwmValue[channel]) {
  451.                         if ((speed&0x80) == 0x80) {
  452.                             fadeSpeed[channel] = (speed&0x7f)+1;
  453.                             fadeSpeedFrac[channel] = 1;
  454.                         } else {
  455.                             fadeSpeed[channel] = 1;
  456.                             fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  457.                         }
  458.                         if (fadeTarget[channel] < pwmValue[channel]) {
  459.                             fadeSpeed[channel] = -fadeSpeed[channel];
  460.                         }
  461.                     }
  462.                 }
  463.             }
  464.         break;
  465.  
  466.         case CAN_MODULE_CMD_HWPWM_STOP_FADE:    /* StopFade(channel) */
  467.             if (rxMsg->Length == 1) {
  468.                 channel = rxMsg->Data[0]-1;
  469.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  470.                 fadeSpeed[channel] = 0;
  471.                 sendInfo[channel] = 1;      /* send netinfo with the current dimmervalue*/
  472.             }
  473.         break;
  474.  
  475.         case CAN_MODULE_CMD_HWPWM_ABS_FADE: /* AbsFade(channel, speed, endValue) */
  476.             if (rxMsg->Length == 4) {
  477.                 channel = rxMsg->Data[0]-1;
  478.                 uint8_t speed = rxMsg->Data[1];
  479.                 uint16_t endValue = (rxMsg->Data[2]<<8)+(rxMsg->Data[3]);
  480.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  481.                 fadeSpeedCnt[channel] = 0;
  482.                 fadeSpeed[channel] = 0;
  483.                 if (speed == 0) {
  484.                     pwmValue[channel] = endValue;   /* set dimmer value immediately */
  485.                     sendInfo[channel] = 1;      /* send netinfo with the current dimmervalue*/
  486.                 } else {
  487.                     fadeTarget[channel] = endValue;
  488.                     if (fadeTarget[channel] != pwmValue[channel]) {
  489.                         if ((speed&0x80) == 0x80) {
  490.                             fadeSpeed[channel] = (speed&0x7f)+1;
  491.                             fadeSpeedFrac[channel] = 1;
  492.                         } else {
  493.                             fadeSpeed[channel] = 1;
  494.                             fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  495.                         }
  496.                         if (fadeTarget[channel] < pwmValue[channel]) {
  497.                             fadeSpeed[channel] = -fadeSpeed[channel];
  498.                         }
  499.                     }
  500.                 }
  501.                 //printf("abs fade %d %d %d!\n",fadeTarget[channel], endValue ,pwmValue[channel] );
  502.             }
  503.         break;
  504.  
  505.         case CAN_MODULE_CMD_HWPWM_REL_FADE: /* RelFade(channel, speed, direction, steps) */
  506.             if (rxMsg->Length == 5) {
  507.                
  508.                 channel = rxMsg->Data[0]-1;
  509.                 uint8_t speed = rxMsg->Data[1];
  510.                 uint8_t direction = rxMsg->Data[2];
  511.                 uint16_t steps = (rxMsg->Data[3]<<8)+(rxMsg->Data[4]);
  512.                
  513.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  514.                 fadeSpeedCnt[channel] = 0;
  515.                 fadeSpeed[channel] = 0;
  516.                 uint16_t tempDimVal = pwmValue[channel];
  517.                 uint16_t tempDimVal2 = pwmValue[channel];
  518.                 if (direction == CAN_MODULE_ENUM_HWPWM_REL_FADE_DIRECTION_INCREASE) {                   /* if increase */
  519.                     tempDimVal2 += steps;               /* calculate new value */
  520.                     if (tempDimVal2 < tempDimVal) {     /* make overflow test */
  521.                         tempDimVal2 = ACT_HWPWM_MAX_DIM;
  522.                     }
  523.                 } else if (direction == CAN_MODULE_ENUM_HWPWM_REL_FADE_DIRECTION_DECREASE) {            /* if decrease */
  524.                     tempDimVal2 -= steps;
  525.                     if (tempDimVal2 > tempDimVal) {
  526.                         tempDimVal2 = ACT_HWPWM_MIN_DIM;
  527.                     }
  528.                 }
  529.                 if (speed == 0) {
  530.                     pwmValue[channel] = tempDimVal2;        /* set dimmer value immediately */
  531.                     sendInfo[channel] = 1;              /* send netinfo with the current dimmervalue*/
  532.                 } else {
  533.                     fadeTarget[channel] = tempDimVal2;      /* set the fade target */
  534.                    
  535.                     if (fadeTarget[channel] != pwmValue[channel]) {
  536.                         if ((speed&0x80) == 0x80) {
  537.                             fadeSpeed[channel] = (speed&0x7f)+1;
  538.                             fadeSpeedFrac[channel] = 1;
  539.                         } else {
  540.                             fadeSpeed[channel] = 1;
  541.                             fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  542.                         }
  543.                         if (fadeTarget[channel] < pwmValue[channel]) {
  544.                             fadeSpeed[channel] = -fadeSpeed[channel];
  545.                         }
  546.                     }
  547.                 }
  548.             }
  549.         break;
  550. #endif
  551.  
  552.         }
  553.     }
  554. }
  555.  
  556. void act_hwPWM_List(uint8_t ModuleSequenceNumber)
  557. {
  558.     StdCan_Msg_t txMsg;
  559.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  560.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  561.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_HWPWM;
  562.     txMsg.Header.ModuleId = act_hwPWM_ID;
  563.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  564.     txMsg.Length = 6;
  565.  
  566.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  567.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  568.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  569.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  570.    
  571.     txMsg.Data[4] = NUMBER_OF_MODULES;
  572.     txMsg.Data[5] = ModuleSequenceNumber;
  573.  
  574.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  575. }
  576.