Subversion Repositories HomeAutomation

Rev

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