Subversion Repositories HomeAutomation

Rev

Rev 1938 | Rev 1944 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 1938 Rev 1941
Line 1... Line -...
1
 
-
 
2
#include "sns_irTransceive.h"
1
#include "sns_irTransceive.h"
3
 
2
 
4
#ifdef sns_irTransceive_USEEEPROM
3
#ifdef sns_irTransceive_USEEEPROM
5
#include "sns_irTransceive_eeprom.h"
4
#include "sns_irTransceive_eeprom.h"
6
struct eeprom_sns_irTransceive EEMEM eeprom_sns_irTransceive =
5
struct eeprom_sns_irTransceive EEMEM eeprom_sns_irTransceive =
Line 14... Line 13...
14
        CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO,
13
        CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO,
15
        0,
14
        0,
16
        CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO,
15
        CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO,
17
        0,
16
        0,
18
    },
17
    },
19
    0   /* crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts */
18
    0   /* crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts. */
20
};
19
};
21
#endif
20
#endif
22
 
21
 
23
#if IR_RX_ENABLE==1
22
#if IR_RX_ENABLE==1
24
struct {
23
struct {
Line 27... Line 26...
27
    uint8_t             rxlen;
26
    uint8_t             rxlen;
28
    uint8_t             timerNum;
27
    uint8_t             timerNum;
29
    Ir_Protocol_Data_t  proto;
28
    Ir_Protocol_Data_t  proto;
30
    uint8_t             newData;
29
    uint8_t             newData;
31
} irRxChannel[IR_SUPPORTED_NUM_CHANNELS];
30
} irRxChannel[IR_SUPPORTED_NUM_CHANNELS];
32
#endif
31
#endif
33
 
32
 
34
#if IR_TX_ENABLE==1
33
#if IR_TX_ENABLE==1
35
struct {
34
struct {
36
    uint8_t             state;
35
    uint8_t             state;
37
    uint16_t            *txbuf;
36
    uint16_t            *txbuf;
Line 39... Line 38...
39
    uint8_t             timerNum;
38
    uint8_t             timerNum;
40
    uint8_t             repeatCount;
39
    uint8_t             repeatCount;
41
    Ir_Protocol_Data_t  proto;
40
    Ir_Protocol_Data_t  proto;
42
    uint8_t             stopSend;
41
    uint8_t             stopSend;
43
    uint8_t             sendComplete;
42
    uint8_t             sendComplete;
44
    /* Pronto params */
43
    /* Pronto params. */
45
    uint8_t             sendingPronto;
44
    uint8_t             sendingPronto;
46
    uint8_t             onceSeqLen;
45
    uint8_t             onceSeqLen;
47
    uint8_t             repSeqLen;
46
    uint8_t             repSeqLen;
48
    uint8_t             expectedSeqNr;
47
    uint8_t             expectedSeqNr;
49
} irTxChannel[IR_SUPPORTED_NUM_CHANNELS];
48
} irTxChannel[IR_SUPPORTED_NUM_CHANNELS];
Line 54... Line 53...
54
StdCan_Msg_t        irTxMsg;
53
StdCan_Msg_t        irTxMsg;
55
 
54
 
56
#if (sns_irTransceive_SEND_DEBUG==1)
55
#if (sns_irTransceive_SEND_DEBUG==1)
57
void send_debug(uint16_t *buffer, uint8_t len) {
56
void send_debug(uint16_t *buffer, uint8_t len) {
58
    StdCan_Msg_t dbgIrTxMsg;
57
    StdCan_Msg_t dbgIrTxMsg;
59
    /* the protocol is unknown so the raw ir-data is sent, makes it easier to develop a new protocol */
58
    /* the protocol is unknown so the raw ir-data is sent, makes it easier to develop a new protocol. */
60
 
59
 
61
    StdCan_Set_class(dbgIrTxMsg.Header, CAN_MODULE_CLASS_SNS);
60
    StdCan_Set_class(dbgIrTxMsg.Header, CAN_MODULE_CLASS_SNS);
62
    StdCan_Set_direction(dbgIrTxMsg.Header, DIRECTIONFLAG_FROM_OWNER);
61
    StdCan_Set_direction(dbgIrTxMsg.Header, DIRECTIONFLAG_FROM_OWNER);
63
    dbgIrTxMsg.Length = 8;
62
    dbgIrTxMsg.Length = 8;
64
    dbgIrTxMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE;
63
    dbgIrTxMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE;
Line 74... Line 73...
74
        dbgIrTxMsg.Data[4] = (buffer[index+2]>>8)&0xff;
73
        dbgIrTxMsg.Data[4] = (buffer[index+2]>>8)&0xff;
75
        dbgIrTxMsg.Data[5] = (buffer[index+2]>>0)&0xff;
74
        dbgIrTxMsg.Data[5] = (buffer[index+2]>>0)&0xff;
76
        dbgIrTxMsg.Data[6] = (buffer[index+3]>>8)&0xff;
75
        dbgIrTxMsg.Data[6] = (buffer[index+3]>>8)&0xff;
77
        dbgIrTxMsg.Data[7] = (buffer[index+3]>>0)&0xff;
76
        dbgIrTxMsg.Data[7] = (buffer[index+3]>>0)&0xff;
78
 
77
 
79
        /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
78
        /* buffers will be filled when sending more than 2-3 messages, so retry until sent. */
80
        while (StdCan_Put(&dbgIrTxMsg) != StdCan_Ret_OK) {}
79
        while (StdCan_Put(&dbgIrTxMsg) != StdCan_Ret_OK) {}
81
        _delay_ms(1);
80
        _delay_ms(1);
82
    }
81
    }
83
 
82
 
84
    uint8_t lastpacketcnt = len&0x03;
83
    uint8_t lastpacketcnt = len&0x03;
85
    if (lastpacketcnt > 0) {
84
    if (lastpacketcnt > 0) {
86
        dbgIrTxMsg.Length = lastpacketcnt<<1;
85
        dbgIrTxMsg.Length = lastpacketcnt<<1;
87
        for (uint8_t i = 0; i < lastpacketcnt; i++) {
86
        for (uint8_t i = 0; i < lastpacketcnt; i++) {
88
            dbgIrTxMsg.Data[i<<1] = (buffer[(len&0xfc)|i]>>8)&0xff;
87
            dbgIrTxMsg.Data[i<<1] = (buffer[(len&0xfc)|i]>>8)&0xff;
89
            dbgIrTxMsg.Data[(i<<1)+1] = (buffer[(len&0xfc)|i]>>0)&0xff;
88
            dbgIrTxMsg.Data[(i<<1)+1] = (buffer[(len&0xfc)|i]>>0)&0xff;
90
        }
89
        }
91
        /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
90
        /* buffers will be filled when sending more than 2-3 messages, so retry until sent. */
92
        while (StdCan_Put(&dbgIrTxMsg) != StdCan_Ret_OK) {}
91
        while (StdCan_Put(&dbgIrTxMsg) != StdCan_Ret_OK) {}
93
        _delay_ms(1);
92
        _delay_ms(1);
94
    }
93
    }
95
 
94
 
96
}
95
}
97
#endif
96
#endif
98
 
97
 
99
#define sns_irTransceive_BaseFrq (4145146UL)
98
#define sns_irTransceive_BaseFrq (4145146UL)
-
 
99
 
-
 
100
#define channelIsOk(_ch)    ((_ch)>=0 && (_ch)<IR_SUPPORTED_NUM_CHANNELS)
100
 
101
 
101
#ifndef sns_irTransceive_PRONTO_SUPPORT
102
#ifndef sns_irTransceive_PRONTO_SUPPORT
102
#define sns_irTransceive_PRONTO_SUPPORT 0
103
#define sns_irTransceive_PRONTO_SUPPORT 0
103
#endif
104
#endif
104
 
105
 
Line 110... Line 111...
110
    StdCan_Msg_t msg;
111
    StdCan_Msg_t msg;
111
    StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS);
112
    StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS);
112
    StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER);
113
    StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER);
113
    msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE;
114
    msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE;
114
    msg.Header.ModuleId = sns_irTransceive_ID;
115
    msg.Header.ModuleId = sns_irTransceive_ID;
115
    /* Send response command */
116
    /* Send response command. */
116
    msg.Length = 3;
117
    msg.Length = 3;
117
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTORESPONSE;
118
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTORESPONSE;
118
    msg.Data[0] = ((channel<<4)|0xf);
119
    msg.Data[0] = ((channel<<4)|0xf);
119
    msg.Data[1] = 0xF0;
120
    msg.Data[1] = 0xF0;
120
    msg.Data[2] = (uint8_t)responseValue;
121
    msg.Data[2] = (uint8_t)responseValue;
Line 122... Line 123...
122
    _delay_ms(1);
123
    _delay_ms(1);
123
}
124
}
124
 
125
 
125
#if sns_irTransceive_PRONTO_SUPPORT==1
126
#if sns_irTransceive_PRONTO_SUPPORT==1
126
volatile uint32_t sns_irTransceive_LastPronto=0;
127
volatile uint32_t sns_irTransceive_LastPronto=0;
-
 
128
 
127
static uint8_t activeChannel = 0;
129
static uint8_t prontoAllocatedTxChannel = -1;
-
 
130
/* is any channel transmitting (or preparing to transmit) pronto? */
-
 
131
static inline int8_t prontoChannelIsAllocated(void)
-
 
132
{
-
 
133
    if (prontoAllocatedTxChannel >= 0 &&
-
 
134
        prontoAllocatedTxChannel < IR_SUPPORTED_NUM_CHANNELS &&
-
 
135
        irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_DISABLED)
-
 
136
    {
-
 
137
        return 1;
-
 
138
    }
-
 
139
    return 0;
-
 
140
}
-
 
141
 
-
 
142
 
128
#define sns_irTransceive_MAXTIMING (16*1000)
143
#define sns_irTransceive_MAXTIMING (16*1000)
129
 
144
 
