Subversion Repositories HomeAutomation

Rev

Rev 1910 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1156 linlun 1
 
2
#include "act_softPWM.h"
1183 linlun 3
 
1394 linlun 4
#if (act_softPWM_PIN_0_INVERT == 0)
5
    #define set_pin_0_below_trigger gpio_set_pin(act_softPWM_PIN_0)
6
    #define set_pin_0_above_trigger gpio_clr_pin(act_softPWM_PIN_0)
7
#else
1395 linlun 8
    #define set_pin_0_below_trigger gpio_clr_pin(act_softPWM_PIN_0)
9
    #define set_pin_0_above_trigger gpio_set_pin(act_softPWM_PIN_0)
1394 linlun 10
#endif
1183 linlun 11
 
1394 linlun 12
#if (act_softPWM_PIN_1_INVERT == 0)
13
    #define set_pin_1_below_trigger gpio_set_pin(act_softPWM_PIN_1)
14
    #define set_pin_1_above_trigger gpio_clr_pin(act_softPWM_PIN_1)
15
#else
1395 linlun 16
    #define set_pin_1_below_trigger gpio_clr_pin(act_softPWM_PIN_1)
17
    #define set_pin_1_above_trigger gpio_set_pin(act_softPWM_PIN_1)
1394 linlun 18
#endif
1156 linlun 19
 
1394 linlun 20
#if (act_softPWM_PIN_2_INVERT == 0)
21
    #define set_pin_2_below_trigger gpio_set_pin(act_softPWM_PIN_2)
22
    #define set_pin_2_above_trigger gpio_clr_pin(act_softPWM_PIN_2)
23
#else
1395 linlun 24
    #define set_pin_2_below_trigger gpio_clr_pin(act_softPWM_PIN_2)
25
    #define set_pin_2_above_trigger gpio_set_pin(act_softPWM_PIN_2)
1394 linlun 26
#endif
1183 linlun 27
 
1394 linlun 28
#if (act_softPWM_PIN_3_INVERT == 0)
29
    #define set_pin_3_below_trigger gpio_set_pin(act_softPWM_PIN_3)
30
    #define set_pin_3_above_trigger gpio_clr_pin(act_softPWM_PIN_3)
31
#else
1395 linlun 32
    #define set_pin_3_below_trigger gpio_clr_pin(act_softPWM_PIN_3)
33
    #define set_pin_3_above_trigger gpio_set_pin(act_softPWM_PIN_3)
1394 linlun 34
#endif
35
 
36
#if (act_softPWM_PIN_4_INVERT == 0)
37
    #define set_pin_4_below_trigger gpio_set_pin(act_softPWM_PIN_4)
38
    #define set_pin_4_above_trigger gpio_clr_pin(act_softPWM_PIN_4)
39
#else
1395 linlun 40
    #define set_pin_4_below_trigger gpio_clr_pin(act_softPWM_PIN_4)
41
    #define set_pin_4_above_trigger gpio_set_pin(act_softPWM_PIN_4)
1394 linlun 42
#endif
43
 
44
#if (act_softPWM_PIN_5_INVERT == 0)
45
    #define set_pin_5_below_trigger gpio_set_pin(act_softPWM_PIN_5)
46
    #define set_pin_5_above_trigger gpio_clr_pin(act_softPWM_PIN_5)
47
#else
1395 linlun 48
    #define set_pin_5_below_trigger gpio_clr_pin(act_softPWM_PIN_5)
49
    #define set_pin_5_above_trigger gpio_set_pin(act_softPWM_PIN_5)
1394 linlun 50
#endif
51
 
52
#if (act_softPWM_PIN_6_INVERT == 0)
53
    #define set_pin_6_below_trigger gpio_set_pin(act_softPWM_PIN_6)
54
    #define set_pin_6_above_trigger gpio_clr_pin(act_softPWM_PIN_6)
