Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_dimmer230.h"
  3.  
  4.  
  5. int8_t fadeSpeed = 0;
  6. uint8_t fadeSpeedFrac = 0;
  7. uint8_t fadeTarget = 0;
  8. uint8_t fadeSpeedCnt = 0;
  9.  
  10. uint8_t demoEndValue = 0;
  11. uint8_t demoHighValue = 0;
  12. uint8_t demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  13.  
  14. uint8_t netConnected = CAN_MODULE_ENUM_DIMMER230_NETINFO_CONNECTION_DISCONNECTED;
  15.  
  16. uint8_t frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_ERROR_UNKNOWN; 
  17.             //don't calculate net frequency since the internal oscillator is not to be trusted, instead check if 50Hz or 60Hz system
  18.             //should be used for switching powerStepTable depending on frequency
  19. uint16_t xcTimeDiff=0;
  20.             //zero cross sync (time between pos flank of xc-detection and real zero cross)
  21. uint8_t dimmerValue = ACT_DIMMMER230_MIN_DIM;
  22.             //store in eeprom later
  23.             //value of 0 is zero output, value of 255 is max output (ACT_DIMMMER230_MIN_DIM, ACT_DIMMMER230_MAX_DIM)
  24. uint8_t state = ACT_DIMMMER230_STATE_IDLE;
  25. 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};
  26.  
  27. #if act_dimmer230_SYNC>0
  28. uint8_t zeroCrossCnt = 0;
  29. #endif
  30.  
  31. void Net_Connection_callback(uint8_t timer)
  32. {
  33.     netConnected = CAN_MODULE_ENUM_DIMMER230_NETINFO_CONNECTION_DISCONNECTED;
  34. }
  35.  
  36. void Send_Status_callback(uint8_t timer)
  37. {
  38.     StdCan_Msg_t txMsg;
  39.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  40.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  41.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_DIMMER230;
  42.     txMsg.Header.ModuleId = act_dimmer230_ID;
  43.     txMsg.Header.Command = CAN_MODULE_CMD_DIMMER230_NETINFO;
  44.     txMsg.Length = 1;
  45.     txMsg.Data[0] = ((netConnected&0x1)<<7 | (frequency&0x3)<<5);
  46.     StdCan_Put(&txMsg);
  47. }
  48.  
  49. ISR (TIMER1_COMPA_vect)
  50. {
  51.     //testa hur lång denna loop behöver vara
  52.     //verkar fungera upp till 249-250 sen blir det för korta pulser
  53.     act_dimmer230_CHAN1_PORT |= _BV(act_dimmer230_CHAN1_BIT);
  54.     uint8_t dummycnt = 40;
  55.     while (dummycnt > 0)
  56.     {
  57.         dummycnt++;
  58.         asm("nop");
  59.         asm("nop");
  60.     }
  61.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);         
  62.    
  63.     TIMSK1=0;                           //disable timer interrupt
  64.     state = ACT_DIMMMER230_STATE_IDLE;
  65. }
  66.  
  67. ISR (act_dimmer230_ZC_PCINT_vect)
  68. {
  69.     //only execute if zerocross pin is low (after real zerocross)
  70.     if (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)))
  71.     {
  72.         xcTimeDiff = TCNT1;
  73.         xcTimeDiff = xcTimeDiff >> 1; //divide by two
  74.         if (xcTimeDiff > 600) {
  75.             xcTimeDiff = 600;
  76.         }
  77.     }  
  78.     //only execute if zerocross pin is high (before real zerocross)
  79.     else if ((act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)))
  80.     {
  81.  
  82.         Timer_SetTimeout(act_dimmer230_NET_CONNECT_TIMEOUT, 500, TimerTypeOneShot, &Net_Connection_callback);
  83.         netConnected = CAN_MODULE_ENUM_DIMMER230_NETINFO_CONNECTION_CONNECTED;
  84.        
  85.         /* check frequency */
  86.         uint16_t periodTime = TCNT1;
  87.         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)
  88.         {
  89.             frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_50HZ;
  90.         }
  91.         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)
  92.         {
  93.             frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_60HZ;
  94.         }
  95.         else
  96.         {
  97.             frequency = CAN_MODULE_ENUM_DIMMER230_NETINFO_FREQUENCY_ERROR_UNKNOWN;
  98.         }
  99.        
  100.         /* check demo states */
  101.         if (dimmerValue == fadeTarget) {
  102.             switch (demoState)
  103.             {
  104.             case ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING:
  105.             break;
  106.             case ACT_DIMMMER230_DEMO_STATE_DECREASE:
  107.                 demoState = ACT_DIMMMER230_DEMO_STATE_INCREASE;
  108.                 fadeTarget = demoHighValue;
  109.                 fadeSpeed = -fadeSpeed;
  110.             break;
  111.             case ACT_DIMMMER230_DEMO_STATE_INCREASE:
  112.                 demoState = ACT_DIMMMER230_DEMO_STATE_GOBACK;
  113.                 fadeTarget = demoEndValue;
  114.                 fadeSpeed = -fadeSpeed;
  115.             break;
  116.             case ACT_DIMMMER230_DEMO_STATE_GOBACK:
  117.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  118.             break;
  119.             }
  120.         }
  121.        
  122.         /* calculate new time to triac triggering */
  123.         uint16_t newTimerVal = xcTimeDiff;
  124.  
  125.         if (dimmerValue > 0 && dimmerValue <= 127)
  126.         {
  127.             newTimerVal += ACT_DIMMMER230_50HZ_PERIOD_TIME - pgm_read_word(&powerStepTable[dimmerValue-1]);
  128.         }
  129.         else if (dimmerValue < 255)
  130.         {
  131.             newTimerVal += pgm_read_word(&powerStepTable[254-dimmerValue]);
  132.         }
  133.         else if (dimmerValue == 255)
  134.         {
  135.             newTimerVal += 100; //almost max, to make sure we don't fire before zerocross
  136.         }
  137.        
  138.         if (newTimerVal > ACT_DIMMMER230_50HZ_PERIOD_TIME)
  139.         {
  140.             newTimerVal -= ACT_DIMMMER230_50HZ_PERIOD_TIME;
  141.         }
  142.  
  143.         TCNT1 = 0;              //reset timer1 count register
  144.         if (dimmerValue > 0)
  145.         {
  146.             OCR1A = newTimerVal;
  147.  
  148.             //enable timer and timer interrupt
  149.             TIFR1=(1<<OCF1A);       //clear interrupt flag before enabling interrupt
  150.             TIMSK1|=(1<<OCIE1A);
  151.  
  152.             state = ACT_DIMMMER230_STATE_TIMER_ON;
  153.         }
  154.        
  155.         fadeSpeedCnt++;
  156.         if (fadeSpeedCnt == fadeSpeedFrac && dimmerValue != fadeTarget)
  157.         {
  158.             fadeSpeedCnt = 0;
  159.             uint8_t tempDimVal = dimmerValue;
  160.             dimmerValue += fadeSpeed;
  161.             if ((fadeSpeed > 0 && (dimmerValue < tempDimVal || dimmerValue >= fadeTarget)) ||
  162.                 (fadeSpeed < 0 && (dimmerValue > tempDimVal || dimmerValue <= fadeTarget)))
  163.             {
  164.                 dimmerValue = fadeTarget;
  165.             }
  166.         }
  167.        
  168. #if act_dimmer230_SYNC>0
  169.         zeroCrossCnt++;
  170.         if (zeroCrossCnt >= act_dimmer230_SYNC)
  171.         {
  172.             zeroCrossCnt = 0;
  173.             //TODO: send sync-message on can
  174.  
  175.             /*StdCan_Msg_t txMsg;
  176.             txMsg.Length = 6;
  177.             txMsg.Data[0] = (newTimerVal>>8)&0xff;
  178.             txMsg.Data[1] = newTimerVal&0xff;
  179.             txMsg.Data[2] = frequency;  //(periodTime>>8)&0xff;
  180.             //txMsg.Data[3] = periodTime&0xff;
  181.             txMsg.Data[4] = (xcTimeDiff>>8)&0xff;
  182.             txMsg.Data[5] = xcTimeDiff&0xff;
  183.             StdCan_Put(&txMsg); */
  184.         }
  185. #endif     
  186.     }
  187.  
  188. //lastDimmerValue = dimmerValue;
  189. //timerValue = TCNT1;
  190. }
  191.  
  192. void act_dimmer230_Init(void)
  193. {
  194.     // set dimmer channel1 port to output 0
  195.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);
  196.     act_dimmer230_CHAN1_DDR |= _BV(act_dimmer230_CHAN1_BIT);
  197.     // set zero cross detection port to input, no pullup
  198.     act_dimmer230_ZC_PORT &= ~_BV(act_dimmer230_ZC_BIT);
  199.     act_dimmer230_ZC_DDR &= ~_BV(act_dimmer230_ZC_BIT);
  200.    
  201.     TIMSK1=0;                           //disable timer interrupt
  202.     TCCR1A=0;
  203.    
  204.     TCCR1B=(1<<CS11);                   //enable timer, set to prescaler 8, must be changed if cpu freq is changed
  205.  
  206.     //setup interrupt on zerocross, pcint
  207.     act_dimmer230_ZC_PCMSK=(1<<(act_dimmer230_ZC_PCINT_BIT));
  208.     PCIFR=(1<<act_dimmer230_ZC_PCIF);   //clear any pending interrupt before enabling interrupts
  209.     PCICR=(1<<act_dimmer230_ZC_PCIE);   //enable interrupt for PCINT
  210.  
  211.     Timer_SetTimeout(act_dimmer230_SEND_STATUS_TIMEOUT, act_dimmer230_SEND_STATUS_INTERVAL*1000, TimerTypeFreeRunning, &Send_Status_callback);
  212. }
  213.  
  214. void act_dimmer230_Process(void)
  215. {
  216.     ///TODO: Stuff that needs doing is done here
  217.  
  218. }
  219.  
  220. void act_dimmer230_HandleMessage(StdCan_Msg_t *rxMsg)
  221. {
  222.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
  223.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  224.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_DIMMER230 &&
  225.         rxMsg->Header.ModuleId == act_dimmer230_ID)
  226.     {
  227.         switch (rxMsg->Header.Command)
  228.         {
  229.         case CAN_MODULE_CMD_DIMMER230_DEMO:     // Demo(channel, speed, steps)
  230.             if (rxMsg->Length == 3) {
  231.                 uint8_t channel = rxMsg->Data[0];
  232.                 uint8_t speed = rxMsg->Data[1];
  233.                 uint8_t steps = rxMsg->Data[2];
  234.                
  235.                 if (speed == 0) {
  236.                     //do nothing
  237.                 } else {
  238.                     uint8_t diffToMin = dimmerValue - ACT_DIMMMER230_MIN_DIM;
  239.                     uint8_t diffToMax = ACT_DIMMMER230_MAX_DIM - dimmerValue;
  240.                
  241.                     demoEndValue = dimmerValue;
  242.                     if (diffToMin >= steps && diffToMax >= steps)
  243.                     {
  244.                         //not close to min or max
  245.                         fadeTarget = dimmerValue - steps;
  246.                         demoHighValue = dimmerValue + steps;
  247.                     }
  248.                     else if (diffToMin >= steps)
  249.                     {
  250.                         //close to max
  251.                         fadeTarget = dimmerValue - steps - diffToMax;
  252.                         demoHighValue = ACT_DIMMMER230_MAX_DIM;
  253.                     }
  254.                     else if (diffToMax >= steps)
  255.                     {
  256.                         //close to min
  257.                         fadeTarget = ACT_DIMMMER230_MIN_DIM;
  258.                         demoHighValue = dimmerValue + steps + diffToMin;
  259.                     }
  260.                     demoState = ACT_DIMMMER230_DEMO_STATE_DECREASE;
  261.                
  262.                     if (fadeTarget != dimmerValue) {
  263.                         if ((speed&0x80) == 0) {
  264.                             fadeSpeed = speed&0x7f;
  265.                             fadeSpeedFrac = 1;
  266.                         } else {
  267.                             fadeSpeed = 1;
  268.                             fadeSpeedFrac = speed&0x7f;
  269.                         }
  270.                         if (fadeTarget < dimmerValue) {
  271.                             fadeSpeed = -fadeSpeed;
  272.                         }
  273.                     }
  274.                 }
  275.             }
  276.         break;
  277.        
  278.         case CAN_MODULE_CMD_DIMMER230_START_FADE:   // StartFade(channel, speed, direction), just an alias of AbsFade
  279.             if (rxMsg->Length == 3) {
  280.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  281.                 uint8_t channel = rxMsg->Data[0];
  282.                 uint8_t speed = rxMsg->Data[1];
  283.                 uint8_t direction = rxMsg->Data[2];
  284.                
  285.                 fadeSpeedCnt = 0;
  286.                 fadeSpeed = 0;
  287.                 uint8_t endValue = 0;
  288.                 if (direction == 1) {
  289.                     endValue = ACT_DIMMMER230_MAX_DIM;
  290.                 } else if (direction == 0) {
  291.                     endValue = ACT_DIMMMER230_MIN_DIM;
  292.                 }
  293.                    
  294.                 if (speed == 0) {
  295.                     dimmerValue = endValue; //set dimmer value immediately
  296.                 } else {
  297.                     fadeTarget = endValue;
  298.                     if (fadeTarget != dimmerValue) {
  299.                         if ((speed&0x80) == 0) {
  300.                             fadeSpeed = speed&0x7f;
  301.                             fadeSpeedFrac = 1;
  302.                         } else {
  303.                             fadeSpeed = 1;
  304.                             fadeSpeedFrac = speed&0x7f;
  305.                         }
  306.                         if (fadeTarget < dimmerValue) {
  307.                             fadeSpeed = -fadeSpeed;
  308.                         }
  309.                     }
  310.                 }
  311.             }
  312.         break;
  313.  
  314.         case CAN_MODULE_CMD_DIMMER230_STOP_FADE:    // StopFade(channel)
  315.             if (rxMsg->Length == 1) {
  316.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  317.                 fadeSpeed = 0;
  318.             }
  319.         break;
  320.  
  321.         case CAN_MODULE_CMD_DIMMER230_ABS_FADE: // AbsFade(channel, speed, endValue)
  322.             if (rxMsg->Length == 3) {
  323.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  324.                 uint8_t channel = rxMsg->Data[0];
  325.                 uint8_t speed = rxMsg->Data[1];
  326.                 uint8_t endValue = rxMsg->Data[2];
  327.  
  328.                 fadeSpeedCnt = 0;
  329.                 fadeSpeed = 0;
  330.                 if (speed == 0) {
  331.                     dimmerValue = endValue; //set dimmer value immediately
  332.                 } else {
  333.                     fadeTarget = endValue;
  334.                     if (fadeTarget != dimmerValue) {
  335.                         if ((speed&0x80) == 0) {
  336.                             fadeSpeed = speed&0x7f;
  337.                             fadeSpeedFrac = 1;
  338.                         } else {
  339.                             fadeSpeed = 1;
  340.                             fadeSpeedFrac = speed&0x7f;
  341.                         }
  342.                         if (fadeTarget < dimmerValue) {
  343.                             fadeSpeed = -fadeSpeed;
  344.                         }
  345.                     }
  346.                 }
  347.             }
  348.         break;
  349.  
  350.         case CAN_MODULE_CMD_DIMMER230_REL_FADE: // RelFade(channel, speed, direction, steps)
  351.             if (rxMsg->Length == 4) {
  352.                 demoState = ACT_DIMMMER230_DEMO_STATE_NOT_RUNNING;
  353.                 uint8_t channel = rxMsg->Data[0];
  354.                 uint8_t speed = rxMsg->Data[1];
  355.                 uint8_t direction = rxMsg->Data[2];
  356.                 uint8_t steps = rxMsg->Data[3];
  357.                
  358.                 fadeSpeedCnt = 0;
  359.                 fadeSpeed = 0;
  360.                 uint8_t tempDimVal = dimmerValue;
  361.                 uint8_t tempDimVal2 = dimmerValue;
  362.                 if (direction == 1) {                   //if increase
  363.                     tempDimVal2 += steps;               //calculate new value
  364.                     if (tempDimVal2 < tempDimVal) {     //make overflow test
  365.                         tempDimVal2 = ACT_DIMMMER230_MAX_DIM;
  366.                     }
  367.                 } else if (direction == 0) {            //if decrease
  368.                     tempDimVal2 -= steps;
  369.                     if (tempDimVal2 > tempDimVal) {
  370.                         tempDimVal2 = ACT_DIMMMER230_MIN_DIM;
  371.                     }
  372.                 }
  373.                 if (speed == 0) {
  374.                     dimmerValue = tempDimVal2;      //set dimmer value immediately
  375.                 } else {
  376.                     fadeTarget = tempDimVal2;       //set the fade target
  377.                    
  378.                     if (fadeTarget != dimmerValue) {
  379.                         if ((speed&0x80) == 0) {
  380.                             fadeSpeed = speed&0x7f;
  381.                             fadeSpeedFrac = 1;
  382.                         } else {
  383.                             fadeSpeed = 1;
  384.                             fadeSpeedFrac = speed&0x7f;
  385.                         }
  386.                         if (fadeTarget < dimmerValue) {
  387.                             fadeSpeed = -fadeSpeed;
  388.                         }
  389.                     }
  390.                 }
  391.             }
  392.         break;
  393. }
  394.     }
  395. }
  396.  
  397. void act_dimmer230_List(uint8_t ModuleSequenceNumber)
  398. {
  399.     StdCan_Msg_t txMsg;
  400.    
  401.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
  402.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  403.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_DIMMER230;
  404.     txMsg.Header.ModuleId = act_dimmer230_ID;
  405.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  406.     txMsg.Length = 6;
  407.  
  408.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  409.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  410.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  411.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  412.    
  413.     txMsg.Data[4] = NUMBER_OF_MODULES;
  414.     txMsg.Data[5] = ModuleSequenceNumber;
  415.    
  416.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  417. }
  418.