Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_dimmer230.h"
  3.  
  4. //#define USEDEMO
  5.  
  6. int8_t fadeSpeedCh1 = 0;
  7. uint8_t fadeSpeedFracCh1 = 0;
  8. uint8_t fadeTargetCh1 = 0;
  9. uint8_t fadeSpeedCntCh1 = 0;
  10.  
  11. #ifdef USEDEMO
  12. uint8_t demo = 0;
  13. //uint8_t demo = 2; //demo one way
  14. //uint8_t demo = 3; //disable demo
  15. uint8_t democnt = 0;
  16. #define DEMOSTEPS 2
  17. #define DEMOSTEPS2 1
  18. #endif
  19.  
  20. //#define MEASURE_PERIOD
  21. #ifdef MEASURE_PERIOD
  22. uint16_t periodTime = 0;
  23.             //measured during init (by taking the time difference between two zero cross)
  24.             //not used, bad idea, the powerStepTable below asumes 10000
  25. #endif
  26. uint16_t xcTimeDiff=0;
  27.             //zero cross sync (time between pos flank of xc-detection and real zero cross)
  28. uint8_t dimmerValueCh1 = 0;
  29.             //store in eeprom later
  30.             //value of 0 is zero output, value of 255 is max output (ACT_DIMMMER230_MIN_DIM, ACT_DIMMMER230_MAX_DIM)
  31. uint8_t state = ACT_DIMMMER230_STATE_IDLE;
  32. 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};
  33.  
  34. #if act_dimmer230_SYNC>0
  35. uint8_t zeroCrossCnt = 0;
  36. #endif
  37.  
  38. ISR (TIMER1_COMPA_vect)
  39. {
  40.     //testa hur lång denna loop behöver vara
  41.     //verkar fungera upp till 249-250 sen blir det för korta pulser
  42.     act_dimmer230_CHAN1_PORT |= _BV(act_dimmer230_CHAN1_BIT);
  43.     uint8_t dummycnt = 240;
  44.     while (dummycnt > 0)
  45.     {
  46.         dummycnt++;
  47.         asm("nop");
  48.     }
  49.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);         
  50.    
  51.     TIMSK1=0;                           //disable timer interrupt
  52.     state = ACT_DIMMMER230_STATE_IDLE;
  53. }
  54.  
  55. ISR (act_dimmer230_ZC_PCINT_vect)
  56. {
  57.     //only execute if zerocross pin is low
  58.     if (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)))
  59.     {
  60.         uint16_t newTimerVal = xcTimeDiff;
  61.  
  62.         //here new timer value is calculated
  63.  
  64.         if (dimmerValueCh1 > 0 && dimmerValueCh1 <= 127)
  65.         {
  66.             newTimerVal += ACT_DIMMMER230_PERIOD_TIME - pgm_read_word(&powerStepTable[dimmerValueCh1-1]);
  67.         }
  68.         else if (dimmerValueCh1 < 255)
  69.         {
  70.             newTimerVal += pgm_read_word(&powerStepTable[254-dimmerValueCh1]);
  71.         }
  72.         else if (dimmerValueCh1 == 255)
  73.         {
  74.             newTimerVal += 100; //almost max, to make sure we don't fire before zerocross
  75.         }
  76.        
  77.         if (newTimerVal > ACT_DIMMMER230_PERIOD_TIME)
  78.         {
  79.             newTimerVal -= ACT_DIMMMER230_PERIOD_TIME;
  80.         }
  81.  
  82.         if (dimmerValueCh1 > 0)
  83.         {
  84.             TCNT1 = 0;              //reset timer1 count register
  85.             OCR1A = newTimerVal;
  86.  
  87.             //enable timer and timer interrupt
  88.             TIFR1=(1<<OCF1A);       //clear interrupt flag before enabling interrupt
  89.             TIMSK1|=(1<<OCIE1A);
  90.  
  91.             state = ACT_DIMMMER230_STATE_TIMER_ON;
  92.         }
  93.        
  94.         fadeSpeedCntCh1++;
  95.         if (fadeSpeedCntCh1 == fadeSpeedFracCh1)
  96.         {
  97.             fadeSpeedCntCh1 = 0;
  98.             uint8_t tempDimVal = dimmerValueCh1;
  99.             dimmerValueCh1 += fadeSpeedCh1;
  100.             if ((fadeSpeedCh1 > 0 && (dimmerValueCh1 < tempDimVal || dimmerValueCh1 >= fadeTargetCh1)) ||
  101.                 (fadeSpeedCh1 < 0 && (dimmerValueCh1 > tempDimVal || dimmerValueCh1 <= fadeTargetCh1)))
  102.             {
  103.                 dimmerValueCh1 = fadeTargetCh1;
  104.                 fadeSpeedCh1 = 0;
  105.             }
  106.         }
  107.        
  108.        
  109. #if act_dimmer230_SYNC>0
  110.         zeroCrossCnt++;
  111.         if (zeroCrossCnt >= act_dimmer230_SYNC)
  112.         {
  113.             zeroCrossCnt = 0;
  114.             //TODO: send sync-message on can
  115.  
  116.             StdCan_Msg_t txMsg;
  117.             txMsg.Length = 6;
  118.             txMsg.Data[0] = (newTimerVal>>8)&0xff;
  119.             txMsg.Data[1] = newTimerVal&0xff;
  120.             //txMsg.Data[2] = (periodTime>>8)&0xff;
  121.             //txMsg.Data[3] = periodTime&0xff;
  122.             txMsg.Data[4] = (xcTimeDiff>>8)&0xff;
  123.             txMsg.Data[5] = xcTimeDiff&0xff;
  124.             //StdCan_Put(&txMsg);
  125.  
  126. #ifdef USEDEMO
  127.             if (demo == 0 || demo == 2) {
  128.                 democnt++;
  129.                 if (democnt==DEMOSTEPS)
  130.                 {
  131.                     democnt = 0;
  132.                     uint8_t tempDim=dimmerValueCh1;
  133.                     dimmerValueCh1+=DEMOSTEPS2;
  134.                     if (dimmerValueCh1<tempDim && demo == 0) {
  135.                         dimmerValueCh1=ACT_DIMMMER230_MAX_DIM;
  136.                     }
  137.                 }
  138.                 if (dimmerValueCh1 == ACT_DIMMMER230_MAX_DIM && demo == 0) {
  139.                     demo = 1;
  140.                 }
  141.             } else if (demo == 1) {
  142.                 democnt++;
  143.                 if (democnt==DEMOSTEPS)
  144.                 {
  145.                     democnt = 0;
  146.                     uint8_t tempDim=dimmerValueCh1;
  147.                     dimmerValueCh1-=DEMOSTEPS2;
  148.                     if (dimmerValueCh1>tempDim) {
  149.                         dimmerValueCh1=ACT_DIMMMER230_MIN_DIM;
  150.                     }
  151.                 }
  152.                 if (dimmerValueCh1 == ACT_DIMMMER230_MIN_DIM) {
  153.                     demo = 0;
  154.                 }
  155.             }
  156. #endif //USEDEMO
  157.         }
  158. #endif     
  159.     }
  160. }
  161.  
  162. void act_dimmer230_Init(void)
  163. {
  164.     // set dimmer channel1 port to output 0
  165.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);
  166.     act_dimmer230_CHAN1_DDR |= _BV(act_dimmer230_CHAN1_BIT);
  167.     // set zero cross detection port to input, no pullup
  168.     act_dimmer230_ZC_PORT &= ~_BV(act_dimmer230_ZC_BIT);
  169.     act_dimmer230_ZC_DDR &= ~_BV(act_dimmer230_ZC_BIT);
  170.    
  171.     TIMSK1=0;                           //disable timer interrupt
  172.     TCCR1A=0;
  173.    
  174.     //wait for high (ac leaving zero cross)
  175.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  176.     TCCR1B=(1<<CS11);                   //enable timer, set to prescaler 8, must be changed if cpu freq is changed
  177.     //wait for low (ac approaching zero cross)
  178.     while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  179.     uint16_t timeAtFall = TCNT1;    //Timer_GetTicks();
  180.     //wait for high (ac leaving zero cross)
  181.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  182.     uint16_t timeAtRise = TCNT1;    //Timer_GetTicks();
  183.  
  184. #ifdef MEASURE_PERIOD
  185.     //wait for low (ac approaching zero cross)
  186.     while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  187.     //wait for high (ac leaving zero cross)
  188.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  189.     uint16_t timeAtRise2 = TCNT1;   //Timer_GetTicks();
  190.     if (timeAtRise < timeAtRise2) {
  191.         periodTime = timeAtRise2 - timeAtRise;
  192.     }
  193. #endif
  194.  
  195.     // warning, watch out for wrap around on timestamps (something is broken if wrapped)
  196.     if (timeAtFall < timeAtRise) {
  197.         //calculate time from falling edge to ac zero cross value
  198.         xcTimeDiff = timeAtRise-timeAtFall;
  199.         xcTimeDiff = xcTimeDiff >> 1; //divide by two
  200.     }
  201.  
  202.     //setup interrupt on zerocross, pcint
  203.     PCMSK0=(1<<act_dimmer230_ZC_PCINT_BIT);
  204.     PCIFR=(1<<act_dimmer230_ZC_PCIF);   //clear any pending interrupt before enabling interrupts
  205.     PCICR=(1<<act_dimmer230_ZC_PCIE);   //enable interrupt for PCINT
  206. }
  207.  
  208. void act_dimmer230_Process(void)
  209. {
  210.     ///TODO: Stuff that needs doing is done here
  211. }
  212.  
  213. void act_dimmer230_HandleMessage(StdCan_Msg_t *rxMsg)
  214. {
  215.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_CLASS_MODULE_ACT &&
  216.         StdCan_Ret_direction(rxMsg->Header) == DIR_TO_OWNER &&
  217.         rxMsg->Header.ModuleType == CAN_TYPE_MODULE_act_Dimmer230 &&
  218.         rxMsg->Header.ModuleId == act_dimmer230_ID)
  219.     {
  220.         switch (rxMsg->Header.Command)
  221.         {
  222.         case CAN_CMD_MODULE_DIMMER_DEMO:        // Demo(channel, speed, steps)
  223.             if (rxMsg->Length == 3) {
  224.                
  225.             }
  226.         break;
  227.        
  228.         case CAN_CMD_MODULE_DIMMER_START_FADE:  // StartFade(channel, speed, direction), just an alias of ABS_FADE
  229.             if (rxMsg->Length == 3) {
  230.                 uint8_t channel = rxMsg->Data[0];
  231.                 uint8_t speed = rxMsg->Data[1];
  232.                 uint8_t direction = rxMsg->Data[2];
  233.                
  234.                 uint8_t endValue = 0;
  235.                 if (direction == 1) {
  236.                     endValue = ACT_DIMMMER230_MAX_DIM;
  237.                 } else if (direction == 0) {
  238.                     endValue = ACT_DIMMMER230_MIN_DIM;
  239.                 }
  240.                    
  241.                 if (speed == 0) {
  242.                     dimmerValueCh1 = endValue;  //set dimmer value immediately
  243.                 } else {
  244.                     fadeTargetCh1 = endValue;
  245.                     if (fadeTargetCh1 != dimmerValueCh1) {
  246.                         if ((speed&0x80) == 0) {
  247.                             fadeSpeedCh1 = speed&0x7f;
  248.                             fadeSpeedFracCh1 = 1;
  249.                         } else {
  250.                             fadeSpeedCh1 = 1;
  251.                             fadeSpeedFracCh1 = speed&0x7f;
  252.                         }
  253.                         if (fadeTargetCh1 < dimmerValueCh1) {
  254.                             fadeSpeedCh1 = -fadeSpeedCh1;
  255.                         }
  256.                     }
  257.                 }
  258.             }
  259.         break;
  260.  
  261.         case CAN_CMD_MODULE_DIMMER_STOP_FADE:   // StopFade(channel)
  262.             if (rxMsg->Length == 1) {
  263.                 fadeSpeedCh1 = 0;
  264.             }
  265.         break;
  266.  
  267.         case CAN_CMD_MODULE_DIMMER_ABS_FADE:    // AbsFade(channel, speed, endValue)
  268.             if (rxMsg->Length == 3) {
  269.                 uint8_t channel = rxMsg->Data[0];
  270.                 uint8_t speed = rxMsg->Data[1];
  271.                 uint8_t endValue = rxMsg->Data[2];
  272.                 if (speed == 0) {
  273.                     dimmerValueCh1 = endValue;  //set dimmer value immediately
  274.                 } else {
  275.                     fadeTargetCh1 = endValue;
  276.                     if (fadeTargetCh1 != dimmerValueCh1) {
  277.                         if ((speed&0x80) == 0) {
  278.                             fadeSpeedCh1 = speed&0x7f;
  279.                             fadeSpeedFracCh1 = 1;
  280.                         } else {
  281.                             fadeSpeedCh1 = 1;
  282.                             fadeSpeedFracCh1 = speed&0x7f;
  283.                         }
  284.                         if (fadeTargetCh1 < dimmerValueCh1) {
  285.                             fadeSpeedCh1 = -fadeSpeedCh1;
  286.                         }
  287.                     }
  288.                 }
  289.             }
  290.         break;
  291.  
  292.         case CAN_CMD_MODULE_DIMMER_REL_FADE:    // RelFade(channel, speed, direction, steps)
  293.             if (rxMsg->Length == 4) {
  294.                 uint8_t channel = rxMsg->Data[0];
  295.                 uint8_t speed = rxMsg->Data[1];
  296.                 uint8_t direction = rxMsg->Data[2];
  297.                 uint8_t steps = rxMsg->Data[3];
  298.                
  299.                 uint8_t tempDimVal = dimmerValueCh1;
  300.                 uint8_t tempDimVal2 = dimmerValueCh1;
  301.                 if (direction == 1) {                   //if increase
  302.                     tempDimVal2 += steps;               //calculate new value
  303.                     if (tempDimVal2 < tempDimVal) {     //make overflow test
  304.                         tempDimVal2 = ACT_DIMMMER230_MAX_DIM;
  305.                     }
  306.                 } else if (direction == 0) {            //if decrease
  307.                     tempDimVal2 -= steps;
  308.                     if (tempDimVal2 > tempDimVal) {
  309.                         tempDimVal2 = ACT_DIMMMER230_MIN_DIM;
  310.                     }
  311.                 }
  312.                 if (speed == 0) {
  313.                     dimmerValueCh1 = tempDimVal2;       //set dimmer value immediately
  314.                 } else {
  315.                     fadeTargetCh1 = tempDimVal2;        //set the fade target
  316.                    
  317.                     if (fadeTargetCh1 != dimmerValueCh1) {
  318.                         if ((speed&0x80) == 0) {
  319.                             fadeSpeedCh1 = speed&0x7f;
  320.                             fadeSpeedFracCh1 = 1;
  321.                         } else {
  322.                             fadeSpeedCh1 = 1;
  323.                             fadeSpeedFracCh1 = speed&0x7f;
  324.                         }
  325.                         if (fadeTargetCh1 < dimmerValueCh1) {
  326.                             fadeSpeedCh1 = -fadeSpeedCh1;
  327.                         }
  328.                     }
  329.                 }
  330.                
  331.             }
  332.         break;
  333. }
  334.     }
  335. }
  336.  
  337. void act_dimmer230_List(uint8_t ModuleSequenceNumber)
  338. {
  339.     StdCan_Msg_t txMsg;
  340.    
  341.     StdCan_Set_class(txMsg.Header, CAN_CLASS_MODULE_DEF); ///TODO: Change this to the actual class type
  342.     StdCan_Set_direction(txMsg.Header, DIR_FROM_OWNER);
  343.     txMsg.Header.ModuleType = CAN_TYPE_MODULE_def_default; ///TODO: Change this to the actual module type
  344.     txMsg.Header.ModuleId = act_dimmer230_ID;
  345.     txMsg.Header.Command = CAN_CMD_MODULE_NMT_LIST;
  346.     txMsg.Length = 6;
  347.  
  348.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  349.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  350.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  351.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  352.    
  353.     txMsg.Data[4] = NUMBER_OF_MODULES;
  354.     txMsg.Data[5] = ModuleSequenceNumber;
  355.    
  356.     StdCan_Put(&txMsg);
  357. }
  358.