Subversion Repositories HomeAutomation

Rev

Rev 1504 | Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1503 myhrman 1
/*-----------------------------------------------------------------------------
2
 * Includes
3
 *---------------------------------------------------------------------------*/
4
#include "act_protectedOutput.h"
5
 
6
 
7
/*-----------------------------------------------------------------------------
8
 * Defines
9
 *---------------------------------------------------------------------------*/
10
#define OUTPUT_ON       (act_protectedOutput_OUTPUT_PIN_ACTIVE_STATE)
11
#define OUTPUT_OFF      (1 - OUTPUT_ON)
12
#define OUTPUT_PIN      act_protectedOutput_OUTPUT_PIN
13
 
14
#define DIAG_ASSERTED   (act_protectedOutput_DIAG_PIN_ASSERTED_STATE)
15
#define DIAG_NORMAL     (1 - DIAG_ASSERTED)
16
#define DIAG_PIN        act_protectedOutput_DIAG_PIN
17
 
18
 
19
/*-----------------------------------------------------------------------------
20
 * Types
21
 *---------------------------------------------------------------------------*/
22
 
23
 
24
/*-----------------------------------------------------------------------------
25
 * Variables
26
 *---------------------------------------------------------------------------*/
27
static uint8_t outputTargetState = OUTPUT_OFF;
28
static uint8_t diagState = DIAG_NORMAL;
29
 
30
// is there a recent status change that we should report via CAN?
31
static uint8_t diagReportPending = 0;
32
 
33
 
34
/*-----------------------------------------------------------------------------
35
 * Internal Function Prototypes
36
 *---------------------------------------------------------------------------*/
37
static void updateOutput(void);
38
static void readDiagPin(void);
39
static void pcIntCallback(uint8_t id, uint8_t status);
40
 
41
 
42
/*-----------------------------------------------------------------------------
43
 * Function Implementations
44
 *---------------------------------------------------------------------------*/
45
 
46
static void updateOutput() {
47
    if (outputTargetState == OUTPUT_OFF) {
48
        gpio_set_statement(OUTPUT_OFF, OUTPUT_PIN);
49
    }
50
    else if (outputTargetState == OUTPUT_ON) {
51
        if (diagState == DIAG_NORMAL) {
52
            gpio_set_statement(OUTPUT_ON, OUTPUT_PIN);
53
        }
54
        else {
55
            // DIAG override, we cannot set ON state right now
56
            gpio_set_statement(OUTPUT_OFF, OUTPUT_PIN);
57
        }
58
    }
59
}
60
 
61
 
62
static void readDiagPin() {
63
    diagState = gpio_get_state(DIAG_PIN);
64
}
65
 
66
 
67
static void pcIntCallback(uint8_t id, uint8_t status) {
68
    // new state of the DIAG pin?
69
    if (id == act_protectedOutput_DIAG_PIN_PCINT) {
70
        diagState = status;
71
        updateOutput();
72
        // DIAG asserted?
73
        if (diagState == DIAG_ASSERTED) {
74
            // if retry-timer mechanism is enabled, initiate timer
75
            if (act_protectedOutput_RETRY_TIMER_TIME_S > 0) {
76
                Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0);
77
            }
78
            // if the retry-mechanism is disabled, change the target output state to OFF
79
            else {
80
                outputTargetState = OUTPUT_OFF;
81
            }
82
        }
83
        // something interesting obviously happened. let's report it
84
        diagReportPending = 1;
85
    }
86
}
87
 
88
 
89
void act_protectedOutput_Init() {
90
    if (act_protectedOutput_DIAG_PIN_PULL_ENABLED) {
91
        // if DIAG is asserted low, we need pull-up
92
        gpio_set_statement(act_protectedOutput_DIAG_PIN_ASSERTED_STATE == 0 ? 1 : 0, DIAG_PIN);
93
    }
94
    gpio_set_in(DIAG_PIN);
95
    Pcint_SetCallbackPin(act_protectedOutput_DIAG_PIN_PCINT, DIAG_PIN, &pcIntCallback);
96
 
97
    gpio_set_statement(OUTPUT_OFF, OUTPUT_PIN);
98
    gpio_set_out(act_protectedOutput_OUTPUT_PIN);
99
 
100
    outputTargetState = OUTPUT_OFF;
101
    diagState = DIAG_NORMAL;
102
 
103
    //obsolete: replaced polling by PCINT callback
104
    //Timer_SetTimeout(act_protectedOutput_DIAG_POLL_TIMER, act_protectedOutput_DIAG_POLL_TIMER_TIME_MS, TimerTypeFreeRunning, 0);
105
}
106
 
