Subversion Repositories HomeAutomation

Rev

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