130
static void pronto_sendData(uint16_t *buffer, uint8_t len, uint8_t channel, uint16_t modfreq)
145
static void pronto_sendData(uint16_t *buffer, uint8_t len, uint8_t channel, uint16_t modfreq)
131
{
146
{
132
    uint32_t currentTime = Timer_GetTicks();
147
    uint32_t currentTime = Timer_GetTicks();
133
 
148
 
134
    StdCan_Msg_t msg;
149
    StdCan_Msg_t msg;
135
 
150
 
136
    StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS);
151
    StdCan_Set_class(msg.Header, CAN_MODULE_CLASS_SNS);
137
    StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER);
152
    StdCan_Set_direction(msg.Header, DIRECTIONFLAG_FROM_OWNER);
138
    msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE;
153
    msg.Header.ModuleType = CAN_MODULE_TYPE_SNS_IRTRANSCEIVE;
139
    msg.Header.ModuleId = sns_irTransceive_ID;
154
    msg.Header.ModuleId = sns_irTransceive_ID;
140
 
155
 
141
    /* Send timing command */
156
    /* Send timing command. */
142
    msg.Length = 5;
157
    msg.Length = 5;
143
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOTIMING;
158
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOTIMING;
144
 
159
 
145
    if ((currentTime < sns_irTransceive_LastPronto+sns_irTransceive_MAXTIMING) && (sns_irTransceive_LastPronto != 0))
160
    if ((currentTime < sns_irTransceive_LastPronto+sns_irTransceive_MAXTIMING) && (sns_irTransceive_LastPronto != 0))
146
    {
161
    {
147
        /* Calculate elapsed time since last pronto packet */
162
        /* Calculate elapsed time since last pronto packet. */
148
        uint32_t elapsedTime = ((currentTime - sns_irTransceive_LastPronto) * 1000) & 0x00FFFFFFUL; /* 24bit value */
163
        uint32_t elapsedTime = ((currentTime - sns_irTransceive_LastPronto) * 1000) & 0x00FFFFFFUL; /* 24bit value. */
149
 
164
 
150
        /* Remove length of the last received sequence */
165
        /* Remove length of the last received sequence. */
151
        uint32_t sequenceLength = IR_MAX_PULSE_WIDTH; /* timeout value not included in buffer */
166
        uint32_t sequenceLength = IR_MAX_PULSE_WIDTH; /* timeout value not included in buffer. */
152
        for (uint8_t i = 0; i < len; i++) {
167
        for (uint8_t i = 0; i < len; i++) {
153
            sequenceLength += (uint32_t)buffer[i];
168
            sequenceLength += (uint32_t)buffer[i];
154
        }
169
        }
155
        if (sequenceLength <= elapsedTime) {
170
        if (sequenceLength <= elapsedTime) {
156
            elapsedTime -= sequenceLength;
171
            elapsedTime -= sequenceLength;
Line 164... Line 179...
164
        while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
179
        while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
165
        _delay_ms(1);
180
        _delay_ms(1);
166
    }
181
    }
167
    sns_irTransceive_LastPronto = currentTime;
182
    sns_irTransceive_LastPronto = currentTime;
168
 
183
 
169
    /* Calculate frequency divider */
184
    /* Calculate frequency divider. */
170
    uint16_t divider = (uint16_t)(sns_irTransceive_BaseFrq / (1000*(uint32_t)modfreq));
185
    uint16_t divider = (uint16_t)(sns_irTransceive_BaseFrq / (1000*(uint32_t)modfreq));
171
 
186
 
172
    /* Send pronto start */
187
    /* Send pronto start. */
173
    msg.Length = 8;
188
    msg.Length = 8;
174
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART;
189
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART;
175
 
190
 
176
    msg.Data[0] = ((channel<<4)|0x0);   /* Channel and Prontoformat 0x0000 */
191
    msg.Data[0] = ((channel<<4)|0x0);   /* Channel and Prontoformat 0x0000. */
177
    msg.Data[1] = 0x00;
192
    msg.Data[1] = 0x00;
178
    msg.Data[2] = (divider & 0xFF00) >> 8;  /* Freq divider */
193
    msg.Data[2] = (divider & 0xFF00) >> 8;  /* Freq divider. */
179
    msg.Data[3] = (divider & 0x00FF) >> 0;
194
    msg.Data[3] = (divider & 0x00FF) >> 0;
180
    msg.Data[4] = 0x00; /* Once seq length, first byte always 0 */
195
    msg.Data[4] = 0x00; /* Once seq length, first byte always 0. */
181
    msg.Data[5] = (len + 1) / 2;
196
    msg.Data[5] = (len + 1) / 2;
182
    msg.Data[6] = 0x00; /* Repeat seq length, always 0 for ir receive */
197
    msg.Data[6] = 0x00; /* Repeat seq length, always 0 for ir receive. */
183
    msg.Data[7] = 0x00;
198
    msg.Data[7] = 0x00;
184
 
199
 
185
    while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
200
    while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
186
    _delay_ms(1);
201
    _delay_ms(1);
187
 
202
 
188
    /* Send pronto data */
203
    /* Send pronto data. */
189
    //uint16_t divider = ((1000000ULL*modfreq)/sns_irTransceive_BaseFrq);
204
    //uint16_t divider = ((1000000ULL*modfreq)/sns_irTransceive_BaseFrq);
190
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1;
205
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1;
191
    uint8_t seqNr = 0;
206
    uint8_t seqNr = 0;
192
    /* Counter for buffer */
207
    /* Counter for buffer. */
193
    uint8_t i = 0;
208
    uint8_t i = 0;
194
    /* Counter for filling can frame data */
209
    /* Counter for filling can frame data. */
195
    uint8_t j = 0;
210
    uint8_t j = 0;
196
    /* Remember byte if data does not fit 8 bit */
211
    /* Remember byte if data does not fit 8 bit. */
197
    uint8_t mem = 0;
212
    uint8_t mem = 0;
198
    while (i < len)
213
    while (i < len)
199
    {
214
    {
200
        if (mem > 0)
215
        if (mem > 0)
201
        {
216
        {
202
            /* If byte was memorized then buffer it */
217
            /* If byte was memorized then buffer it. */
203
            msg.Data[j] = mem;
218
            msg.Data[j] = mem;
204
            /* Clear memory */
219
            /* Clear memory. */
205
            mem = 0;
220
            mem = 0;
206
        }
221
        }
207
        else
222
        else
208
        {
223
        {
209
            /* Convert µs to pronto hex modulation pulses */
224
            /* Convert µs to pronto hex modulation pulses. */
210
            uint16_t data = (uint16_t)(((uint32_t)buffer[i] * (uint32_t)modfreq) / 1000);
225
            uint16_t data = (uint16_t)(((uint32_t)buffer[i] * (uint32_t)modfreq) / 1000);
211
 
226
 
212
            /* Protocol compression */
227
            /* Protocol compression. */
213
            if (data >= 256)
228
            if (data >= 256)
214
            {
229
            {
215
                /* If data does not fit into 8 bit, then split, memorize low byte */
230
                /* If data does not fit into 8 bit, then split, memorize low byte. */
216
                mem = data&0xff;
231
                mem = data&0xff;
217
                /* Buffer high byte */
232
                /* Buffer high byte. */
218
                msg.Data[j] = (data>>8)&0xff;
233
                msg.Data[j] = (data>>8)&0xff;
219
                j++;
234
                j++;
220
                if (j==8)
235
                if (j==8)
221
                {
236
                {
222
                    /* If send buffer is full, send frame */
237
                    /* If send buffer is full, send frame. */
223
                    /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */
238
                    /* Can buffers will be filled when sending more than 2-3 messages, so retry until sent. */
224
                    while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
239
                    while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
225
                    _delay_ms(1);
240
                    _delay_ms(1);
226
                    j=0;
241
                    j=0;
227
                    seqNr = (seqNr + 1) % 16;
242
                    seqNr = (seqNr + 1) % 16;
228
                    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
243
                    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
229
                }
244
                }
230
                /* Set complementary burst pair to 0 to indicate 16bit transmission */
245
                /* Set complementary burst pair to 0 to indicate 16bit transmission. */
231
                msg.Data[j] = 0;
246
                msg.Data[j] = 0;
232
            }
247
            }
233
            else
248
            else
234
            {
249
            {
235
                msg.Data[j] = data&0xff;
250
                msg.Data[j] = data&0xff;
Line 239... Line 254...
239
        }
254
        }
240
 
255
 
241
        j++;
256
        j++;
242
        if (j==8)
257
        if (j==8)
243
        {
258
        {
244
            /* If send buffer is full, send frame */
259
            /* If send buffer is full, send frame. */
245
            /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */
260
            /* Can buffers will be filled when sending more than 2-3 messages, so retry until sent. */
246
            while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
261
            while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
247
            _delay_ms(1);
262
            _delay_ms(1);
248
            j=0;
263
            j=0;
249
            seqNr = (seqNr + 1) % 16;
264
            seqNr = (seqNr + 1) % 16;
250
            msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
265
            msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
251
        }
266
        }
252
    }
267
    }
253
 
268
 
254
    /* End with max pulse TODO fix uglyness */
269
    /* End with max pulse. TODO: fix uglyness. */
255
    msg.Data[j] = ((IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))>>8) & 0xFF;
270
    msg.Data[j] = ((IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))>>8) & 0xFF;
256
    j++;
271
    j++;
257
    if (j==8)
272
    if (j==8)
258
    {
273
    {
259
        /* If send buffer is full, send frame */
274
        /* If send buffer is full, send frame. */
260
        /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */
275
        /* Can buffers will be filled when sending more than 2-3 messages, so retry until sent. */
261
        while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
276
        while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
262
        _delay_ms(1);
277
        _delay_ms(1);
263
        j=0;
278
        j=0;
264
        seqNr = (seqNr + 1) % 16;
279
        seqNr = (seqNr + 1) % 16;
265
        msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
280
        msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
Line 268... Line 283...
268
    j++;
283
    j++;
269
    msg.Data[j] = (IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))&0xff;
284
    msg.Data[j] = (IR_MAX_PULSE_WIDTH/((1000000ULL*109)/sns_irTransceive_BaseFrq))&0xff;
270
    j++;
285
    j++;
271
    if (j==8)
286
    if (j==8)
272
    {
287
    {
273
        /* If send buffer is full, send frame */
288
        /* If send buffer is full, send frame. */
274
        /* can buffers will be filled when sending more than 2-3 messages, so retry until sent */
289
        /* Can buffers will be filled when sending more than 2-3 messages, so retry until sent. */
275
        while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
290
        while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
276
        _delay_ms(1);
291
        _delay_ms(1);
277
        j=0;
292
        j=0;
278
        seqNr = (seqNr + 1) % 16;
293
        seqNr = (seqNr + 1) % 16;
279
        msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
294
        msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1 + seqNr;
280
    }
295
    }
281
 
296
 
282
    /* Msg command kept from for loop, but increase 16 to send ProntoEnd */
297
    /* Msg command kept from for loop, but increase 16 to send ProntoEnd. */
283
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1 + seqNr;
298
    msg.Header.Command = CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1 + seqNr;
284
    msg.Length = j;
299
    msg.Length = j;
285
    /* data kept from loop, if any */
300
    /* Data kept from loop, if any. */
286
    /* buffers will be filled when sending more than 2-3 messages, so retry until sent */
301
    /* Buffers will be filled when sending more than 2-3 messages, so retry until sent. */
287
    while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
302
    while (StdCan_Put(&msg) != StdCan_Ret_OK) {}
288
    _delay_ms(1);
303
    _delay_ms(1);
289
}
304
}
290
 
305
 
291
 
306
 
Line 293... Line 308...
293
{
308
{
294
    static uint8_t waitingForLSB = FALSE;
309
    static uint8_t waitingForLSB = FALSE;
295
    static uint8_t previousValueWas16bit = FALSE;
310
    static uint8_t previousValueWas16bit = FALSE;
296
 
311
 
297
    if (irTxChannel[channel].txlen >= MAX_NR_TIMES) {
312
    if (irTxChannel[channel].txlen >= MAX_NR_TIMES) {
298
        /* Max length exceeded */
313
        /* Max length exceeded. */
299
        return -1;
314
        return -1;
300
    }
315
    }
301
 
316
 
302
    if (irTxChannel[channel].txlen == 0) {
317
    if (irTxChannel[channel].txlen == 0) {
303
        waitingForLSB = FALSE;
318
        waitingForLSB = FALSE;
304
        if (data == 0) {
319
        if (data == 0) {
305
            /* Cannot start with 0x00 */
320
            /* Cannot start with 0x00. */
306
            return -2;
321
            return -2;
307
        }
322
        }
308
    }
323
    }
309
 
324
 
310
    /* 0x00 means that previously received time is MSB of 16bit value, and that next byte will be LSB */
325
    /* 0x00 means that previously received time is MSB of 16bit value, and that next byte will be LSB. */
311
    if (data == 0 && !waitingForLSB && previousValueWas16bit==FALSE) {
326
    if (data == 0 && !waitingForLSB && previousValueWas16bit==FALSE) {
312
        /* Convert previous time to MSB of the 16bit value. next received byte will become LSB */
327
        /* Convert previous time to MSB of the 16bit value. next received byte will become LSB. */
313
        irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8;
328
        irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] <<= 8;
314
 
329
 
315
        /* Flag that next received byte is LSB rather than a new timing value */
330
        /* Flag that next received byte is LSB rather than a new timing value. */
316
        waitingForLSB = TRUE;
331
        waitingForLSB = TRUE;
317
    }
332
    }
318
 
333
 
319
    /* Non-zero value! is this part of a 16bit-value? use the data as LSB for previously received time */
334
    /* Non-zero value! is this part of a 16bit-value? use the data as LSB for previously received time. */
320
    else if (waitingForLSB) {
335
    else if (waitingForLSB) {
321
        /* Let this byte be LSB of previous 16bit value */
336
        /* Let this byte be LSB of previous 16bit value. */
322
        irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] |= data;
337
        irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1] |= data;
323
 
338
 
324
        /* We've now completed reception of the 16bit value */
339
        /* We've now completed reception of the 16bit value. */
325
        waitingForLSB = FALSE;
340
        waitingForLSB = FALSE;
326
 
341
 
327
        previousValueWas16bit = TRUE;
342
        previousValueWas16bit = TRUE;
328
    }
343
    }
329
 
344
 
330
    /* Non-zero value! simply new 8bit value */
345
    /* Non-zero value! simply new 8bit value. */
331
    else {
346
    else {
332
        /* Check if we're already done */
347
        /* Check if we're already done. */
333
        if (irTxChannel[channel].txlen >= (((uint16_t)irTxChannel[channel].onceSeqLen + (uint16_t)irTxChannel[channel].repSeqLen))) {
348
        if (irTxChannel[channel].txlen >= (((uint16_t)irTxChannel[channel].onceSeqLen + (uint16_t)irTxChannel[channel].repSeqLen))) {
334
            /* Too much data received, not necessarily a problem in case frames are padded */
349
            /* Too much data received, not necessarily a problem in case frames are padded. */
335
            return 2;
350
            return 2;
336
        }
351
        }
337
 
352
 
338
        irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data;
353
        irTxChannel[channel].txbuf[irTxChannel[channel].txlen] = data;
339
 
354
 
Line 415... Line 430...
415
#if IR_RX_ENABLE==1
430
#if IR_RX_ENABLE==1
416
                    gpio_set_pin(sns_irTransceive_VCC_EN0_PIN);
431
                    gpio_set_pin(sns_irTransceive_VCC_EN0_PIN);
417
                    IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN);
432
                    IrTransceiver_DeInitRxChannel(channel, sns_irTransceive_RX0_PCINT, sns_irTransceive_RX0_PIN);
418
#endif
433
#endif
419
                    IrTransceiver_InitTxChannel(channel, sns_irTransceive_TX_done_callback, sns_irTransceive_TX0_PIN);
434
                    IrTransceiver_InitTxChannel(channel, sns_irTransceive_TX_done_callback, sns_irTransceive_TX0_PIN);
420
 
435
 
421
#if sns_irTransceive_ENABLE_PCA95xx==1
436
#if sns_irTransceive_ENABLE_PCA95xx==1
422
                    Pca95xx_set_out(sns_irTransceive_TX0_PWRl);
437
                    Pca95xx_set_out(sns_irTransceive_TX0_PWRl);
423
                    Pca95xx_set_out(sns_irTransceive_TX0_PWRh);
438
                    Pca95xx_set_out(sns_irTransceive_TX0_PWRh);
424
                    if (power&0x1)
439
                    if (power&0x1)
425
                    {
440
                    {
426
                        Pca95xx_set_in(sns_irTransceive_TX0_PWRl);
441
                        Pca95xx_set_in(sns_irTransceive_TX0_PWRl);
427
                    }
442
                    }
428
                    if (power&0x2)
443
                    if (power&0x2)
Line 523... Line 538...
523
    if (IR_SUPPORTED_NUM_CHANNELS>=2) irTxChannel[1].timerNum=sns_irTransceive_TX1_REPEATE_TIMER;
538
    if (IR_SUPPORTED_NUM_CHANNELS>=2) irTxChannel[1].timerNum=sns_irTransceive_TX1_REPEATE_TIMER;
524
    if (IR_SUPPORTED_NUM_CHANNELS>=3) irTxChannel[2].timerNum=sns_irTransceive_TX2_REPEATE_TIMER;
539
    if (IR_SUPPORTED_NUM_CHANNELS>=3) irTxChannel[2].timerNum=sns_irTransceive_TX2_REPEATE_TIMER;
525
#endif
540
#endif
526
 
541
 
527
    IrTransceiver_Init();
542
    IrTransceiver_Init();
528
    /* Configure all TX VCC pins as outputs and disable them */
543
    /* Configure all TX VCC pins as outputs and disable them. */
529
    gpio_set_out(sns_irTransceive_VCC_EN0_PIN);
544
    gpio_set_out(sns_irTransceive_VCC_EN0_PIN);
530
    gpio_set_out(sns_irTransceive_VCC_EN1_PIN);
545
    gpio_set_out(sns_irTransceive_VCC_EN1_PIN);
531
    gpio_set_out(sns_irTransceive_VCC_EN2_PIN);
546
    gpio_set_out(sns_irTransceive_VCC_EN2_PIN);
532
    gpio_set_pin(sns_irTransceive_VCC_EN0_PIN);
547
    gpio_set_pin(sns_irTransceive_VCC_EN0_PIN);
533
    gpio_set_pin(sns_irTransceive_VCC_EN1_PIN);
548
    gpio_set_pin(sns_irTransceive_VCC_EN1_PIN);
534
    gpio_set_pin(sns_irTransceive_VCC_EN2_PIN);
549
    gpio_set_pin(sns_irTransceive_VCC_EN2_PIN);
535
 
550
 
536
    /* TX-pins must be set in case transmitter is nexa */
551
    /* TX-pins must be set in case transmitter is nexa. */
537
    gpio_set_out(sns_irTransceive_MOD_PIN);
552
    gpio_set_out(sns_irTransceive_MOD_PIN);
538
    gpio_set_out(sns_irTransceive_TX0_PIN);
553
    gpio_set_out(sns_irTransceive_TX0_PIN);
539
    gpio_set_out(sns_irTransceive_TX1_PIN);
554
    gpio_set_out(sns_irTransceive_TX1_PIN);
540
    gpio_set_out(sns_irTransceive_TX2_PIN);
555
    gpio_set_out(sns_irTransceive_TX2_PIN);
541
#if IR_TX_ACTIVE_LOW==1
556
#if IR_TX_ACTIVE_LOW==1
542
    gpio_set_pin(sns_irTransceive_TX0_PIN);
557
    gpio_set_pin(sns_irTransceive_TX0_PIN);
543
    gpio_set_pin(sns_irTransceive_TX1_PIN);
558
    gpio_set_pin(sns_irTransceive_TX1_PIN);
544
    gpio_set_pin(sns_irTransceive_TX2_PIN);
559
    gpio_set_pin(sns_irTransceive_TX2_PIN);
545
#endif
560
#endif
546
 
561
 
547
    /* IR tx power pins on PCA95xx */
562
    /* IR tx power pins on PCA95xx. */
548
#if sns_irTransceive_ENABLE_PCA95xx==1
563
#if sns_irTransceive_ENABLE_PCA95xx==1
549
    Pca95xx_Init(0);
564
    Pca95xx_Init(0);
550
 
565
 
551
    Pca95xx_clr_pin(sns_irTransceive_TX0_PWRl);
566
    Pca95xx_clr_pin(sns_irTransceive_TX0_PWRl);
552
    Pca95xx_set_out(sns_irTransceive_TX0_PWRl);
567
    Pca95xx_set_out(sns_irTransceive_TX0_PWRl);
Line 565... Line 580...
565
#endif
580
#endif
566
 
581
 
567
#ifdef sns_irTransceive_USEEEPROM
582
#ifdef sns_irTransceive_USEEEPROM
568
    if (EEDATA_OK)
583
    if (EEDATA_OK)
569
    {
584
    {
570
      /* Use stored data to set initial values for the module */
585
      /* Use stored data to set initial values for the module. */
571
        sns_irTransceive_setConfig(0, eeprom_read_byte(EEDATA.ch0_config), eeprom_read_byte(EEDATA.ch0_txpower), eeprom_read_word(EEDATA16.ch0_modfreq));
586
        sns_irTransceive_setConfig(0, eeprom_read_byte(EEDATA.ch0_config), eeprom_read_byte(EEDATA.ch0_txpower), eeprom_read_word(EEDATA16.ch0_modfreq));
572
        sns_irTransceive_setConfig(1, eeprom_read_byte(EEDATA.ch1_config), eeprom_read_byte(EEDATA.ch1_txpower), eeprom_read_word(EEDATA16.ch1_modfreq));
587
        sns_irTransceive_setConfig(1, eeprom_read_byte(EEDATA.ch1_config), eeprom_read_byte(EEDATA.ch1_txpower), eeprom_read_word(EEDATA16.ch1_modfreq));
573
        sns_irTransceive_setConfig(2, eeprom_read_byte(EEDATA.ch2_config), eeprom_read_byte(EEDATA.ch2_txpower), eeprom_read_word(EEDATA16.ch2_modfreq));
588
        sns_irTransceive_setConfig(2, eeprom_read_byte(EEDATA.ch2_config), eeprom_read_byte(EEDATA.ch2_txpower), eeprom_read_word(EEDATA16.ch2_modfreq));
574
    }
589
    }
575
    else
590
    else
576
    {
591
    {
577
    /* The CRC of the EEPROM is not correct, store default values and update CRC */
592
    /* The CRC of the EEPROM is not correct, store default values and update CRC. */
578
        eeprom_write_byte_crc(EEDATA.ch0_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC);
593
        eeprom_write_byte_crc(EEDATA.ch0_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC);
579
        eeprom_write_byte_crc(EEDATA.ch0_txpower, 0, WITHOUT_CRC);
594
        eeprom_write_byte_crc(EEDATA.ch0_txpower, 0, WITHOUT_CRC);
580
        eeprom_write_word_crc(EEDATA16.ch0_modfreq, sns_irTransceive_BaseFrq/38000UL, WITHOUT_CRC);
595
        eeprom_write_word_crc(EEDATA16.ch0_modfreq, sns_irTransceive_BaseFrq/38000UL, WITHOUT_CRC);
581
        eeprom_write_byte_crc(EEDATA.ch1_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC);
596
        eeprom_write_byte_crc(EEDATA.ch1_config, CAN_MODULE_ENUM_IRTRANSCEIVE_IRCONFIG_DIRECTION_AUTO, WITHOUT_CRC);
582
        eeprom_write_byte_crc(EEDATA.ch1_txpower, 0, WITHOUT_CRC);
597
        eeprom_write_byte_crc(EEDATA.ch1_txpower, 0, WITHOUT_CRC);
Line 605... Line 620...
605
        switch (irRxChannel[channel].state)
620
        switch (irRxChannel[channel].state)
606
        {
621
        {
607
        case sns_irTransceive_STATE_IDLE:
622
        case sns_irTransceive_STATE_IDLE:
608
        {
623
        {
609
            if (irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) {
624
            if (irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) {
610
                /* Send button release command on CAN */
625
                /* Send button release command on CAN. */
611
                irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED;
626
                irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED;
612
                irTxMsg.Data[0] |= channel<<4;
627
                irTxMsg.Data[0] |= channel<<4;
613
                irTxMsg.Data[1] = irRxChannel[channel].proto.protocol;
628
                irTxMsg.Data[1] = irRxChannel[channel].proto.protocol;
614
                irTxMsg.Data[2] = (irRxChannel[channel].proto.data>>24)&0xff;
629
                irTxMsg.Data[2] = (irRxChannel[channel].proto.data>>24)&0xff;
615
                irTxMsg.Data[3] = (irRxChannel[channel].proto.data>>16)&0xff;
630
                irTxMsg.Data[3] = (irRxChannel[channel].proto.data>>16)&0xff;
Line 632... Line 647...
632
            break;
647
            break;
633
 
648
 
634
        case sns_irTransceive_STATE_RECEIVING:
649
        case sns_irTransceive_STATE_RECEIVING:
635
            if (irRxChannel[channel].newData == TRUE) {
650
            if (irRxChannel[channel].newData == TRUE) {
636
//printf("sRx\n");
651
//printf("sRx\n");
637
                /* TODO: move this line to the RX callback */
652
                /* TODO: move this line to the RX callback. */
638
                IrTransceiver_DisableRx(channel);
653
                IrTransceiver_DisableRx(channel);
639
                cli();
654
                cli();
640
                irRxChannel[channel].newData = FALSE;
655
                irRxChannel[channel].newData = FALSE;
641
                sei();
656
                sei();
642
 
657
 
643
                /* Let protocol driver parse and then send on CAN */
658
                /* Let protocol driver parse and then send on CAN. */
644
                uint8_t res2 = parseProtocol(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, &irRxChannel[channel].proto);
659
                uint8_t res2 = parseProtocol(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, &irRxChannel[channel].proto);
645
                if (res2 == IR_OK && irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) {
660
                if (res2 == IR_OK && irRxChannel[channel].proto.protocol != IR_PROTO_UNKNOWN) {
646
                    irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED;
661
                    irTxMsg.Data[0] = 0xf&CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED;
647
                    irTxMsg.Data[0] |= channel<<4;
662
                    irTxMsg.Data[0] |= channel<<4;
648
                    irTxMsg.Data[1] = irRxChannel[channel].proto.protocol;
663
                    irTxMsg.Data[1] = irRxChannel[channel].proto.protocol;
Line 662... Line 677...
662
                    pronto_sendData(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, channel, irRxChannel[channel].proto.modfreq);
677
                    pronto_sendData(irRxChannel[channel].rxbuf, irRxChannel[channel].rxlen, channel, irRxChannel[channel].proto.modfreq);
663
                    irRxChannel[channel].proto.timeout=1;
678
                    irRxChannel[channel].proto.timeout=1;
664
#endif
679
#endif
665
                }
680
                }
666
 
681
 
667
                /* Enable the receiver again */
682
                /* Enable the receiver again. */
668
                IrTransceiver_EnableRx(channel);
683
                IrTransceiver_EnableRx(channel);
669
 
684
 
670
                irRxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE;
685
                irRxChannel[channel].state = sns_irTransceive_STATE_START_PAUSE;
671
//gpio_clr_pin(EXP_H);
686
//gpio_clr_pin(EXP_H);
672
//gpio_clr_pin(EXP_J);
687
//gpio_clr_pin(EXP_J);
673
            }
688
            }
674
            break;
689
            break;
675
 
690
 
676
        case sns_irTransceive_STATE_START_PAUSE:
691
        case sns_irTransceive_STATE_START_PAUSE:
677
//printf("sP\n");
692
//printf("sP\n");
678
            /* set a timer so we can send release button event when no new IR is arriving */
693
            /* Set a timer so we can send release button event when no new IR is arriving. */
679
            Timer_SetTimeout(irRxChannel[channel].timerNum, irRxChannel[channel].proto.timeout, TimerTypeOneShot, 0);
694
            Timer_SetTimeout(irRxChannel[channel].timerNum, irRxChannel[channel].proto.timeout, TimerTypeOneShot, 0);
680
            irRxChannel[channel].state = sns_irTransceive_STATE_PAUSING;
695
            irRxChannel[channel].state = sns_irTransceive_STATE_PAUSING;
681
            break;
696
            break;
682
 
697
 
683
        case sns_irTransceive_STATE_PAUSING:
698
        case sns_irTransceive_STATE_PAUSING:
684
            /* reset timer if new IR arrived */
699
            /* Reset timer if new IR arrived. */
685
            if (irRxChannel[channel].newData == TRUE || IrTransceiver_GetStoreEnableRx(channel) == TRUE) {
700
            if (irRxChannel[channel].newData == TRUE || IrTransceiver_GetStoreEnableRx(channel) == TRUE) {
686
//printf("sT\n");
701
//printf("sT\n");
687
                cli();
702
                cli();
688
                irRxChannel[channel].newData = FALSE;
703
                irRxChannel[channel].newData = FALSE;
689
                sei();
704
                sei();
Line 691... Line 706...
691
            }
706
            }
692
 
707
 
693
            if (Timer_Expired(irRxChannel[channel].timerNum)) {
708
            if (Timer_Expired(irRxChannel[channel].timerNum)) {
694
//printf("sD\n");
709
//printf("sD\n");
695
                irRxChannel[channel].state = sns_irTransceive_STATE_IDLE;
710
                irRxChannel[channel].state = sns_irTransceive_STATE_IDLE;
696
            }
711
            }
697
            break;
712
            break;
698
 
713
 
699
        default:
714
        default:
700
            break;
715
            break;
701
        }
716
        }
Line 704... Line 719...
704
#if IR_TX_ENABLE==1
719
#if IR_TX_ENABLE==1
705
        switch (irTxChannel[channel].state)
720
        switch (irTxChannel[channel].state)
706
        {
721
        {
707
        case sns_irTransceive_STATE_IDLE:
722
        case sns_irTransceive_STATE_IDLE:
708
        {
723
        {
709
            /* transmission is started when a command is received on can */
724
            /* Transmission is started when a command is received on can. */
710
            irTxChannel[channel].stopSend = FALSE;
725
            irTxChannel[channel].stopSend = FALSE;
711
            irTxChannel[channel].repeatCount = 0;
726
            irTxChannel[channel].repeatCount = 0;
712
            irTxChannel[channel].proto.framecnt = 0;
727
            irTxChannel[channel].proto.framecnt = 0;
713
            irTxChannel[channel].sendingPronto = FALSE;
728
            irTxChannel[channel].sendingPronto = FALSE;
714
            break;
729
            break;
Line 723... Line 738...
723
                break;
738
                break;
724
            }
739
            }
725
 
740
 
726
            /* Start IR transmission. */
741
            /* Start IR transmission. */
727
            /* TODO Send respone. Function call may fail when different modulation frequencies are used simultaneously. */
742
            /* TODO Send respone. Function call may fail when different modulation frequencies are used simultaneously. */
728
            IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen, irTxChannel[channel].proto.modfreq);
743
            IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen, irTxChannel[channel].proto.modfreq);
729
 
744
 
730
            /* Enter transmitting state. */
745
            /* Enter transmitting state. */
731
            irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
746
            irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
732
            break;
747
            break;
733
        }
748
        }
734
 
749
 
735
        case sns_irTransceive_STATE_START_TRANSMIT_PRONTO:
750
        case sns_irTransceive_STATE_START_TRANSMIT_PRONTO:
736
        {
751
        {
737
            /* Once sequence exists? */
752
            /* Once sequence exists? */
738
            if (irTxChannel[channel].onceSeqLen>0) {
753
            if (irTxChannel[channel].onceSeqLen>0) {
739
                /* Start IR transmission of the once sequence. */
754
                /* Start IR transmission of the once sequence. */
-
 
755
                int res;
740
                if(IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1, irTxChannel[channel].proto.modfreq) < 0) {
756
                if((res=IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].onceSeqLen - 1, irTxChannel[channel].proto.modfreq)) < 0) {
741
                    /* Send error code. */
757
                    /* Send response code. */
-
 
758
                    switch (res) {
-
 
759
                        case -1: /* Invalid freq. */
-
 
760
                        case -2: /* No data. */
-
 
761
                            /* Generic error code, probably invalid packet. */
742
                    pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ABORTED);
762
                            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
763
                            break;
-
 
764
                        case -3: /* Channel busy. */
-
 
765
                            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_CHANNELBUSY);
-
 
766
                            break;
-
 
767
                        case -4: /* Frequency cannot be changed due to transmission on other channels. */
-
 
768
                            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_OTHERFREQUENCYLOCKED);
-
 
769
                            break;
743
 
770
                    }
744
                    /* Enter idle state. */
771
                    /* Enter idle state. */
745
                    irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
772
                    irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
-
 
773
                    prontoAllocatedTxChannel = -1;
746
                    break;
774
                    break;
747
                }
775
                }
748
                else {
776
                else {
749
                    /* Enter transmitting state. */
777
                    /* Enter transmitting state. */
750
                                irTxChannel[channel].sendingPronto = TRUE;
778
                    irTxChannel[channel].sendingPronto = TRUE;
751
                                irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
779
                    irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
752
                    break;
780
                    break;
753
                }
781
                }
754
            }
782
            }
755
            /* Repeat sequence exists? */
783
            /* Repeat sequence exists? */
756
            else if (irTxChannel[channel].repSeqLen>0) {
784
            else if (irTxChannel[channel].repSeqLen>0) {
757
                /* Start IR transmission of the repeat sequence. */
785
                /* Start IR transmission of the repeat sequence. */
-
 
786
                int res;
758
                    if(IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].repSeqLen - 1, irTxChannel[channel].proto.modfreq) < 0) {
787
                if((res=IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].repSeqLen - 1, irTxChannel[channel].proto.modfreq)) < 0) {
-
 
788
                    /* Send response code. */
-
 
789
                    switch (res) {
-
 
790
                        case -1: /* Invalid freq. */
-
 
791
                        case -2: /* No data. */
759
                                        /* Send error code. */
792
                            /* Generic error code, probably invalid packet. */
760
                                        pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ABORTED);
793
                            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
794
                            break;
-
 
795
                        case -3: /* Channel busy. */
-
 
796
                            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_CHANNELBUSY);
