View difference between Paste ID: HNrhvgDH and wuvs4Air
SHOW: | | - or go back to the newest paste.
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-
            send_code(pentax);                      // Send Pentax IR code
109+
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-
            send_code(pentax);
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
}