Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_hwPWM.h"
  3. #include <avr/pgmspace.h>
  4.  
  5. uint16_t pwmValue[4];
  6. uint8_t sendInfo[4] = {0,0,0,0};
  7.  
  8. int8_t fadeSpeed[4] = {0,0,0,0};
  9. uint8_t fadeSpeedFrac[4] = {0,0,0,0};
  10. uint16_t fadeTarget[4] = {0,0,0,0};
  11. uint8_t fadeSpeedCnt[4] = {0,0,0,0};
  12.  
  13. uint16_t demoEndValue[4] = {0,0,0,0};
  14. uint16_t demoHighValue[4] = {0,0,0,0};
  15. 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};
  16.  
  17. static uint16_t lookuptable[257] PROGMEM =
  18. {
  19.   0 ,  4    ,  8    ,  12   ,  17   ,  21   ,  25   ,  30   ,  34   ,  39   ,  //0
  20. 43  ,  48   ,  52   ,  57   ,  62   ,  67   ,  72   ,  77   ,  82   ,  87   ,  //10
  21. 93  ,  98   ,  104  ,  109  , 115   ,  120  ,  126  ,  132  ,  138  ,  144  ,  //20
  22. 150 ,  156  ,  162  ,  169  ,  175  ,  182  ,  188  ,  195  ,  202  ,  209  ,  //30
  23. 216 ,  223  ,  230  ,  237  ,  245  ,  252  ,  260  ,  267  ,  275  ,  283  ,  //40
  24. 291 ,  299  ,  308  ,  316  ,  325  ,  333  ,  342  ,  351  ,  360  ,  369  ,  //50
  25. 378 ,  388  ,  397  ,  407  ,  417  ,  427  ,  437  ,  447  ,  457  ,  468  ,  //60
  26. 478 ,  489  ,  500  ,  511  ,  523  ,  534  ,  546  ,  557  ,  569  ,  581  ,  //70
  27. 594 ,  606  ,  619  ,  632  ,  645  ,  658  ,  671  ,  685  ,  698  ,  712  ,  //80
  28. 726 ,  741  ,  755  ,  770  ,  785  ,  800  ,  815  ,  831  ,  847  ,  863  ,  //90
  29. 879 ,  896  ,  912  ,  929  ,  946  ,  964  ,  982  ,  999  ,  1018 ,  1036 ,  //100
  30. 1055    ,  1074 ,  1093 ,  1113 ,  1132 ,  1152 ,  1173 ,  1193 ,  1214 ,  1236 ,  //110
  31. 1257    ,  1279 ,  1301 ,  1324 ,  1346 ,  1369 ,  1393 ,  1417 ,  1441 ,  1465 ,  //120
  32. 1490    ,  1515 ,  1540 ,  1566 ,  1593 ,  1619 ,  1646 ,  1673 ,  1701 ,  1729 ,  //130
  33. 1758    ,  1787 ,  1816 ,  1846 ,  1876 ,  1907 ,  1938 ,  1969 ,  2001 ,  2033 ,  //140
  34. 2066    ,  2099 ,  2133 ,  2167 ,  2202 ,  2237 ,  2273 ,  2309 ,  2346 ,  2383 ,  //150
  35. 2421    ,  2459 ,  2498 ,  2538 ,  2577 ,  2618 ,  2659 ,  2701 ,  2743 ,  2786 ,  //160
  36. 2829    ,  2873 ,  2918 ,  2963 ,  3009 ,  3056 ,  3103 ,  3151 ,  3200 ,  3249 ,  //170
  37. 3299    ,  3350 ,  3402 ,  3454 ,  3507 ,  3560 ,  3615 ,  3670 ,  3726 ,  3783 ,  //180
  38. 3840    ,  3899 ,  3958 ,  4018 ,  4079 ,  4141 ,  4203 ,  4267 ,  4331 ,  4397 ,  //190
  39. 4463    ,  4530 ,  4598 ,  4667 ,  4737 ,  4808 ,  4881 ,  4954 ,  5028 ,  5103 ,  //200
  40. 5179    ,  5257 ,  5335 ,  5415 ,  5495 ,  5577 ,  5660 ,  5744 ,  5830 ,  5916 ,  //210
  41. 6004    ,  6093 ,  6183 ,  6275 ,  6368 ,  6462 ,  6557 ,  6654 ,  6752 ,  6852 ,  //220
  42. 6953    ,  7055 ,  7159 ,  7265 ,  7371 ,  7480 ,  7590 ,  7701 ,  7814 ,  7929 ,  //230
  43. 8045    ,  8163 ,  8283 ,  8404 ,  8527 ,  8652 ,  8778 ,  8906 ,  9036 ,  9168 ,  //240
  44. 9302    ,  9438 ,  9575 ,  9715 ,  9856 ,  10000,  10000               //250
  45. };
  46.  
  47.  
  48. #if act_hwPWM_USEEEPROM==1
  49. #include "act_hwPWM_eeprom.h"
  50. struct eeprom_act_hwPWM EEMEM eeprom_act_hwPWM =
  51. {
  52.     {
  53.         ///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.
  54.         0x0000, // ch 1
  55.         0x0000, // ch 2
  56.         0x0000, // ch 3
  57.         0x0000  // ch 4
  58.     },
  59.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  60. };
  61. #endif
  62.  
  63. #if act_hwPWM_ENABLE_FADE == 1
  64. void act_hwPWM_timer_callback(uint8_t timer)
  65. {
  66.     uint8_t channel = 0;
  67.     for (channel = 0; channel < 4; channel++) {
  68.         /* Check demo states */
  69.         if (pwmValue[channel] == fadeTarget[channel]) {
  70.             switch (demoState[channel])
  71.             {
  72.             case ACT_HWPWM_DEMO_STATE_NOT_RUNNING:
  73.             break;
  74.             case ACT_HWPWM_DEMO_STATE_DECREASE:
  75.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_INCREASE;
  76.                 fadeTarget[channel] = demoHighValue[channel];
  77.                 fadeSpeed[channel] = -fadeSpeed[channel];
  78.             break;
  79.             case ACT_HWPWM_DEMO_STATE_INCREASE:
  80.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_GOBACK;
  81.                 fadeTarget[channel] = demoEndValue[channel];
  82.                 fadeSpeed[channel] = -fadeSpeed[channel];
  83.             break;
  84.             case ACT_HWPWM_DEMO_STATE_GOBACK:
  85.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  86.             break;
  87.             }
  88.         }
  89.        
  90.         /* Change the dimmerValue according to the current fading */
  91.         fadeSpeedCnt[channel]++;
  92.         if (fadeSpeedCnt[channel] == fadeSpeedFrac[channel] && pwmValue[channel] != (fadeTarget[channel]))
  93.         {
  94.             fadeSpeedCnt[channel] = 0;
  95.             uint16_t tempDimVal = pwmValue[channel];
  96.             pwmValue[channel] += (fadeSpeed[channel]*39);
  97.             if ((fadeSpeed[channel] > 0 && (pwmValue[channel] < tempDimVal || pwmValue[channel] >= (fadeTarget[channel]))) ||
  98.                 (fadeSpeed[channel] < 0 && (pwmValue[channel] > tempDimVal || pwmValue[channel] <= (fadeTarget[channel]))))
  99.             {
  100.                 pwmValue[channel] = (fadeTarget[channel]);
  101.             }
  102.             if (pwmValue[channel] > 10000) {
  103.                 pwmValue[channel] = 10000;
  104.             }
  105.             /* if targetvalue was reached then send the netinfo packet */
  106.             if (pwmValue[channel] == fadeTarget[channel])
  107.             {
  108.                 sendInfo[channel] = 1;
  109.             }
  110.         }
  111.     }
  112.  
  113. }
  114. #endif
  115.  
  116.  
  117. void act_hwPWM_Init(void)
  118. {
  119. #if act_hwPWM_USEEEPROM==1
  120.     if (EEDATA_OK)
  121.     {
  122.       ///TODO: Use stored data to set initial values for the module
  123.       pwmValue[0] = eeprom_read_word(EEDATA16.ch1);
  124.       pwmValue[1] = eeprom_read_word(EEDATA16.ch2);
  125.       pwmValue[2] = eeprom_read_word(EEDATA16.ch3);
  126.       pwmValue[3] = eeprom_read_word(EEDATA16.ch4);
  127.     } else
  128.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  129.       eeprom_write_word_crc(EEDATA16.ch1, 0x0000, WITHOUT_CRC);
  130.       eeprom_write_word_crc(EEDATA16.ch2, 0x0000, WITHOUT_CRC);
  131.       eeprom_write_word_crc(EEDATA16.ch3, 0x0000, WITHOUT_CRC);
  132.       eeprom_write_word_crc(EEDATA16.ch4, 0x0000, WITHOUT_CRC);
  133.       EEDATA_UPDATE_CRC;
  134.     }
  135. #endif
  136.     TCCR1A = 0;
  137.     TCCR1B = 0;
  138.     TCCR0A = 0;
  139.     TCCR0B = 0;
  140.  
  141.     /* set up pwm values */
  142.     cli();
  143.     #if act_hwPWM_CH1_COM>0
  144.     OCR_1=(uint16_t)(pwmValue[0]*act_hwPWM_CH1_FACT)>>8;
  145.     #endif
  146.     #if act_hwPWM_CH2_COM>0
  147.     OCR_2=(uint16_t)(pwmValue[1]*act_hwPWM_CH2_FACT)>>8;
  148.     #endif
  149.     #if act_hwPWM_CH3_COM>0
  150.     OCR_3=(uint16_t)(pwmValue[2]*act_hwPWM_CH3_FACT)>>8;
  151.     #endif
  152.     #if act_hwPWM_CH4_COM>0
  153.     OCR_4=(uint16_t)(pwmValue[3]*act_hwPWM_CH4_FACT)>>8;
  154.     #endif
  155.     sei();
  156.  
  157.     /* set up waveform generation mode for timer 1 */
  158.     #if act_hwPWM_CH1_COM>0
  159.     TCCR1A=((act_hwPWM_CH1_WGM&0x03)<<WGM00);
  160.     TCCR1B=(((act_hwPWM_CH1_WGM>>2)&0x03)<<WGM12);
  161.     #elif act_hwPWM_CH2_COM>0
  162.     TCCR1A=((act_hwPWM_CH2_WGM&0x03)<<WGM00);
  163.     TCCR1B=(((act_hwPWM_CH2_WGM>>2)&0x03)<<WGM12);
  164.     #endif
  165.  
  166.     /* enable outputs for timer 1 */
  167.     #if act_hwPWM_CH1_COM>0
  168.     gpio_set_out(EXP_B);
  169.     #endif
  170.     #if act_hwPWM_CH2_COM>0
  171.     gpio_set_out(EXP_C);
  172.     #endif
  173.  
  174.     /* set up counter mode for timer 1 */
  175.     #if act_hwPWM_CH1_COM>0 || act_hwPWM_CH2_COM>0
  176.     if (pwmValue[0]>0)
  177.     {
  178.         TCCR1A|=(act_hwPWM_CH1_COM<<COM1B0);
  179.     }
  180.     if (pwmValue[1]>0)
  181.     {
  182.         TCCR1A|=(act_hwPWM_CH2_COM<<COM1A0);
  183.     }
  184.     ICR1 = 0xffff;
  185.     #endif
  186.  
  187.     /* enable timer 1 */
  188.     #if act_hwPWM_CH1_COM>0
  189.     TCCR1B|=(act_hwPWM_CH1_CS<<CS10);
  190.     #elif act_hwPWM_CH2_COM>0
  191.     TCCR1B|=(act_hwPWM_CH2_CS<<CS10);
  192.     #endif
  193.  
  194.  
  195.     /* set up waveform generation mode for timer 0 */
  196.     #if act_hwPWM_CH3_COM>0
  197.     TCCR0A=((act_hwPWM_CH3_WGM&0x03)<<WGM00);
  198.     TCCR0B=(((act_hwPWM_CH3_WGM>>2)&0x01)<<WGM02);
  199.     #elif act_hwPWM_CH4_COM>0
  200.     TCCR0A=((act_hwPWM_CH4_WGM&0x03)<<WGM00);
  201.     TCCR0B=(((act_hwPWM_CH4_WGM>>2)&0x01)<<WGM02);
  202.     #endif
  203.  
  204.     /* enable outputs for timer 0 */
  205.     #if act_hwPWM_CH3_COM>0
  206.     gpio_set_out(EXP_F);
  207.     #endif
  208.     #if act_hwPWM_CH4_COM>0
  209.     gpio_set_out(EXP_G);
  210.     #endif
  211.  
  212.     /* set up counter mode for timer 0 */
  213.     #if act_hwPWM_CH3_COM>0 || act_hwPWM_CH4_COM>0
  214.     if (pwmValue[2]>0)
  215.     {
  216.         TCCR0A|=(act_hwPWM_CH3_COM<<COM0A0);
  217.     }
  218.     if (pwmValue[3]>0)
  219.     {
  220.         TCCR0A|=(act_hwPWM_CH4_COM<<COM0B0);
  221.     }
  222.     #endif
  223.  
  224.     /* enable timer 0 */
  225.     #if act_hwPWM_CH3_COM>0
  226.     TCCR0B|=(act_hwPWM_CH3_CS<<CS00);
  227.     #elif act_hwPWM_CH4_COM>0
  228.     TCCR0B|=(act_hwPWM_CH4_CS<<CS00);
  229.     #endif
  230.     //printf("1A %x, 1B %x, 0A %x, 0B %x\n", TCCR1A, TCCR1B, TCCR0A, TCCR0B);
  231.    
  232. #if act_hwPWM_ENABLE_FADE == 1
  233.     Timer_SetTimeout(act_hwPWM_FADE_TIMER, 10, TimerTypeFreeRunning, &act_hwPWM_timer_callback);
  234. #endif
  235.    
  236.     /* Setup timeout for sending the status packet */
  237.     Timer_SetTimeout(act_hwPWM_SEND_STATUS_TIMEOUT, act_hwPWM_SEND_STATUS_INTERVAL_S*1000, TimerTypeFreeRunning, 0);
  238.     //printf("Hello world!\n");
  239. }
  240. uint8_t channel_to_send = 1;
  241. void act_hwPWM_Process(void)
  242. {
  243.     if (Timer_Expired(act_hwPWM_SEND_STATUS_TIMEOUT))
  244.     {
  245.         if (channel_to_send >4) {
  246.           #if act_hwPWM_CH1_COM==0
  247.           channel_to_send = 2;
  248.               #if act_hwPWM_CH2_COM==0
  249.               channel_to_send = 3;
  250.               #if act_hwPWM_CH3_COM==0
  251.                   channel_to_send = 4;
  252.               #else
  253.                   channel_to_send=3;
  254.                 #endif 
  255.               #else
  256.                   channel_to_send=2;
  257.             #endif     
  258.              
  259.           #else
  260.             channel_to_send=1;
  261.           #endif       
  262.        
  263.         }
  264.         sendInfo[channel_to_send-1] = 1;
  265.         channel_to_send++;
  266. #if act_hwPWM_CH1_COM==0
  267.           if (channel_to_send == 1)
  268.             channel_to_send++;
  269. #endif     
  270. #if act_hwPWM_CH2_COM==0
  271.           if (channel_to_send == 2)
  272.             channel_to_send++;
  273. #endif 
  274. #if act_hwPWM_CH3_COM==0
  275.           if (channel_to_send == 3)
  276.             channel_to_send++;
  277. #endif 
  278. #if act_hwPWM_CH4_COM==0
  279.           if (channel_to_send == 4)
  280.             channel_to_send++;
  281. #endif 
  282.        
  283.        
  284.     }
  285.     /* Send netinfo packet (if pwmvalue has changed, and periodically) */
  286.     uint8_t index;
  287.     for(index =0;index < 4; index++){
  288.         if (pwmValue[index] > ACT_HWPWM_MAX_DIM) {
  289.             pwmValue[index] = ACT_HWPWM_MAX_DIM;
  290.         }
  291.         if (sendInfo[index])
  292.         {
  293.             sendInfo[index] = 0;
  294.             StdCan_Msg_t txMsg;
  295.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  296.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  297.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_HWPWM;
  298.             txMsg.Header.ModuleId = act_hwPWM_ID;
  299.             txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PWM;
  300.             txMsg.Length = 3;
  301.             txMsg.Data[0] = index;
  302.             txMsg.Data[1] = (0xff&(pwmValue[index]>>8));
  303.             txMsg.Data[2] = (0xff&(pwmValue[index]));
  304.             StdCan_Put(&txMsg);
  305.            
  306.             //printf("CH1 PWM: %u, LED: %u, ledindex: %u, ocr: %u\n",pwmValue[1],(uint16_t)(pgm_read_word(&lookuptable[(pwmValue[1]/39)])), (pwmValue[1]/39),OCR_2);
  307.         }
  308.     }
  309.    
  310.     if (Timer_Expired(act_hwPWM_STORE_VALUE_TIMEOUT))
  311.     {
  312.         if (pwmValue[0] != eeprom_read_word(EEDATA16.ch1))
  313.         {
  314.             eeprom_write_word_crc(EEDATA16.ch1, pwmValue[0], WITH_CRC);
  315.         }
  316.         if (pwmValue[1] != eeprom_read_word(EEDATA16.ch2))
  317.         {
  318.             eeprom_write_word_crc(EEDATA16.ch2, pwmValue[1], WITH_CRC);
  319.         }
  320.         if (pwmValue[2] != eeprom_read_word(EEDATA16.ch3))
  321.         {
  322.             eeprom_write_word_crc(EEDATA16.ch3, pwmValue[2], WITH_CRC);
  323.         }
  324.         if (pwmValue[3] != eeprom_read_word(EEDATA16.ch4))
  325.         {
  326.             eeprom_write_word_crc(EEDATA16.ch4, pwmValue[3], WITH_CRC);
  327.         }
  328.     }
  329.                    
  330. #if act_hwPWM_CH1_COM>0
  331. # if act_hwPWM_CH1_LED>0
  332. #  define CH1_calculation ((pgm_read_word(&lookuptable[(pwmValue[0]/39)])*act_hwPWM_CH1_FACT)>>8)
  333. # else
  334. #  define CH1_calculation ((pwmValue[0]*act_hwPWM_CH1_FACT)>>8)
  335. # endif
  336.     if (OCR_1 != (uint16_t)CH1_calculation) {
  337.         cli(); 
  338.         OCR_1=(uint16_t)CH1_calculation;
  339.         if (OCR_1==0)
  340.         {
  341.             TCCR1A&=~((1<<COM1B0)|(1<<COM1B1));
  342.         }
  343.         else
  344.         {
  345.             TCCR1A|=(act_hwPWM_CH1_COM<<COM1B0);
  346.         }
  347.         sei();
  348.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  349.         //printf("CH0 PWM: %u, LED: %u, ORG: %u\n",pwmValue[0],(uint16_t)((lookuptable[(pwmValue[0]/39)-1]*act_hwPWM_CH1_FACT)>>8), (uint16_t)((pwmValue[0]*act_hwPWM_CH1_FACT)>>8));
  350.     }
  351. #endif
  352. #if act_hwPWM_CH2_COM>0
  353. # if act_hwPWM_CH2_LED>0
  354. #  define CH2_calculation ((pgm_read_word(&lookuptable[(pwmValue[1]/39)])*act_hwPWM_CH2_FACT)>>8)
  355. # else
  356. #  define CH2_calculation ((pwmValue[1]*act_hwPWM_CH2_FACT)>>8)
  357. # endif
  358.     if (OCR_2 != (uint16_t)CH2_calculation) {
  359.         cli(); 
  360.         OCR_2=(uint16_t)CH2_calculation;
  361.         if (OCR_2==0)
  362.         {
  363.             TCCR1A&=~((1<<COM1A0)|(1<<COM1A1));
  364.         }
  365.         else
  366.         {
  367.             TCCR1A|=(act_hwPWM_CH2_COM<<COM1A0);
  368.         }
  369.         sei();
  370.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  371.         //printf("CH1 PWM: %u, LED: %u, ORG: %u, ocr: %u\n",pwmValue[1],(uint16_t)((lookuptable[(pwmValue[1]/39)-1]*act_hwPWM_CH2_FACT)>>8), (uint16_t)((pwmValue[1]*act_hwPWM_CH2_FACT)>>8),OCR_2);
  372.     }
  373. #endif
  374. #if act_hwPWM_CH3_COM>0
  375. # if act_hwPWM_CH3_LED>0
  376. #  define CH3_calculation ((pgm_read_word(&lookuptable[(pwmValue[2]/39)])*act_hwPWM_CH3_FACT)>>8)
  377. # else
  378. #  define CH3_calculation ((pwmValue[2]*act_hwPWM_CH3_FACT)>>8)
  379. # endif
  380.     if (OCR_3 != (uint16_t)CH3_calculation) {
  381.         cli(); 
  382.         OCR_3=(uint16_t)CH3_calculation;
  383.         if (OCR_3==0)
  384.         {
  385.             TCCR0A &= ~((1<<COM0A0)|(1<<COM0A1));
  386.         }
  387.         else
  388.         {
  389.             TCCR0A|=(act_hwPWM_CH3_COM<<COM0A0);
  390.         }
  391.         sei();
  392.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  393.         //printf("CH2 PWM: %u, LED: %u, ORG: %u\n",pwmValue[2],(uint16_t)((lookuptable[(pwmValue[2]/39)-1]*act_hwPWM_CH3_FACT)>>8), (uint16_t)((pwmValue[2]*act_hwPWM_CH3_FACT)>>8));
  394.     }
  395. #endif
  396. #if act_hwPWM_CH4_COM>0
  397. # if act_hwPWM_CH4_LED>0
  398. #  define CH4_calculation ((pgm_read_word(&lookuptable[(pwmValue[3]/39)])*act_hwPWM_CH4_FACT)>>8)
  399. # else
  400. #  define CH4_calculation ((pwmValue[3]*act_hwPWM_CH4_FACT)>>8)
  401. # endif
  402.     if (OCR_4 != (uint16_t)CH4_calculation) {
  403.         cli(); 
  404.         OCR_4=(uint16_t)CH4_calculation;
  405.         if (OCR_4==0)
  406.         {
  407.             TCCR0A &= ~((1<<COM0B0)|(1<<COM0B1));
  408.         }
  409.         else
  410.         {
  411.             TCCR0A|=(act_hwPWM_CH4_COM<<COM0B0);
  412.         }
  413.         sei();
  414.         Timer_SetTimeout(act_hwPWM_STORE_VALUE_TIMEOUT, act_hwPWM_STORE_VALUE_TIMEOUT_TIME*1000, TimerTypeOneShot, 0);
  415.         //printf("CH3 PWM: %u, LED: %u, ORG: %u\n",pwmValue[3],(uint16_t)((lookuptable[(pwmValue[3]/39)-1]*act_hwPWM_CH4_FACT)>>8), (uint16_t)((pwmValue[3]*act_hwPWM_CH4_FACT)>>8));
  416.     }
  417. #endif
  418. }
  419.  
  420. void act_hwPWM_HandleMessage(StdCan_Msg_t *rxMsg)
  421. {
  422.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  423.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  424.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_HWPWM &&
  425.         rxMsg->Header.ModuleId == act_hwPWM_ID)
  426.     {
  427.         uint8_t channel = 0;
  428.         switch (rxMsg->Header.Command)
  429.         {
  430.         case CAN_MODULE_CMD_PHYSICAL_PWM:
  431.             if (rxMsg->Length == 3) {
  432.                 channel = rxMsg->Data[0];
  433.                 pwmValue[channel] = (rxMsg->Data[1]<<8)+(rxMsg->Data[2]);
  434.             }
  435.            
  436.         break;
  437. #if act_hwPWM_ENABLE_FADE == 1
  438.         case CAN_MODULE_CMD_HWPWM_DEMO:     /* Demo(channel, speed, steps) */
  439.             if (rxMsg->Length == 4) {
  440.                 channel = rxMsg->Data[0];
  441.                 uint8_t speed = rxMsg->Data[1];
  442.                 uint16_t steps = (rxMsg->Data[2]<<8)+(rxMsg->Data[3]);
  443.                
  444.                 fadeSpeedCnt[channel] = 0;
  445.                 fadeSpeed[channel] = 0;
  446.                 if (speed == 0) {
  447.                     /* do nothing */
  448.                 } else {
  449.                     uint16_t diffToMin = pwmValue[channel] - ACT_HWPWM_MIN_DIM;
  450.                     uint16_t diffToMax = ACT_HWPWM_MAX_DIM - pwmValue[channel];
  451.                
  452.                     demoEndValue[channel] = pwmValue[channel];
  453.                     if (diffToMin >= steps && diffToMax >= steps)
  454.                     {
  455.                         /* not close to min or max */
  456.                         fadeTarget[channel] = pwmValue[channel] - steps;
  457.                         demoHighValue[channel] = pwmValue[channel] + steps;
  458.                     }
  459.                     else if (diffToMin >= steps)
  460.                     {
  461.                         /* close to max */
  462.                         fadeTarget[channel] = pwmValue[channel] - steps - steps + diffToMax;
  463.                         demoHighValue[channel] = ACT_HWPWM_MAX_DIM;
  464.                     }
  465.                     else if (diffToMax >= steps)
  466.                     {
  467.                         /* close to min */
  468.                         fadeTarget[channel] = ACT_HWPWM_MIN_DIM;
  469.                         demoHighValue[channel] = pwmValue[channel] + steps + steps - diffToMin;
  470.                     }
  471.                     demoState[channel] = ACT_HWPWM_DEMO_STATE_DECREASE;
  472.                
  473.                     if ((speed&0x80) == 0x80) {
  474.                         fadeSpeed[channel] = (speed&0x7f)+1;
  475.                         fadeSpeedFrac[channel] = 1;
  476.                     } else {
  477.                         fadeSpeed[channel] = 1;
  478.                         fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  479.                     }
  480.                     if (fadeTarget[channel] <= pwmValue[channel]) {
  481.                         fadeSpeed[channel] = -fadeSpeed[channel];
  482.                     }
  483.                 }
  484.             }
  485.         break;
  486.        
  487.         case CAN_MODULE_CMD_HWPWM_START_FADE:   /* StartFade(channel, speed, direction) */
  488.             if (rxMsg->Length == 3) {
  489.                
  490.                 channel = rxMsg->Data[0];
  491.                 uint8_t speed = rxMsg->Data[1];
  492.                 uint8_t direction = rxMsg->Data[2];
  493.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  494.                 fadeSpeedCnt[channel] = 0;
  495.                 fadeSpeed[channel] = 0;
  496.                 uint16_t endValue = 0;
  497.                 if (direction == CAN_MODULE_ENUM_HWPWM_START_FADE_DIRECTION_INCREASE) {
  498.                     endValue = ACT_HWPWM_MAX_DIM;
  499.                 } else if (direction == CAN_MODULE_ENUM_HWPWM_START_FADE_DIRECTION_DECREASE) {
  500.                     endValue = ACT_HWPWM_MIN_DIM;
  501.                 }
  502.                    
  503.                 if (speed == 0) {
  504.                     pwmValue[channel] = endValue;   /* set dimmer value immediately */
  505.                     sendInfo[channel] = 1;      /* send netinfo with the current dimmervalue*/
  506.                 } else {
  507.                     fadeTarget[channel] = endValue;
  508.                     if (fadeTarget[channel] != pwmValue[channel]) {
  509.                         if ((speed&0x80) == 0x80) {
  510.                             fadeSpeed[channel] = (speed&0x7f)+1;
  511.                             fadeSpeedFrac[channel] = 1;
  512.                         } else {
  513.                             fadeSpeed[channel] = 1;
  514.                             fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  515.                         }
  516.                         if (fadeTarget[channel] < pwmValue[channel]) {
  517.                             fadeSpeed[channel] = -fadeSpeed[channel];
  518.                         }
  519.                     }
  520.                 }
  521.             }
  522.         break;
  523.  
  524.         case CAN_MODULE_CMD_HWPWM_STOP_FADE:    /* StopFade(channel) */
  525.             if (rxMsg->Length == 1) {
  526.                 channel = rxMsg->Data[0];
  527.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  528.                 fadeSpeed[channel] = 0;
  529.                 sendInfo[channel] = 1;      /* send netinfo with the current dimmervalue*/
  530.             }
  531.         break;
  532.  
  533.         case CAN_MODULE_CMD_HWPWM_ABS_FADE: /* AbsFade(channel, speed, endValue) */
  534.             if (rxMsg->Length == 4) {
  535.                 channel = rxMsg->Data[0];
  536.                 uint8_t speed = rxMsg->Data[1];
  537.                 uint16_t endValue = (rxMsg->Data[2]<<8)+(rxMsg->Data[3]);
  538.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  539.                 fadeSpeedCnt[channel] = 0;
  540.                 fadeSpeed[channel] = 0;
  541.                 if (speed == 0) {
  542.                     pwmValue[channel] = endValue;   /* set dimmer value immediately */
  543.                     sendInfo[channel] = 1;      /* send netinfo with the current dimmervalue*/
  544.                 } else {
  545.                     fadeTarget[channel] = endValue;
  546.                     if (fadeTarget[channel] != pwmValue[channel]) {
  547.                         if ((speed&0x80) == 0x80) {
  548.                             fadeSpeed[channel] = (speed&0x7f)+1;
  549.                             fadeSpeedFrac[channel] = 1;
  550.                         } else {
  551.                             fadeSpeed[channel] = 1;
  552.                             fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  553.                         }
  554.                         if (fadeTarget[channel] < pwmValue[channel]) {
  555.                             fadeSpeed[channel] = -fadeSpeed[channel];
  556.                         }
  557.                     }
  558.                 }
  559.                 //printf("abs fade %d %d %d!\n",fadeTarget[channel], endValue ,pwmValue[channel] );
  560.             }
  561.         break;
  562.  
  563.         case CAN_MODULE_CMD_HWPWM_REL_FADE: /* RelFade(channel, speed, direction, steps) */
  564.             if (rxMsg->Length == 5) {
  565.                
  566.                 channel = rxMsg->Data[0];
  567.                 uint8_t speed = rxMsg->Data[1];
  568.                 uint8_t direction = rxMsg->Data[2];
  569.                 uint16_t steps = (rxMsg->Data[3]<<8)+(rxMsg->Data[4]);
  570.                
  571.                 demoState[channel] = ACT_HWPWM_DEMO_STATE_NOT_RUNNING;
  572.                 fadeSpeedCnt[channel] = 0;
  573.                 fadeSpeed[channel] = 0;
  574.                 uint16_t tempDimVal = pwmValue[channel];
  575.                 uint16_t tempDimVal2 = pwmValue[channel];
  576.                 if (direction == CAN_MODULE_ENUM_HWPWM_REL_FADE_DIRECTION_INCREASE) {                   /* if increase */
  577.                     tempDimVal2 += steps;               /* calculate new value */
  578.                     if (tempDimVal2 < tempDimVal) {     /* make overflow test */
  579.                         tempDimVal2 = ACT_HWPWM_MAX_DIM;
  580.                     }
  581.                 } else if (direction == CAN_MODULE_ENUM_HWPWM_REL_FADE_DIRECTION_DECREASE) {            /* if decrease */
  582.                     tempDimVal2 -= steps;
  583.                     if (tempDimVal2 > tempDimVal) {
  584.                         tempDimVal2 = ACT_HWPWM_MIN_DIM;
  585.                     }
  586.                 }
  587.                 if (speed == 0) {
  588.                     pwmValue[channel] = tempDimVal2;        /* set dimmer value immediately */
  589.                     sendInfo[channel] = 1;              /* send netinfo with the current dimmervalue*/
  590.                 } else {
  591.                     fadeTarget[channel] = tempDimVal2;      /* set the fade target */
  592.                    
  593.                     if (fadeTarget[channel] != pwmValue[channel]) {
  594.                         if ((speed&0x80) == 0x80) {
  595.                             fadeSpeed[channel] = (speed&0x7f)+1;
  596.                             fadeSpeedFrac[channel] = 1;
  597.                         } else {
  598.                             fadeSpeed[channel] = 1;
  599.                             fadeSpeedFrac[channel] = 0x80-(speed&0x7f);
  600.                         }
  601.                         if (fadeTarget[channel] < pwmValue[channel]) {
  602.                             fadeSpeed[channel] = -fadeSpeed[channel];
  603.                         }
  604.                     }
  605.                 }
  606.             }
  607.         break;
  608. #endif
  609.  
  610.         }
  611.     }
  612. }
  613.  
  614. void act_hwPWM_List(uint8_t ModuleSequenceNumber)
  615. {
  616.     StdCan_Msg_t txMsg;
  617.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  618.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  619.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_HWPWM;
  620.     txMsg.Header.ModuleId = act_hwPWM_ID;
  621.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  622.     txMsg.Length = 6;
  623.  
  624.     uint32_t HwId=BIOS_GetHwId();
  625.     txMsg.Data[0] = HwId&0xff;
  626.     txMsg.Data[1] = (HwId>>8)&0xff;
  627.     txMsg.Data[2] = (HwId>>16)&0xff;
  628.     txMsg.Data[3] = (HwId>>24)&0xff;
  629.    
  630.     txMsg.Data[4] = NUMBER_OF_MODULES;
  631.     txMsg.Data[5] = ModuleSequenceNumber;
  632.  
  633.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  634. }
  635.