55
#else
1395 linlun 56
    #define set_pin_6_below_trigger gpio_clr_pin(act_softPWM_PIN_6)
57
    #define set_pin_6_above_trigger gpio_set_pin(act_softPWM_PIN_6)
1394 linlun 58
#endif
59
 
60
#if (act_softPWM_PIN_7_INVERT == 0)
61
    #define set_pin_7_below_trigger gpio_set_pin(act_softPWM_PIN_7)
62
    #define set_pin_7_above_trigger gpio_clr_pin(act_softPWM_PIN_7)
63
#else
1395 linlun 64
    #define set_pin_7_below_trigger gpio_clr_pin(act_softPWM_PIN_7)
65
    #define set_pin_7_above_trigger gpio_set_pin(act_softPWM_PIN_7)
1394 linlun 66
#endif
67
 
68
static uint16_t currentTimer = 0;
69
static uint16_t maxTimer = 10;
1395 linlun 70
static uint8_t resolution = 1;
1394 linlun 71
static uint8_t act_softPWM_ReportInterval =0;
72
static uint8_t currentSendChannelId = 0;
73
 
1978 arune 74
#if act_softPWM_USEEEPROM==1
1156 linlun 75
#include "act_softPWM_eeprom.h"
76
struct eeprom_act_softPWM EEMEM eeprom_act_softPWM =
77
{
78
    {
79
        ///TODO: Define initialization values on the EEPROM variables here, this will generate a *.eep file that can be used to store this values to the node, can in future be done with a EEPROM module and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file. 
1369 linlun 80
        10000,  // x
81
        10,
1180 linlun 82
        0x14    //Reportinteval 20 sec.
1156 linlun 83
    },
84
 
85
};
86
#endif
1183 linlun 87
 
1394 linlun 88
static uint16_t pwmValue[NUMBEROFCHANNELS];
89
static uint16_t pwmValueCAN[NUMBEROFCHANNELS];
90
 
1370 linlun 91
#if act_softPWM_ACTIVATE_AUTOOFF != 0
1394 linlun 92
static uint8_t offCounter[NUMBEROFCHANNELS];
1370 linlun 93
#endif
1394 linlun 94
 
1156 linlun 95
void act_softPWM_Init(void)
96
{
1978 arune 97
#if act_softPWM_USEEEPROM==1
1379 linlun 98
    //if (EEDATA_OK)
99
    //{
100
     // ;
101
    //} else
102
    //{ //The CRC of the EEPROM is not correct, store default values and update CRC
1369 linlun 103
        eeprom_write_word_crc(EEDATA16.maxTimer, 10000 , WITHOUT_CRC);
1379 linlun 104
        eeprom_write_byte_crc(EEDATA.resolution, 1 , WITHOUT_CRC);
105
        eeprom_write_byte_crc(EEDATA.ReportInterval, 0x05 , WITHOUT_CRC);
1180 linlun 106
        EEDATA_UPDATE_CRC;
1379 linlun 107
    //}
108
    act_softPWM_ReportInterval = eeprom_read_byte(EEDATA.ReportInterval);
1369 linlun 109
    maxTimer = eeprom_read_word(EEDATA16.maxTimer);
110
    resolution = eeprom_read_byte(EEDATA.resolution);
1180 linlun 111
    Timer_SetTimeout(act_softPWM_SEND_TIMER, act_softPWM_ReportInterval*1000 , TimerTypeFreeRunning, 0);
1156 linlun 112
#endif  
113
    ///TODO: Initialize hardware etc here
1369 linlun 114
uint8_t i;
1373 linlun 115
for (i=0; i < NUMBEROFCHANNELS; i++) {
1369 linlun 116
    pwmValue[i] = 0;
1379 linlun 117
    pwmValueCAN[i] = 0;
1369 linlun 118
}
1394 linlun 119
#ifdef act_softPWM_PIN_0
120
    gpio_set_out(act_softPWM_PIN_0);
121
    set_pin_0_below_trigger;
1177 linlun 122
#endif
1394 linlun 123
#ifdef act_softPWM_PIN_1
124
    gpio_set_out(act_softPWM_PIN_1);
125
    set_pin_1_below_trigger;
1177 linlun 126
#endif
1394 linlun 127
#ifdef act_softPWM_PIN_2
128
    gpio_set_out(act_softPWM_PIN_2);
129
    set_pin_2_below_trigger;
1177 linlun 130
#endif
1394 linlun 131
#ifdef act_softPWM_PIN_3
132
    gpio_set_out(act_softPWM_PIN_3);
133
    set_pin_3_below_trigger;
1177 linlun 134
#endif
1394 linlun 135
#ifdef act_softPWM_PIN_4
136
    gpio_set_out(act_softPWM_PIN_4);
137
    set_pin_4_below_trigger;
1177 linlun 138
#endif
1394 linlun 139
#ifdef act_softPWM_PIN_5
140
    gpio_set_out(act_softPWM_PIN_5);
141
    set_pin_5_below_trigger;
1177 linlun 142
#endif
1394 linlun 143
#ifdef act_softPWM_PIN_6
144
    gpio_set_out(act_softPWM_PIN_6);
145
    set_pin_6_below_trigger;
1177 linlun 146
#endif
1394 linlun 147
#ifdef act_softPWM_PIN_7
148
    gpio_set_out(act_softPWM_PIN_7);
149
    set_pin_7_below_trigger;
1177 linlun 150
#endif
1156 linlun 151
 
1177 linlun 152
    Timer_SetTimeout(act_softPWM_TIMER, resolution, TimerTypeFreeRunning, NULL);
1156 linlun 153
}
154
 
