Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. #include "act_dimmer230.h"
  3.  
  4. uint8_t demo = 0;
  5. //uint8_t demo = 2; //disable demo
  6.  
  7. //uint16_t periodTime = 0;
  8.             //measured during init (by taking the time difference between two zero cross)
  9.             //not used, bad idea, the powerStepTable below asumes 10000
  10. uint16_t xcTimeDiff=0;
  11.             //zero cross sync (difference between pos and neg flank of zero cross, divided by 2)
  12. uint8_t dimmerValueCh1 = 0;
  13.             //store in eeprom later
  14.             //value of 0 is zero output, value of 255 is max output
  15. uint8_t state = ACT_DIMMMER230_STATE_IDLE;
  16. 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};
  17.  
  18. #if act_dimmer230_SYNC>0
  19. uint8_t zeroCrossCnt = 0;
  20. #endif
  21.  
  22. ISR (TIMER1_COMPA_vect)
  23. {
  24.     //testa hur lång denna loop behöver vara
  25.     //verkar fungera upp till 249-250 sen blir det för korta pulser
  26.     PORTC |= _BV(PC4);
  27.     uint8_t dummycnt = 240;
  28.     while (dummycnt > 0)
  29.     {
  30.         dummycnt++;
  31.         asm("nop");
  32.     }
  33.     PORTC &= ~_BV(PC4);        
  34.    
  35.     TIMSK1=0;                           //disable timer interrupt
  36.     state = ACT_DIMMMER230_STATE_IDLE;
  37. }
  38.  
  39. ISR (act_dimmer230_ZC_PCINT_vect)
  40. {
  41.     //only execute if zerocross pin is low
  42.     if (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)))
  43.     {
  44.         uint16_t newTimerVal = xcTimeDiff;
  45.  
  46.         //here new timer value is calculated
  47.  
  48.         if (dimmerValueCh1 > 0 && dimmerValueCh1 <= 127)
  49.         {
  50.             newTimerVal += ACT_DIMMMER230_PERIOD_TIME - pgm_read_word(&powerStepTable[dimmerValueCh1-1]);
  51.         }
  52.         else if (dimmerValueCh1 < 255)
  53.         {
  54.             newTimerVal += pgm_read_word(&powerStepTable[254-dimmerValueCh1]);
  55.         }
  56.         else if (dimmerValueCh1 == 255)
  57.         {
  58.             newTimerVal += 100; //almost max, to make sure we don't fire before zerocross
  59.         }
  60.        
  61.         if (newTimerVal > ACT_DIMMMER230_PERIOD_TIME)
  62.         {
  63.             newTimerVal -= ACT_DIMMMER230_PERIOD_TIME;
  64.         }
  65.  
  66.         if (dimmerValueCh1 > 0)
  67.         {
  68.             TCNT1 = 0;              //reset timer1 count register
  69.             OCR1A = newTimerVal;
  70.  
  71.             //enable timer and timer interrupt
  72.             TIFR1=(1<<OCF1A);       //clear interrupt flag before enabling interrupt
  73.             TIMSK1|=(1<<OCIE1A);
  74.  
  75.             state = ACT_DIMMMER230_STATE_TIMER_ON;
  76.         }
  77.  
  78. #if act_dimmer230_SYNC>0
  79.         zeroCrossCnt++;
  80.         if (zeroCrossCnt >= act_dimmer230_SYNC)
  81.         {
  82.             zeroCrossCnt = 0;
  83.             //TODO: send on can
  84.  
  85.             StdCan_Msg_t txMsg;
  86.             txMsg.Length = 6;
  87.             txMsg.Data[0] = (newTimerVal>>8)&0xff;
  88.             txMsg.Data[1] = newTimerVal&0xff;
  89.             //txMsg.Data[2] = (periodTime>>8)&0xff;
  90.             //txMsg.Data[3] = periodTime&0xff;
  91.             txMsg.Data[4] = (xcTimeDiff>>8)&0xff;
  92.             txMsg.Data[5] = xcTimeDiff&0xff;
  93.             //StdCan_Put(&txMsg);
  94.  
  95.             if (demo == 0) {
  96.                 dimmerValueCh1++;
  97.                 if (dimmerValueCh1 == 255) {
  98.                     demo = 1;
  99.                 }
  100.             } else if (demo == 1) {
  101.                 dimmerValueCh1--;
  102.                 if (dimmerValueCh1 == 0) {
  103.                     demo = 0;
  104.                 }
  105.             }
  106.         }
  107. #endif     
  108.     }
  109. }
  110.  
  111. void act_dimmer230_Init(void)
  112. {
  113.     // set dimmer channel1 port to output 0
  114.     act_dimmer230_CHAN1_PORT &= ~_BV(act_dimmer230_CHAN1_BIT);
  115.     act_dimmer230_CHAN1_DDR |= _BV(act_dimmer230_CHAN1_BIT);
  116.     // set zero cross detection port to input, no pullup
  117.     act_dimmer230_ZC_PORT &= ~_BV(act_dimmer230_ZC_BIT);
  118.     act_dimmer230_ZC_DDR &= ~_BV(act_dimmer230_ZC_BIT);
  119.    
  120.     TIMSK1=0;                           //disable timer interrupt
  121.     TCCR1A=0;
  122.    
  123.     //wait for high (ac leaving zero cross)
  124.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  125.     TCCR1B=(1<<CS11);                   //enable timer, set to prescaler 8, must be changed if cpu freq is changed
  126.     //wait for low (ac approaching zero cross)
  127.     while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  128.     uint16_t timeAtFall = TCNT1;    //Timer_GetTicks();
  129.     //wait for high (ac leaving zero cross)
  130.     while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  131.     uint16_t timeAtRise = TCNT1;    //Timer_GetTicks();
  132.  
  133.     //wait for low (ac approaching zero cross)
  134.     //while (act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT)) { }
  135.     //wait for high (ac leaving zero cross)
  136.     //while (!(act_dimmer230_ZC_PIN&(1<<act_dimmer230_ZC_BIT))) { }
  137.     //uint16_t timeAtRise2 = TCNT1; //Timer_GetTicks();
  138.     //if (timeAtRise < timeAtRise2) {
  139.     //  periodTime = timeAtRise2 - timeAtRise;
  140.     //}
  141.  
  142.     // warning, watch out for wrap around on timestamps (something is broken if wrapped)
  143.     if (timeAtFall < timeAtRise) {
  144.         //calculate time from falling edge to ac zero cross value
  145.         xcTimeDiff = timeAtRise-timeAtFall;
  146.         xcTimeDiff = xcTimeDiff >> 1; //divide by two
  147.     }
  148.  
  149.     //setup interrupt on zerocross, pcint
  150.     PCMSK0=(1<<act_dimmer230_ZC_PCINT_BIT);
  151.     PCIFR=(1<<act_dimmer230_ZC_PCIF);   //clear any pending interrupt before enabling interrupts
  152.     PCICR=(1<<act_dimmer230_ZC_PCIE);   //enable interrupt for PCINT
  153. }
  154.  
  155. void act_dimmer230_Process(void)
  156. {
  157.     ///TODO: Stuff that needs doing is done here
  158. }
  159.  
  160. void act_dimmer230_HandleMessage(StdCan_Msg_t *rxMsg)
  161. {
  162.     if (    StdCan_Ret_class(rxMsg->Header) == CAN_CLASS_MODULE_DEF && ///TODO: Change this to the actual class type
  163.         StdCan_Ret_direction(rxMsg->Header) == DIR_TO_OWNER &&
  164.         rxMsg->Header.ModuleType == CAN_TYPE_MODULE_def_default && ///TODO: Change this to the actual module type
  165.         rxMsg->Header.ModuleId == act_dimmer230_ID)
  166.     {
  167.         switch (rxMsg->Header.Command)
  168.         {
  169.         case 0:
  170.         ///TODO: Do something dummy
  171.         break;
  172.         }
  173.     }
  174. }
  175.  
  176. void act_dimmer230_List(uint8_t ModuleSequenceNumber)
  177. {
  178.     StdCan_Msg_t txMsg;
  179.    
  180.     StdCan_Set_class(txMsg.Header, CAN_CLASS_MODULE_DEF); ///TODO: Change this to the actual class type
  181.     StdCan_Set_direction(txMsg.Header, DIR_FROM_OWNER);
  182.     txMsg.Header.ModuleType = CAN_TYPE_MODULE_def_default; ///TODO: Change this to the actual module type
  183.     txMsg.Header.ModuleId = act_dimmer230_ID;
  184.     txMsg.Header.Command = CAN_CMD_MODULE_NMT_LIST;
  185.     txMsg.Length = 6;
  186.  
  187.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  188.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  189.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  190.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  191.    
  192.     txMsg.Data[4] = NUMBER_OF_MODULES;
  193.     txMsg.Data[5] = ModuleSequenceNumber;
  194.    
  195.     StdCan_Put(&txMsg);
  196. }
  197.