-
 
797
                            break;
-
 
798
                        case -4: /* Frequency cannot be changed due to transmission on other channels. */
-
 
799
                            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_OTHERFREQUENCYLOCKED);
-
 
800
                            break;
761
 
801
                    }
762
                                        /* Enter idle state. */
802
                    /* Enter idle state. */
763
                                        irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
803
                    irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
764
                                        break;
804
                    prontoAllocatedTxChannel = -1;
765
                                }
805
                    break;
-
 
806
                }
766
                else {
807
                else {
767
                                        /* Enter transmitting state. */
808
                    /* Enter transmitting state. */
768
                                        irTxChannel[channel].sendingPronto = TRUE;
809
                    irTxChannel[channel].sendingPronto = TRUE;
769
                                        irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
810
                    irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
770
                    break;
811
                    break;
771
                                }
812
                }
772
            }
813
            }
773
            /* Neither once sequence nor repeat sequence exists! */
814
            /* Neither once sequence nor repeat sequence exists! */
774
            /* Send error code. */
815
            /* Generic error code, probably invalid packet. */
775
                        pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ABORTED);
816
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
776
                        /* Enter idle state. */
817
            /* Enter idle state. */
777
                        irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
818
            irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
-
 
819
            prontoAllocatedTxChannel = -1;