155
void act_softPWM_Process(void)
156
{
157
    if (Timer_Expired(act_softPWM_TIMER)) {
158
        currentTimer++;
1379 linlun 159
        if (currentTimer >= maxTimer) {
160
//printf("cleard Timer %d\n",pwmValue[0]);
1156 linlun 161
            currentTimer=0;
1394 linlun 162
            #ifdef act_softPWM_PIN_0
1379 linlun 163
                if (pwmValue[0]!=0) {
1394 linlun 164
                    set_pin_0_below_trigger;
165
                }
1177 linlun 166
            #endif
1394 linlun 167
            #ifdef act_softPWM_PIN_1 
168
                if (pwmValue[1]!=0) {
169
                    set_pin_1_below_trigger;
170
                }
1177 linlun 171
            #endif
1394 linlun 172
            #ifdef act_softPWM_PIN_2 
173
                if (pwmValue[2]!=0) {
174
                    set_pin_2_below_trigger;
175
                }
1177 linlun 176
            #endif
1394 linlun 177
            #ifdef act_softPWM_PIN_3 
178
                if (pwmValue[3]!=0) {
179
                    set_pin_3_below_trigger;
180
                }
1177 linlun 181
            #endif
1394 linlun 182
            #ifdef act_softPWM_PIN_4 
183
                if (pwmValue[4]!=0) {
184
                    set_pin_4_below_trigger;
185
                }
1177 linlun 186
            #endif
1394 linlun 187
            #ifdef act_softPWM_PIN_5 
188
                if (pwmValue[5]!=0) {
189
                    set_pin_5_below_trigger;
190
                }
1177 linlun 191
            #endif
1394 linlun 192
            #ifdef act_softPWM_PIN_6 
193
                if (pwmValue[6]!=0) {
194
                    set_pin_6_below_trigger;
195
                }
1177 linlun 196
            #endif
1394 linlun 197
            #ifdef act_softPWM_PIN_7 
198
                if (pwmValue[7]!=0) {
199
                    set_pin_7_below_trigger;
200
                }
1177 linlun 201
            #endif
1156 linlun 202
        }
1394 linlun 203
        #ifdef act_softPWM_PIN_0
1395 linlun 204
        if (currentTimer >= pwmValue[0] && gpio_get_state(act_softPWM_PIN_0) != act_softPWM_PIN_0_INVERT) {
1394 linlun 205
            set_pin_0_above_trigger;
1156 linlun 206
        }
1177 linlun 207
        #endif
1394 linlun 208
        #ifdef act_softPWM_PIN_1
1395 linlun 209
        if (currentTimer >= pwmValue[1] && gpio_get_state(act_softPWM_PIN_1) != act_softPWM_PIN_1_INVERT) {
1394 linlun 210
            set_pin_1_above_trigger;
1156 linlun 211
        }
1177 linlun 212
        #endif
1394 linlun 213
        #ifdef act_softPWM_PIN_2
1395 linlun 214
        if (currentTimer >= pwmValue[2] && gpio_get_state(act_softPWM_PIN_2) != act_softPWM_PIN_2_INVERT) {
1394 linlun 215
            set_pin_2_above_trigger;
1156 linlun 216
        }
1177 linlun 217
        #endif
1394 linlun 218
        #ifdef act_softPWM_PIN_3
1395 linlun 219
        if (currentTimer >= pwmValue[3] && gpio_get_state(act_softPWM_PIN_3) != act_softPWM_PIN_3_INVERT) {
1394 linlun 220
            set_pin_3_above_trigger;
1177 linlun 221
        }
222
        #endif
1394 linlun 223
        #ifdef act_softPWM_PIN_4
1395 linlun 224
        if (currentTimer >= pwmValue[4] && gpio_get_state(act_softPWM_PIN_4) != act_softPWM_PIN_4_INVERT) {
1394 linlun 225
            set_pin_4_above_trigger;
1177 linlun 226
        }
227
        #endif
1394 linlun 228
        #ifdef act_softPWM_PIN_5
1395 linlun 229
        if (currentTimer >= pwmValue[5] && gpio_get_state(act_softPWM_PIN_5) != act_softPWM_PIN_5_INVERT) {
1394 linlun 230
            set_pin_5_above_trigger;
1177 linlun 231
        }
232
        #endif
1394 linlun 233
        #ifdef act_softPWM_PIN_6
1395 linlun 234
        if (currentTimer >= pwmValue[6] && gpio_get_state(act_softPWM_PIN_6) != act_softPWM_PIN_6_INVERT) {
1394 linlun 235
            set_pin_6_above_trigger;
1177 linlun 236
        }
237
        #endif
1394 linlun 238
        #ifdef act_softPWM_PIN_7
1395 linlun 239
        if (currentTimer >= pwmValue[7] && gpio_get_state(act_softPWM_PIN_7) != act_softPWM_PIN_7_INVERT) {
1394 linlun 240
            set_pin_7_above_trigger;
1177 linlun 241
        }
242
        #endif
1156 linlun 243
    }
1180 linlun 244
    if (Timer_Expired(act_softPWM_SEND_TIMER)) {
1379 linlun 245
//printf("sending...\n");
1184 linlun 246
        while(1)
247
        {
248
            if (0
1394 linlun 249
                #ifdef act_softPWM_PIN_0
1184 linlun 250
                || currentSendChannelId == 0
251
                #endif
1394 linlun 252
                #ifdef act_softPWM_PIN_1
1184 linlun 253
                || currentSendChannelId == 1
254
                #endif
1394 linlun 255
                #ifdef act_softPWM_PIN_2
1184 linlun 256
                || currentSendChannelId == 2
257
                #endif
1394 linlun 258
                #ifdef act_softPWM_PIN_3
1184 linlun 259
                || currentSendChannelId == 3
260
                #endif
1394 linlun 261
                #ifdef act_softPWM_PIN_4
1184 linlun 262
                || currentSendChannelId == 4
263
                #endif
1394 linlun 264
                #ifdef act_softPWM_PIN_5
1184 linlun 265
                || currentSendChannelId == 5
266
                #endif
1394 linlun 267
                #ifdef act_softPWM_PIN_6
1184 linlun 268
                || currentSendChannelId == 6
269
                #endif
1394 linlun 270
                #ifdef act_softPWM_PIN_7
1184 linlun 271
                || currentSendChannelId == 7
272
                #endif
273
            ) {
274
                break;
275
            }
276
            currentSendChannelId++;
277
            if (currentSendChannelId >= NUMBEROFCHANNELS)
278
                currentSendChannelId=0;
279
        }
1379 linlun 280
//printf(" %d\n",currentSendChannelId);
1180 linlun 281
        StdCan_Msg_t txMsg;
282
        StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
283
        StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
284
        txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_SOFTPWM;
285
        txMsg.Header.ModuleId = act_softPWM_ID;
286
        txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PWM;
287
        txMsg.Length = 3;
288
        txMsg.Data[0] = currentSendChannelId;
1762 linlun 289
        txMsg.Data[1] = (pwmValueCAN[currentSendChannelId]>>8)&0xff;
290
        txMsg.Data[2] = (pwmValueCAN[currentSendChannelId])&0xff;
1369 linlun 291
        while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
1379 linlun 292
//printf("sent pwm2: %d %d\n",pwmValueCAN[currentSendChannelId],currentSendChannelId); 
1370 linlun 293
#if act_softPWM_ACTIVATE_AUTOOFF != 0
294
        offCounter[currentSendChannelId]--;
295
        if (offCounter[currentSendChannelId] == 0) {
296
            pwmValue[currentSendChannelId] = 0;
1379 linlun 297
            pwmValueCAN[currentSendChannelId] = 0;
1370 linlun 298
            offCounter[currentSendChannelId] = 1;
299
        }
300
#endif
1180 linlun 301
        currentSendChannelId++;
302
        if (currentSendChannelId >= NUMBEROFCHANNELS)
303
            currentSendChannelId=0;
304
    }
1156 linlun 305
}
306
 
