• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

M16C/5Mマイコンを使用したCAN動作チェッカー


Commit MetaInfo

修訂927d1d744005445519b3c846697b1dbdbb7f604e (tree)
時間2017-01-07 15:35:36
作者Yasushi Tanaka <tanaka_yasushi2008@yaho...>
CommiterYasushi Tanaka

Log Message

Add canop module

Change Summary

差異

--- /dev/null
+++ b/Hew/CANTarget5M/Source/app/canop.c
@@ -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+}
--- a/Hew/CANTarget5M/Source/app/main.c
+++ b/Hew/CANTarget5M/Source/app/main.c
@@ -7,6 +7,7 @@
77
88 #include "common.h"
99 #include "target.h"
10+#include "debug.h"
1011 #include "clock.h"
1112 #include "timer.h"
1213 #include "led.h"
@@ -14,6 +15,7 @@
1415 #include "uart.h"
1516 #include "log.h"
1617 #include "can.h"
18+#include "canop.h"
1719
1820 /*
1921 * 初期化
@@ -29,7 +31,11 @@ static void init(void)
2931 uart_init(0, 5000);
3032 uart_init(3, 5000);
3133 log_init();
32- can_init(CAN_TEST_EXT_LOOPBACK);
34+
35+ /* CANは初期化しない */
36+
37+ /* アプリケーション層 */
38+ canop_init();
3339 }
3440
3541 /*
@@ -37,81 +43,21 @@ static void init(void)
3743 */
3844 void main(void)
3945 {
40- uint16 freerun;
41- uint16 diff;
42- can_pdu NEAR *pdu;
43- uint16 id;
44- uint8 loop;
45-
4646 /* 初期化 */
4747 init();
4848
4949 /* 割り込み許可 */
5050 cpu_force_ei();
5151
52- /* フリーランタイマの現在値を取得 */
53- freerun = timer_freerun();
54-
55- id = 0;
56-
5752 /* 無限ループ */
5853 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+ /* ドライバ層 */
9155 led_task();
9256 sw_task();
9357 uart_task();
9458 can_task();
9559
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();
11662 }
11763 }
--- a/Hew/CANTarget5M/Source/driver/can.c
+++ b/Hew/CANTarget5M/Source/driver/can.c
@@ -198,11 +198,20 @@ static void can_init_reset(void)
198198 uint16 ctlr;
199199 uint8 pd;
200200
201- /* スリープモードを解除し、リセットモードに遷移する */
201+ /* スリープモードを解除する */
202+ slpm_c0ctlr = 0;
203+
204+ /* スリープモードが解除されるまで待つ */
205+ cpu_nop();
206+ while (slpst_c0str == 1)
207+ {
208+ cpu_nop();
209+ }
210+
211+ /* リセットモードへ遷移する */
202212 ctlr = c0ctlr;
203213 ctlr &= (uint16)(~0x0003);
204214 ctlr |= 0x0001;
205- ctlr &= (uint16)(~0x0004);
206215 c0ctlr = ctlr;
207216
208217 /* リセットモードに遷移するまで待つ */
@@ -460,6 +469,38 @@ void can_init(uint8 test_mode)
460469
461470 /*
462471 * 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
463504 * 空きPDUから取得
464505 * ※すべてのPDUが使用中の場合はNULLを返す
465506 */
--- a/Hew/CANTarget5M/Source/include/can.h
+++ b/Hew/CANTarget5M/Source/include/can.h
@@ -158,6 +158,12 @@ void can_init(uint8 test_mode);
158158
159159 /*
160160 * CAN
161+ * スリープ
162+ */
163+void can_sleep(void);
164+
165+/*
166+ * CAN
161167 * タスク
162168 */
163169 void can_task(void);
--- /dev/null
+++ b/Hew/CANTarget5M/Source/include/canop.h
@@ -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 */