778
                        break;
820
            break;
779
        }
821
        }
780
 
822
 
781
        case sns_irTransceive_STATE_PRONTO_REPEAT:
823
        case sns_irTransceive_STATE_PRONTO_REPEAT:
782
        {
824
        {
783
            /* Check if done. */
825
            /* Check if done. */
784
            if ((irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) || irTxChannel[channel].stopSend) {
826
            if ((irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats && irTxChannel[channel].proto.repeats != 0xFF) || irTxChannel[channel].stopSend) {
785
                /* Pronto transmission was stopped/completed */
827
                /* Pronto transmission was stopped/completed. */
786
                pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED);
828
                pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED);
787
                irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
829
                irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
-
 
830
                prontoAllocatedTxChannel = -1;
788
                break;
831
                break;
789
            }
832
            }
790
 
833
 
791
            if (irTxChannel[channel].repeatCount < 255) {
834
            if (irTxChannel[channel].repeatCount < 255) {
792
                irTxChannel[channel].repeatCount++;
835
                irTxChannel[channel].repeatCount++;
793
            }
836
            }
794
 
837
 
795
            /* Repeat sequence exists? */
838
            /* Repeat sequence exists? */
796
            if (irTxChannel[channel].repSeqLen > 0) {
839
            if (irTxChannel[channel].repSeqLen > 0) {
797
                /* Use repeat seq */
840
                /* Use repeat seq. */
798
                uint16_t offset = ((uint16_t)irTxChannel[channel].onceSeqLen);
841
                uint16_t offset = ((uint16_t)irTxChannel[channel].onceSeqLen);
799
                /* Don't transmit last passive. last passive handled by timer */
842
                /* Don't transmit last passive. last passive handled by timer. */
800
                IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, offset, ((uint16_t)irTxChannel[channel].repSeqLen) - 1, irTxChannel[channel].proto.modfreq);
843
                IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, offset, ((uint16_t)irTxChannel[channel].repSeqLen) - 1, irTxChannel[channel].proto.modfreq);
801
            }
844
            }
802
            /* Once sequence exists? */
845
            /* Once sequence exists? */
803
            else if (irTxChannel[channel].onceSeqLen > 0) {
846
            else if (irTxChannel[channel].onceSeqLen > 0) {
804
                /* Use once seq */
847
                /* Use once seq. */
805
                /* Don't transmit last passive. last passive handled by timer */
848
                /* Don't transmit last passive. last passive handled by timer. */
806
                IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1, irTxChannel[channel].proto.modfreq);
849
                IrTransceiver_Transmit(channel, irTxChannel[channel].txbuf, 0, irTxChannel[channel].txlen - 1, irTxChannel[channel].proto.modfreq);
807
            }
850
            }
808
            irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
851
            irTxChannel[channel].state = sns_irTransceive_STATE_TRANSMITTING;
809
        }
852
        }
810
 
853
 
811
        case sns_irTransceive_STATE_TRANSMITTING:
854
        case sns_irTransceive_STATE_TRANSMITTING:
812
        {
855
        {
813
            if (irTxChannel[channel].sendComplete == TRUE)
856
            if (irTxChannel[channel].sendComplete == TRUE)
814
            {
857
            {
815
                cli();
858
                cli();
816
                irTxChannel[channel].sendComplete = FALSE;
859
                irTxChannel[channel].sendComplete = FALSE;
817
                sei();
860
                sei();
818
 
861
 
819
                if (irTxChannel[channel].sendingPronto)
862
                if (irTxChannel[channel].sendingPronto)
820
                {
863
                {
821
                    /* First repeat, or no repeat sequence defined => use last passive time in once seq */
864
                    /* First repeat, or no repeat sequence defined => use last passive time in once seq. */
822
                    if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0)
865
                    if(irTxChannel[channel].repeatCount == 0 || irTxChannel[channel].repSeqLen == 0)
823
                    {
866
                    {
824
                        /* Use last passive time as timeout */
867
                        /* Use last passive time as timeout. */
825
                        uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000;
868
                        uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].onceSeqLen - 1] / 1000;
826
                        Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0);
869
                        Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0);
827
                    }
870
                    }
828
                    /* Second, or later repeat => use last passive time in repeat seq */
871
                    /* Second, or later repeat => use last passive time in repeat seq. */
829
                    else
872
                    else
830
                    {
873
                    {
831
                        /* Use last passive time as timeout */
874
                        /* Use last passive time as timeout. */
832
                        uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1]  / 1000;
875
                        uint16_t lastPasTime = irTxChannel[channel].txbuf[irTxChannel[channel].txlen - 1]  / 1000;
833
                        Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0);
876
                        Timer_SetTimeout(irTxChannel[channel].timerNum, lastPasTime==0 ? 1 : lastPasTime, TimerTypeOneShot, 0);
834
                    }
877
                    }
835
                    irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING;
878
                    irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING;
836
                }
879
                }
Line 859... Line 902...
859
            irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING;
902
            irTxChannel[channel].state = sns_irTransceive_STATE_PAUSING;
860
            break;
903
            break;
861
        }
904
        }
862
 
905
 
863
        case sns_irTransceive_STATE_PAUSING:
906
        case sns_irTransceive_STATE_PAUSING:
864
        {
907
        {
865
            if (irTxChannel[channel].sendingPronto)
908
            if (irTxChannel[channel].sendingPronto)
866
            {
909
            {
867
                if (Timer_Expired(irTxChannel[channel].timerNum))
910
                if (Timer_Expired(irTxChannel[channel].timerNum))
868
                {
911
                {
869
                    irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT;
912
                    irTxChannel[channel].state = sns_irTransceive_STATE_PRONTO_REPEAT;
870
                }
913
                }
871
                break;
914
                break;
872
            }
915
            }
873
 
916
 
874
            if (Timer_Expired(irTxChannel[channel].timerNum))
917
            if (Timer_Expired(irTxChannel[channel].timerNum))
875
            {
918
            {
876
                irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT;
919
                irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT;
877
            }
920
            }
878
 
921
 
879
            /* Transmission is stopped when such command is recevied on can */
922
            /* Transmission is stopped when such command is recevied on can. */
880
            if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats)
923
            if (irTxChannel[channel].stopSend == TRUE && irTxChannel[channel].repeatCount >= irTxChannel[channel].proto.repeats)
881
            {
924
            {
882
                /* Non-pronto transmission was stopped/completed */
925
                /* Non-pronto transmission was stopped/completed. */
-
 
926
                // TODO: use another non-pronto code here? /jm
883
                pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED);
927
                pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_STOPPED);
884
 
928
 
885
                irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
929
                irTxChannel[channel].state = sns_irTransceive_STATE_IDLE;
886
            }
930
            }
887
            break;
931
            break;
888
        }
932
        }
889
        default:
933
        default:
890
            break;
934
            break;
891
        }
935
        }
892
#endif
936
#endif
893
 
937
 
894
    }
938
    }
895
}
939
}
896
 
940
 
897
 
941
 
898
/* Handle incoming CAN data */
942
/* Handle incoming CAN data. */
899
void sns_irTransceive_HandleMessage(StdCan_Msg_t *rxMsg)
943
void sns_irTransceive_HandleMessage(StdCan_Msg_t *rxMsg)
900
{
944
{
901
    /* Sanity check. */
945
    /* Sanity check. */
902
    if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS ||
946
    if (StdCan_Ret_class(rxMsg->Header) != CAN_MODULE_CLASS_SNS ||
903
        StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER ||
947
        StdCan_Ret_direction(rxMsg->Header) != DIRECTIONFLAG_TO_OWNER ||
904
        rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE ||
948
        rxMsg->Header.ModuleType != CAN_MODULE_TYPE_SNS_IRTRANSCEIVE ||
905
        rxMsg->Header.ModuleId != sns_irTransceive_ID) return;
949
        rxMsg->Header.ModuleId != sns_irTransceive_ID) return;
Line 915... Line 959...
915
        /* Get button status. */
959
        /* Get button status. */
916
        uint8_t buttonStatus = rxMsg->Data[0] & 0x0F;
960
        uint8_t buttonStatus = rxMsg->Data[0] & 0x0F;
917
 
961
 
918
        /* Sanity check. */
962
        /* Sanity check. */
919
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
963
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
920
            /* Invalid channel */
964
            /* Invalid channel. */
921
            break;
965
            break;
922
        }
966
        }
923
 
967
 
924
        /* Check if channel is busy sending Pronto */
968
        /* Check if channel is busy sending Pronto. */
925
        if (irTxChannel[channel].sendingPronto) {
969
        if (irTxChannel[channel].sendingPronto) {
926
            /* Channel busy */
970
            /* Channel busy. */
927
            break;
971
            break;
928
        }
972
        }
929
 
973
 
930
        if (buttonStatus == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED)
974
        if (buttonStatus == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_PRESSED)
931
        {
975
        {
932
            if (irTxChannel[channel].state == sns_irTransceive_STATE_IDLE)
976
            if (irTxChannel[channel].state == sns_irTransceive_STATE_IDLE)
933
            {
977
            {
934
                irTxChannel[channel].proto.protocol = rxMsg->Data[1];
978
                irTxChannel[channel].proto.protocol = rxMsg->Data[1];
935
                irTxChannel[channel].proto.data = rxMsg->Data[2];
979
                irTxChannel[channel].proto.data = rxMsg->Data[2];
936
                irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8;
980
                irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8;
937
                irTxChannel[channel].proto.data |= rxMsg->Data[3];
981
                irTxChannel[channel].proto.data |= rxMsg->Data[3];
938
                irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8;
982
                irTxChannel[channel].proto.data = irTxChannel[channel].proto.data<<8;
Line 942... Line 986...
942
 
986
 
943
                irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT;
987
                irTxChannel[channel].state = sns_irTransceive_STATE_START_TRANSMIT;
944
            }
988
            }
945
        }
989
        }
946
        else if (buttonStatus == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED)
990
        else if (buttonStatus == CAN_MODULE_ENUM_PHYSICAL_IR_STATUS_RELEASED)
947
        {
991
        {
948
            if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE)
992
            if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE)
949
            {
993
            {
950
                irTxChannel[channel].stopSend = TRUE;
994
                irTxChannel[channel].stopSend = TRUE;
951
            }
995
            }
952
        }
996
        }
953
        break;
997
        break;
954
    }
998
    }
955
 
999
 
956
#if sns_irTransceive_PRONTO_SUPPORT==1
1000
#if sns_irTransceive_PRONTO_SUPPORT==1
957
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART:
1001
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTART:
958
    {
1002
    {
959
        /* Get IR channel. */
1003
        /* Get IR channel. */
960
        uint8_t channel = rxMsg->Data[0] >> 4;
1004
        uint8_t channel = rxMsg->Data[0] >> 4;
961
 
1005
 
962
        /* Sanity check. */
1006
        /* Sanity check. */
963
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1007
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
-
 
1008
            /* Invalid channel. Generic error code. */
-
 
1009
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1010
            break;
-
 
1011
        }
-
 
1012
 
-
 
1013
        /* Check channel configuration. */
-
 
1014
        if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) {
964
            /* Invalid channel */
1015
            /* Not a TX channel. */
965
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1016
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
966
            break;
1017
            break;
967
        }
1018
        }
-
 
1019
 
-
 
1020
        /* Check if channel is busy. */
968
        if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) {
1021
        if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) {
969
            /* We're already transmitting on this channel */
1022
            /* We're already transmitting on this channel. */
970
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ABORTED);
1023
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_CHANNELBUSY);
971
            break;
1024
            break;
972
        }
1025
        }
973
 
1026
 
974
        /* Check if format is supported. */
1027
        /* Check if format is supported. */
975
        if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) {
1028
        if ((((uint16_t)(rxMsg->Data[0] & 0x0F) << 8) | (uint16_t)(rxMsg->Data[1])) != 0) {
976
            /* Invalid pronto format */
1029
            /* Invalid pronto format. Generic error code. */
977
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1030
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1031
            break;
-
 
1032
        }
-
 
1033
 
-
 
1034
        /* Check if any other pronto transmission is ongoing (i.e. if the pronto activeChannel is busy). */
-
 
1035
        if (prontoChannelIsAllocated() && irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_IDLE) {
-
 
1036
            /* Pronto data is already being transmitted (or prepared) on another channel. */
-
 
1037
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_ALREADYSENDINGPRONTO);
978
            break;
1038
            break;
979
        }
1039
        }
980
 
1040
 
981
        /* Extract received data. */
1041
        /* Extract received data. */
982
 
1042
 
983
        uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0);
1043
        uint32_t divider = (rxMsg->Data[2] << 8) | (rxMsg->Data[3] << 0);
984
        if (divider == 0) {
1044
        if (divider == 0) {
985
            /* Invalid wFrqDiv value */
1045
            /* Invalid wFrqDiv value. Generic error code. */
986
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1046
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
987
            break;
1047
            break;
988
        }
1048
        }
989
        uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000));
1049
        uint32_t freqkHz = (sns_irTransceive_BaseFrq / (divider*1000));
990
        if (freqkHz == 0) {
1050
        if (freqkHz == 0) {
991
            /* Invalid wFrqDiv value */
1051
            /* Invalid wFrqDiv value. Generic error code. */
992
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1052
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
993
            break;
1053
            break;
994
        }
1054
        }
995
        irTxChannel[channel].proto.modfreq = freqkHz;
1055
        irTxChannel[channel].proto.modfreq = freqkHz;
996
 
1056
 
997
        /* TODO: reconfigure with new modfreq, if no other channels sending pronto */
1057
        /* In case other channels are busy sending with other modfreqs, this will be reported by IrTransceiver_Transmit. */
998
 
1058
 
999
        /* Convert lenghts to bytes */
1059
        /* Convert lenghts to bytes. */
1000
        irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0));
1060
        irTxChannel[channel].onceSeqLen = 2*((((uint16_t)rxMsg->Data[4]) << 8) | (((uint16_t)rxMsg->Data[5]) << 0));
1001
        irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0));
1061
        irTxChannel[channel].repSeqLen = 2*((((uint16_t)rxMsg->Data[6]) << 8) | (((uint16_t)rxMsg->Data[7]) << 0));
1002
 
1062
 
1003
        /* Enter prepering pronto state and clear transmit buffer. */
1063
        /* Enter prepering pronto state and clear transmit buffer. */
1004
        irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO;
1064
        irTxChannel[channel].state = sns_irTransceive_STATE_PREPARING_PRONTO;
1005
        irTxChannel[channel].txlen = 0;
1065
        irTxChannel[channel].txlen = 0;
1006
        irTxChannel[channel].expectedSeqNr = 0;
1066
        irTxChannel[channel].expectedSeqNr = 0;
1007
        activeChannel = channel;
