Advertisement
cpolymeris

MSP430 DSLR intervalometer 3

Jun 20th, 2012
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <msp430.h>
  2. #include <signal.h>
  3.  
  4. #define IR_LED      BIT6
  5. #define TRIGGER     BIT3
  6. #define STATUS_LED  BIT0
  7.  
  8. static volatile int cycle_count;                    // IR carrier cycle count
  9. unsigned long time = 0;                             // current time, 1 click = 32.8ms
  10. unsigned long last_shot = 0;                        // time of last manual shot
  11. unsigned long interval = 100;                       // currently set interval
  12. unsigned long trigger_down_time = 0;                // time button was depressed
  13. int trigger_down = 0;
  14. int interval_on = 0;
  15. int manual_shot = 0;
  16.  
  17. #pragma vector = WDT_VECTOR
  18. __interrupt void wdt_isr(void)
  19. {
  20.     time++;
  21.     __bic_SR_register_on_exit(LPM1_bits);
  22. }
  23.  
  24. #pragma vector = TIMERA0_VECTOR                     // Timer A Capture/Compare 0 interrupt
  25. __interrupt void timera0_isr(void)                  // This ISR must be very simple because there may
  26.                                                     // be as few as 16 cycles available for it to complete
  27. {                                                   //
  28.     --cycle_count;                                  // Decrement cycle count
  29. }
  30.  
  31. #pragma vector = PORT1_VECTOR
  32. __interrupt void port1_isr(void)
  33. {
  34.     if (P1IFG & TRIGGER)
  35.     {
  36.         P1IES ^= TRIGGER;                           // switch interrupt direction
  37.         trigger_down = !trigger_down;               // toggle state
  38.         trigger_down_time = time;
  39.         manual_shot = trigger_down;
  40.         __bic_SR_register_on_exit(LPM1_bits);
  41.     }
  42.  
  43.     P1IFG = 0;                                     // clear p1 interrupts
  44. }                                              
  45.  
  46.  
  47.  
  48. static const int pentax[] = {
  49.     26,                                             // Carrier period in us ( 1 MHz / 38 kHz ~= 26 )
  50.     8,                                              // Number of pairs
  51.     500, 115,                                       // 13 ms on, 3 ms off
  52.     38, 39,                                         // 1 ms on, 1 ms off
  53.     38, 39,                                         // 1 ms on, 1 ms off
  54.     38, 39,                                         // 1 ms on, 1 ms off
  55.     38, 39,                                         // 1 ms on, 1 ms off
  56.     38, 39,                                         // 1 ms on, 1 ms off
  57.     38, 39,                                         // 1 ms on, 1 ms off
  58.     38, 39                                          // 1 ms on, 1 ms off
  59. };
  60.  
  61. static const int nikon[] = {
  62.     26,              
  63.     4,                      
  64.     76, 1064,              
  65.     15, 60,                
  66.     15, 136,                
  67.     15, 38                
  68. };
  69.  
  70. static const int canon[] = {
  71.     30,                      
  72.     2,                      
  73.     16, 231,              
  74.     16, 33              
  75. };
  76.  
  77. void send_code(const int *code)
  78. {
  79.     TACCR0 = *code++ - 1 ;                          // Set timer period
  80.     TACCR1 = TACCR0 >> 1;                           // Set timer on duration - 50% duty cycle
  81.     int pair = *code++;                             // Get pair count
  82.     cycle_count = 5;                                // Setup some initial IR off lead in
  83.     TACCTL0 = CCIE;                                 // Enable Timer A CC0 interrupt
  84.     do {                                            // Do all pairs
  85.         int cc = *code++;                           // Get on cycles
  86.         while(cycle_count > 0);                     // Wait for off cycles to complete
  87.         TACCTL1 = OUTMOD_7;                         // Turn on IR
  88.         cycle_count += cc;                          // Set on cycle count
  89.         cc = *code++;                               // Get off cycles
  90.         while(cycle_count > 0);                     // Wait for on cycles to complete
  91.         TACCTL1 = OUTMOD_0;                         // Turn off IR
  92.         cycle_count += cc;                          // Set off cycle count                                                  
  93.     } while(--pair);                                // Decrement pair count, do next pair if not zero
  94.     while(cycle_count > 0);                         // Wait for off cycles to complete
  95.     TACCTL0 = 0;                                    // Turn off Timer A CC0 interrupt
  96. }
  97.  
  98. void send_all_codes()
  99. {
  100.     send_code(pentax);
  101.     send_code(nikon);
  102.     send_code(canon);
  103. }
  104.  
  105. int main(void)
  106. {
  107.     WDTCTL = WDTPW | WDTHOLD;                       // Disable watchdog reset
  108.     DCOCTL = 0;                                     // Run at 1 MHz
  109.     BCSCTL1 = CALBC1_1MHZ;                          //
  110.     DCOCTL = CALDCO_1MHZ;                           //
  111.  
  112.     P1DIR |= TRIGGER;                               // Set P1.3 to input
  113.     P1IE  |= TRIGGER;                               // P1.3 enabled interrupts
  114.     P1IES |= TRIGGER;                               // P1.3 Hi/lo edge
  115.     P1IFG &= ~TRIGGER;                              // P1.3 clear IFG
  116.  
  117.     TACTL = TASSEL_2 | MC_1;                        // Timer A config: SMCLK, count up
  118.     TACCTL1 = OUTMOD_0;                             // Make sure IR is off
  119.  
  120.     P1OUT = IR_LED;                                  
  121.     P1DIR = STATUS_LED | IR_LED;                    // Enable PWM output on P1.6
  122.     P1SEL = IR_LED;
  123.  
  124.     WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL;
  125.     IE1 |= WDTIE;
  126.  
  127.     eint();                                         // Enable global interrupts
  128.  
  129.     while(1) {            
  130.         if (interval_on && (time - last_shot >= interval)) // intervalometer
  131.         {
  132.             send_all_codes();                      // Send Pentax IR code
  133.             last_shot = time;
  134.         }
  135.  
  136.         if (manual_shot)                            // manual triggering
  137.         {
  138.             manual_shot = 0;
  139.             send_all_codes();
  140.             interval = time - last_shot;            // save interval
  141.             interval = (interval > 15? interval: 15);
  142.             last_shot = time;
  143.         }
  144.        
  145.         if (trigger_down && (time - trigger_down_time) > 30)
  146.                                                     //  hold button for 1 sec to switch modes
  147.         {
  148.             trigger_down_time = time;
  149.             interval_on = !interval_on;
  150.             if (interval_on)
  151.                 P1OUT ^= STATUS_LED;
  152.             else
  153.                 P1OUT &= ~STATUS_LED;
  154.         }
  155.        
  156.         __bis_SR_register(LPM1_bits + GIE);
  157.     }
  158.     return 1;
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement