@@ -107,10 +107,22 @@ void CAN1_TX_IRQHandler() {
107
107
CAN -> TSR |= CAN_TSR_RQCP0 ;
108
108
}
109
109
110
- uint16_t gas_set = 0 ;
110
+ // two independent values
111
+ uint16_t gas_set_0 = 0 ;
112
+ uint16_t gas_set_1 = 0 ;
113
+
114
+ #define MAX_TIMEOUT 10
111
115
uint32_t timeout = 0 ;
112
116
uint32_t current_index = 0 ;
113
117
118
+ #define NO_FAULT 0
119
+ #define FAULT_BAD_CHECKSUM 1
120
+ #define FAULT_SEND 2
121
+ #define FAULT_SCE 3
122
+ #define FAULT_STARTUP 4
123
+ #define FAULT_TIMEOUT 5
124
+ uint8_t state = FAULT_STARTUP ;
125
+
114
126
void CAN1_RX0_IRQHandler () {
115
127
while (CAN -> RF0R & CAN_RF0R_FMP0 ) {
116
128
#ifdef DEBUG
@@ -119,21 +131,33 @@ void CAN1_RX0_IRQHandler() {
119
131
uint32_t address = CAN -> sFIFOMailBox [0 ].RIR >>21 ;
120
132
if (address == CAN_GAS_INPUT ) {
121
133
uint8_t * dat = (uint8_t * )& CAN -> sFIFOMailBox [0 ].RDLR ;
122
- uint16_t value = (dat [0 ] << 8 ) | dat [1 ];
123
- uint8_t index = (dat [2 ] >> 4 ) & 3 ;
124
- if (can_cksum (dat , 2 , CAN_GAS_INPUT , index ) == (dat [2 ] & 0xF )) {
134
+ uint8_t * dat2 = (uint8_t * )& CAN -> sFIFOMailBox [0 ].RDHR ;
135
+ uint16_t value_0 = (dat [0 ] << 8 ) | dat [1 ];
136
+ uint16_t value_1 = (dat [2 ] << 8 ) | dat [3 ];
137
+ uint8_t enable = (dat2 [0 ] >> 7 ) & 1 ;
138
+ uint8_t index = (dat2 [1 ] >> 4 ) & 3 ;
139
+ if (can_cksum (dat , 5 , CAN_GAS_INPUT , index ) == (dat2 [1 ] & 0xF )) {
125
140
if (((current_index + 1 )& 3 ) == index ) {
126
- // TODO: set and start timeout
127
141
#ifdef DEBUG
128
142
puts ("setting gas " );
129
143
puth (value );
130
144
puts ("\n" );
131
145
#endif
132
- gas_set = value ;
146
+ if (enable ) {
147
+ gas_set_0 = value_0 ;
148
+ gas_set_1 = value_1 ;
149
+ } else {
150
+ // clear the fault state if values are 0
151
+ if (value_0 == 0 && value_1 == 0 ) state = NO_FAULT ;
152
+ gas_set_0 = gas_set_1 = 0 ;
153
+ }
154
+ // clear the timeout
133
155
timeout = 0 ;
134
156
}
135
- // TODO: better lockout? prevents same spam
136
157
current_index = index ;
158
+ } else {
159
+ // wrong checksum = fault
160
+ state = FAULT_BAD_CHECKSUM ;
137
161
}
138
162
}
139
163
// next
@@ -142,6 +166,7 @@ void CAN1_RX0_IRQHandler() {
142
166
}
143
167
144
168
void CAN1_SCE_IRQHandler () {
169
+ state = FAULT_SCE ;
145
170
can_sce (CAN );
146
171
}
147
172
@@ -162,33 +187,39 @@ void TIM3_IRQHandler() {
162
187
163
188
// check timer for sending the user pedal and clearing the CAN
164
189
if ((CAN -> TSR & CAN_TSR_TME0 ) == CAN_TSR_TME0 ) {
165
- uint8_t * dat = (uint8_t * )& CAN -> sTxMailBox [0 ].TDLR ;
166
- CAN -> sTxMailBox [0 ].TDLR = (((pdl0 >>8 )& 0xFF )<<0 ) |
167
- (((pdl0 >>0 )& 0xFF )<<8 ) |
168
- (((pdl1 >>8 )& 0xFF )<<16 ) |
169
- (((pdl1 >>0 )& 0xFF )<<24 );
170
- CAN -> sTxMailBox [0 ].TDHR = can_cksum (dat , 4 , CAN_GAS_OUTPUT , pkt_idx ) | (pkt_idx << 4 );
171
- CAN -> sTxMailBox [0 ].TDTR = 5 ; // len of packet is 4
190
+ uint8_t dat [8 ];
191
+ dat [0 ] = (pdl0 >>8 )& 0xFF ;
192
+ dat [1 ] = (pdl0 >>0 )& 0xFF ;
193
+ dat [2 ] = (pdl1 >>8 )& 0xFF ;
194
+ dat [3 ] = (pdl1 >>0 )& 0xFF ;
195
+ dat [4 ] = state ;
196
+ dat [5 ] = can_cksum (dat , 5 , CAN_GAS_OUTPUT , pkt_idx );
197
+ CAN -> sTxMailBox [0 ].TDLR = dat [0 ] | (dat [1 ]<<8 ) | (dat [2 ]<<16 ) | (dat [3 ]<<24 );
198
+ CAN -> sTxMailBox [0 ].TDHR = dat [4 ] | (dat [5 ]<<8 );
199
+ CAN -> sTxMailBox [0 ].TDTR = 6 ; // len of packet is 5
172
200
CAN -> sTxMailBox [0 ].TIR = (CAN_GAS_OUTPUT << 21 ) | 1 ;
173
201
++ pkt_idx ;
174
202
pkt_idx &= 3 ;
175
203
} else {
176
204
// old can packet hasn't sent!
177
- // TODO: do something?
205
+ state = FAULT_SEND ;
178
206
#ifdef DEBUG
179
207
puts ("CAN MISS\n" );
180
208
#endif
181
209
}
182
210
183
-
184
211
// blink the LED
185
212
set_led (LED_GREEN , led_value );
186
213
led_value = !led_value ;
187
214
188
215
TIM3 -> SR = 0 ;
189
216
190
217
// up timeout for gas set
191
- timeout ++ ;
218
+ if (timeout == MAX_TIMEOUT ) {
219
+ state = FAULT_TIMEOUT ;
220
+ } else {
221
+ timeout += 1 ;
222
+ }
192
223
}
193
224
194
225
// ***************************** main code *****************************
@@ -199,13 +230,16 @@ void pedal() {
199
230
pdl1 = adc_get (ADCCHAN_ACCEL1 );
200
231
201
232
// write the pedal to the DAC
202
- if (timeout < 10 ) {
203
- dac_set (0 , max (gas_set , pdl0 ));
204
- dac_set (1 , max (gas_set * 2 , pdl1 ));
233
+ if (timeout < MAX_TIMEOUT && state == NO_FAULT ) {
234
+ dac_set (0 , max (gas_set_0 , pdl0 ));
235
+ dac_set (1 , max (gas_set_1 , pdl1 ));
205
236
} else {
206
237
dac_set (0 , pdl0 );
207
238
dac_set (1 , pdl1 );
208
239
}
240
+
241
+ // feed the watchdog
242
+ IWDG -> KR = 0xAAAA ;
209
243
}
210
244
211
245
int main () {
@@ -239,6 +273,13 @@ int main() {
239
273
240
274
NVIC_EnableIRQ (TIM3_IRQn );
241
275
276
+ // setup watchdog
277
+ IWDG -> KR = 0x5555 ;
278
+ IWDG -> PR = 0 ; // divider /4
279
+ // 0 = 0.125 ms, let's have a 50ms watchdog
280
+ IWDG -> RLR = 400 - 1 ;
281
+ IWDG -> KR = 0xCCCC ;
282
+
242
283
puts ("**** INTERRUPTS ON ****\n" );
243
284
__enable_irq ();
244
285
0 commit comments