1067
        prontoAllocatedTxChannel = channel;
1008
 
1068
 
1009
        /* We're now waiting for pronto data */
1069
        /* We're now waiting for pronto data. */
1010
        pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_WAITING);
1070
        pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_WAITING);
1011
        break;
1071
        break;
1012
    }
1072
    }
1013
 
1073
 
1014
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP:
1074
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOSTOP:
1015
    {
1075
    {
1016
        /* Get IR channel. */
1076
        /* Get IR channel. */
1017
        uint8_t channel = rxMsg->Data[0] >> 4;
1077
        uint8_t channel = rxMsg->Data[0] >> 4;
1018
 
1078
 
1019
        /* Sanity check. */
1079
        /* Sanity check. */
1020
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1080
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1021
            /* Invalid channel */
1081
            /* Invalid channel. */
1022
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1082
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1083
            break;
-
 
1084
        }
-
 
1085
 
-
 
1086
        /* Check channel configuration. */
-
 
1087
        if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) {
-
 
1088
            /* Not a TX channel. */
-
 
1089
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1023
            break;
1090
            break;
1024
        }
1091
        }
1025
 
1092
 
1026
        irTxChannel[channel].stopSend = TRUE;
1093
        irTxChannel[channel].stopSend = TRUE;
1027
 
1094
 
-
 
1095
        if (!prontoChannelIsAllocated()) {
-
 
1096
            /* Nothing to stop. No pronto TX channel allocated right now. */
-
 
1097
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED);
-
 
1098
            break;
-
 
1099
        }
-
 
1100
 
1028
        /* State check. If we're not currently transmitting anything, the STOPPED reponse will never occur. */
1101
        /* State check. If we're not currently transmitting anything, the STOPPED reponse will never occur. */
1029
        /* TODO: better way to check this? /jm */
1102
        if (prontoChannelIsAllocated() &&
1030
        if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_START_TRANSMIT_PRONTO &&
1103
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_START_TRANSMIT_PRONTO &&
1031
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_TRANSMITTING &&
1104
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_TRANSMITTING &&
1032
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_PRONTO_REPEAT &&
1105
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PRONTO_REPEAT &&
1033
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_PAUSING &&
1106
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PAUSING &&
1034
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_START_PAUSE)
1107
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_START_PAUSE)
1035
        {
1108
        {
1036
            /* Nothing to stop. Not in TX state. Respond that we're already stopped */
1109
            /* Nothing to stop. Not in TX state. Respond that we're already stopped. */
1037
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED);
1110
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED);
-
 
1111
            break;
-
 
1112
        }
-
 
1113
 
-
 
1114
        /* Is pronto activeChannel active, but wrong channel specified? */
-
 
1115
        if (prontoChannelIsAllocated() && prontoAllocatedTxChannel != channel) {
-
 
1116
            /* Wrong pronto channel specified. */
-
 
1117
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR_WRONGPRONTOCHANNEL);
1038
            break;
1118
            break;
1039
        }
1119
        }
1040
 
1120
 
1041
        /* Response will be sent when transmission has been completed (i.e. stopped) */
1121
        /* Response will be sent when transmission has been completed (i.e. stopped). */
1042
        break;
1122
        break;
1043
    }
1123
    }
1044
 
1124
 
1045
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOCONTINUE:
1125
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOCONTINUE:
1046
    {
1126
    {
1047
        /* Get IR channel. */
1127
        /* Get IR channel. */
1048
        uint8_t channel = rxMsg->Data[0] >> 4;
1128
        uint8_t channel = rxMsg->Data[0] >> 4;
1049
 
1129
 
1050
        /* Sanity check. */
1130
        /* Sanity check. */
1051
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1131
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1052
            /* Invalid channel */
1132
            /* Invalid channel. */
1053
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1133
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1054
            break;
1134
            break;
1055
        }
1135
        }
1056
 
1136
 
-
 
1137
        /* Check channel configuration. */
-
 
1138
        if (irTxChannel[channel].state == sns_irTransceive_STATE_DISABLED) {
-
 
1139
            /* Not a TX channel. */
-
 
1140
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1141
            break;
-
 
1142
        }
-
 
1143
 
-
 
1144
        /* Check if channel is busy. */
-
 
1145
        if (irTxChannel[channel].state != sns_irTransceive_STATE_IDLE) {
-
 
1146
            /* We're already transmitting on this channel. */
-
 
1147
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_BUSY_CHANNELBUSY);
-
 
1148
            break;
-
 
1149
        }
-
 
1150
 
-
 
1151
        if (!prontoChannelIsAllocated()) {
-
 
1152
            /* Nothing to continue. No pronto TX channel allocated right now. */
-
 
1153
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED);
-
 
1154
            break;
-
 
1155
        }
-
 
1156
 
1057
        /* State check. We must already be in some transmit state */
1157
        /* State check. We must already be in some transmit state. */
1058
        /* TODO: better way to check this? /jm */
1158
        if (prontoChannelIsAllocated() &&
1059
        if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_START_TRANSMIT_PRONTO &&
1159
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_START_TRANSMIT_PRONTO &&
1060
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_TRANSMITTING &&
1160
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_TRANSMITTING &&
1061
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_PRONTO_REPEAT &&
1161
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PRONTO_REPEAT &&
1062
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_PAUSING &&
1162
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PAUSING &&
1063
            irTxChannel[activeChannel].state != sns_irTransceive_STATE_START_PAUSE)
1163
            irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_START_PAUSE)
1064
        {
1164
        {
1065
            /* Too late to continue! Not in TX state anymore */
1165
            /* Too late to continue! Not in TX state anymore. */
1066
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED);
1166
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ALREADYSTOPPED);
-
 
1167
            break;
-
 
1168
        }
-
 
1169
 
-
 
1170
        /* Is pronto activeChannel active, but wrong channel specified? */
-
 
1171
        if (prontoChannelIsAllocated() && prontoAllocatedTxChannel != channel) {
-
 
1172
            /* Wrong pronto channel specified. */
-
 
1173
            pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR_WRONGPRONTOCHANNEL);
1067
            break;
1174
            break;
1068
        }
1175
        }
1069
 
1176
 
1070
        /* Reset repeat counter, i.e. request additional repeats. */
1177
        /* Reset repeat counter, i.e. request additional repeats. */
1071
        irTxChannel[channel].repeatCount = 0;
1178
        irTxChannel[channel].repeatCount = 0;
1072
 
1179
 
1073
        /* The repeat period was extended. Still transmitting */
1180
        /* The repeat period was extended. Still transmitting. */
1074
        pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_TRANSMITTING);
1181
        pronto_sendResponse(channel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_TRANSMITTING);
1075
        break;
1182
        break;
1076
    }
1183
    }
1077
 
1184
 
1078
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1:  /* Fall through */
1185
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1:  /* Fall through. */
1079
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA2:  /* Fall through */
1186
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA2:  /* Fall through. */
1080
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA3:  /* Fall through */
1187
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA3:  /* Fall through. */
1081
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA4:  /* Fall through */
1188
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA4:  /* Fall through. */
1082
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA5:  /* Fall through */
1189
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA5:  /* Fall through. */
1083
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA6:  /* Fall through */
1190
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA6:  /* Fall through. */
1084
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA7:  /* Fall through */
1191
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA7:  /* Fall through. */
1085
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA8:  /* Fall through */
1192
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA8:  /* Fall through. */
1086
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA9:  /* Fall through */
1193
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA9:  /* Fall through. */
1087
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA10: /* Fall through */
1194
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA10: /* Fall through. */
1088
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA11: /* Fall through */
1195
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA11: /* Fall through. */
1089
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA12: /* Fall through */
1196
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA12: /* Fall through. */
1090
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA13: /* Fall through */
1197
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA13: /* Fall through. */
1091
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA14: /* Fall through */
1198
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA14: /* Fall through. */
1092
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA15: /* Fall through */
1199
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA15: /* Fall through. */
1093
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA16:
1200
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA16:
1094
    {
1201
    {
-
 
1202
        if (!prontoChannelIsAllocated()) {
-
 
1203
            /* Invalid state. */
-
 
1204
            pronto_sendResponse(0, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1205
            break;
-
 
1206
        }
-
 
1207
 
1095
        if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) {
1208
        if (irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) {
1096
            /* Invalid state. CAN msg probably out of order */
1209
            /* Invalid state. CAN msg probably out of order. */
-
 
1210
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1211
            break;
-
 
1212
        }
-
 
1213
 
-
 
1214
        if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[prontoAllocatedTxChannel].expectedSeqNr % 16)) {
-
 
1215
            /* Unexpected CAN msg, out of order. */
1097
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1216
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1217
            irTxChannel[prontoAllocatedTxChannel].state = sns_irTransceive_STATE_IDLE;
1098
            break;
1218
            break;
1099
        }
1219
        }
1100
 
1220
 
1101
        if ((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTODATA1) != (irTxChannel[activeChannel].expectedSeqNr % 16)) {
-
 
1102
            /* Unexpected CAN msg, out of order */
-
 
1103
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1104
            irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE;
-
 
1105
            break;
-
 
1106
        }
-
 
1107
 
-
 
1108
        /* Decode pronto data */
1221
        /* Decode pronto data. */
1109
        for (uint8_t i = 0; i < rxMsg->Length; i++) {
1222
        for (uint8_t i = 0; i < rxMsg->Length; i++) {
1110
            if (decodeProntoData(activeChannel, rxMsg->Data[i]) != 1) {
1223
            if (decodeProntoData(prontoAllocatedTxChannel, rxMsg->Data[i]) != 1) {
1111
                /* Decode error */
1224
                /* Decode error. */
1112
                pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1225
                pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1113
                irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE;
1226
                irTxChannel[prontoAllocatedTxChannel].state = sns_irTransceive_STATE_IDLE;
1114
                return;
1227
                return;
1115
            }
1228
            }
1116
        }
1229
        }
1117
 
1230
 
1118
        irTxChannel[activeChannel].expectedSeqNr++;
1231
        irTxChannel[prontoAllocatedTxChannel].expectedSeqNr++;
1119
 
1232
 
1120
        /* We're still waiting for more pronto data, or for pronto end */
