Subversion Repositories HomeAutomation

Rev

Rev 1373 | Rev 1387 | Go to most recent revision | 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
 
4
 
1177 linlun 5
uint16_t currentTimer = 0;
6
uint16_t maxTimer = 10;
7
uint8_t resolution = 1;
1369 linlun 8
uint8_t act_softPWM_ReportInterval;
1180 linlun 9
uint8_t currentSendChannelId = 0;
1156 linlun 10
 
1183 linlun 11
 
1156 linlun 12
#ifdef act_softPWM_USEEEPROM
13
#include "act_softPWM_eeprom.h"
14
struct eeprom_act_softPWM EEMEM eeprom_act_softPWM =
15
{
16
    {
17
        ///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 18
        10000,  // x
19
        10,
1180 linlun 20
        0x14    //Reportinteval 20 sec.
1156 linlun 21
    },
22
 
23
};
24
#endif
1183 linlun 25
 
1180 linlun 26
uint16_t pwmValue[NUMBEROFCHANNELS];
1379 linlun 27
uint16_t pwmValueCAN[NUMBEROFCHANNELS];
1370 linlun 28
#if act_softPWM_ACTIVATE_AUTOOFF != 0
29
uint8_t offCounter[NUMBEROFCHANNELS];
30
#endif
1156 linlun 31
void act_softPWM_Init(void)
32
{
33
#ifdef act_softPWM_USEEEPROM
1379 linlun 34
    //if (EEDATA_OK)
35
    //{
36
     // ;
37
    //} else
38
    //{ //The CRC of the EEPROM is not correct, store default values and update CRC
1369 linlun 39
        eeprom_write_word_crc(EEDATA16.maxTimer, 10000 , WITHOUT_CRC);
1379 linlun 40
        eeprom_write_byte_crc(EEDATA.resolution, 1 , WITHOUT_CRC);
41
        eeprom_write_byte_crc(EEDATA.ReportInterval, 0x05 , WITHOUT_CRC);
1180 linlun 42
        EEDATA_UPDATE_CRC;
1379 linlun 43
    //}
44
    act_softPWM_ReportInterval = eeprom_read_byte(EEDATA.ReportInterval);
1369 linlun 45
    maxTimer = eeprom_read_word(EEDATA16.maxTimer);
46
    resolution = eeprom_read_byte(EEDATA.resolution);
1180 linlun 47
    Timer_SetTimeout(act_softPWM_SEND_TIMER, act_softPWM_ReportInterval*1000 , TimerTypeFreeRunning, 0);
1156 linlun 48
#endif  
49
    ///TODO: Initialize hardware etc here
1369 linlun 50
uint8_t i;
1373 linlun 51
for (i=0; i < NUMBEROFCHANNELS; i++) {
1369 linlun 52
    pwmValue[i] = 0;
1379 linlun 53
    pwmValueCAN[i] = 0;
1369 linlun 54
}
1177 linlun 55
#ifdef PIN_0
56
    gpio_set_out(PIN_0);
57
    gpio_clr_pin(PIN_0);
58
#endif
59
#ifdef PIN_1
60
    gpio_set_out(PIN_1);
61
    gpio_clr_pin(PIN_1);
62
#endif
63
#ifdef PIN_2
64
    gpio_set_out(PIN_2);
65
    gpio_clr_pin(PIN_2);
66
#endif
67
#ifdef PIN_3
68
    gpio_set_out(PIN_3);
69
    gpio_clr_pin(PIN_3);
70
#endif
71
#ifdef PIN_4
72
    gpio_set_out(PIN_4);
73
    gpio_clr_pin(PIN_4);
74
#endif
75
#ifdef PIN_5
76
    gpio_set_out(PIN_5);
77
    gpio_clr_pin(PIN_5);
78
#endif
79
#ifdef PIN_6
80
    gpio_set_out(PIN_6);
81
    gpio_clr_pin(PIN_6);
82
#endif
83
#ifdef PIN_7
84
    gpio_set_out(PIN_7);
85
    gpio_clr_pin(PIN_7);
86
#endif
1156 linlun 87
 
1177 linlun 88
    Timer_SetTimeout(act_softPWM_TIMER, resolution, TimerTypeFreeRunning, NULL);
1156 linlun 89
}
90
 
