M16C/5Mマイコンを使用したCAN動作チェッカー
Revision | 927d1d744005445519b3c846697b1dbdbb7f604e (tree) |
---|---|
Time | 2017-01-07 15:35:36 |
Author | Yasushi Tanaka <tanaka_yasushi2008@yaho...> |
Commiter | Yasushi Tanaka |
Add canop module
@@ -0,0 +1,322 @@ | ||
1 | +/* | |
2 | + * CAN Target Simulator | |
3 | + * for M16C/5M family + NC30WA v5.45 | |
4 | + * | |
5 | + * [ CANオペレーション ] | |
6 | + */ | |
7 | + | |
8 | +#include "common.h" | |
9 | +#include "target.h" | |
10 | +#include "debug.h" | |
11 | +#include "timer.h" | |
12 | +#include "led.h" | |
13 | +#include "sw.h" | |
14 | +#include "log.h" | |
15 | +#include "can.h" | |
16 | +#include "canop.h" | |
17 | + | |
18 | +/* | |
19 | + * CANオペレーション | |
20 | + * モード切り替えSW | |
21 | + */ | |
22 | +#define CANOP_SW_MODE (0) | |
23 | + /* モード切り替えスイッチ */ | |
24 | + | |
25 | +/* | |
26 | + * CANオペレーション | |
27 | + * 動作状態LED | |
28 | + */ | |
29 | +#define CANOP_LED_MODE (7) | |
30 | + /* 動作状態LED */ | |
31 | + | |
32 | +/* | |
33 | + * CANオペレーション | |
34 | + * ワークエリア | |
35 | + */ | |
36 | +static uint8 canop_mode; | |
37 | + /* 動作モード */ | |
38 | +static BOOL canop_sw; | |
39 | + /* スイッチ状態 */ | |
40 | +static uint16 canop_freerun; | |
41 | + /* フリーランタイマ */ | |
42 | +static uint16 canop_id; | |
43 | + /* 送信ID */ | |
44 | +static BOOL canop_led; | |
45 | + /* LED状態 */ | |
46 | + | |
47 | +/* | |
48 | + * CANオペレーション | |
49 | + * 初期化 | |
50 | + */ | |
51 | +void canop_init(void) | |
52 | +{ | |
53 | + /* 動作モード(停止) */ | |
54 | + canop_mode = CANOP_MODE_NONE; | |
55 | + | |
56 | + /* SW */ | |
57 | + canop_sw = sw_get(CANOP_SW_MODE); | |
58 | + | |
59 | + /* フリーランタイマ */ | |
60 | + canop_freerun = timer_freerun(); | |
61 | + | |
62 | + /* 送信ID */ | |
63 | + canop_id = 0; | |
64 | + | |
65 | + /* LED状態 */ | |
66 | + canop_led = FALSE; | |
67 | +} | |
68 | + | |
69 | +/* | |
70 | + * CANオペレーション | |
71 | + * タスク(定期送信サブ) | |
72 | + */ | |
73 | +static void canop_interval_send(void) | |
74 | +{ | |
75 | + can_pdu NEAR *pdu; | |
76 | + uint8 data; | |
77 | + uint8 loop; | |
78 | + | |
79 | + /* 空きPDUを取得 */ | |
80 | + pdu = can_tx_get(); | |
81 | + | |
82 | + /* PDUが取得できれば */ | |
83 | + if (pdu != NULL) | |
84 | + { | |
85 | + /* ID */ | |
86 | + pdu->sid = canop_id; | |
87 | + | |
88 | + /* DLC */ | |
89 | + pdu->dlc = (uint8)(((canop_id >> 4) & 0x0007) + 1); | |
90 | + ASSERT((pdu->dlc >= 1) && (pdu->dlc <= 8)); | |
91 | + | |
92 | + /* DATA */ | |
93 | + data = (uint8)(canop_id >> 4); | |
94 | + for (loop=0; loop<pdu->dlc; loop++) | |
95 | + { | |
96 | + pdu->data[loop] = data++; | |
97 | + } | |
98 | + | |
99 | + /* 送信リクエスト */ | |
100 | + can_tx_req(pdu); | |
101 | + | |
102 | + /* 次のIDへ進める */ | |
103 | + canop_id = (uint16)((canop_id + 0x10) & 0x7f0); | |
104 | + } | |
105 | +} | |
106 | + | |
107 | +/* | |
108 | + * CANオペレーション | |
109 | + * タスク(定期送信モード) | |
110 | + */ | |
111 | +static void canop_interval(void) | |
112 | +{ | |
113 | + uint16 diff; | |
114 | + | |
115 | + /* フリーランタイマ差分を得る */ | |
116 | + diff = timer_freerun() - canop_freerun; | |
117 | + | |
118 | + /* 差分があれば送信 */ | |
119 | + if (diff >= 1000) | |
120 | + { | |
121 | + /* バスオフ状態でなければ */ | |
122 | + if (can_is_busoff() == FALSE) | |
123 | + { | |
124 | + /* 定期送信 */ | |
125 | + canop_interval_send(); | |
126 | + } | |
127 | + | |
128 | + /* LED点滅 */ | |
129 | + if (canop_led == FALSE) | |
130 | + { | |
131 | + /* OFF->ON */ | |
132 | + led_on(CANOP_LED_MODE); | |
133 | + canop_led = TRUE; | |
134 | + } | |
135 | + else | |
136 | + { | |
137 | + /* ON->OFF */ | |
138 | + led_off(CANOP_LED_MODE); | |
139 | + canop_led = FALSE; | |
140 | + } | |
141 | + | |
142 | + /* 時間を加算 */ | |
143 | + canop_freerun += 1000; | |
144 | + } | |
145 | +} | |
146 | + | |
147 | +/* | |
148 | + * CANオペレーション | |
149 | + * タスク(返信モード) | |
150 | + */ | |
151 | +static void canop_reply(void) | |
152 | +{ | |
153 | + can_pdu NEAR *pdu_rx; | |
154 | + can_pdu NEAR *pdu_tx; | |
155 | + uint8 loop; | |
156 | + | |
157 | + /* 受信PDU取得 */ | |
158 | + pdu_rx = can_rx_get(); | |
159 | + | |
160 | + /* 受信PDUがあれば */ | |
161 | + while (pdu_rx != NULL) | |
162 | + { | |
163 | + /* 送信PDU取得 */ | |
164 | + pdu_tx = can_tx_get(); | |
165 | + | |
166 | + /* ID */ | |
167 | + pdu_tx->sid = (uint16)(pdu_rx->sid ^ 0x0001); | |
168 | + | |
169 | + /* DLC */ | |
170 | + pdu_tx->dlc = pdu_rx->dlc; | |
171 | + | |
172 | + /* DATA */ | |
173 | + for (loop=0; loop<pdu_tx->dlc; loop++) | |
174 | + { | |
175 | + pdu_tx->data[loop] = pdu_rx->data[loop]; | |
176 | + } | |
177 | + | |
178 | + /* 送信リクエスト */ | |
179 | + can_tx_req(pdu_tx); | |
180 | + | |
181 | + /* 受信データを廃棄 */ | |
182 | + can_rx_free(pdu_rx); | |
183 | + | |
184 | + /* 次の受信PDUを取得 */ | |
185 | + pdu_rx = can_rx_get(); | |
186 | + } | |
187 | +} | |
188 | + | |
189 | +/* | |
190 | + * CANオペレーション | |
191 | + * モード遷移 | |
192 | + */ | |
193 | +static void canop_task_mode(uint8 mode) | |
194 | +{ | |
195 | + /* CANスリープ */ | |
196 | + if (canop_mode != CANOP_MODE_NONE) | |
197 | + { | |
198 | + can_sleep(); | |
199 | + } | |
200 | + | |
201 | + /* モード遷移 */ | |
202 | + canop_mode = mode; | |
203 | + | |
204 | + /* フリーランタイマ初期化 */ | |
205 | + canop_freerun = timer_freerun(); | |
206 | + | |
207 | + /* 送信ID初期化 */ | |
208 | + canop_id = 0; | |
209 | + | |
210 | + /* LED初期化 */ | |
211 | + if (canop_mode == CANOP_MODE_NONE) | |
212 | + { | |
213 | + /* 停止モードのときは、LED消灯 */ | |
214 | + canop_led = FALSE; | |
215 | + led_off(CANOP_LED_MODE); | |
216 | + } | |
217 | + else | |
218 | + { | |
219 | + /* それ以外は、LED点灯 */ | |
220 | + canop_led = TRUE; | |
221 | + led_on(CANOP_LED_MODE); | |
222 | + } | |
223 | + | |
224 | + /* CAN初期化 */ | |
225 | + if (canop_mode != CANOP_MODE_NONE) | |
226 | + { | |
227 | + can_init(CAN_TEST_NORMAL); | |
228 | + } | |
229 | +} | |
230 | + | |
231 | +/* | |
232 | + * CANオペレーション | |
233 | + * SWタスク | |
234 | + */ | |
235 | +static void canop_task_sw(void) | |
236 | +{ | |
237 | + BOOL sw; | |
238 | + uint8 mode; | |
239 | + | |
240 | + /* SWが押される度にモードを切り替える */ | |
241 | + sw = sw_get(CANOP_SW_MODE); | |
242 | + | |
243 | + /* 0->1の遷移のみ切り替える */ | |
244 | + if ((canop_sw == FALSE) && (sw == TRUE)) | |
245 | + { | |
246 | + /* SWが押された。遷移先のモードを決定 */ | |
247 | + mode = (uint8)(canop_mode + 1); | |
248 | + if (mode >= CANOP_MODE_MAX) | |
249 | + { | |
250 | + /* 返信モードの次は、停止モードに遷移 */ | |
251 | + mode = CANOP_MODE_NONE; | |
252 | + } | |
253 | + | |
254 | + /* モード遷移 */ | |
255 | + canop_task_mode(mode); | |
256 | + } | |
257 | + | |
258 | + /* 現在のSWを記憶 */ | |
259 | + canop_sw = sw; | |
260 | +} | |
261 | + | |
262 | +/* | |
263 | + * CANオペレーション | |
264 | + * 受信タスク | |
265 | + */ | |
266 | +static void canop_task_recv(void) | |
267 | +{ | |
268 | + can_pdu NEAR *pdu; | |
269 | + | |
270 | + /* REPLY以外であれば受信を試みる */ | |
271 | + if (canop_mode != CANOP_MODE_REPLY) | |
272 | + { | |
273 | + /* 受信PDU取得 */ | |
274 | + pdu = can_rx_get(); | |
275 | + | |
276 | + /* 受信PDUがあれば */ | |
277 | + while (pdu != NULL) | |
278 | + { | |
279 | + /* 読み捨てる */ | |
280 | + can_rx_free(pdu); | |
281 | + | |
282 | + /* 次の受信PDUを取得 */ | |
283 | + pdu = can_rx_get(); | |
284 | + } | |
285 | + } | |
286 | +} | |
287 | + | |
288 | +/* | |
289 | + * CANオペレーション | |
290 | + * タスク | |
291 | + */ | |
292 | +void canop_task(void) | |
293 | +{ | |
294 | + /* 動作モード別 */ | |
295 | + switch (canop_mode) | |
296 | + { | |
297 | + /* 停止モード */ | |
298 | + case CANOP_MODE_NONE: | |
299 | + break; | |
300 | + | |
301 | + /* 定期送信モード */ | |
302 | + case CANOP_MODE_INTERVAL: | |
303 | + canop_interval(); | |
304 | + break; | |
305 | + | |
306 | + /* 返信モード */ | |
307 | + case CANOP_MODE_REPLY: | |
308 | + canop_reply(); | |
309 | + break; | |
310 | + | |
311 | + /* ここに来ることはない */ | |
312 | + default: | |
313 | + ASSERT(FALSE); | |
314 | + break; | |
315 | + } | |
316 | + | |
317 | + /* SWタスク */ | |
318 | + canop_task_sw(); | |
319 | + | |
320 | + /* 受信タスク */ | |
321 | + canop_task_recv(); | |
322 | +} |
@@ -7,6 +7,7 @@ | ||
7 | 7 | |
8 | 8 | #include "common.h" |
9 | 9 | #include "target.h" |
10 | +#include "debug.h" | |
10 | 11 | #include "clock.h" |
11 | 12 | #include "timer.h" |
12 | 13 | #include "led.h" |
@@ -14,6 +15,7 @@ | ||
14 | 15 | #include "uart.h" |
15 | 16 | #include "log.h" |
16 | 17 | #include "can.h" |
18 | +#include "canop.h" | |
17 | 19 | |
18 | 20 | /* |
19 | 21 | * 初期化 |
@@ -29,7 +31,11 @@ static void init(void) | ||
29 | 31 | uart_init(0, 5000); |
30 | 32 | uart_init(3, 5000); |
31 | 33 | log_init(); |
32 | - can_init(CAN_TEST_EXT_LOOPBACK); | |
34 | + | |
35 | + /* CANは初期化しない */ | |
36 | + | |
37 | + /* アプリケーション層 */ | |
38 | + canop_init(); | |
33 | 39 | } |
34 | 40 | |
35 | 41 | /* |
@@ -37,81 +43,21 @@ static void init(void) | ||
37 | 43 | */ |
38 | 44 | void main(void) |
39 | 45 | { |
40 | - uint16 freerun; | |
41 | - uint16 diff; | |
42 | - can_pdu NEAR *pdu; | |
43 | - uint16 id; | |
44 | - uint8 loop; | |
45 | - | |
46 | 46 | /* 初期化 */ |
47 | 47 | init(); |
48 | 48 | |
49 | 49 | /* 割り込み許可 */ |
50 | 50 | cpu_force_ei(); |
51 | 51 | |
52 | - /* フリーランタイマの現在値を取得 */ | |
53 | - freerun = timer_freerun(); | |
54 | - | |
55 | - id = 0; | |
56 | - | |
57 | 52 | /* 無限ループ */ |
58 | 53 | for (;;) { |
59 | - diff = (uint16)(timer_freerun() - freerun); | |
60 | - if (diff >= 1000) | |
61 | - { | |
62 | - freerun += 1000; | |
63 | - | |
64 | - if (can_is_busoff() == FALSE) | |
65 | - { | |
66 | - for (loop=0; loop<1; loop++) | |
67 | - { | |
68 | - pdu = can_tx_get(); | |
69 | - if (pdu != NULL) | |
70 | - { | |
71 | - pdu->sid = id; | |
72 | - pdu->dlc = 8; | |
73 | - pdu->data[0] = 0x00; | |
74 | - pdu->data[1] = 0x01; | |
75 | - pdu->data[2] = 0x02; | |
76 | - pdu->data[3] = 0x03; | |
77 | - pdu->data[4] = 0x04; | |
78 | - pdu->data[5] = 0x05; | |
79 | - pdu->data[6] = 0x06; | |
80 | - pdu->data[7] = 0x07; | |
81 | - | |
82 | - can_tx_req(pdu); | |
83 | - | |
84 | - id = (id + 1) & 0x7ff; | |
85 | - } | |
86 | - } | |
87 | - | |
88 | - } | |
89 | - } | |
90 | - | |
54 | + /* ドライバ層 */ | |
91 | 55 | led_task(); |
92 | 56 | sw_task(); |
93 | 57 | uart_task(); |
94 | 58 | can_task(); |
95 | 59 | |
96 | - for (loop=0; loop<4; loop++) | |
97 | - { | |
98 | - if (sw_get(loop) == TRUE) | |
99 | - { | |
100 | - led_on((uint8)(loop + 4)); | |
101 | - } | |
102 | - else | |
103 | - { | |
104 | - led_off((uint8)(loop + 4)); | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - | |
109 | - pdu = can_rx_get(); | |
110 | - while (pdu != NULL) | |
111 | - { | |
112 | - LOG_U2("rx_id", pdu->sid); | |
113 | - can_rx_free(pdu); | |
114 | - pdu = can_rx_get(); | |
115 | - } | |
60 | + /* アプリケーション層 */ | |
61 | + canop_task(); | |
116 | 62 | } |
117 | 63 | } |
@@ -198,11 +198,20 @@ static void can_init_reset(void) | ||
198 | 198 | uint16 ctlr; |
199 | 199 | uint8 pd; |
200 | 200 | |
201 | - /* スリープモードを解除し、リセットモードに遷移する */ | |
201 | + /* スリープモードを解除する */ | |
202 | + slpm_c0ctlr = 0; | |
203 | + | |
204 | + /* スリープモードが解除されるまで待つ */ | |
205 | + cpu_nop(); | |
206 | + while (slpst_c0str == 1) | |
207 | + { | |
208 | + cpu_nop(); | |
209 | + } | |
210 | + | |
211 | + /* リセットモードへ遷移する */ | |
202 | 212 | ctlr = c0ctlr; |
203 | 213 | ctlr &= (uint16)(~0x0003); |
204 | 214 | ctlr |= 0x0001; |
205 | - ctlr &= (uint16)(~0x0004); | |
206 | 215 | c0ctlr = ctlr; |
207 | 216 | |
208 | 217 | /* リセットモードに遷移するまで待つ */ |
@@ -460,6 +469,38 @@ void can_init(uint8 test_mode) | ||
460 | 469 | |
461 | 470 | /* |
462 | 471 | * CAN |
472 | + * スリープ | |
473 | + */ | |
474 | +void can_sleep(void) | |
475 | +{ | |
476 | + uint16 ctlr; | |
477 | + | |
478 | + /* リセットモードへ遷移する */ | |
479 | + ctlr = c0ctlr; | |
480 | + ctlr &= (uint16)(~0x0003); | |
481 | + ctlr |= 0x0001; | |
482 | + c0ctlr = ctlr; | |
483 | + | |
484 | + /* リセットモードに遷移するまで待つ */ | |
485 | + cpu_nop(); | |
486 | + while ((c0strl & 0x03) != 0x01) | |
487 | + { | |
488 | + cpu_nop(); | |
489 | + } | |
490 | + | |
491 | + /* スリープモードへ遷移する */ | |
492 | + slpm_c0ctlr = 1; | |
493 | + | |
494 | + /* スリープモードに遷移するまで待つ */ | |
495 | + cpu_nop(); | |
496 | + while (slpst_c0str == 0) | |
497 | + { | |
498 | + cpu_nop(); | |
499 | + } | |
500 | +} | |
501 | + | |
502 | +/* | |
503 | + * CAN | |
463 | 504 | * 空きPDUから取得 |
464 | 505 | * ※すべてのPDUが使用中の場合はNULLを返す |
465 | 506 | */ |
@@ -158,6 +158,12 @@ void can_init(uint8 test_mode); | ||
158 | 158 | |
159 | 159 | /* |
160 | 160 | * CAN |
161 | + * スリープ | |
162 | + */ | |
163 | +void can_sleep(void); | |
164 | + | |
165 | +/* | |
166 | + * CAN | |
161 | 167 | * タスク |
162 | 168 | */ |
163 | 169 | void can_task(void); |
@@ -0,0 +1,36 @@ | ||
1 | +/* | |
2 | + * CAN Target Simulator | |
3 | + * for M16C/5M family + NC30WA v5.45 | |
4 | + * | |
5 | + * [ CANオペレーション ] | |
6 | + */ | |
7 | + | |
8 | +#ifndef CANOP_H | |
9 | +#define CANOP_H | |
10 | + | |
11 | +/* | |
12 | + * CANオペレーション | |
13 | + * 動作モード | |
14 | + */ | |
15 | +#define CANOP_MODE_NONE (0) | |
16 | + /* 停止モード */ | |
17 | +#define CANOP_MODE_INTERVAL (1) | |
18 | + /* 定期送信モード */ | |
19 | +#define CANOP_MODE_REPLY (2) | |
20 | + /* 返信モード */ | |
21 | +#define CANOP_MODE_MAX (3) | |
22 | + /* モード上限値 */ | |
23 | + | |
24 | +/* | |
25 | + * CANオペレーション | |
26 | + * 初期化 | |
27 | + */ | |
28 | +void canop_init(void); | |
29 | + | |
30 | +/* | |
31 | + * CANオペレーション | |
32 | + * タスク | |
33 | + */ | |
34 | +void canop_task(void); | |
35 | + | |
36 | +#endif /* CANOP_H */ |