1233
        /* We're still waiting for more pronto data, or for pronto end. */
1121
        pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_WAITING);
1234
        pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_WAITING);
1122
        break;
1235
        break;
1123
    }
1236
    }
1124
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1:   /* Fall through */
1237
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1:   /* Fall through. */
1125
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND2:   /* Fall through */
1238
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND2:   /* Fall through. */
1126
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND3:   /* Fall through */
1239
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND3:   /* Fall through. */
1127
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND4:   /* Fall through */
1240
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND4:   /* Fall through. */
1128
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND5:   /* Fall through */
1241
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND5:   /* Fall through. */
1129
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND6:   /* Fall through */
1242
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND6:   /* Fall through. */
1130
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND7:   /* Fall through */
1243
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND7:   /* Fall through. */
1131
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND8:   /* Fall through */
1244
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND8:   /* Fall through. */
1132
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND9:   /* Fall through */
1245
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND9:   /* Fall through. */
1133
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND10:  /* Fall through */
1246
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND10:  /* Fall through. */
1134
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND11:  /* Fall through */
1247
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND11:  /* Fall through. */
1135
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND12:  /* Fall through */
1248
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND12:  /* Fall through. */
1136
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND13:  /* Fall through */
1249
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND13:  /* Fall through. */
1137
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND14:  /* Fall through */
1250
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND14:  /* Fall through. */
1138
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15:  /* Fall through */
1251
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND15:  /* Fall through. */
1139
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16:  /* Fall through */
1252
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND16:  /* Fall through. */
1140
    {
1253
    {
-
 
1254
        if (!prontoChannelIsAllocated()) {
-
 
1255
            /* Invalid state. */
-
 
1256
            pronto_sendResponse(0, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
-
 
1257
            break;
-
 
1258
        }
-
 
1259
 
1141
        if (irTxChannel[activeChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) {
1260
        if (irTxChannel[prontoAllocatedTxChannel].state != sns_irTransceive_STATE_PREPARING_PRONTO) {
1142
            /* Invalid state. CAN msg probably out of order */
1261
            /* Invalid state. CAN msg probably out of order. */
1143
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1262
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1144
            break;
1263
            break;
1145
        }
1264
        }
1146
 
1265
 
1147
        if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[activeChannel].expectedSeqNr % 16)) {
1266
        if (((rxMsg->Header.Command - CAN_MODULE_CMD_IRTRANSCEIVE_IRPRONTOEND1) % 16) != (irTxChannel[prontoAllocatedTxChannel].expectedSeqNr % 16)) {
1148
            /* Unexpected CAN msg, out of order */
1267
            /* Unexpected CAN msg, out of order. */
1149
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1268
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1150
            irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE;
1269
            irTxChannel[prontoAllocatedTxChannel].state = sns_irTransceive_STATE_IDLE;
1151
            break;
1270
            break;
1152
        }
1271
        }
1153
 
1272
 
1154
        /* Decode remaining pronto data (if any). -1 because last byte is repeat count */
1273
        /* Decode remaining pronto data (if any). -1 because last byte is repeat count. */
1155
        for (uint16_t i = 0; i < rxMsg->Length - 1; i++) {
1274
        for (uint16_t i = 0; i < rxMsg->Length - 1; i++) {
1156
            if (decodeProntoData(activeChannel, rxMsg->Data[i]) < 0) {
1275
            if (decodeProntoData(prontoAllocatedTxChannel, rxMsg->Data[i]) < 0) {
1157
                /* Decode error */
1276
                /* Decode error. */
1158
                pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1277
                pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1159
                irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE;
1278
                irTxChannel[prontoAllocatedTxChannel].state = sns_irTransceive_STATE_IDLE;
1160
                return;
1279
                return;
1161
            }
1280
            }
1162
        }
1281
        }
1163
 
1282
 
1164
        /* Sanity check */
1283
        /* Sanity check. */
1165
        if (irTxChannel[activeChannel].txlen != (((uint16_t)irTxChannel[activeChannel].onceSeqLen + (uint16_t)irTxChannel[activeChannel].repSeqLen))) {
1284
        if (irTxChannel[prontoAllocatedTxChannel].txlen != (((uint16_t)irTxChannel[prontoAllocatedTxChannel].onceSeqLen + (uint16_t)irTxChannel[prontoAllocatedTxChannel].repSeqLen))) {
1166
            /* Length doesn't match the expected length */
1285
            /* Length doesn't match the expected length. */
1167
            pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1286
            pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_ERROR);
1168
            irTxChannel[activeChannel].state = sns_irTransceive_STATE_IDLE;
1287
            irTxChannel[prontoAllocatedTxChannel].state = sns_irTransceive_STATE_IDLE;
1169
            break;
1288
            break;
1170
        }
1289
        }
1171
 
1290
 
1172
        /* Last byte determines nr of repeats. 0xFF means INF, 0 means no repeats */
1291
        /* Last byte determines nr of repeats. 0xFF means INF, 0 means no repeats. */
1173
        irTxChannel[activeChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1];
1292
        irTxChannel[prontoAllocatedTxChannel].proto.repeats = rxMsg->Data[rxMsg->Length - 1];
1174
        irTxChannel[activeChannel].proto.timeout = 1; /* TODO: timer is buggy and doesn't support timeout 0, so we're forced to use 1ms extra between repeats */
1293
        irTxChannel[prontoAllocatedTxChannel].proto.timeout = 1; /* TODO: timer is buggy and doesn't support timeout 0, so we're forced to use 1ms extra between repeats. */
1175
 
1294
 
1176
        /* Convert pronto data to µs */
1295
        /* Convert pronto data to µs. */
1177
        uint32_t nsPerTick = 1000000UL / ((uint32_t)irTxChannel[activeChannel].proto.modfreq);
1296
        uint32_t nsPerTick = 1000000UL / ((uint32_t)irTxChannel[prontoAllocatedTxChannel].proto.modfreq);
1178
        for (uint16_t i = 0; i < irTxChannel[activeChannel].txlen; i++) {
1297
        for (uint16_t i = 0; i < irTxChannel[prontoAllocatedTxChannel].txlen; i++) {
1179
            uint32_t us = (((uint32_t)irTxChannel[activeChannel].txbuf[i]) * nsPerTick) / 1000UL;
1298
            uint32_t us = (((uint32_t)irTxChannel[prontoAllocatedTxChannel].txbuf[i]) * nsPerTick) / 1000UL;
1180
            if (us > 0xFFFFUL) {
1299
            if (us > 0xFFFFUL) {
1181
                us = 0xFFFFUL;
1300
                us = 0xFFFFUL;
1182
            }
1301
            }
1183
            irTxChannel[activeChannel].txbuf[i] = (uint16_t)us;
1302
            irTxChannel[prontoAllocatedTxChannel].txbuf[i] = (uint16_t)us;
1184
        }
1303
        }
1185
 
1304
 
1186
        /* Send IR data */
1305
        /* Send IR data. */
1187
        irTxChannel[activeChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO;
1306
        irTxChannel[prontoAllocatedTxChannel].state = sns_irTransceive_STATE_START_TRANSMIT_PRONTO;
1188
 
1307
 
1189
        /* We're now transmitting the pronto data */
1308
        /* We're now transmitting the pronto data. */
1190
        pronto_sendResponse(activeChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_TRANSMITTING);
1309
        pronto_sendResponse(prontoAllocatedTxChannel, CAN_MODULE_ENUM_IRTRANSCEIVE_IRPRONTORESPONSE_RESPONSE_TRANSMITTING);
1191
        break;
1310
        break;
1192
    }
1311
    }
1193
 
1312
 
1194
/* TODO: In IR state machine add sending a response frame when ir stops sending, also implement pronto repeat */
1313
/* TODO: In IR state machine add sending a response frame when ir stops sending, also implement pronto repeat. */
1195
#endif
1314
#endif
1196
#endif
1315
#endif
1197
 
1316
 
1198
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRCONFIG:
1317
    case CAN_MODULE_CMD_IRTRANSCEIVE_IRCONFIG:
1199
    {
1318
    {
1200
        /* Get IR channel. */
1319
        /* Get IR channel. */
1201
        uint8_t channel = rxMsg->Data[0] >> 4;
1320
        uint8_t channel = rxMsg->Data[0] >> 4;
1202
 
1321
 
1203
        /* Sanity check. */
1322
        /* Sanity check. */
1204
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1323
        if (channel >= IR_SUPPORTED_NUM_CHANNELS) {
1205
            /* Invalid channel */
1324
            /* Invalid channel. */
1206
            break;
1325
            break;
1207
        }
1326
        }
1208
 
1327
 
1209
        uint8_t config = rxMsg->Data[0] & 0x0f;
1328
        uint8_t config = rxMsg->Data[0] & 0x0f;
1210
        uint8_t power = rxMsg->Data[1]>>6;
1329
        uint8_t power = rxMsg->Data[1]>>6;
1211
        uint32_t divider = ((uint16_t)rxMsg->Data[2] << 8) | ((uint16_t)rxMsg->Data[3] << 0);
1330
        uint32_t divider = ((uint16_t)rxMsg->Data[2] << 8) | ((uint16_t)rxMsg->Data[3] << 0);
1212
        if (divider == 0) {
1331
        if (divider == 0) {
1213
            /* Invalid modfreq */
1332
            /* Invalid modfreq. */
1214
            break;
1333
            break;
1215
        }
1334
        }
1216
        uint32_t modfreq = (sns_irTransceive_BaseFrq / (divider*1000));
1335
        uint32_t modfreq = (sns_irTransceive_BaseFrq / (divider*1000));
1217
        if (modfreq == 0) {
1336
        if (modfreq == 0) {
1218
            /* Invalid modfreq */
1337
            /* Invalid modfreq. */
1219
            break;
1338
            break;
1220
        }
1339
        }
1221
        sns_irTransceive_setConfig(channel, config, power, modfreq);
1340
        sns_irTransceive_setConfig(channel, config, power, modfreq);
1222
 
1341
 
1223
#ifdef sns_irTransceive_USEEEPROM
1342
#ifdef sns_irTransceive_USEEEPROM