91
void act_softPWM_Process(void)
92
{
93
    if (Timer_Expired(act_softPWM_TIMER)) {
94
        currentTimer++;
1379 linlun 95
        if (currentTimer >= maxTimer) {
96
//printf("cleard Timer %d\n",pwmValue[0]);
1156 linlun 97
            currentTimer=0;
1370 linlun 98
            #ifdef PIN_0
1379 linlun 99
                if (pwmValue[0]!=0) {
1370 linlun 100
                    gpio_set_pin(PIN_0);
1379 linlun 101
//printf("pwm_0 On %d %d %d\n", pwmValue[0], currentTimer, maxTimer); 
102
}
1177 linlun 103
            #endif
104
            #ifdef PIN_1 
1370 linlun 105
                if (pwmValue[1]!=0)
106
                    gpio_set_pin(PIN_1);
1177 linlun 107
            #endif
108
            #ifdef PIN_2 
1370 linlun 109
                if (pwmValue[2]!=0)
110
                    gpio_set_pin(PIN_2);
1177 linlun 111
            #endif
112
            #ifdef PIN_3 
1370 linlun 113
                if (pwmValue[3]!=0)
114
                    gpio_set_pin(PIN_3);
1177 linlun 115
            #endif
116
            #ifdef PIN_4 
1370 linlun 117
                if (pwmValue[4]!=0)
118
                    gpio_set_pin(PIN_4);
1177 linlun 119
            #endif
120
            #ifdef PIN_5 
1370 linlun 121
                if (pwmValue[5]!=0)
122
                    gpio_set_pin(PIN_5);
1177 linlun 123
            #endif
124
            #ifdef PIN_6 
1370 linlun 125
                if (pwmValue[6]!=0)
126
                    gpio_set_pin(PIN_6);
1177 linlun 127
            #endif
128
            #ifdef PIN_7 
1370 linlun 129
                if (pwmValue[7]!=0)
130
                    gpio_set_pin(PIN_7);
1177 linlun 131
            #endif
1156 linlun 132
        }
1177 linlun 133
        #ifdef PIN_0
1379 linlun 134
        if (currentTimer >= pwmValue[0] && gpio_get_state(PIN_0) != 0) {
1177 linlun 135
            gpio_clr_pin(PIN_0);
1379 linlun 136
//printf("pwm_0 Off %d %d %d\n", pwmValue[0], currentTimer, maxTimer);
1156 linlun 137
        }
1177 linlun 138
        #endif
139
        #ifdef PIN_1
1379 linlun 140
        if (currentTimer >= pwmValue[1] && gpio_get_state(PIN_1) != 0) {
1177 linlun 141
            gpio_clr_pin(PIN_1);
1156 linlun 142
        }
1177 linlun 143
        #endif
144
        #ifdef PIN_2
1379 linlun 145
        if (currentTimer >= pwmValue[2] && gpio_get_state(PIN_2) != 0) {
1177 linlun 146
            gpio_clr_pin(PIN_2);
1156 linlun 147
        }
1177 linlun 148
        #endif
149
        #ifdef PIN_3
1379 linlun 150
        if (currentTimer >= pwmValue[3] && gpio_get_state(PIN_3) != 0) {
1177 linlun 151
            gpio_clr_pin(PIN_3);
152
        }
153
        #endif
154
        #ifdef PIN_4
1379 linlun 155
        if (currentTimer >= pwmValue[4] && gpio_get_state(PIN_4) != 0) {
1177 linlun 156
            gpio_clr_pin(PIN_4);
157
        }
158
        #endif
159
        #ifdef PIN_5
1379 linlun 160
        if (currentTimer >= pwmValue[5] && gpio_get_state(PIN_5) != 0) {
1177 linlun 161
            gpio_clr_pin(PIN_5);
162
        }
163
        #endif
164
        #ifdef PIN_6
1379 linlun 165
        if (currentTimer >= pwmValue[6] && gpio_get_state(PIN_6) != 0) {
1177 linlun 166
            gpio_clr_pin(PIN_6);
167
        }
168
        #endif
169
        #ifdef PIN_7
1379 linlun 170
        if (currentTimer >= pwmValue[7] && gpio_get_state(PIN_7) != 0) {
1177 linlun 171
            gpio_clr_pin(PIN_7);
172
        }
173
        #endif
1156 linlun 174
    }
1180 linlun 175
    if (Timer_Expired(act_softPWM_SEND_TIMER)) {
1379 linlun 176
//printf("sending...\n");
1184 linlun 177
        while(1)
178
        {
179
            if (0
180
                #ifdef PIN_0
181
                || currentSendChannelId == 0
182
                #endif
183
                #ifdef PIN_1
184
                || currentSendChannelId == 1
185
                #endif
186
                #ifdef PIN_2
187
                || currentSendChannelId == 2
188
                #endif
189
                #ifdef PIN_3
190
                || currentSendChannelId == 3
191
                #endif
192
                #ifdef PIN_4
193
                || currentSendChannelId == 4
194
                #endif
195
                #ifdef PIN_5
196
                || currentSendChannelId == 5
197
                #endif
198
                #ifdef PIN_6
199
                || currentSendChannelId == 6
200
                #endif
201
                #ifdef PIN_7
202
                || currentSendChannelId == 7
203
                #endif
204
            ) {
205
                break;
206
            }
207
            currentSendChannelId++;
208
            if (currentSendChannelId >= NUMBEROFCHANNELS)
209
                currentSendChannelId=0;
210
        }
1379 linlun 211
//printf(" %d\n",currentSendChannelId);
1180 linlun 212
        StdCan_Msg_t txMsg;
213
        StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
214
        StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
215
        txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_SOFTPWM;
216
        txMsg.Header.ModuleId = act_softPWM_ID;
217
        txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PWM;
218
        txMsg.Length = 3;
219
        txMsg.Data[0] = currentSendChannelId;
1379 linlun 220
        txMsg.Data[1] = (pwmValueCAN[currentSendChannelId]>>8)&0xff;
221
        txMsg.Data[2] = (pwmValueCAN[currentSendChannelId])&0xff;
1369 linlun 222
        while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
1379 linlun 223
//printf("sent pwm2: %d %d\n",pwmValueCAN[currentSendChannelId],currentSendChannelId); 
1370 linlun 224
#if act_softPWM_ACTIVATE_AUTOOFF != 0
225
        offCounter[currentSendChannelId]--;
226
        if (offCounter[currentSendChannelId] == 0) {
227
            pwmValue[currentSendChannelId] = 0;
1379 linlun 228
            pwmValueCAN[currentSendChannelId] = 0;
1370 linlun 229
            offCounter[currentSendChannelId] = 1;
230
        }
231
#endif
1180 linlun 232
        currentSendChannelId++;
233
        if (currentSendChannelId >= NUMBEROFCHANNELS)
234
            currentSendChannelId=0;
235
    }
1156 linlun 236
}
237
 
