Subversion Repositories HomeAutomation

Rev

Rev 1068 | Rev 1075 | 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 = 40;
  44.     while (dummycnt > 0)
  45.     {
  46.         dummycnt++;
  47.         asm("nop");
  48.         asm("nop");
  49.     }
  50.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);         
  51.    
  52.     TIMSK1=0;                           //disable timer interrupt
  53.     state = ACT_DIMMMER230_STATE_IDLE;
  54. }
  55.  
  56. ISR (act_dimmer230_ZC_PCINT_vect)
  57. {
  58.     //only execute if zerocross pin is high
  59.     if ((act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)))
  60.     {
  61. PORTD ^= (1<<PD2);
  62.         uint16_t newTimerVal = xcTimeDiff;
  63.  
  64.         //here new timer value is calculated
  65.  
  66.         if (dimmerValueCh1 > 0 && dimmerValueCh1 <= 127)
  67.         {
  68.             newTimerVal += ACT_DIMMMER230_PERIOD_TIME - pgm_read_word(&powerStepTable[dimmerValueCh1-1]);
  69.         }
  70.         else if (dimmerValueCh1 < 255)
  71.         {
  72.             newTimerVal += pgm_read_word(&powerStepTable[254-dimmerValueCh1]);
  73.         }
  74.         else if (dimmerValueCh1 == 255)
  75.         {
  76.             newTimerVal += 100; //almost max, to make sure we don't fire before zerocross
  77.         }
  78.        
  79.         if (newTimerVal > ACT_DIMMMER230_PERIOD_TIME)
  80.         {
  81.             newTimerVal -= ACT_DIMMMER230_PERIOD_TIME;
  82.         }
  83.  
  84.         if (dimmerValueCh1 > 0)
  85.         {
  86.             TCNT1 = 0;              //reset timer1 count register
  87.             OCR1A = newTimerVal;
  88.  
  89.             //enable timer and timer interrupt
  90.             TIFR1=(1<<OCF1A);       //clear interrupt flag before enabling interrupt
  91.             TIMSK1|=(1<<OCIE1A);
  92.  
  93.             state = ACT_DIMMMER230_STATE_TIMER_ON;
  94.         }
  95.        
  96.         fadeSpeedCntCh1++;
  97.         if (fadeSpeedCntCh1 == fadeSpeedFracCh1)
  98.         {
  99.             fadeSpeedCntCh1 = 0;
  100.             uint8_t tempDimVal = dimmerValueCh1;
  101.             dimmerValueCh1 += fadeSpeedCh1;
  102.             if ((fadeSpeedCh1 > 0 && (dimmerValueCh1 < tempDimVal || dimmerValueCh1 >= fadeTargetCh1)) ||
  103.                 (fadeSpeedCh1 < 0 && (dimmerValueCh1 > tempDimVal || dimmerValueCh1 <= fadeTargetCh1)))
  104.             {
  105.                 dimmerValueCh1 = fadeTargetCh1;
  106.                 fadeSpeedCh1 = 0;
  107.             }
  108.         }
  109.        
  110.        
  111. #if act_dimmer230_SYNC>0
  112.         zeroCrossCnt++;
  113.         if (zeroCrossCnt >= act_dimmer230_SYNC)
  114.         {
  115.             zeroCrossCnt = 0;
  116.             //TODO: send sync-message on can
  117.  
  118.             StdCan_Msg_t txMsg;
  119.             txMsg.Length = 6;
  120.             txMsg.Data[0] = (newTimerVal>>8)&0xff;
  121.             txMsg.Data[1] = newTimerVal&0xff;
  122.             //txMsg.Data[2] = (periodTime>>8)&0xff;
  123.             //txMsg.Data[3] = periodTime&0xff;
  124.             txMsg.Data[4] = (xcTimeDiff>>8)&0xff;
  125.             txMsg.Data[5] = xcTimeDiff&0xff;
  126.             StdCan_Put(&txMsg);
  127.  
  128. #ifdef USEDEMO
  129.             if (demo == 0 || demo == 2) {
  130.                 democnt++;
  131.                 if (democnt==DEMOSTEPS)
  132.                 {
  133.                     democnt = 0;
  134.                     uint8_t tempDim=dimmerValueCh1;
  135.                     dimmerValueCh1+=DEMOSTEPS2;
  136.                     if (dimmerValueCh1<tempDim && demo == 0) {
  137.                         dimmerValueCh1=ACT_DIMMMER230_MAX_DIM;
  138.                     }
  139.                 }
  140.                 if (dimmerValueCh1 == ACT_DIMMMER230_MAX_DIM && demo == 0) {
  141.                     demo = 1;
  142.                 }
  143.             } else if (demo == 1) {
  144.                 democnt++;
  145.                 if (democnt==DEMOSTEPS)
  146.                 {
  147.                     democnt = 0;
  148.                     uint8_t tempDim=dimmerValueCh1;
  149.                     dimmerValueCh1-=DEMOSTEPS2;
  150.                     if (dimmerValueCh1>tempDim) {
  151.                         dimmerValueCh1=ACT_DIMMMER230_MIN_DIM;
  152.                     }
  153.                 }
  154.                 if (dimmerValueCh1 == ACT_DIMMMER230_MIN_DIM) {
  155.                     demo = 0;
  156.                 }
  157.             }
  158. #endif //USEDEMO
  159.         }
  160. #endif     
  161.     }
  162. }
  163.  
  164. void act_dimmer230_Init(void)
  165. {
  166. DDRD |= (1<<PD2);
  167. PORTD &= ~(1<<PD2);
  168.  
  169.     // set dimmer channel1 port to output 0
  170.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);
  171.     act_dimmer230_CHAN1_DDR |= _BV(act_dimmer230_CHAN1_BIT);
  172.     // set zero cross detection port to input, no pullup
  173.     act_dimmer230_ZC_PORT &= ~_BV(act_dimmer230_ZC_BIT);
  174.     act_dimmer230_ZC_DDR &= ~_BV(act_dimmer230_ZC_BIT);
  175.    
  176.     TIMSK1=0;                           //disable timer interrupt
  177.     TCCR1A=0;
  178.    
  179.     //wait for low (ac leaving zero cross)
  180.     while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  181.     TCCR1B=(1<<CS11);                   //enable timer, set to prescaler 8, must be changed if cpu freq is changed
  182.     //wait for high (ac approaching zero cross)
  183.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  184.     uint16_t timeAtFall = TCNT1;    //Timer_GetTicks();
  185.     //wait for low (ac leaving zero cross)
  186.     while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  187.     uint16_t timeAtRise = TCNT1;    //Timer_GetTicks();
  188.  
  189. #ifdef MEASURE_PERIOD
  190.     //wait for high (ac approaching zero cross)
  191.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  192.     //wait for low (ac leaving zero cross)
  193.     while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  194.     uint16_t timeAtRise2 = TCNT1;   //Timer_GetTicks();
  195.     if (timeAtRise < timeAtRise2) {
  196.         periodTime = timeAtRise2 - timeAtRise;
  197.     }
  198. #endif
  199.  
  200.     // warning, watch out for wrap around on timestamps (something is broken if wrapped)
  201.     if (timeAtFall < timeAtRise) {
  202.         //calculate time from falling edge to ac zero cross value
  203.         xcTimeDiff = timeAtRise-timeAtFall;
  204.         xcTimeDiff = xcTimeDiff >> 1; //divide by two
  205.     }
  206.  
  207.     //setup interrupt on zerocross, pcint
  208.     act_dimmer230_ZC_PCMSK=(1<<act_dimmer230_ZC_PCINT_BIT);
  209.     PCIFR=(1<<act_dimmer230_ZC_PCIF);   //clear any pending interrupt before enabling interrupts
  210.     PCICR=(1<<act_dimmer230_ZC_PCIE);   //enable interrupt for PCINT
  211.  
  212. //PORTD ^= (1<<PD2);
  213.  
  214.  
  215.     //printf("Hello world!\n");
  216. }
  217.  
  218. void act_dimmer230_Process(void)
  219. {
  220.     ///TODO: Stuff that needs doing is done here
  221. /*if (PIND & (1<<PD7)) {
  222.     PORTD |= (1<<PD2);
  223. } else {
  224.     PORTD &= ~(1<<PD2);
  225. }*/
  226.  
  227. }
  228.  
  229. void act_dimmer230_HandleMessage(StdCan_Msg_t *rxMsg)
  230. {
  231.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  232.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  233.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_DIMMER230 &&
  234.         rxMsg->Header.ModuleId == act_dimmer230_ID)
  235.     {
  236.         switch (rxMsg->Header.Command)
  237.         {
  238.         case CAN_MODULE_CMD_DIMMER230_DEMO:     // Demo(channel, speed, steps)
  239.             if (rxMsg->Length == 3) {
  240.                
  241.             }
  242.         break;
  243.        
  244.         case CAN_MODULE_CMD_DIMMER230_START_FADE:   // StartFade(channel, speed, direction), just an alias of ABS_FADE
  245.             if (rxMsg->Length == 3) {
  246.                 uint8_t channel = rxMsg->Data[0];
  247.                 uint8_t speed = rxMsg->Data[1];
  248.                 uint8_t direction = rxMsg->Data[2];
  249.                
  250.                 fadeSpeedCntCh1 = 0;
  251.                 fadeSpeedCh1 = 0;
  252.                 uint8_t endValue = 0;
  253.                 if (direction == 1) {
  254.                     endValue = ACT_DIMMMER230_MAX_DIM;
  255.                 } else if (direction == 0) {
  256.                     endValue = ACT_DIMMMER230_MIN_DIM;
  257.                 }
  258.                    
  259.                 if (speed == 0) {
  260.                     dimmerValueCh1 = endValue;  //set dimmer value immediately
  261.                 } else {
  262.                     fadeTargetCh1 = endValue;
  263.                     if (fadeTargetCh1 != dimmerValueCh1) {
  264.                         if ((speed&0x80) == 0) {
  265.                             fadeSpeedCh1 = speed&0x7f;
  266.                             fadeSpeedFracCh1 = 1;
  267.                         } else {
  268.                             fadeSpeedCh1 = 1;
  269.                             fadeSpeedFracCh1 = speed&0x7f;
  270.                         }
  271.                         if (fadeTargetCh1 < dimmerValueCh1) {
  272.                             fadeSpeedCh1 = -fadeSpeedCh1;
  273.                         }
  274.                     }
  275.                 }
  276.             }
  277.         break;
  278.  
  279.         case CAN_MODULE_CMD_DIMMER230_STOP_FADE:    // StopFade(channel)
  280.             if (rxMsg->Length == 1) {
  281.                 fadeSpeedCh1 = 0;
  282.             }
  283.         break;
  284.  
  285.         case CAN_MODULE_CMD_DIMMER230_ABS_FADE: // AbsFade(channel, speed, endValue)
  286.             if (rxMsg->Length == 3) {
  287.                 uint8_t channel = rxMsg->Data[0];
  288.                 uint8_t speed = rxMsg->Data[1];
  289.                 uint8_t endValue = rxMsg->Data[2];
  290.  
  291.                 fadeSpeedCntCh1 = 0;
  292.                 fadeSpeedCh1 = 0;
  293.                 if (speed == 0) {
  294.                     dimmerValueCh1 = endValue;  //set dimmer value immediately
  295.                 } else {
  296.                     fadeTargetCh1 = endValue;
  297.                     if (fadeTargetCh1 != dimmerValueCh1) {
  298.                         if ((speed&0x80) == 0) {
  299.                             fadeSpeedCh1 = speed&0x7f;
  300.                             fadeSpeedFracCh1 = 1;
  301.                         } else {
  302.                             fadeSpeedCh1 = 1;
  303.                             fadeSpeedFracCh1 = speed&0x7f;
  304.                         }
  305.                         if (fadeTargetCh1 < dimmerValueCh1) {
  306.                             fadeSpeedCh1 = -fadeSpeedCh1;
  307.                         }
  308.                     }
  309.                 }
  310.             }
  311.         break;
  312.  
  313.         case CAN_MODULE_CMD_DIMMER230_REL_FADE: // RelFade(channel, speed, direction, steps)
  314.             if (rxMsg->Length == 4) {
  315.                 uint8_t channel = rxMsg->Data[0];
  316.                 uint8_t speed = rxMsg->Data[1];
  317.                 uint8_t direction = rxMsg->Data[2];
  318.                 uint8_t steps = rxMsg->Data[3];
  319.                
  320.                 fadeSpeedCntCh1 = 0;
  321.                 fadeSpeedCh1 = 0;
  322.                 uint8_t tempDimVal = dimmerValueCh1;
  323.                 uint8_t tempDimVal2 = dimmerValueCh1;
  324.                 if (direction == 1) {                   //if increase
  325.                     tempDimVal2 += steps;               //calculate new value
  326.                     if (tempDimVal2 < tempDimVal) {     //make overflow test
  327.                         tempDimVal2 = ACT_DIMMMER230_MAX_DIM;
  328.                     }
  329.                 } else if (direction == 0) {            //if decrease
  330.                     tempDimVal2 -= steps;
  331.                     if (tempDimVal2 > tempDimVal) {
  332.                         tempDimVal2 = ACT_DIMMMER230_MIN_DIM;
  333.                     }
  334.                 }
  335.                 if (speed == 0) {
  336.                     dimmerValueCh1 = tempDimVal2;       //set dimmer value immediately
  337.                 } else {
  338.                     fadeTargetCh1 = tempDimVal2;        //set the fade target
  339.                    
  340.                     if (fadeTargetCh1 != dimmerValueCh1) {
  341.                         if ((speed&0x80) == 0) {
  342.                             fadeSpeedCh1 = speed&0x7f;
  343.                             fadeSpeedFracCh1 = 1;
  344.                         } else {
  345.                             fadeSpeedCh1 = 1;
  346.                             fadeSpeedFracCh1 = speed&0x7f;
  347.                         }
  348.                         if (fadeTargetCh1 < dimmerValueCh1) {
  349.                             fadeSpeedCh1 = -fadeSpeedCh1;
  350.                         }
  351.                     }
  352.                 }
  353.                
  354.             }
  355.         break;
  356. }
  357.     }
  358. }
  359.  
  360. void act_dimmer230_List(uint8_t ModuleSequenceNumber)
  361. {
  362.     StdCan_Msg_t txMsg;
  363.    
  364.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  365.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  366.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_DIMMER230;
  367.     txMsg.Header.ModuleId = act_dimmer230_ID;
  368.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  369.     txMsg.Length = 6;
  370.  
  371.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  372.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  373.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  374.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  375.    
  376.     txMsg.Data[4] = NUMBER_OF_MODULES;
  377.     txMsg.Data[5] = ModuleSequenceNumber;
  378.    
  379.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  380. }
  381.