• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

C言語でBBC micro:bit V2およびDFRobot micro:Maqueenを操作する


Commit MetaInfo

Revisiónfffcf59a576a33775b3bff4d556faa1b0922f786 (tree)
Tiempo2023-09-20 22:42:46
Autorxm6_original <tanaka_yasushi2008@yaho...>
Commiterxm6_original

Log Message

NeoPixel実装終了

Cambiar Resumen

Diferencia incremental

--- a/Maqueen_Lv2/.cproject
+++ b/Maqueen_Lv2/.cproject
@@ -190,13 +190,13 @@
190190 </extensions>
191191 </storageModule>
192192 <storageModule moduleId="cdtBuildSystem" version="4.0.0">
193- <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.461201669" name="Release" optionalBuildProperties="" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release">
193+ <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.461201669" name="Release" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release">
194194 <folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.release.461201669." name="/" resourcePath="">
195195 <toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release.1909335911" name="Arm Cross GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.release">
196196 <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.1612481688" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" value="true" valueType="boolean"/>
197197 <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.1951698445" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting"/>
198198 <option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.1686877566" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" value="true" valueType="boolean"/>
199- <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1757564908" name="最適化レベル" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.size" valueType="enumerated"/>
199+ <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1757564908" name="最適化レベル" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.fast" valueType="enumerated"/>
200200 <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1433027581" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" value="true" valueType="boolean"/>
201201 <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1899825495" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" value="true" valueType="boolean"/>
202202 <option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.405573372" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" value="true" valueType="boolean"/>
--- a/Maqueen_Lv2/include/pf_motor.h
+++ b/Maqueen_Lv2/include/pf_motor.h
@@ -48,7 +48,7 @@ void pf_motor_task(void);
4848
4949 //! @brief モータ駆動
5050 //! @details モータ定期タスクで実際のモータ出力が行われる
51-//! @details pf_motor_freeとは排他的に動作する
51+//! @details pf_motor_ctrlとは排他的に動作する
5252 //! @param [in] dir モータ駆動方向
5353 void pf_motor_drive(PF_MOTOR_DIR dir);
5454
--- a/Maqueen_Lv2/src/main.c
+++ b/Maqueen_Lv2/src/main.c
@@ -37,6 +37,7 @@
3737 #include "pf_motor.h"
3838 #include "pf_ultra.h"
3939 #include "pf_music.h"
40+#include "pf_neopixel.h"
4041
4142 //! @brief プラットフォーム初期化
4243 //! @attention 初期化順序に注意する
@@ -63,6 +64,7 @@ static void pf_init(void)
6364 pf_motor_init();
6465 pf_ultra_init();
6566 pf_music_init();
67+ pf_neopixel_init();
6668 }
6769
6870 //! @brief 定期タスク(入力系)
@@ -80,6 +82,7 @@ static void pf_output_task(void)
8082 {
8183 pf_led_task();
8284 pf_motor_task();
85+ pf_neopixel_task();
8386 }
8487
8588 //! @brief ボタン過去状態
@@ -331,7 +334,7 @@ static void app_display_task(void)
331334 }
332335 break;
333336
334- // 走行状態
337+ // 矩形走行状態
335338 case APP_MODE_ID_SQUARE:
336339 if (FALSE == app_run)
337340 {
@@ -343,6 +346,7 @@ static void app_display_task(void)
343346 }
344347 break;
345348
349+ // ライントレース走行状態
346350 case APP_MODE_ID_LINE:
347351 if (FALSE == app_run)
348352 {
@@ -405,6 +409,90 @@ static void app_led_task(void)
405409 }
406410 }
407411
412+//! @brief NeoPixel
413+static void app_neopixel_task(void)
414+{
415+ PF_NEOPIXEL_COLOR color;
416+ u4 wheelpos;
417+ u4 r;
418+ u4 g;
419+ u4 b;
420+
421+ // オート変数初期化
422+ wheelpos = (app_step >> 1) & 0xFFU;
423+ color.r = 0;
424+ color.g = 0;
425+ color.b = 0;
426+ r = 0;
427+ g = 0;
428+ b = 0;
429+
430+ // 矩形走行状態のみ
431+ if ((APP_MODE_ID_SQUARE == app_mode) && (TRUE == app_run))
432+ {
433+ if (wheelpos < 85)
434+ {
435+ r = 255 - wheelpos * 3;
436+ g = 0;
437+ b = wheelpos * 3;
438+ }
439+ else
440+ {
441+ if (wheelpos < 170)
442+ {
443+ wheelpos -= 85;
444+ r = 255;
445+ g = wheelpos * 3;
446+ b = 255 - wheelpos * 3;
447+ }
448+ else
449+ {
450+ wheelpos -= 170;
451+ r = wheelpos * 3;
452+ g = 255 - wheelpos * 3;
453+ b = 0;
454+ }
455+ }
456+
457+ // 輝度を1/4に落とす
458+ r >>= 2;
459+ g >>= 2;
460+ b >>= 2;
461+
462+ // ID_RGB0はRGBの順
463+ color.r = (u1)r;
464+ color.g = (u1)g;
465+ color.b = (u1)b;
466+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB0, &color);
467+
468+ // ID_RGB1はGBRの順
469+ color.r = (u1)g;
470+ color.g = (u1)b;
471+ color.b = (u1)r;
472+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB1, &color);
473+
474+ // ID_RGB2はBRGの順
475+ color.r = (u1)b;
476+ color.g = (u1)r;
477+ color.b = (u1)g;
478+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB2, &color);
479+
480+ // ID_RGB3はRBGの順
481+ color.r = (u1)r;
482+ color.g = (u1)b;
483+ color.b = (u1)g;
484+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB3, &color);
485+ }
486+ else
487+ {
488+ // NeoPixel消灯
489+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB0, &color);
490+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB1, &color);
491+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB2, &color);
492+ pf_neopixel_ctrl(PF_NEOPIXEL_ID_RGB3, &color);
493+ }
494+}
495+
408496 //! @brief 走行(矩形)
409497 static void app_run_square(void)
410498 {
@@ -550,6 +638,9 @@ static void app_task(void)
550638 // LED表示
551639 app_led_task();
552640
641+ // NeoPixel
642+ app_neopixel_task();
643+
553644 // 走行(矩形)
554645 if ((APP_MODE_ID_SQUARE == app_mode) && (TRUE == app_run))
555646 {
--- a/Maqueen_Lv2/src/pf/neopixelsend.S
+++ /dev/null
@@ -1,110 +0,0 @@
1-/*
2- Portions of this code based on code provided under MIT license from Microsoft
3- https://github.com/Microsoft/pxt-ws2812b
4-
5- MIT License
6-
7- Copyright (c) Microsoft Corporation. All rights reserved.
8-
9- Permission is hereby granted, free of charge, to any person obtaining a copy
10- of this software and associated documentation files (the "Software"), to deal
11- in the Software without restriction, including without limitation the rights
12- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13- copies of the Software, and to permit persons to whom the Software is
14- furnished to do so, subject to the following conditions:
15-
16- The above copyright notice and this permission notice shall be included in all
17- copies or substantial portions of the Software.'
18-
19- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25- SOFTWARE
26-*/
27-
28-.global sendNeopixelBuffer
29-
30- /* declared as extern void sendBuffer(uint32_t pin, uint8_t* data_address, uint16_t num_bytes) */
31-
32-sendNeopixelBuffer:
33- push {r0, r1, r2, r3, r4, r5, r6}
34-
35- /*
36- We are expecting from the callee:
37- r0 = pinmask to waggle in the GPIO register
38- r1 = address of the data we are supposed to be sending
39- r2 = number of bytes to send
40-
41- Setup the initial values
42- r1 = Pin mask in the GPIO register
43- r2 = GPIO clear register
44- r3 = GPIO SET
45- r4 = Address pointer for the data - we cast this as a byte earlier because it really is.
46- r5 = Length of the data
47- r6 = Parallel to serial conversion mask
48- */
49- mov r4, r1
50- mov r5, r2
51-
52- /*load the pin set and clr addresses by a cunning combo of shifts and adds*/
53- movs r3, #160
54- movs r1, #0x0c
55- lsl r3, r3, #15
56- add r3, #05
57- lsl r3, r3, #8
58- add r2, r3, r1
59- add r3, #0x08
60-
61- mov r1, r0 /* finally move the pin mask from r0 to r1*/
62-
63- /*
64- This code serialises the data bits for each LED.
65- The data byte is loaded in the common section (label .common) and then each bit is masked and tested for '0' (label .nextbit)
66- If it is a '0' we turn off the pin asap and then move to the code that advances to the next bit/byte. If a '1' we leave the pin on and do the same thing.
67- If the mask (r6) is still valid then we are still moving out the current byte, so repeat.
68- If it is '0' then we have done this byte and need to load the next byte from the pointer in r4.
69- r5 contains the count of bytes.
70- Once we run r5 down to '0' we exit the data shifting and return.
71- */
72-
73- mrs r6, PRIMASK /* disable interrupts whilst we mess with timing critical waggling. */
74- push {r6}
75- cpsid i
76-
77- b .start
78-
79- .nextbit:
80- str r1, [r3, #0]
81- tst r6, r0
82- bne .bitisone
83- str r1, [r2, #0]
84- .bitisone:
85- lsr r6, #1
86- bne .justbit
87-
88- add r4, #1
89- sub r5, #1
90- beq .stop
91-
92- .start:
93- movs r6, #0x80
94- nop
95-
96- .common:
97- str r1, [r2, #0]
98- ldrb r0, [r4, #0]
99- b .nextbit
100-
101- .justbit:
102- b .common
103-
104- .stop:
105- str r1, [r2, #0]
106-
107- pop {r6}
108- msr PRIMASK, r6
109- pop {r0, r1, r2, r3, r4, r5, r6}
110- bx lr
--- a/Maqueen_Lv2/src/pf/pf_motor.c
+++ b/Maqueen_Lv2/src/pf/pf_motor.c
@@ -397,7 +397,7 @@ void pf_motor_task(void)
397397
398398 //! @brief モータ駆動
399399 //! @details モータ定期タスクで実際のモータ出力が行われる
400-//! @details pf_motor_freeとは排他的に動作する
400+//! @details pf_motor_ctrlとは排他的に動作する
401401 //! @param [in] dir モータ駆動方向
402402 void pf_motor_drive(PF_MOTOR_DIR dir)
403403 {
--- a/Maqueen_Lv2/src/pf/pf_neopixel.c
+++ b/Maqueen_Lv2/src/pf/pf_neopixel.c
@@ -23,19 +23,17 @@
2323 // DEALINGS IN THE SOFTWARE.
2424
2525 #include "pf_types.h"
26+#include "nrf52833.h"
2627 #include "pf_gpio.h"
28+#include "pf_interrupt.h"
2729 #include "pf_neopixel.h"
2830
2931 //! @brief NepPixelあたりの送信バイト数
30-#define PF_NEOPIXEL_SEND_BYTES ((u4)24U)
32+#define PF_NEOPIXEL_SEND_BYTES ((u4)3U)
3133
3234 //! @brief R/G/Bの階調マスク値
3335 #define PF_NEOPIXEL_COLOR_MASK ((u1)0x7FU)
3436
35-//! @brief 外部関数(アセンブラ)定義
36-//! @details pin=13<<1, num_bytes=(Gx8,Bx8,Rx8)xLEDs=96を指定する
37-extern void sendNeopixelBuffer(uint32_t pin, uint8_t* data_address, uint16_t num_bytes);
38-
3937 //! @brief NeoPixel動作情報構造体
4038 typedef struct PF_NEOPIXEL_INFO_Tag
4139 {
@@ -52,14 +50,14 @@ static PF_NEOPIXEL_INFO pf_neopixel_info;
5250 static void pf_neopixel_init_id(PF_NEOPIXEL_ID id)
5351 {
5452 // 現在の状態は消灯
55- pf_neopixel_info.current[id].r = 0U;
56- pf_neopixel_info.current[id].g = 0U;
57- pf_neopixel_info.current[id].b = 0U;
53+ pf_neopixel_info.current[id].r = 0;
54+ pf_neopixel_info.current[id].g = 0;
55+ pf_neopixel_info.current[id].b = 0;
5856
5957 // 目的とする状態は消灯
60- pf_neopixel_info.target[id].r = 0U;
61- pf_neopixel_info.target[id].g = 0U;
62- pf_neopixel_info.target[id].b = 0U;
58+ pf_neopixel_info.target[id].r = 0;
59+ pf_neopixel_info.target[id].g = 0;
60+ pf_neopixel_info.target[id].b = 0;
6361 }
6462
6563 //! @brief NeoPixel初期化
@@ -79,11 +77,183 @@ void pf_neopixel_init(void)
7977 }
8078 }
8179
80+//! @brief NeoPixel送信(約888kbps)
81+//! @param [in] pinmask NRF_P0->OUTSETまたはNRF_P0->OUTCLRへの出力値
82+//! @param [in] buf 送信バッファ
83+//! @param [in] bytes 送信バイト数
84+//! @attention 割り込み禁止区間が非常に長い(約200us)ことに注意する
85+static void pf_neopixel_888k(u4 pinmask, const u1 *buf, u4 bytes)
86+{
87+ u4 enable;
88+ u4 val;
89+ u1 data;
90+ u1 bit;
91+
92+ // オート変数初期化
93+ enable = 0;
94+ val = 0;
95+ data = 0;
96+ bit = 0;
97+
98+ // ms境界まで残り250us未満の場合、次のms開始まで待つ(ラップアラウンドを避ける)
99+ while (SysTick->VAL < (SystemCoreClock / 4000))
100+ {
101+ ;
102+ }
103+
104+ // 割り込み禁止
105+ enable = pf_interrupt_global_disable();
106+
107+ // 現在のSysTickカウンタ
108+ val = SysTick->VAL;
109+
110+ // バイトループ
111+ while (bytes > 0)
112+ {
113+ // データフェッチ
114+ data = *buf;
115+ bit = 0x80;
116+
117+ // 8ビットループ
118+ while (0 != bit)
119+ {
120+ // 現在のSysTickカウンタを保存し、H出力
121+ val = SysTick->VAL;
122+ NRF_P0->OUTSET = pinmask;
123+
124+ // 判定
125+ if (0 != (data & bit))
126+ {
127+ // H区間を812.5nsホールド(T1H)
128+ while ((val - SysTick->VAL) < 52)
129+ {
130+ ;
131+ }
132+
133+ // 現在のSysTickカウンタを保存し、L出力
134+ val = SysTick->VAL;
135+ NRF_P0->OUTCLR = pinmask;
136+
137+ // L区間を312.5nsホールド(T1L)
138+ while ((val - SysTick->VAL) < 20)
139+ {
140+ ;
141+ }
142+ }
143+ else
144+ {
145+ // H区間を312.5nsホールド(T0H)
146+ while ((val - SysTick->VAL) < 20)
147+ {
148+ ;
149+ }
150+
151+ // 現在のSysTickカウンタを保存し、L出力
152+ val = SysTick->VAL;
153+ NRF_P0->OUTCLR = pinmask;
154+
155+ // L区間を812.5nsホールド(T0L)
156+ while ((val - SysTick->VAL) < 52)
157+ {
158+ ;
159+ }
160+ }
161+
162+ // 次のビットへ
163+ bit >>= 1;
164+ }
165+
166+ // 次のデータへ
167+ buf++;
168+ bytes--;
169+ }
170+
171+ // 割り込み復元
172+ pf_interrupt_global_restore(enable);
173+}
174+
175+//! @brief NeoPixel送信
176+static void pf_neopixel_send(void)
177+{
178+ PF_NEOPIXEL_ID id;
179+ u4 pin;
180+ u1 *ptr;
181+
182+ // オート変数初期化
183+ id = 0;
184+ pin = 0;
185+ ptr = NULL;
186+
187+ // 'L'出力
188+ pf_gpio_output(PF_GPIO_ID_MAQUEEN_NEOPIXEL, FALSE);
189+
190+ // すべてのIDをループ
191+ for (id = 0; id < PF_NEOPIXEL_ID_MAX; id++)
192+ {
193+ // 目的とするIDのバッファをポイント
194+ ptr = &pf_neopixel_info.buf[id][0];
195+
196+ // 送信データを作成(G)
197+ *ptr = pf_neopixel_info.target[id].g;
198+ ptr++;
199+
200+ // 送信データを作成(R)
201+ *ptr = pf_neopixel_info.target[id].r;
202+ ptr++;
203+
204+ // 送信データを作成(B)
205+ *ptr = pf_neopixel_info.target[id].b;
206+ ptr++;
207+ }
208+
209+ // GPIOからピンを取得
210+ pin = pf_gpio_get_pin(PF_GPIO_ID_MAQUEEN_NEOPIXEL);
211+
212+ // 送信(内部で割り込み禁止されるため処理時間に注意)
213+ pf_neopixel_888k(1U << pin, &(pf_neopixel_info.buf[0][0]), PF_NEOPIXEL_ID_MAX * PF_NEOPIXEL_SEND_BYTES);
214+}
215+
82216 //! @brief NeoPixel定期タスク
83217 //! @remarks プラットフォーム定期タスク(出力系)処理から呼び出すこと
84218 void pf_neopixel_task(void)
85219 {
220+ BOOL send;
221+ PF_NEOPIXEL_ID id;
222+
223+ // オート変数初期化
224+ send = FALSE;
225+ id = 0;
86226
227+ // すべてのIDをループ
228+ for (id = 0; id < PF_NEOPIXEL_ID_MAX; id++)
229+ {
230+ // R比較
231+ if (pf_neopixel_info.current[id].r != pf_neopixel_info.target[id].r)
232+ {
233+ pf_neopixel_info.current[id].r = pf_neopixel_info.target[id].r;
234+ send = TRUE;
235+ }
236+
237+ // G比較
238+ if (pf_neopixel_info.current[id].g != pf_neopixel_info.target[id].g)
239+ {
240+ pf_neopixel_info.current[id].g = pf_neopixel_info.target[id].g;
241+ send = TRUE;
242+ }
243+
244+ // B比較
245+ if (pf_neopixel_info.current[id].b != pf_neopixel_info.target[id].b)
246+ {
247+ pf_neopixel_info.current[id].b = pf_neopixel_info.target[id].b;
248+ send = TRUE;
249+ }
250+ }
251+
252+ // 必要に応じて送信
253+ if (TRUE == send)
254+ {
255+ pf_neopixel_send();
256+ }
87257 }
88258
89259 //! @brief NeoPixel制御
--- a/Maqueen_Lv2/src/pf/pf_ultra.c
+++ b/Maqueen_Lv2/src/pf/pf_ultra.c
@@ -259,7 +259,7 @@ void pf_ultra_task(void)
259259 pf_ultra_info.count++;
260260
261261 // 測定周期チェック
262- if (((PF_ULTRA_MEASURE_CYCLE_MS) / (PF_SYSTICK_SYNC_MS)) >= pf_ultra_info.count)
262+ if (pf_ultra_info.count >= ((PF_ULTRA_MEASURE_CYCLE_MS) / (PF_SYSTICK_SYNC_MS)))
263263 {
264264 // カウンタリセット
265265 pf_ultra_info.count = 0;