1180 linlun 238
 
239
 
1156 linlun 240
void act_softPWM_HandleMessage(StdCan_Msg_t *rxMsg)
241
{
242
    if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
243
        StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
244
        rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_SOFTPWM &&
245
        rxMsg->Header.ModuleId == act_softPWM_ID)
246
    {
247
        switch (rxMsg->Header.Command)
248
        {
1379 linlun 249
//printf("Got can\n");
1177 linlun 250
        case CAN_MODULE_CMD_PHYSICAL_PWM:
1379 linlun 251
//printf("Got pwm value\n");
1369 linlun 252
            if (rxMsg->Length == 3)
1184 linlun 253
            {
1379 linlun 254
//printf("3\n");
1369 linlun 255
                if (rxMsg->Data[0] < NUMBEROFCHANNELS) {
1379 linlun 256
                    pwmValueCAN[rxMsg->Data[0]] = ((uint16_t)((rxMsg->Data[1]<<8) + rxMsg->Data[2]));
257
                    pwmValue[rxMsg->Data[0]] = ((uint16_t)((((uint32_t)pwmValueCAN[rxMsg->Data[0]])*(maxTimer))/10000));
258
                    rxMsg->Data[1] = (uint8_t)(0x00ff & (pwmValueCAN[rxMsg->Data[0]]>>8));
259
                    rxMsg->Data[2] = (uint8_t)(0x00ff & pwmValueCAN[rxMsg->Data[0]]);
1369 linlun 260
                    StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
261
                    rxMsg->Length = 3;
262
                    while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1379 linlun 263
//printf("sent pwm3: %d %d %d\n",pwmValue[rxMsg->Data[0]],maxTimer,resolution); 
1370 linlun 264
                    #if act_softPWM_ACTIVATE_AUTOOFF != 0
265
                    offCounter[rxMsg->Data[0]] = act_softPWM_ACTIVATE_AUTOOFF;
266
                    #endif
1369 linlun 267
                }
1243 arune 268
            } else if (rxMsg->Length == 1) {
1379 linlun 269
                rxMsg->Data[1] = (uint8_t)(0x00ff & (pwmValueCAN[rxMsg->Data[0]]>>8));
270
                rxMsg->Data[2] = (uint8_t)(0x00ff & pwmValueCAN[rxMsg->Data[0]]);
1184 linlun 271
                StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
1369 linlun 272
                rxMsg->Length = 3;
273
                while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1379 linlun 274
            } else {
275
                rxMsg->Data[0] = (8);
276
                rxMsg->Data[1] = (uint8_t)(0x00ff & (pwmValueCAN[0]>>8));
277
                rxMsg->Data[2] = (uint8_t)(0x00ff & pwmValueCAN[0]);
278
                StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
279
                rxMsg->Length = 3;
280
                while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1177 linlun 281
            }
282
            break;
283
        case CAN_MODULE_CMD_SOFTPWM_CONFIG:
284
            maxTimer = (((uint16_t)rxMsg->Data[0])<<8) + rxMsg->Data[1];
285
            resolution = rxMsg->Data[2];
286
            Timer_SetTimeout(act_softPWM_TIMER, resolution, TimerTypeFreeRunning, NULL);
1369 linlun 287
            eeprom_write_word_crc(EEDATA16.maxTimer, maxTimer , WITHOUT_CRC);
288
            eeprom_write_byte_crc(EEDATA.resolution, resolution , WITHOUT_CRC);
289
            EEDATA_UPDATE_CRC;
290
            StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
291
            while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
1177 linlun 292
            break;
1180 linlun 293
        case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
294
            if (rxMsg->Length > 0)
295
            {
296
                act_softPWM_ReportInterval = rxMsg->Data[0];
1242 arune 297
                eeprom_write_byte_crc(EEDATA.ReportInterval, act_softPWM_ReportInterval , WITH_CRC);
1180 linlun 298
                Timer_SetTimeout(act_softPWM_SEND_TIMER, act_softPWM_ReportInterval*1000 , TimerTypeFreeRunning, 0);
299
            }
1177 linlun 300
 
1180 linlun 301
            StdCan_Msg_t txMsg;
302
 
303
            StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
304
            StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
305
            txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_SOFTPWM;
306
            txMsg.Header.ModuleId = act_softPWM_ID;
307
            txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL;
308
            txMsg.Length = 1;
309
            txMsg.Data[0] = act_softPWM_ReportInterval;
1369 linlun 310
            while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
1180 linlun 311
            break;
1156 linlun 312
        }
313
    }
314
}
315
 
316
void act_softPWM_List(uint8_t ModuleSequenceNumber)
317
{
318
    StdCan_Msg_t txMsg;
319
 
320
    StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT); ///TODO: Change this to the actual class type
321
    StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
322
    txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_SOFTPWM; ///TODO: Change this to the actual module type
323
    txMsg.Header.ModuleId = act_softPWM_ID;
324
    txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
325
    txMsg.Length = 6;
326
 
327
    txMsg.Data[0] = NODE_HW_ID_BYTE0;
328
    txMsg.Data[1] = NODE_HW_ID_BYTE1;
329
    txMsg.Data[2] = NODE_HW_ID_BYTE2;
330
    txMsg.Data[3] = NODE_HW_ID_BYTE3;
331
 
332
    txMsg.Data[4] = NUMBER_OF_MODULES;
333
    txMsg.Data[5] = ModuleSequenceNumber;
334
 
335
    while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
336
}