1180 linlun 307
 
308
 
1156 linlun 309
void act_softPWM_HandleMessage(StdCan_Msg_t *rxMsg)
310
{
311
    if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
312
        StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
313
        rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_SOFTPWM &&
314
        rxMsg->Header.ModuleId == act_softPWM_ID)
315
    {
316
        switch (rxMsg->Header.Command)
317
        {
1379 linlun 318
//printf("Got can\n");
1177 linlun 319
        case CAN_MODULE_CMD_PHYSICAL_PWM:
1379 linlun 320
//printf("Got pwm value\n");
1369 linlun 321
            if (rxMsg->Length == 3)
1184 linlun 322
            {
1379 linlun 323
//printf("3\n");
1369 linlun 324
                if (rxMsg->Data[0] < NUMBEROFCHANNELS) {
1379 linlun 325
                    pwmValueCAN[rxMsg->Data[0]] = ((uint16_t)((rxMsg->Data[1]<<8) + rxMsg->Data[2]));
1394 linlun 326
                    if (pwmValueCAN[rxMsg->Data[0]] >= 10000) {
327
                        pwmValue[rxMsg->Data[0]] = maxTimer+1;
1762 linlun 328
                        pwmValueCAN[rxMsg->Data[0]] = 10000;
1394 linlun 329
                    } else {
330
                        pwmValue[rxMsg->Data[0]] = ((uint16_t)((((uint32_t)pwmValueCAN[rxMsg->Data[0]])*(maxTimer))/10000));
331
                    }
1379 linlun 332
                    rxMsg->Data[1] = (uint8_t)(0x00ff & (pwmValueCAN[rxMsg->Data[0]]>>8));
333
                    rxMsg->Data[2] = (uint8_t)(0x00ff & pwmValueCAN[rxMsg->Data[0]]);
1369 linlun 334
                    StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
335
                    rxMsg->Length = 3;
336
                    while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1379 linlun 337
//printf("sent pwm3: %d %d %d\n",pwmValue[rxMsg->Data[0]],maxTimer,resolution); 
1370 linlun 338
                    #if act_softPWM_ACTIVATE_AUTOOFF != 0
339
                    offCounter[rxMsg->Data[0]] = act_softPWM_ACTIVATE_AUTOOFF;
340
                    #endif
1369 linlun 341
                }
1243 arune 342
            } else if (rxMsg->Length == 1) {
1379 linlun 343
                rxMsg->Data[1] = (uint8_t)(0x00ff & (pwmValueCAN[rxMsg->Data[0]]>>8));
344
                rxMsg->Data[2] = (uint8_t)(0x00ff & pwmValueCAN[rxMsg->Data[0]]);
1184 linlun 345
                StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
1369 linlun 346
                rxMsg->Length = 3;
347
                while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1379 linlun 348
            } else {
349
                rxMsg->Data[0] = (8);
350
                rxMsg->Data[1] = (uint8_t)(0x00ff & (pwmValueCAN[0]>>8));
351
                rxMsg->Data[2] = (uint8_t)(0x00ff & pwmValueCAN[0]);
352
                StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
353
                rxMsg->Length = 3;
354
                while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1177 linlun 355
            }
356
            break;
357
        case CAN_MODULE_CMD_SOFTPWM_CONFIG:
358
            maxTimer = (((uint16_t)rxMsg->Data[0])<<8) + rxMsg->Data[1];
359
            resolution = rxMsg->Data[2];
360
            Timer_SetTimeout(act_softPWM_TIMER, resolution, TimerTypeFreeRunning, NULL);
1369 linlun 361
            eeprom_write_word_crc(EEDATA16.maxTimer, maxTimer , WITHOUT_CRC);
362
            eeprom_write_byte_crc(EEDATA.resolution, resolution , WITHOUT_CRC);
363
            EEDATA_UPDATE_CRC;
364
            StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
365
            while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1177 linlun 366
            break;
1180 linlun 367
        case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
368
            if (rxMsg->Length > 0)
369
            {
370
                act_softPWM_ReportInterval = rxMsg->Data[0];
1242 arune 371
                eeprom_write_byte_crc(EEDATA.ReportInterval, act_softPWM_ReportInterval , WITH_CRC);
1180 linlun 372
                Timer_SetTimeout(act_softPWM_SEND_TIMER, act_softPWM_ReportInterval*1000 , TimerTypeFreeRunning, 0);
373
            }
1177 linlun 374
 
1180 linlun 375
            StdCan_Msg_t txMsg;
376
 
377
            StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
378
            StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
379
            txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_SOFTPWM;
380
            txMsg.Header.ModuleId = act_softPWM_ID;
381
            txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
382
            txMsg.Length = 1;
383
            txMsg.Data[0] = act_softPWM_ReportInterval;
1369 linlun 384
            while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
1180 linlun 385
            break;
1156 linlun 386
        }
387
    }
388
}
389
 
390
void act_softPWM_List(uint8_t ModuleSequenceNumber)
391
{
392
    StdCan_Msg_t txMsg;
393
 
394
    StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
395
    StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
396
    txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_SOFTPWM; ///TODO: Change this to the actual module type
397
    txMsg.Header.ModuleId = act_softPWM_ID;
398
    txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
399
    txMsg.Length = 6;
400
 
1910 arune 401
    uint32_t HwId=BIOS_GetHwId();
402
    txMsg.Data[0] = HwId&0xff;
403
    txMsg.Data[1] = (HwId>>8)&0xff;
404
    txMsg.Data[2] = (HwId>>16)&0xff;
405
    txMsg.Data[3] = (HwId>>24)&0xff;
1156 linlun 406
 
407
    txMsg.Data[4] = NUMBER_OF_MODULES;
408
    txMsg.Data[5] = ModuleSequenceNumber;
409
 
410
    while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
411
}