107
 
108
void act_protectedOutput_Process() {
109
#if 0
110
    if (Timer_Expired(act_protectedOutput_DIAG_POLL_TIMER)) {
111
        // time to poll DIAG pin
112
        readDiagPin();
113
        updateOutput();
114
        if (diagState == DIAG_ASSERTED) {
115
            // if DIAG was asserted, init retry timer
116
            if (act_protectedOutput_RETRY_TIMER_TIME_S > 0) {
117
                Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0);
118
            }
119
        }
120
    }
121
#endif
122
 
123
    // shall we retry to set target output state?
124
    if (Timer_Expired(act_protectedOutput_RETRY_TIMER)) {
125
        // read DIAG pin again and update outputs accordingly
126
        readDiagPin();
127
        updateOutput();
128
        // if DIAG was still asserted, initiate another timer run
129
        Timer_SetTimeout(act_protectedOutput_RETRY_TIMER, act_protectedOutput_RETRY_TIMER_TIME_S*1000, TimerTypeOneShot, 0);
130
    }
131
 
132
    // shall we report diag status to CAN?
133
    if (diagReportPending) {
134
        StdCan_Msg_t txMsg;
135
        StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
136
        StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
137
        txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_INPUT;
138
        txMsg.Header.ModuleId = sns_input_ID;
139
        txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_PINSTATUS;
140
        txMsg.Length = 2;
141
        txMsg.Data[0] = 0; //TODO: add support for more channels
142
        // we follow the standard SNS_INPUT format, but the data corresponds to the "health" rather than physical level
143
        if (diagState == DIAG_NORMAL) {
144
            txMsg.Data[1] = 1;  //healthy, target output state stable
145
        } else {
146
            txMsg.Data[1] = 0;  //not healthy, DIAG pin ASSERTED, not in target output state
147
        }
148
        while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
149
        diagReportPending = 0;
150
    }
151
}
152
 
153
 
154
void act_protectedOutput_HandleMessage(StdCan_Msg_t *rxMsg) {
155
    if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
156
        StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
157
        rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_OUTPUT &&
158
        rxMsg->Header.ModuleId == act_protectedOutput_ID)
159
    {
160
        switch (rxMsg->Header.Command) {
161
 
162
            case CAN_MODULE_CMD_PHYSICAL_SETPIN:
163
 
164
                if (rxMsg->Length == 2) {
165
                    //TODO: add support for more channels
166
                    if (rxMsg->Data[0] == 0) {
167
                        outputTargetState = rxMsg->Data[1];
168
                        readDiagPin();
169
                        updateOutput();
170
                    }              
171
                    StdCan_Set_direction(rxMsg->Header, DIRECTIONFLAG_FROM_OWNER);
172
                    rxMsg->Length = 2;
173
                    while (StdCan_Put(rxMsg) != StdCan_Ret_OK);
174
                }
175
                break;
176
        }
177
    }
178
}
179
 
180
 
181
void act_protectedOutput_List(uint8_t ModuleSequenceNumber)
182
{
183
    StdCan_Msg_t txMsg;
184
    StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
185
    StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
186
    txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_OUTPUT;
187
    txMsg.Header.ModuleId = act_protectedOutput_ID;
188
    txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
189
    txMsg.Length = 6;
190
 
191
    txMsg.Data[0] = NODE_HW_ID_BYTE0;
192
    txMsg.Data[1] = NODE_HW_ID_BYTE1;
193
    txMsg.Data[2] = NODE_HW_ID_BYTE2;
194
    txMsg.Data[3] = NODE_HW_ID_BYTE3;
195
 
196
    txMsg.Data[4] = NUMBER_OF_MODULES;
197
    txMsg.Data[5] = ModuleSequenceNumber;
198
 
199
    while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
200
}
201