C言語でBBC micro:bit V2およびDFRobot micro:Maqueenを操作する
Revision | 3ffc896044bf590dd9dda7e0666858bf46d3b90b (tree) |
---|---|
Time | 2023-09-09 09:44:17 |
Author | ![]() |
Commiter | xm6_original |
I2C・ラインセンサ・モータ制御を追加
@@ -32,7 +32,7 @@ typedef enum PF_BUTTON_ID_Tag | ||
32 | 32 | { |
33 | 33 | PF_BUTTON_ID_BUTTON_A, //!< BUTTON A(Display面から見て左側) |
34 | 34 | PF_BUTTON_ID_BUTTON_B, //!< BUTTON B(Display面から見て右側) |
35 | - PF_BUTTON_ID_MAX //!< (IDの個数を表す)I | |
35 | + PF_BUTTON_ID_MAX, //!< (IDの個数を表す) | |
36 | 36 | } PF_BUTTON_ID; |
37 | 37 | |
38 | 38 | //! @brief ボタン初期化 |
@@ -40,7 +40,7 @@ typedef enum PF_BUTTON_ID_Tag | ||
40 | 40 | void pf_button_init(void); |
41 | 41 | |
42 | 42 | //! @brief ボタン定期タスク |
43 | -//! @remarks 定期タスク(入力系)処理から呼び出すこと | |
43 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
44 | 44 | void pf_button_task(void); |
45 | 45 | |
46 | 46 | //! @brief ボタンの押下状態を取得 |
@@ -28,16 +28,16 @@ | ||
28 | 28 | #include "pf_types.h" |
29 | 29 | |
30 | 30 | //! @brief 行の最大数 |
31 | -#define PF_DISPLAY_ROW_MAX 5 | |
31 | +#define PF_DISPLAY_ROW_MAX ((u4)5U) | |
32 | 32 | |
33 | 33 | //! @brief 列の最大数 |
34 | -#define PF_DISPLAY_COL_MAX 5 | |
34 | +#define PF_DISPLAY_COL_MAX ((u4)5U) | |
35 | 35 | |
36 | 36 | //! @brief 明るさの最小値 |
37 | -#define PF_DISPLAY_BRIGHTNESS_MIN 4 | |
37 | +#define PF_DISPLAY_BRIGHTNESS_MIN ((u4)4U) | |
38 | 38 | |
39 | 39 | //! @brief 明るさの最大値 |
40 | -#define PF_DISPLAY_BRIGHTNESS_MAX 96 | |
40 | +#define PF_DISPLAY_BRIGHTNESS_MAX ((u4)96U) | |
41 | 41 | |
42 | 42 | //! @brief イメージのID |
43 | 43 | typedef enum PF_DISPLAY_ID_Tag |
@@ -83,7 +83,7 @@ void pf_display_init(void); | ||
83 | 83 | |
84 | 84 | //! @brief Display表示(文字) |
85 | 85 | //! @param [in] ch ASCII文字(0x20~0x7F) |
86 | -void pf_display_chr(char ch); | |
86 | +void pf_display_ch(char ch); | |
87 | 87 | |
88 | 88 | //! @brief Display表示(ID) |
89 | 89 | //! @param [in] id イメージのID |
@@ -44,9 +44,15 @@ typedef enum PF_GPIO_ID_Tag | ||
44 | 44 | PF_GPIO_ID_COL5, //!< Display COL5 |
45 | 45 | PF_GPIO_ID_BUTTON_A, //!< BUTTON A |
46 | 46 | PF_GPIO_ID_BUTTON_B, //!< BUTTON B |
47 | + PF_GPIO_ID_INTERNAL_SCL, //!< 内部I2Cバス SCL | |
48 | + PF_GPIO_ID_INTERNAL_SDA, //!< 内部I2Cバス SDA | |
49 | + PF_GPIO_ID_EXTERNAL_SCL, //!< 外部I2Cバス SCL | |
50 | + PF_GPIO_ID_EXTERNAL_SDA, //!< 外部I2Cバス SDA | |
47 | 51 | PF_GPIO_ID_MAQUEEN_LED_L, //!< MAQUEEN LED L |
48 | 52 | PF_GPIO_ID_MAQUEEN_LED_R, //!< MAQUEEN LED R |
49 | - PF_GPIO_ID_MAX //!< (IDの個数を表す)I | |
53 | + PF_GPIO_ID_MAQUEEN_PATROL_L, //!< MAQUEEN PATROL L | |
54 | + PF_GPIO_ID_MAQUEEN_PATROL_R, //!< MAUQEEN PATROL R | |
55 | + PF_GPIO_ID_MAX, //!< (IDの個数を表す) | |
50 | 56 | } PF_GPIO_ID; |
51 | 57 | |
52 | 58 | //! @brief GPIO初期化 |
@@ -0,0 +1,91 @@ | ||
1 | +//! @file pf_i2c.h | |
2 | +//! @brief プラットフォーム(I2C)ヘッダファイル | |
3 | + | |
4 | +// The MIT License (MIT) | |
5 | +// Copyright (c) 2023 @xm6_original | |
6 | +// | |
7 | +// Permission is hereby granted, free of charge, to any person obtaining a | |
8 | +// copy of this software and associated documentation files (the "Software"), | |
9 | +// to deal in the Software without restriction, including without limitation | |
10 | +// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | +// and/or sell copies of the Software, and to permit persons to whom the | |
12 | +// Software is furnished to do so, subject to the following conditions: | |
13 | +// | |
14 | +// The above copyright notice and this permission notice shall be included in | |
15 | +// all copies or substantial portions of the Software. | |
16 | +// | |
17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
22 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
23 | +// DEALINGS IN THE SOFTWARE. | |
24 | + | |
25 | +#ifndef PF_I2C_H | |
26 | +#define PF_I2C_H | |
27 | + | |
28 | +#include "pf_types.h" | |
29 | + | |
30 | +//! @brief I2Cコールバック関数 | |
31 | +//! @param [in] status 通信ステータス(TRUE=成功/FALSE=失敗) | |
32 | +typedef void (*PF_I2C_CALLBACK)(BOOL status); | |
33 | + | |
34 | +//! @brief I2C通信先のID | |
35 | +typedef enum PF_I2C_ID_Tag | |
36 | +{ | |
37 | + PF_I2C_ID_ACCELEROMETER, //!< 加速度センサ | |
38 | + PF_I2C_ID_MAGNETOMETER, //!< 磁気センサ | |
39 | + PF_I2C_ID_MAQUEEN_MOTOR, //!< MAQUEEN モータ | |
40 | + PF_I2C_ID_MAX //!< (IDの個数を表す) | |
41 | +} PF_I2C_ID; | |
42 | + | |
43 | +//! @brief I2Cエラー情報構造体 | |
44 | +typedef struct PF_I2C_ERROR_Tag | |
45 | +{ | |
46 | + u4 overrun; //!< オーバーラン発生回数(受信動作が不正) | |
47 | + u4 anack; //!< アドレスNACK発生回数 | |
48 | + u4 dnack; //!< データNACK発生回数 | |
49 | +} PF_I2C_ERROR; | |
50 | + | |
51 | +//! @brief I2C初期化 | |
52 | +//! @remarks プラットフォーム初期化処理から呼び出すこと | |
53 | +void pf_i2c_init(void); | |
54 | + | |
55 | +//! @brief I2C送信 | |
56 | +//! @param [in] id I2C通信先のID | |
57 | +//! @param [in] buf 送信バッファへのポインタ | |
58 | +//! @param [in] bytes 送信バイト数 | |
59 | +//! @return 送信ステータス(TRUE=送信開始/FALSE=デバイスBUSY) | |
60 | +//! @attention 呼び出し側で送信バッファのライフタイムを保証すること | |
61 | +BOOL pf_i2c_send(PF_I2C_ID id, const u1 *buf, u4 bytes); | |
62 | + | |
63 | +//! @brief I2C受信 | |
64 | +//! @param [in] id I2C通信先のID | |
65 | +//! @param [in] reg 受信レジスタ | |
66 | +//! @param [in] buf 受信バッファへのポインタ | |
67 | +//! @param [in] bytes 受信バイト数 | |
68 | +//! @return 受信ステータス(TRUE=受信開始/FALSE=デバイスBUSY) | |
69 | +BOOL pf_i2c_recv(PF_I2C_ID id, u1 reg, u1 *buf, u4 bytes); | |
70 | + | |
71 | +//! @brief I2Cエラー情報取得 | |
72 | +//! @param [in] id I2C通信先のID | |
73 | +//! @param [out] error エラー情報構造体へのポインタ | |
74 | +//! @remarks プラットフォーム内部のエラー情報はクリアされる | |
75 | +void pf_i2c_error(PF_I2C_ID id, PF_I2C_ERROR *error); | |
76 | + | |
77 | +//! @brief I2Cコールバック関数設定 | |
78 | +//! @param [in] id I2C通信先のID | |
79 | +//! @param [in] func I2Cコールバック関数へのポインタ | |
80 | +//! @attention I2Cコールバック関数は割り込みコンテキストで呼び出される | |
81 | +void pf_i2c_callback(PF_I2C_ID id, PF_I2C_CALLBACK func); | |
82 | + | |
83 | +//! @brief I2C割り込みハンドラ(チャネル0=内部I2Cバス) | |
84 | +//! @attention データ競合(割り込み干渉)に注意する | |
85 | +void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void); | |
86 | + | |
87 | +//! @brief I2C割り込みハンドラ(チャネル1=外部I2Cバス) | |
88 | +//! @attention データ競合(割り込み干渉)に注意する | |
89 | +void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void); | |
90 | + | |
91 | +#endif // PF_I2C_H |
@@ -31,9 +31,10 @@ | ||
31 | 31 | typedef enum PF_INTERRUPT_PRI_Tag |
32 | 32 | { |
33 | 33 | PF_INTERRUPT_PRI_SYSTICK = 0, //!< SysTick |
34 | - PF_INTERRUPT_PRI_POWER, //!< Power | |
35 | 34 | PF_INTERRUPT_PRI_UART, //!< UART |
36 | 35 | PF_INTERRUPT_PRI_DISPLAY_TIMER, //!< Display Timer |
36 | + PF_INTERRUPT_PRI_I2C_INT, //!< I2C(内部) | |
37 | + PF_INTERRUPT_PRI_I2C_EXT, //!< I2C(外部) | |
37 | 38 | } PF_INTERRUPT_PRI; |
38 | 39 | |
39 | 40 | //! @brief グローバル割り込み禁止 |
@@ -30,15 +30,19 @@ | ||
30 | 30 | //! @brief LEDのID |
31 | 31 | typedef enum PF_LED_ID_Tag |
32 | 32 | { |
33 | - PF_LED_ID_MAQUEEN_L, //!< micro:Maqueenの左側赤色LED | |
34 | - PF_LED_ID_MAQUEEN_R, //!< micro:Maqueenの右側赤色LED | |
35 | - PF_LED_ID_MAX //!< (IDの個数を表す) | |
33 | + PF_LED_ID_L, //!< 左側LED | |
34 | + PF_LED_ID_R, //!< 右側LED | |
35 | + PF_LED_ID_MAX, //!< (IDの個数を表す) | |
36 | 36 | } PF_LED_ID; |
37 | 37 | |
38 | 38 | //! @brief LED初期化 |
39 | 39 | //! @remarks プラットフォーム初期化処理から呼び出すこと |
40 | 40 | void pf_led_init(void); |
41 | 41 | |
42 | +//! @brief LED定期タスク | |
43 | +//! @remarks プラットフォーム定期タスク(出力系)処理から呼び出すこと | |
44 | +void pf_led_task(void); | |
45 | + | |
42 | 46 | //! @brief LED制御 |
43 | 47 | //! @param [in] id LEDのID |
44 | 48 | //! @param [in] ctrl LED制御情報(TRUE=LED点灯/FALSE=LED消灯) |
@@ -0,0 +1,54 @@ | ||
1 | +//! @file pf_motor.h | |
2 | +//! @brief プラットフォーム(モータ)ヘッダファイル | |
3 | + | |
4 | +// The MIT License (MIT) | |
5 | +// Copyright (c) 2023 @xm6_original | |
6 | +// | |
7 | +// Permission is hereby granted, free of charge, to any person obtaining a | |
8 | +// copy of this software and associated documentation files (the "Software"), | |
9 | +// to deal in the Software without restriction, including without limitation | |
10 | +// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | +// and/or sell copies of the Software, and to permit persons to whom the | |
12 | +// Software is furnished to do so, subject to the following conditions: | |
13 | +// | |
14 | +// The above copyright notice and this permission notice shall be included in | |
15 | +// all copies or substantial portions of the Software. | |
16 | +// | |
17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
22 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
23 | +// DEALINGS IN THE SOFTWARE. | |
24 | + | |
25 | +#ifndef PF_MOTOR_H | |
26 | +#define PF_MOTOR_H | |
27 | + | |
28 | +#include "pf_types.h" | |
29 | + | |
30 | +//! @brief モータ駆動方向 | |
31 | +typedef enum PF_MOTOR_DIR_Tag | |
32 | +{ | |
33 | + PF_MOTOR_DIR_FORWARD, //!< 前進 | |
34 | + PF_MOTOR_DIR_LEFT, //!< 左回転 | |
35 | + PF_MOTOR_DIR_RIGHT, //!< 右回転 | |
36 | + PF_MOTOR_DIR_BACKWORD, //!< 後進 | |
37 | + PF_MOTOR_DIR_STOP, //!< 停止 | |
38 | + PF_MOTOR_DIR_MAX, //!< (方向の個数を表す) | |
39 | +} PF_MOTOR_DIR; | |
40 | + | |
41 | +//! @brief モータ初期化 | |
42 | +//! @remarks プラットフォーム初期化処理から呼び出すこと | |
43 | +void pf_motor_init(void); | |
44 | + | |
45 | +//! @brief モータ定期タスク | |
46 | +//! @remarks プラットフォーム定期タスク(出力系)処理から呼び出すこと | |
47 | +void pf_motor_task(void); | |
48 | + | |
49 | +//! @brief モータ駆動 | |
50 | +//! @details モータ定期タスクで実際のモータ出力が行われる | |
51 | +//! @param [in] dir モータ駆動方向 | |
52 | +void pf_motor_drive(PF_MOTOR_DIR dir); | |
53 | + | |
54 | +#endif // PF_MOTOR_H |
@@ -0,0 +1,59 @@ | ||
1 | +//! @file pf_patrol.h | |
2 | +//! @brief プラットフォーム(ラインセンサ)ヘッダファイル | |
3 | + | |
4 | +// The MIT License (MIT) | |
5 | +// Copyright (c) 2023 @xm6_original | |
6 | +// | |
7 | +// Permission is hereby granted, free of charge, to any person obtaining a | |
8 | +// copy of this software and associated documentation files (the "Software"), | |
9 | +// to deal in the Software without restriction, including without limitation | |
10 | +// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | +// and/or sell copies of the Software, and to permit persons to whom the | |
12 | +// Software is furnished to do so, subject to the following conditions: | |
13 | +// | |
14 | +// The above copyright notice and this permission notice shall be included in | |
15 | +// all copies or substantial portions of the Software. | |
16 | +// | |
17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
22 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
23 | +// DEALINGS IN THE SOFTWARE. | |
24 | + | |
25 | +#ifndef PF_PATROL_H | |
26 | +#define PF_PATROL_H | |
27 | + | |
28 | +#include "pf_types.h" | |
29 | + | |
30 | +//! @brief ラインセンサのID | |
31 | +typedef enum PF_PATROL_ID_Tag | |
32 | +{ | |
33 | + PF_PATROL_ID_L, //!< 左センサ | |
34 | + PF_PATROL_ID_R, //!< 右センサ | |
35 | + PF_PATROL_ID_MAX, //!< (IDの個数を表す) | |
36 | +} PF_PATROL_ID; | |
37 | + | |
38 | +//! @brief ラインセンサで検出できる色 | |
39 | +typedef enum PF_PATROL_COLOR_Tag | |
40 | +{ | |
41 | + PF_PATROL_COLOR_WHITE = 0, //!< 白色 | |
42 | + PF_PATROL_COLOR_BLACK, //!< 黒色 | |
43 | + PF_PATROL_COLOR_MAX, //!< (色の個数を表す) | |
44 | +} PF_PATROL_COLOR; | |
45 | + | |
46 | +//! @brief ラインセンサ初期化 | |
47 | +//! @remarks プラットフォーム初期化処理から呼び出すこと | |
48 | +void pf_patrol_init(void); | |
49 | + | |
50 | +//! @brief ラインセンサ定期タスク | |
51 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
52 | +void pf_patrol_task(void); | |
53 | + | |
54 | +//! @brief ラインセンサの白黒状態を取得 | |
55 | +//! @param [in] id ラインセンサのID | |
56 | +//! @return 色状態(PF_PATROL_COLOR_WHITE=白色/PF_PATROL_COLOR_BLACK=黒色) | |
57 | +PF_PATROL_COLOR pf_patrol_get(PF_PATROL_ID id); | |
58 | + | |
59 | +#endif // PF_PATROL_H |
@@ -32,8 +32,8 @@ | ||
32 | 32 | //! @attention Display初期化の後で呼び出すこと |
33 | 33 | void pf_power_init(void); |
34 | 34 | |
35 | -//! @brief Power割り込みハンドラ | |
36 | -//! @attention 割り込み発生以降、Displayの動作が×固定になる | |
37 | -void POWER_CLOCK_IRQHandler(void); | |
35 | +//! @brief Power定期タスク | |
36 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
37 | +void pf_power_task(void); | |
38 | 38 | |
39 | 39 | #endif // PF_POWER_H |
@@ -33,9 +33,9 @@ | ||
33 | 33 | //! @brief SysTick時刻情報構造体 |
34 | 34 | typedef struct PF_SYSTICK_TIME_Tag |
35 | 35 | { |
36 | - u4 sec; //!< [sec]秒 | |
37 | - u4 ms; //!< [ms]ミリ秒(0~999) | |
38 | - u4 us; //!< [us]マイクロ秒(0~999) | |
36 | + u4 sec; //!< 秒(0~) | |
37 | + u4 ms; //!< ミリ秒(0~999) | |
38 | + u4 us; //!< マイクロ秒(0~999) | |
39 | 39 | } PF_SYSTICK_TIME; |
40 | 40 | |
41 | 41 | //! @brief SysTick初期化 |
@@ -27,13 +27,22 @@ | ||
27 | 27 | |
28 | 28 | #include "pf_types.h" |
29 | 29 | |
30 | +//! @brief UARTエラー情報構造体 | |
31 | +typedef struct PF_UART_ERROR_Tag | |
32 | +{ | |
33 | + u4 overrun; //!< オーバーランエラー発生回数 | |
34 | + u4 parity; //!< パリティエラー発生回数 | |
35 | + u4 framing; //!< フレーミングエラー発生回数 | |
36 | + u4 brk; //!< ブレーク信号受信回数 | |
37 | +} PF_UART_ERROR; | |
38 | + | |
30 | 39 | //! @brief UART初期化 |
31 | 40 | //! @remarks プラットフォーム初期化処理から呼び出すこと |
32 | 41 | //! @attention GPIO初期化の後で呼び出すこと |
33 | 42 | void pf_uart_init(void); |
34 | 43 | |
35 | 44 | //! @brief UART定期タスク |
36 | -//! @remarks 定期タスク(出力系)処理から呼び出すこと | |
45 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
37 | 46 | void pf_uart_task(void); |
38 | 47 | |
39 | 48 | //! @brief UART送信 |
@@ -47,6 +56,11 @@ void pf_uart_send(const u1 *buf, u4 bytes); | ||
47 | 56 | //! @return 受信したバイト数 |
48 | 57 | u4 pf_uart_recv(u1 *buf, u4 bytes); |
49 | 58 | |
59 | +//! @brief UARTエラー情報取得 | |
60 | +//! @param [out] error エラー情報構造体へのポインタ | |
61 | +//! @remarks プラットフォーム内部のエラー情報はクリアされる | |
62 | +void pf_uart_error(PF_UART_ERROR *error); | |
63 | + | |
50 | 64 | //! @brief UART1文字出力 |
51 | 65 | //! @param [in] ch 送信する文字(0xFF以外) |
52 | 66 | void pf_uart_putc(u1 ch); |
@@ -29,46 +29,58 @@ | ||
29 | 29 | #include "pf_timer.h" |
30 | 30 | #include "pf_uart.h" |
31 | 31 | #include "pf_display.h" |
32 | +#include "pf_i2c.h" | |
32 | 33 | #include "pf_power.h" |
33 | 34 | #include "pf_button.h" |
34 | 35 | #include "pf_led.h" |
36 | +#include "pf_patrol.h" | |
37 | +#include "pf_motor.h" | |
35 | 38 | |
36 | 39 | //! @brief プラットフォーム初期化 |
37 | 40 | //! @attention 初期化順序に注意する |
38 | 41 | static void pf_init(void) |
39 | 42 | { |
40 | - // Phase1: クロックをHFXO(外部発振子)に切り替える | |
43 | + // Step1: クロックをHFXO(外部発振子)に切り替える | |
41 | 44 | pf_clock_init(); |
42 | 45 | |
43 | - // Phase2: 低位モジュールを初期化する | |
46 | + // Step2: 低位モジュールを初期化する | |
44 | 47 | pf_gpio_init(); |
45 | 48 | pf_systick_init(); |
46 | 49 | pf_timer_init(); |
47 | 50 | |
48 | - // Phase3: 中位モジュール(低位モジュールに依存するモジュール)を初期化する | |
51 | + // Step3: 中位モジュール(低位モジュールに依存するモジュール)を初期化する | |
49 | 52 | pf_uart_init(); |
50 | 53 | pf_display_init(); |
54 | + pf_i2c_init(); | |
51 | 55 | |
52 | - // Phase4: その他のモジュールを初期化する | |
56 | + // Step4: 高位モジュール(低位モジュールまたは中位モジュールに依存するモジュール)を初期化する | |
53 | 57 | pf_power_init(); |
54 | 58 | pf_button_init(); |
55 | 59 | pf_led_init(); |
60 | + pf_patrol_init(); | |
61 | + pf_motor_init(); | |
56 | 62 | } |
57 | 63 | |
58 | 64 | //! @brief 定期タスク(入力系) |
59 | 65 | static void pf_input_task(void) |
60 | 66 | { |
67 | + pf_power_task(); | |
68 | + pf_uart_task(); | |
61 | 69 | pf_button_task(); |
70 | + pf_patrol_task(); | |
62 | 71 | } |
63 | 72 | |
64 | 73 | //! @brief 定期タスク(出力系) |
65 | 74 | static void pf_output_task(void) |
66 | 75 | { |
67 | - pf_uart_task(); | |
76 | + pf_led_task(); | |
77 | + pf_motor_task(); | |
68 | 78 | } |
69 | 79 | |
70 | 80 | static BOOL button_prev[2]; |
71 | 81 | static PF_DISPLAY_ID display_id; |
82 | +static char display_ch = 0x20; | |
83 | +static PF_MOTOR_DIR motor_dir = 0; | |
72 | 84 | |
73 | 85 | //! @brief アプリケーションタスク |
74 | 86 | static void app_task(void) |
@@ -83,8 +95,9 @@ static void app_task(void) | ||
83 | 95 | if (button_now[0]) |
84 | 96 | { |
85 | 97 | pf_uart_log("Button A: OFF -> ON"); |
86 | - pf_display_id(display_id); | |
87 | 98 | |
99 | + // アイコン系 | |
100 | + pf_display_id(display_id); | |
88 | 101 | display_id++; |
89 | 102 | if (display_id >= PF_DISPLAY_ID_MAX) |
90 | 103 | { |
@@ -102,15 +115,52 @@ static void app_task(void) | ||
102 | 115 | if (button_now[1]) |
103 | 116 | { |
104 | 117 | pf_uart_log("Button B: OFF -> ON"); |
105 | - pf_led_ctrl(PF_LED_ID_MAQUEEN_L, TRUE); | |
118 | + | |
119 | + // キャラクタ系 | |
120 | + pf_display_ch(display_ch); | |
121 | + if (display_ch == 0x7F) | |
122 | + { | |
123 | + display_ch = 0x20; | |
124 | + } | |
125 | + else | |
126 | + { | |
127 | + display_ch++; | |
128 | + } | |
129 | + | |
130 | + // モータ駆動 | |
131 | + pf_motor_drive(motor_dir); | |
132 | + motor_dir++; | |
133 | + if (motor_dir >= PF_MOTOR_DIR_MAX) | |
134 | + { | |
135 | + motor_dir = 0; | |
136 | + } | |
106 | 137 | } |
107 | 138 | else |
108 | 139 | { |
109 | 140 | pf_uart_log("Button B: ON -> OFF\n"); |
110 | - pf_led_ctrl(PF_LED_ID_MAQUEEN_L, FALSE); | |
111 | 141 | } |
112 | 142 | } |
113 | 143 | |
144 | + // ラインセンサとLEDの連携制御(黒色で点灯、白色で消灯) | |
145 | + if (PF_PATROL_COLOR_BLACK == pf_patrol_get(PF_PATROL_ID_L)) | |
146 | + { | |
147 | + pf_led_ctrl(PF_LED_ID_L, TRUE); | |
148 | + } | |
149 | + else | |
150 | + { | |
151 | + pf_led_ctrl(PF_LED_ID_L, FALSE); | |
152 | + } | |
153 | + | |
154 | + if (PF_PATROL_COLOR_BLACK == pf_patrol_get(PF_PATROL_ID_R)) | |
155 | + { | |
156 | + pf_led_ctrl(PF_LED_ID_R, TRUE); | |
157 | + } | |
158 | + else | |
159 | + { | |
160 | + pf_led_ctrl(PF_LED_ID_R, FALSE); | |
161 | + } | |
162 | + | |
163 | + // ボタン情報を更新 | |
114 | 164 | button_prev[0] = button_now[0]; |
115 | 165 | button_prev[1] = button_now[1]; |
116 | 166 | } |
@@ -27,12 +27,18 @@ | ||
27 | 27 | #include "pf_button.h" |
28 | 28 | |
29 | 29 | //! @brief チャタリング防止のためのフィルタ段数(最低2段以上にすること) |
30 | -#define PF_BUTTON_FILTER_MAX (3) | |
30 | +#define PF_BUTTON_FILTER_MAX ((u4)3U) | |
31 | + | |
32 | +//! @brief ボタン→GPIO IDテーブル | |
33 | +static const PF_GPIO_ID pf_button_to_gpio[PF_BUTTON_ID_MAX] = | |
34 | +{ | |
35 | + PF_GPIO_ID_BUTTON_A, //!< BUTTON A(Display面から見て左側) | |
36 | + PF_GPIO_ID_BUTTON_B, //!< BUTTON B(Display面から見て右側) | |
37 | +}; | |
31 | 38 | |
32 | 39 | //! @brief ボタン情報構造体 |
33 | 40 | typedef struct PF_BUTTON_INFO_Tag |
34 | 41 | { |
35 | - PF_GPIO_ID gpio; //!< GPIOピンのID | |
36 | 42 | BOOL prev[PF_BUTTON_FILTER_MAX]; //!< 過去データ |
37 | 43 | BOOL now; //!< 現在データ |
38 | 44 | } PF_BUTTON_INFO; |
@@ -49,18 +55,6 @@ static void pf_button_init_id(PF_BUTTON_ID id) | ||
49 | 55 | // オート変数初期化 |
50 | 56 | loop = 0; |
51 | 57 | |
52 | - // GPIOピンのIDを設定 | |
53 | - if (0 == id) | |
54 | - { | |
55 | - // ボタンA | |
56 | - pf_button_info[id].gpio = PF_GPIO_ID_BUTTON_A; | |
57 | - } | |
58 | - else | |
59 | - { | |
60 | - // ボタンB | |
61 | - pf_button_info[id].gpio = PF_GPIO_ID_BUTTON_B; | |
62 | - } | |
63 | - | |
64 | 58 | // 過去データをすべてFALSE(押されていない)に初期化 |
65 | 59 | for (loop = 0; loop < PF_BUTTON_FILTER_MAX; loop++) |
66 | 60 | { |
@@ -75,16 +69,16 @@ static void pf_button_init_id(PF_BUTTON_ID id) | ||
75 | 69 | //! @remarks プラットフォーム初期化処理から呼び出すこと |
76 | 70 | void pf_button_init(void) |
77 | 71 | { |
78 | - u4 id; | |
72 | + PF_BUTTON_ID id; | |
79 | 73 | |
80 | 74 | // オート変数初期化 |
81 | 75 | id = 0; |
82 | 76 | |
83 | 77 | // すべてのIDをループ |
84 | - for (id = 0; id < (u4)PF_BUTTON_ID_MAX; id++) | |
78 | + for (id = 0; id < PF_BUTTON_ID_MAX; id++) | |
85 | 79 | { |
86 | 80 | // 1つのIDを初期化 |
87 | - pf_button_init_id((PF_BUTTON_ID)id); | |
81 | + pf_button_init_id(id); | |
88 | 82 | } |
89 | 83 | } |
90 | 84 |
@@ -92,17 +86,19 @@ void pf_button_init(void) | ||
92 | 86 | //! @param [in] id ボタンのID |
93 | 87 | static void pf_button_task_id(PF_BUTTON_ID id) |
94 | 88 | { |
89 | + PF_GPIO_ID gpio; | |
95 | 90 | u4 loop; |
96 | 91 | BOOL result; |
97 | 92 | BOOL now; |
98 | 93 | |
99 | 94 | // オート変数初期化 |
95 | + gpio = pf_button_to_gpio[id]; | |
100 | 96 | loop = 0; |
101 | 97 | result = FALSE; |
102 | 98 | now = FALSE; |
103 | 99 | |
104 | 100 | // 現在のボタン押下情報を取得(GPIOからの入力が'L'で押されている) |
105 | - if (FALSE == pf_gpio_input(pf_button_info[id].gpio)) | |
101 | + if (FALSE == pf_gpio_input(gpio)) | |
106 | 102 | { |
107 | 103 | // 押されている |
108 | 104 | result = TRUE; |
@@ -140,19 +136,19 @@ static void pf_button_task_id(PF_BUTTON_ID id) | ||
140 | 136 | } |
141 | 137 | |
142 | 138 | //! @brief ボタン定期タスク |
143 | -//! @remarks 定期タスク(入力系)処理から呼び出すこと | |
139 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
144 | 140 | void pf_button_task(void) |
145 | 141 | { |
146 | - u4 id; | |
142 | + PF_BUTTON_ID id; | |
147 | 143 | |
148 | 144 | // オート変数初期化 |
149 | 145 | id = 0; |
150 | 146 | |
151 | 147 | // すべてのIDをループ |
152 | - for (id = 0; id < (u4)PF_BUTTON_ID_MAX; id++) | |
148 | + for (id = 0; id < PF_BUTTON_ID_MAX; id++) | |
153 | 149 | { |
154 | 150 | // 1つのIDを処理 |
155 | - pf_button_task_id((PF_BUTTON_ID)id); | |
151 | + pf_button_task_id(id); | |
156 | 152 | } |
157 | 153 | } |
158 | 154 |
@@ -34,18 +34,17 @@ void pf_clock_init(void) | ||
34 | 34 | { |
35 | 35 | // X1クロック(32MHz)有効イベントをクリア |
36 | 36 | NRF_CLOCK->EVENTS_HFCLKSTARTED = |
37 | - CLOCK_EVENTS_HFCLKSTARTED_EVENTS_HFCLKSTARTED_NotGenerated | |
37 | + CLOCK_EVENTS_HFCLKSTARTED_EVENTS_HFCLKSTARTED_NotGenerated | |
38 | 38 | << CLOCK_EVENTS_HFCLKSTARTED_EVENTS_HFCLKSTARTED_Pos; |
39 | 39 | |
40 | 40 | // X1クロック(32MHz)を有効にし、高精度クロック64MHzで動作開始 |
41 | 41 | NRF_CLOCK->TASKS_HFCLKSTART = |
42 | - CLOCK_TASKS_HFCLKSTART_TASKS_HFCLKSTART_Trigger | |
43 | - << CLOCK_TASKS_HFCLKSTART_TASKS_HFCLKSTART_Pos; | |
42 | + CLOCK_TASKS_HFCLKSTART_TASKS_HFCLKSTART_Trigger << CLOCK_TASKS_HFCLKSTART_TASKS_HFCLKSTART_Pos; | |
44 | 43 | |
45 | 44 | // 高精度クロック(64MHz)が有効になるまで待つ |
46 | 45 | while ((CLOCK_EVENTS_HFCLKSTARTED_EVENTS_HFCLKSTARTED_NotGenerated |
47 | - << CLOCK_EVENTS_HFCLKSTARTED_EVENTS_HFCLKSTARTED_Pos) | |
48 | - == NRF_CLOCK->EVENTS_HFCLKSTARTED) | |
46 | + << CLOCK_EVENTS_HFCLKSTARTED_EVENTS_HFCLKSTARTED_Pos) | |
47 | + == NRF_CLOCK->EVENTS_HFCLKSTARTED) | |
49 | 48 | { |
50 | 49 | // 何もしない |
51 | 50 | } |
@@ -28,26 +28,6 @@ | ||
28 | 28 | #include "pf_timer.h" |
29 | 29 | #include "pf_display.h" |
30 | 30 | |
31 | -//! @brief 行→GPIO IDテーブル | |
32 | -static const PF_GPIO_ID pf_display_row_to_id[PF_DISPLAY_ROW_MAX] = | |
33 | -{ | |
34 | - PF_GPIO_ID_ROW1, //!< ROW1 | |
35 | - PF_GPIO_ID_ROW2, //!< ROW2 | |
36 | - PF_GPIO_ID_ROW3, //!< ROW3 | |
37 | - PF_GPIO_ID_ROW4, //!< ROW4 | |
38 | - PF_GPIO_ID_ROW5, //!< ROW5 | |
39 | -}; | |
40 | - | |
41 | -//! @brief 列→GPIO IDテーブル | |
42 | -static const PF_GPIO_ID pf_display_col_to_id[PF_DISPLAY_COL_MAX] = | |
43 | -{ | |
44 | - PF_GPIO_ID_COL1, //!< COL1 | |
45 | - PF_GPIO_ID_COL2, //!< COL2 | |
46 | - PF_GPIO_ID_COL3, //!< COL3 | |
47 | - PF_GPIO_ID_COL4, //!< COL4 | |
48 | - PF_GPIO_ID_COL5, //!< COL5 | |
49 | -}; | |
50 | - | |
51 | 31 | //! @brief Display情報構造体 |
52 | 32 | typedef struct PF_DISPLAY_INFO_Tag |
53 | 33 | { |
@@ -61,6 +41,26 @@ typedef struct PF_DISPLAY_INFO_Tag | ||
61 | 41 | //! @brief Display情報 |
62 | 42 | static PF_DISPLAY_INFO pf_display_info; |
63 | 43 | |
44 | +//! @brief 行→GPIO IDテーブル | |
45 | +static const PF_GPIO_ID pf_display_row_to_id[PF_DISPLAY_ROW_MAX] = | |
46 | +{ | |
47 | + PF_GPIO_ID_ROW1, //!< ROW1 | |
48 | + PF_GPIO_ID_ROW2, //!< ROW2 | |
49 | + PF_GPIO_ID_ROW3, //!< ROW3 | |
50 | + PF_GPIO_ID_ROW4, //!< ROW4 | |
51 | + PF_GPIO_ID_ROW5, //!< ROW5 | |
52 | +}; | |
53 | + | |
54 | +//! @brief 列→GPIO IDテーブル | |
55 | +static const PF_GPIO_ID pf_display_col_to_id[PF_DISPLAY_COL_MAX] = | |
56 | +{ | |
57 | + PF_GPIO_ID_COL1, //!< COL1 | |
58 | + PF_GPIO_ID_COL2, //!< COL2 | |
59 | + PF_GPIO_ID_COL3, //!< COL3 | |
60 | + PF_GPIO_ID_COL4, //!< COL4 | |
61 | + PF_GPIO_ID_COL5, //!< COL5 | |
62 | +}; | |
63 | + | |
64 | 64 | //! @brief micro:bit標準フォント(pendolino3) from codal-core(BitmapFont.cpp) |
65 | 65 | static const u1 pf_display_pendolino3[96][PF_DISPLAY_ROW_MAX * PF_DISPLAY_COL_MAX] = |
66 | 66 | { |
@@ -1231,7 +1231,7 @@ void pf_display_init(void) | ||
1231 | 1231 | |
1232 | 1232 | //! @brief Display表示(文字) |
1233 | 1233 | //! @param [in] ch ASCII文字(0x20~0x7F) |
1234 | -void pf_display_chr(char ch) | |
1234 | +void pf_display_ch(char ch) | |
1235 | 1235 | { |
1236 | 1236 | const u1 *font; |
1237 | 1237 | u4 offset; |
@@ -1363,8 +1363,7 @@ void pf_display_brightness(u4 brightness) | ||
1363 | 1363 | cc[1] = MICROSEC_TO_TIMERCC(1000); |
1364 | 1364 | |
1365 | 1365 | // パラメータチェック |
1366 | - if ((brightness >= PF_DISPLAY_BRIGHTNESS_MIN) | |
1367 | - && (brightness <= PF_DISPLAY_BRIGHTNESS_MAX)) | |
1366 | + if ((brightness >= PF_DISPLAY_BRIGHTNESS_MIN) && (brightness <= PF_DISPLAY_BRIGHTNESS_MAX)) | |
1368 | 1367 | { |
1369 | 1368 | // 強制フラグチェック |
1370 | 1369 | if (FALSE == pf_display_info.force) |
@@ -51,18 +51,18 @@ typedef enum PF_GPIO_PULL_Tag | ||
51 | 51 | //! @brief 駆動特性 |
52 | 52 | typedef enum PF_GPIO_DRIVE_Tag |
53 | 53 | { |
54 | - PF_GPIO_DRIVE_S0S1 = 0x0000, //!< '0':標準/'1':標準 | |
55 | - PF_GPIO_DRIVE_H0S1 = 0x0100, //!< '0':高駆動/'1':標準 | |
56 | - PF_GPIO_DRIVE_S0H1 = 0x0200, //!< '0':標準/'1':高駆動 | |
57 | - PF_GPIO_DRIVE_H0H1 = 0x0300, //!< '0':高駆動/'1':高駆動 | |
58 | - PF_GPIO_DRIVE_D0S1 = 0x0400, //!< '0':未接続/'1':標準 | |
59 | - PF_GPIO_DRIVE_D0H1 = 0x0500, //!< '0':未接続/'1':高駆動 | |
60 | - PF_GPIO_DRIVE_S0D1 = 0x0600, //!< '0':標準/'1':未接続 | |
61 | - PF_GPIO_DRIVE_H0D1 = 0x0700, //!< '0':高駆動/'1':未接続 | |
54 | + PF_GPIO_DRIVE_S0S1 = 0x0000, //!< '0'=標準/'1'=標準 | |
55 | + PF_GPIO_DRIVE_H0S1 = 0x0100, //!< '0'=高駆動/'1'=標準 | |
56 | + PF_GPIO_DRIVE_S0H1 = 0x0200, //!< '0'=標準/'1'=高駆動 | |
57 | + PF_GPIO_DRIVE_H0H1 = 0x0300, //!< '0'=高駆動/'1'=高駆動 | |
58 | + PF_GPIO_DRIVE_D0S1 = 0x0400, //!< '0'=未接続/'1'=標準 | |
59 | + PF_GPIO_DRIVE_D0H1 = 0x0500, //!< '0'=未接続/'1'=高駆動 | |
60 | + PF_GPIO_DRIVE_S0D1 = 0x0600, //!< '0'=標準/'1'=未接続 | |
61 | + PF_GPIO_DRIVE_H0D1 = 0x0700, //!< '0'=高駆動/'1'=未接続 | |
62 | 62 | } PF_GPIO_DRIVE; |
63 | 63 | |
64 | -//! @brief GPIOピン設定情報構造体 | |
65 | -typedef struct PF_GPIO_INFO_Tag | |
64 | +//! @brief GPIOピン初期化情報構造体 | |
65 | +typedef struct PF_GPIO_INIT_Tag | |
66 | 66 | { |
67 | 67 | u4 port; //!< ポート(0~1) |
68 | 68 | u4 pin; //!< ピン(0~31) |
@@ -71,11 +71,11 @@ typedef struct PF_GPIO_INFO_Tag | ||
71 | 71 | PF_GPIO_INBUF inbuf; //!< 入力バッファ |
72 | 72 | PF_GPIO_PULL pull; //!< プルアップ・プルダウン |
73 | 73 | PF_GPIO_DRIVE drive; //!< 駆動特性 |
74 | -} PF_GPIO_INFO; | |
74 | +} PF_GPIO_INIT; | |
75 | 75 | |
76 | -//! @brief GPIOピン設定情報テーブル | |
77 | -//! @todo 未使用ピンをすべてプルアップ有効の入力にするよう設定すること | |
78 | -const PF_GPIO_INFO pf_gpio_table[PF_GPIO_ID_MAX] = | |
76 | +//! @brief GPIOピン初期化情報テーブル | |
77 | +//! @todo 未使用ピンがすべてプルアップ有効の入力にするよう設定すること | |
78 | +const PF_GPIO_INIT pf_gpio_init_table[PF_GPIO_ID_MAX] = | |
79 | 79 | { |
80 | 80 | // PF_GPIO_ID_UART_TXD |
81 | 81 | { |
@@ -232,6 +232,50 @@ const PF_GPIO_INFO pf_gpio_table[PF_GPIO_ID_MAX] = | ||
232 | 232 | PF_GPIO_DRIVE_S0S1, // 駆動特性 |
233 | 233 | }, |
234 | 234 | |
235 | + // PF_GPIO_ID_INTERNAL_SCL | |
236 | + { | |
237 | + 0, // ポート | |
238 | + 8, // ピン | |
239 | + FALSE, // 初期出力レベル | |
240 | + PF_GPIO_DIR_INPUT, // 入出力方向 | |
241 | + PF_GPIO_INBUF_DISCONNECT, // 入力バッファ | |
242 | + PF_GPIO_PULL_NONE, // プルアップ・プルダウン | |
243 | + PF_GPIO_DRIVE_S0D1, // 駆動特性 | |
244 | + }, | |
245 | + | |
246 | + // PF_GPIO_ID_INTERNAL_SDA | |
247 | + { | |
248 | + 0, // ポート | |
249 | + 16, // ピン | |
250 | + FALSE, // 初期出力レベル | |
251 | + PF_GPIO_DIR_INPUT, // 入出力方向 | |
252 | + PF_GPIO_INBUF_DISCONNECT, // 入力バッファ | |
253 | + PF_GPIO_PULL_NONE, // プルアップ・プルダウン | |
254 | + PF_GPIO_DRIVE_S0D1, // 駆動特性 | |
255 | + }, | |
256 | + | |
257 | + // PF_GPIO_ID_EXTERNAL_SCL | |
258 | + { | |
259 | + 0, // ポート | |
260 | + 26, // ピン | |
261 | + FALSE, // 初期出力レベル | |
262 | + PF_GPIO_DIR_INPUT, // 入出力方向 | |
263 | + PF_GPIO_INBUF_DISCONNECT, // 入力バッファ | |
264 | + PF_GPIO_PULL_NONE, // プルアップ・プルダウン | |
265 | + PF_GPIO_DRIVE_S0D1, // 駆動特性 | |
266 | + }, | |
267 | + | |
268 | + // PF_GPIO_ID_EXTERNAL_SDA | |
269 | + { | |
270 | + 1, // ポート | |
271 | + 0, // ピン | |
272 | + FALSE, // 初期出力レベル | |
273 | + PF_GPIO_DIR_INPUT, // 入出力方向 | |
274 | + PF_GPIO_INBUF_DISCONNECT, // 入力バッファ | |
275 | + PF_GPIO_PULL_NONE, // プルアップ・プルダウン | |
276 | + PF_GPIO_DRIVE_S0D1, // 駆動特性 | |
277 | + }, | |
278 | + | |
235 | 279 | // PF_GPIO_ID_MAQUEEN_LED_L |
236 | 280 | { |
237 | 281 | 0, // ポート |
@@ -253,6 +297,28 @@ const PF_GPIO_INFO pf_gpio_table[PF_GPIO_ID_MAX] = | ||
253 | 297 | PF_GPIO_PULL_NONE, // プルアップ・プルダウン |
254 | 298 | PF_GPIO_DRIVE_S0S1, // 駆動特性 |
255 | 299 | }, |
300 | + | |
301 | + // PF_GPIO_ID_MAQUEEN_PATROL_L | |
302 | + { | |
303 | + 0, // ポート | |
304 | + 17, // ピン | |
305 | + FALSE, // 初期出力レベル | |
306 | + PF_GPIO_DIR_INPUT, // 入出力方向 | |
307 | + PF_GPIO_INBUF_CONNECT, // 入力バッファ | |
308 | + PF_GPIO_PULL_UP, // プルアップ・プルダウン | |
309 | + PF_GPIO_DRIVE_S0S1, // 駆動特性 | |
310 | + }, | |
311 | + | |
312 | + // PF_GPIO_ID_MAQUEEN_PATROL_R | |
313 | + { | |
314 | + 0, // ポート | |
315 | + 1, // ピン | |
316 | + FALSE, // 初期出力レベル | |
317 | + PF_GPIO_DIR_INPUT, // 入出力方向 | |
318 | + PF_GPIO_INBUF_CONNECT, // 入力バッファ | |
319 | + PF_GPIO_PULL_UP, // プルアップ・プルダウン | |
320 | + PF_GPIO_DRIVE_S0S1, // 駆動特性 | |
321 | + }, | |
256 | 322 | }; |
257 | 323 | |
258 | 324 | //! @brief GPIOデバイス取得 |
@@ -266,7 +332,7 @@ static NRF_GPIO_Type* pf_gpio_get_dev(PF_GPIO_ID id) | ||
266 | 332 | dev = NULL; |
267 | 333 | |
268 | 334 | // ポート別振り分け |
269 | - if (0 == pf_gpio_table[id].port) | |
335 | + if (0 == pf_gpio_init_table[id].port) | |
270 | 336 | { |
271 | 337 | dev = NRF_P0; |
272 | 338 | } |
@@ -288,36 +354,35 @@ static void pf_gpio_init_id(PF_GPIO_ID id) | ||
288 | 354 | dev = NULL; |
289 | 355 | |
290 | 356 | // 出力方向の場合、先に出力値を設定する |
291 | - if (PF_GPIO_DIR_OUTPUT == pf_gpio_table[id].dir) | |
357 | + if (PF_GPIO_DIR_OUTPUT == pf_gpio_init_table[id].dir) | |
292 | 358 | { |
293 | - pf_gpio_output(id, pf_gpio_table[id].level); | |
359 | + pf_gpio_output(id, pf_gpio_init_table[id].level); | |
294 | 360 | } |
295 | 361 | |
296 | 362 | // IDからデバイスを取得 |
297 | 363 | dev = pf_gpio_get_dev(id); |
298 | 364 | |
299 | 365 | // コンフィグ設定 |
300 | - dev->PIN_CNF[pf_gpio_table[id].pin] = (u4)( | |
301 | - pf_gpio_table[id].dir | |
302 | - | pf_gpio_table[id].inbuf | |
303 | - | pf_gpio_table[id].pull | |
304 | - | pf_gpio_table[id].drive); | |
366 | + dev->PIN_CNF[pf_gpio_init_table[id].pin] = (u4)(pf_gpio_init_table[id].dir | |
367 | + | pf_gpio_init_table[id].inbuf | |
368 | + | pf_gpio_init_table[id].pull | |
369 | + | pf_gpio_init_table[id].drive); | |
305 | 370 | } |
306 | 371 | |
307 | 372 | //! @brief GPIO初期化 |
308 | 373 | //! @remarks プラットフォーム初期化処理から呼び出すこと |
309 | 374 | void pf_gpio_init(void) |
310 | 375 | { |
311 | - u4 id; | |
376 | + PF_GPIO_ID id; | |
312 | 377 | |
313 | 378 | // オート変数初期化 |
314 | 379 | id = 0; |
315 | 380 | |
316 | 381 | // すべてのIDをループ |
317 | - for (id = 0; id < (u4)PF_GPIO_ID_MAX; id++) | |
382 | + for (id = 0; id < PF_GPIO_ID_MAX; id++) | |
318 | 383 | { |
319 | 384 | // 1つのIDを初期化 |
320 | - pf_gpio_init_id((PF_GPIO_ID)id); | |
385 | + pf_gpio_init_id(id); | |
321 | 386 | } |
322 | 387 | } |
323 | 388 |
@@ -334,7 +399,7 @@ u4 pf_gpio_get_port(PF_GPIO_ID id) | ||
334 | 399 | // パラメータチェック |
335 | 400 | if (id < PF_GPIO_ID_MAX) |
336 | 401 | { |
337 | - port = pf_gpio_table[id].port; | |
402 | + port = pf_gpio_init_table[id].port; | |
338 | 403 | } |
339 | 404 | |
340 | 405 | return port; |
@@ -353,7 +418,7 @@ u4 pf_gpio_get_pin(PF_GPIO_ID id) | ||
353 | 418 | // パラメータチェック |
354 | 419 | if (id < PF_GPIO_ID_MAX) |
355 | 420 | { |
356 | - pin = pf_gpio_table[id].pin; | |
421 | + pin = pf_gpio_init_table[id].pin; | |
357 | 422 | } |
358 | 423 | |
359 | 424 | return pin; |
@@ -380,7 +445,7 @@ BOOL pf_gpio_input(PF_GPIO_ID id) | ||
380 | 445 | dev = pf_gpio_get_dev(id); |
381 | 446 | |
382 | 447 | // 当該ピンのみを取り出した情報を取得 |
383 | - in = dev->IN & (1 << pf_gpio_table[id].pin); | |
448 | + in = dev->IN & (1 << pf_gpio_init_table[id].pin); | |
384 | 449 | |
385 | 450 | // 0で'L'レベル、1で'H'レベル |
386 | 451 | if (0 == in) |
@@ -418,12 +483,12 @@ void pf_gpio_output(PF_GPIO_ID id, BOOL level) | ||
418 | 483 | if (FALSE == level) |
419 | 484 | { |
420 | 485 | // 'L'レベル |
421 | - dev->OUTCLR = 1 << pf_gpio_table[id].pin; | |
486 | + dev->OUTCLR = 1 << pf_gpio_init_table[id].pin; | |
422 | 487 | } |
423 | 488 | else |
424 | 489 | { |
425 | 490 | // 'H'レベル |
426 | - dev->OUTSET = 1 << pf_gpio_table[id].pin; | |
491 | + dev->OUTSET = 1 << pf_gpio_init_table[id].pin; | |
427 | 492 | } |
428 | 493 | } |
429 | 494 | } |
@@ -0,0 +1,673 @@ | ||
1 | +//! @file pf_i2c.c | |
2 | +//! @brief プラットフォーム(I2C)実装ファイル | |
3 | + | |
4 | +// The MIT License (MIT) | |
5 | +// Copyright (c) 2023 @xm6_original | |
6 | +// | |
7 | +// Permission is hereby granted, free of charge, to any person obtaining a | |
8 | +// copy of this software and associated documentation files (the "Software"), | |
9 | +// to deal in the Software without restriction, including without limitation | |
10 | +// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | +// and/or sell copies of the Software, and to permit persons to whom the | |
12 | +// Software is furnished to do so, subject to the following conditions: | |
13 | +// | |
14 | +// The above copyright notice and this permission notice shall be included in | |
15 | +// all copies or substantial portions of the Software. | |
16 | +// | |
17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
22 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
23 | +// DEALINGS IN THE SOFTWARE. | |
24 | + | |
25 | +#include "pf_types.h" | |
26 | +#include "nrf52833.h" | |
27 | +#include "nrf52833_bitfields.h" | |
28 | +#include "pf_gpio.h" | |
29 | +#include "pf_interrupt.h" | |
30 | +#include "pf_i2c.h" | |
31 | + | |
32 | +//! @brief I2Cチャネルの最大数 | |
33 | +#define PF_I2C_CHANNEL_MAX (2) | |
34 | + | |
35 | +//! @brief I2Cアドレス情報構造体 | |
36 | +typedef struct PF_I2C_ADDR_Tag | |
37 | +{ | |
38 | + u4 addr; //!< I2Cアドレス | |
39 | + u4 channel; //!< I2Cチャネル(0=内部/1=外部) | |
40 | +} PF_I2C_ADDR; | |
41 | + | |
42 | +//! @brief I2Cアドレス情報テーブル | |
43 | +static const PF_I2C_ADDR pf_i2c_addr_table[PF_I2C_ID_MAX] = | |
44 | +{ | |
45 | + // PF_I2C_ID_ACCELEROMETER | |
46 | + { | |
47 | + 0x19, | |
48 | + 0, | |
49 | + }, | |
50 | + | |
51 | + // PF_I2C_ID_MAGNETOMETER | |
52 | + { | |
53 | + 0x1E, | |
54 | + 0, | |
55 | + }, | |
56 | + | |
57 | + // PF_I2C_ID_MAQUEEN_MOTOR | |
58 | + { | |
59 | + 0x10, | |
60 | + 1, | |
61 | + }, | |
62 | +}; | |
63 | + | |
64 | +//! @brief I2C動作情報構造体 | |
65 | +typedef struct PF_I2C_STATUS_Tag | |
66 | +{ | |
67 | + PF_I2C_CALLBACK callback; //!< コールバック関数 | |
68 | + BOOL busy; //!< BUSYフラグ | |
69 | + BOOL status; //!< 通信ステータス(TRUE=成功/FALSE=失敗) | |
70 | + u4 overrun; //!< オーバーラン発生回数(受信動作が不正) | |
71 | + u4 anack; //!< アドレスNACK発生回数 | |
72 | + u4 dnack; //!< データNACK発生回数 | |
73 | + u1 reg; //!< 受信レジスタ | |
74 | +} PF_I2C_STATUS; | |
75 | + | |
76 | +//! @brief I2C動作情報テーブル | |
77 | +static PF_I2C_STATUS pf_i2c_status[PF_I2C_ID_MAX]; | |
78 | + | |
79 | +//! @brief I2Cチャネル→デバイステーブル | |
80 | +static NRF_TWIM_Type* const pf_i2c_channel_to_dev[PF_I2C_CHANNEL_MAX] = | |
81 | +{ | |
82 | + NRF_TWIM0, //!< チャネル0(内部) | |
83 | + NRF_TWIM1, //!< チャネル1(外部) | |
84 | +}; | |
85 | + | |
86 | +//! @brief I2Cチャネル→割り込み優先度テーブル | |
87 | +static const PF_INTERRUPT_PRI pf_i2c_channel_to_pri[PF_I2C_CHANNEL_MAX] = | |
88 | +{ | |
89 | + PF_INTERRUPT_PRI_I2C_INT, //!< チャネル0(内部) | |
90 | + PF_INTERRUPT_PRI_I2C_EXT, //!< チャネル1(外部) | |
91 | +}; | |
92 | + | |
93 | +//! @brief I2Cチャネル→割り込み番号テーブル | |
94 | +static const IRQn_Type pf_i2c_channel_to_irq[PF_I2C_CHANNEL_MAX] = | |
95 | +{ | |
96 | + SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn, //!< チャネル0(内部) | |
97 | + SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn, //!< チャネル1(外部) | |
98 | +}; | |
99 | + | |
100 | +//! @brief I2C割り込み禁止 | |
101 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
102 | +//! @return 直前のI2C割り込み禁止状態(1:割り込み禁止/0:割り込み許可) | |
103 | +static u4 pf_i2c_interrupt_disable(u4 channel) | |
104 | +{ | |
105 | + u4 enable; | |
106 | + PF_INTERRUPT_PRI pri; | |
107 | + | |
108 | + // オート変数初期化 | |
109 | + enable = 0; | |
110 | + pri = pf_i2c_channel_to_pri[channel]; | |
111 | + | |
112 | + // ローカル割り込み禁止 | |
113 | + enable = pf_interrupt_local_disable(pri); | |
114 | + | |
115 | + return enable; | |
116 | +} | |
117 | + | |
118 | +//! @brief I2C割り込み復元 | |
119 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
120 | +//! @param [in] enable pf_i2c_interrupt_disable(channel)の返り値 | |
121 | +static void pf_i2c_interrupt_restore(u4 channel, u4 enable) | |
122 | +{ | |
123 | + PF_INTERRUPT_PRI pri; | |
124 | + | |
125 | + // オート変数初期化 | |
126 | + pri = pf_i2c_channel_to_pri[channel]; | |
127 | + | |
128 | + // ローカル割り込み復元 | |
129 | + pf_interrupt_local_restore(pri, enable); | |
130 | +} | |
131 | + | |
132 | +//! @brief I2CデバイスBUSYチェック | |
133 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
134 | +//! @return デバイスBUSY状態(TRUE=デバイスBUSY/FALSE=デバイスREADY) | |
135 | +//! @attention I2C割り込み禁止状態で呼び出すこと | |
136 | +static BOOL pf_i2c_get_busy(u4 channel) | |
137 | +{ | |
138 | + BOOL busy; | |
139 | + PF_I2C_ID id; | |
140 | + | |
141 | + // オート変数初期化 | |
142 | + busy = FALSE; | |
143 | + id = 0; | |
144 | + | |
145 | + // すべてのIDをループ | |
146 | + for (id = 0; id < PF_I2C_ID_MAX; id++) | |
147 | + { | |
148 | + // 当該チャネルに該当するか | |
149 | + if (channel == pf_i2c_addr_table[id].channel) | |
150 | + { | |
151 | + // BUSYであれば | |
152 | + if (TRUE == pf_i2c_status[id].busy) | |
153 | + { | |
154 | + // そのチャネルはBUSY | |
155 | + busy = TRUE; | |
156 | + break; | |
157 | + } | |
158 | + } | |
159 | + } | |
160 | + | |
161 | + return busy; | |
162 | +} | |
163 | + | |
164 | +//! @brief 動作中のIDを取得 | |
165 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
166 | +//! @return I2C通信先のID | |
167 | +//! @attention I2C割り込み禁止状態で呼び出すこと | |
168 | +static PF_I2C_ID pf_i2c_get_id(u4 channel) | |
169 | +{ | |
170 | + PF_I2C_ID id; | |
171 | + | |
172 | + // オート変数初期化 | |
173 | + id = 0; | |
174 | + | |
175 | + // すべてのIDをループ | |
176 | + for (id = 0; id < PF_I2C_ID_MAX; id++) | |
177 | + { | |
178 | + // 当該チャネルに該当するか | |
179 | + if (channel == pf_i2c_addr_table[id].channel) | |
180 | + { | |
181 | + // BUSYであれば | |
182 | + if (TRUE == pf_i2c_status[id].busy) | |
183 | + { | |
184 | + // このIDが該当する | |
185 | + break; | |
186 | + } | |
187 | + } | |
188 | + } | |
189 | + | |
190 | + return id; | |
191 | +} | |
192 | + | |
193 | +//! @brief I2C初期化(単一のID) | |
194 | +//! @param [in] id I2C通信先のID | |
195 | +static void pf_i2c_init_id(PF_I2C_ID id) | |
196 | +{ | |
197 | + // コールバック関数なし | |
198 | + pf_i2c_status[id].callback = NULL; | |
199 | + | |
200 | + // デバイスREADY | |
201 | + pf_i2c_status[id].busy = FALSE; | |
202 | + | |
203 | + // エラーなし | |
204 | + pf_i2c_status[id].overrun = 0; | |
205 | + pf_i2c_status[id].anack = 0; | |
206 | + pf_i2c_status[id].dnack = 0; | |
207 | + | |
208 | + // 受信レジスタ0 | |
209 | + pf_i2c_status[id].reg = 0; | |
210 | +} | |
211 | + | |
212 | +//! @brief I2C初期化(デバイス) | |
213 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
214 | +static void pf_i2c_init_dev(u4 channel) | |
215 | +{ | |
216 | + NRF_TWIM_Type *dev; | |
217 | + PF_INTERRUPT_PRI pri; | |
218 | + IRQn_Type irq; | |
219 | + u4 scl_port; | |
220 | + u4 scl_pin; | |
221 | + u4 sda_port; | |
222 | + u4 sda_pin; | |
223 | + | |
224 | + // オート変数初期化 | |
225 | + dev = pf_i2c_channel_to_dev[channel]; | |
226 | + pri = pf_i2c_channel_to_pri[channel]; | |
227 | + irq = pf_i2c_channel_to_irq[channel]; | |
228 | + scl_port = 0; | |
229 | + scl_pin = 0; | |
230 | + sda_port = 0; | |
231 | + sda_pin = 0; | |
232 | + | |
233 | + // I2C無効化 | |
234 | + dev->ENABLE = TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos; | |
235 | + | |
236 | + // 割り込み有効化(転送完了およびエラー) | |
237 | + dev->INTEN = (TWIM_INTEN_STOPPED_Enabled << TWIM_INTEN_STOPPED_Pos) | |
238 | + | (TWIM_INTEN_ERROR_Enabled << TWIM_INTEN_ERROR_Pos); | |
239 | + | |
240 | + // 割り込み設定 | |
241 | + NVIC_SetPriority(irq, pri); | |
242 | + NVIC_ClearPendingIRQ(irq); | |
243 | + NVIC_EnableIRQ(irq); | |
244 | + | |
245 | + // 転送速度(400kbps) | |
246 | + dev->FREQUENCY = TWIM_FREQUENCY_FREQUENCY_K400 << TWIM_FREQUENCY_FREQUENCY_Pos; | |
247 | + | |
248 | + // pf_gpioよりポート番号およびピン番号を取得 | |
249 | + if (0 == channel) | |
250 | + { | |
251 | + // SCL(チャネル0) | |
252 | + scl_port = pf_gpio_get_port(PF_GPIO_ID_INTERNAL_SCL); | |
253 | + scl_pin = pf_gpio_get_pin(PF_GPIO_ID_INTERNAL_SCL); | |
254 | + | |
255 | + // SDA(チャネル0) | |
256 | + sda_port = pf_gpio_get_port(PF_GPIO_ID_INTERNAL_SDA); | |
257 | + sda_pin = pf_gpio_get_pin(PF_GPIO_ID_INTERNAL_SDA); | |
258 | + } | |
259 | + else | |
260 | + { | |
261 | + // SCL(チャネル1) | |
262 | + scl_port = pf_gpio_get_port(PF_GPIO_ID_EXTERNAL_SCL); | |
263 | + scl_pin = pf_gpio_get_pin(PF_GPIO_ID_EXTERNAL_SCL); | |
264 | + | |
265 | + // SDA(チャネル1) | |
266 | + sda_port = pf_gpio_get_port(PF_GPIO_ID_EXTERNAL_SDA); | |
267 | + sda_pin = pf_gpio_get_pin(PF_GPIO_ID_EXTERNAL_SDA); | |
268 | + } | |
269 | + | |
270 | + // SCLピン設定(pf_gpioで管理しているポート番号・ピン番号に接続する) | |
271 | + dev->PSEL.SCL = (scl_pin << TWIM_PSEL_SCL_PIN_Pos) | (scl_port << TWIM_PSEL_SCL_PORT_Pos) | |
272 | + | (TWIM_PSEL_SCL_CONNECT_Connected << TWIM_PSEL_SCL_CONNECT_Pos); | |
273 | + | |
274 | + // SDAピン設定 | |
275 | + dev->PSEL.SDA = (sda_pin << TWIM_PSEL_SDA_PIN_Pos) | (sda_port << TWIM_PSEL_SDA_PORT_Pos) | |
276 | + | (TWIM_PSEL_SDA_CONNECT_Connected << TWIM_PSEL_SDA_CONNECT_Pos); | |
277 | + | |
278 | + // Array Listは使用しない | |
279 | + dev->RXD.LIST = TWIM_RXD_LIST_LIST_Disabled << TWIM_RXD_LIST_LIST_Pos; | |
280 | + dev->TXD.LIST = TWIM_TXD_LIST_LIST_Disabled << TWIM_TXD_LIST_LIST_Pos; | |
281 | + | |
282 | + // I2C有効化 | |
283 | + dev->ENABLE = TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos; | |
284 | +} | |
285 | + | |
286 | +//! @brief I2C初期化 | |
287 | +//! @remarks プラットフォーム初期化処理から呼び出すこと | |
288 | +void pf_i2c_init(void) | |
289 | +{ | |
290 | + PF_I2C_ID id; | |
291 | + | |
292 | + // オート変数初期化 | |
293 | + id = 0; | |
294 | + | |
295 | + // すべてのIDをループ | |
296 | + for (id = 0; id < PF_I2C_ID_MAX; id++) | |
297 | + { | |
298 | + // 1つのIDを初期化 | |
299 | + pf_i2c_init_id(id); | |
300 | + } | |
301 | + | |
302 | + // デバイス初期化(内部) | |
303 | + pf_i2c_init_dev(0); | |
304 | + | |
305 | + // デバイス初期化(外部) | |
306 | + pf_i2c_init_dev(1); | |
307 | +} | |
308 | + | |
309 | +//! @brief I2C送信(デバイス) | |
310 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
311 | +//! @param [in] addr I2Cアドレス | |
312 | +//! @param [in] buf 送信バッファへのポインタ | |
313 | +//! @param [in] bytes 送信バイト数 | |
314 | +//! @attention デバイスREADYの場合に限り呼び出すこと | |
315 | +static void pf_i2c_send_dev(u4 channel, u4 addr, const u1 *buf, u4 bytes) | |
316 | +{ | |
317 | + NRF_TWIM_Type *dev; | |
318 | + | |
319 | + // オート変数初期化 | |
320 | + dev = pf_i2c_channel_to_dev[channel]; | |
321 | + | |
322 | + // イベントのショートカット | |
323 | + dev->SHORTS = TWIM_SHORTS_LASTTX_STOP_Enabled << TWIM_SHORTS_LASTTX_STOP_Pos; | |
324 | + | |
325 | + // 通信先I2Cアドレス | |
326 | + dev->ADDRESS = addr; | |
327 | + | |
328 | + // 送信バッファ | |
329 | + dev->TXD.PTR = (u4)buf; | |
330 | + | |
331 | + // 送信バイト数 | |
332 | + dev->TXD.MAXCNT = bytes; | |
333 | + | |
334 | + // 送信開始 | |
335 | + dev->TASKS_STARTTX = TWIM_TASKS_STARTTX_TASKS_STARTTX_Trigger | |
336 | + << TWIM_TASKS_STARTTX_TASKS_STARTTX_Pos; | |
337 | +} | |
338 | + | |
339 | +//! @brief I2C送信 | |
340 | +//! @param [in] id I2C通信先のID | |
341 | +//! @param [in] buf 送信バッファへのポインタ | |
342 | +//! @param [in] bytes 送信バイト数 | |
343 | +//! @return 送信ステータス(TRUE=送信開始/FALSE=デバイスBUSY) | |
344 | +//! @attention 呼び出し側で送信バッファのライフタイムを保証すること | |
345 | +BOOL pf_i2c_send(PF_I2C_ID id, const u1 *buf, u4 bytes) | |
346 | +{ | |
347 | + u4 channel; | |
348 | + u4 enable; | |
349 | + BOOL busy; | |
350 | + BOOL result; | |
351 | + | |
352 | + // オート変数初期化 | |
353 | + channel = 0; | |
354 | + enable = 0; | |
355 | + busy = FALSE; | |
356 | + result = FALSE; | |
357 | + | |
358 | + // パラメータチェック | |
359 | + if ((id < PF_I2C_ID_MAX) && (NULL != buf) && (bytes > 0)) | |
360 | + { | |
361 | + // チャネル取得 | |
362 | + channel = pf_i2c_addr_table[id].channel; | |
363 | + | |
364 | + // I2C割り込み禁止 | |
365 | + enable = pf_i2c_interrupt_disable(channel); | |
366 | + | |
367 | + // デバイスBUSYチェック | |
368 | + busy = pf_i2c_get_busy(channel); | |
369 | + | |
370 | + // READYであれば送信開始 | |
371 | + if (FALSE == busy) | |
372 | + { | |
373 | + // 通信成功に初期化 | |
374 | + pf_i2c_status[id].status = TRUE; | |
375 | + | |
376 | + // 送信開始 | |
377 | + pf_i2c_send_dev(channel, pf_i2c_addr_table[id].addr, buf, bytes); | |
378 | + | |
379 | + // BUSYへ変更 | |
380 | + pf_i2c_status[id].busy = TRUE; | |
381 | + | |
382 | + // 送信開始に成功した | |
383 | + result = TRUE; | |
384 | + } | |
385 | + | |
386 | + // I2C割り込み復元 | |
387 | + pf_i2c_interrupt_restore(channel, enable); | |
388 | + } | |
389 | + | |
390 | + return result; | |
391 | +} | |
392 | + | |
393 | +//! @brief I2C受信(デバイス) | |
394 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
395 | +//! @param [in] addr I2Cアドレス | |
396 | +//! @param [in] reg 受信レジスタへのポインタ | |
397 | +//! @param [in] buf 受信バッファへのポインタ | |
398 | +//! @param [in] bytes 受信バイト数 | |
399 | +//! @attention デバイスREADYの場合に限り呼び出すこと | |
400 | +static void pf_i2c_recv_dev(u4 channel, u4 addr, const u1 *reg, u1 *buf, u4 bytes) | |
401 | +{ | |
402 | + NRF_TWIM_Type *dev; | |
403 | + | |
404 | + // オート変数初期化 | |
405 | + dev = pf_i2c_channel_to_dev[channel]; | |
406 | + | |
407 | + // イベントのショートカット | |
408 | + dev->SHORTS = (TWIM_SHORTS_LASTTX_STARTRX_Enabled << TWIM_SHORTS_LASTTX_STARTRX_Pos) | |
409 | + | (TWIM_SHORTS_LASTRX_STOP_Enabled << TWIM_SHORTS_LASTRX_STOP_Pos); | |
410 | + | |
411 | + // 通信先I2Cアドレス | |
412 | + dev->ADDRESS = addr; | |
413 | + | |
414 | + // 送信バッファ(受信レジスタ) | |
415 | + dev->TXD.PTR = (u4)reg; | |
416 | + | |
417 | + // 送信バイト数 | |
418 | + dev->TXD.MAXCNT = 1; | |
419 | + | |
420 | + // 受信バッファ | |
421 | + dev->RXD.PTR = (u4)buf; | |
422 | + | |
423 | + // 送信バイト数 | |
424 | + dev->RXD.MAXCNT = bytes; | |
425 | + | |
426 | + // レジスタ送信開始(レジスタ送信完了後、受信動作に移行する) | |
427 | + dev->TASKS_STARTTX = TWIM_TASKS_STARTTX_TASKS_STARTTX_Trigger | |
428 | + << TWIM_TASKS_STARTTX_TASKS_STARTTX_Pos; | |
429 | +} | |
430 | + | |
431 | +//! @brief I2C受信 | |
432 | +//! @param [in] id I2C通信先のID | |
433 | +//! @param [in] reg 受信レジスタ | |
434 | +//! @param [in] buf 受信バッファへのポインタ | |
435 | +//! @param [in] bytes 受信バイト数 | |
436 | +//! @return 受信ステータス(TRUE=受信開始/FALSE=デバイスBUSY) | |
437 | +BOOL pf_i2c_recv(PF_I2C_ID id, u1 reg, u1 *buf, u4 bytes) | |
438 | +{ | |
439 | + u4 channel; | |
440 | + u4 enable; | |
441 | + BOOL busy; | |
442 | + BOOL result; | |
443 | + | |
444 | + // オート変数初期化 | |
445 | + channel = 0; | |
446 | + enable = 0; | |
447 | + busy = FALSE; | |
448 | + result = FALSE; | |
449 | + | |
450 | + // パラメータチェック | |
451 | + if ((id < PF_I2C_ID_MAX) && (NULL != buf) && (bytes > 0)) | |
452 | + { | |
453 | + // チャネル取得 | |
454 | + channel = pf_i2c_addr_table[id].channel; | |
455 | + | |
456 | + // I2C割り込み禁止 | |
457 | + enable = pf_i2c_interrupt_disable(channel); | |
458 | + | |
459 | + // デバイスBUSYチェック | |
460 | + busy = pf_i2c_get_busy(channel); | |
461 | + | |
462 | + // READYであれば送受信開始 | |
463 | + if (FALSE == busy) | |
464 | + { | |
465 | + // 受信レジスタを記憶 | |
466 | + pf_i2c_status[id].reg = reg; | |
467 | + | |
468 | + // 通信成功に初期化 | |
469 | + pf_i2c_status[id].status = TRUE; | |
470 | + | |
471 | + // 送受信開始 | |
472 | + pf_i2c_recv_dev(channel, pf_i2c_addr_table[id].addr, &pf_i2c_status[id].reg, buf, | |
473 | + bytes); | |
474 | + | |
475 | + // BUSYへ変更 | |
476 | + pf_i2c_status[id].busy = TRUE; | |
477 | + | |
478 | + // 送受信開始に成功した | |
479 | + result = TRUE; | |
480 | + } | |
481 | + | |
482 | + // I2C割り込み復元 | |
483 | + pf_i2c_interrupt_restore(channel, enable); | |
484 | + } | |
485 | + | |
486 | + return result; | |
487 | +} | |
488 | + | |
489 | +//! @brief I2Cエラー情報取得 | |
490 | +//! @param [in] id I2C通信先のID | |
491 | +//! @param [out] error エラー情報構造体へのポインタ | |
492 | +//! @remarks プラットフォーム内部のエラー情報はクリアされる | |
493 | +void pf_i2c_error(PF_I2C_ID id, PF_I2C_ERROR *error) | |
494 | +{ | |
495 | + u4 channel; | |
496 | + channel = 0; | |
497 | + u4 enable; | |
498 | + | |
499 | + // オート変数初期化 | |
500 | + channel = 0; | |
501 | + enable = 0; | |
502 | + | |
503 | + // パラメータチェック | |
504 | + if ((id < PF_I2C_ID_MAX) && (NULL != error)) | |
505 | + { | |
506 | + // チャネル取得 | |
507 | + channel = pf_i2c_addr_table[id].channel; | |
508 | + | |
509 | + // I2C割り込み禁止 | |
510 | + enable = pf_i2c_interrupt_disable(channel); | |
511 | + | |
512 | + // エラー情報を転送 | |
513 | + error->overrun = pf_i2c_status[id].overrun; | |
514 | + error->anack = pf_i2c_status[id].anack; | |
515 | + error->dnack = pf_i2c_status[id].dnack; | |
516 | + | |
517 | + // プラットフォーム内部のエラー情報をクリア | |
518 | + pf_i2c_status[id].overrun = 0; | |
519 | + pf_i2c_status[id].anack = 0; | |
520 | + pf_i2c_status[id].dnack = 0; | |
521 | + | |
522 | + // I2C割り込み復元 | |
523 | + pf_i2c_interrupt_restore(channel, enable); | |
524 | + } | |
525 | +} | |
526 | + | |
527 | +//! @brief I2Cコールバック関数設定 | |
528 | +//! @param [in] id I2C通信先のID | |
529 | +//! @param [in] func I2Cコールバック関数へのポインタ | |
530 | +//! @attention I2Cコールバック関数は割り込みコンテキストで呼び出される | |
531 | +void pf_i2c_callback(PF_I2C_ID id, PF_I2C_CALLBACK func) | |
532 | +{ | |
533 | + u4 channel; | |
534 | + u4 enable; | |
535 | + | |
536 | + // オート変数初期化 | |
537 | + channel = 0; | |
538 | + enable = 0; | |
539 | + | |
540 | + // IDチェック | |
541 | + if (id < PF_I2C_ID_MAX) | |
542 | + { | |
543 | + // チャネル取得 | |
544 | + channel = pf_i2c_addr_table[id].channel; | |
545 | + | |
546 | + // I2C割り込み禁止 | |
547 | + enable = pf_i2c_interrupt_disable(channel); | |
548 | + | |
549 | + // コールバック関数設定 | |
550 | + pf_i2c_status[id].callback = func; | |
551 | + | |
552 | + // I2C割り込み復元 | |
553 | + pf_i2c_interrupt_restore(channel, enable); | |
554 | + } | |
555 | +} | |
556 | + | |
557 | +//! @brief I2C割り込みハンドラ(STOPPED) | |
558 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
559 | +//! @attention データ競合(割り込み干渉)に注意する | |
560 | +static void pf_i2c_isr_stopped(u4 channel) | |
561 | +{ | |
562 | + PF_I2C_ID id; | |
563 | + | |
564 | + // オート変数初期化 | |
565 | + id = PF_I2C_ID_ACCELEROMETER; | |
566 | + | |
567 | + // チャネルから通信先IDを逆引きする | |
568 | + id = pf_i2c_get_id(channel); | |
569 | + | |
570 | + // 通信終了 | |
571 | + pf_i2c_status[id].busy = FALSE; | |
572 | + | |
573 | + // I2Cコールバック関数が登録されていれば、呼び出す | |
574 | + if (NULL != pf_i2c_status[id].callback) | |
575 | + { | |
576 | + pf_i2c_status[id].callback(pf_i2c_status[id].status); | |
577 | + } | |
578 | +} | |
579 | + | |
580 | +//! @brief I2C割り込みハンドラ(ERROR) | |
581 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
582 | +//! @attention データ競合(割り込み干渉)に注意する | |
583 | +static void pf_i2c_isr_error(u4 channel) | |
584 | +{ | |
585 | + PF_I2C_ID id; | |
586 | + NRF_TWIM_Type *dev; | |
587 | + u4 overrun; | |
588 | + u4 anack; | |
589 | + u4 dnack; | |
590 | + | |
591 | + // オート変数初期化 | |
592 | + id = PF_I2C_ID_ACCELEROMETER; | |
593 | + dev = pf_i2c_channel_to_dev[channel]; | |
594 | + overrun = TWIM_ERRORSRC_OVERRUN_Received << TWIM_ERRORSRC_OVERRUN_Pos; | |
595 | + anack = TWIM_ERRORSRC_ANACK_Received << TWIM_ERRORSRC_ANACK_Pos; | |
596 | + dnack = TWIM_ERRORSRC_DNACK_Received << TWIM_ERRORSRC_DNACK_Pos; | |
597 | + | |
598 | + // チャネルから通信先IDを逆引きする | |
599 | + id = pf_i2c_get_id(channel); | |
600 | + | |
601 | + // 通信エラーあり | |
602 | + pf_i2c_status[id].status = FALSE; | |
603 | + | |
604 | + // エラー種別判定(ANACK) | |
605 | + if (anack == (dev->ERRORSRC & anack)) | |
606 | + { | |
607 | + // ANACK発生。'1'を書き込むことでクリアする | |
608 | + pf_i2c_status[id].anack++; | |
609 | + dev->ERRORSRC = anack; | |
610 | + } | |
611 | + | |
612 | + // エラー種別判定(DNACK) | |
613 | + if (dnack == (dev->ERRORSRC & dnack)) | |
614 | + { | |
615 | + // DNACK発生。'1'を書き込むことでクリアする | |
616 | + pf_i2c_status[id].dnack++; | |
617 | + dev->ERRORSRC = dnack; | |
618 | + } | |
619 | + | |
620 | + // エラー種別判定(OVERRUN) | |
621 | + if (overrun == (dev->ERRORSRC & overrun)) | |
622 | + { | |
623 | + // オーバーラン発生。'0'を書き込むことでクリアする | |
624 | + pf_i2c_status[id].overrun++; | |
625 | + dev->ERRORSRC = TWIM_ERRORSRC_OVERRUN_NotReceived << TWIM_ERRORSRC_OVERRUN_Pos; | |
626 | + } | |
627 | + | |
628 | + // ここでI2C通信を打ち切る(この後、pf_i2c_isr_stoppedが呼ばれる) | |
629 | + dev->TASKS_STOP = TWIM_TASKS_STOP_TASKS_STOP_Trigger << TWIM_TASKS_STOP_TASKS_STOP_Pos; | |
630 | +} | |
631 | + | |
632 | +//! @brief 共通割り込みハンドラ | |
633 | +//! @param [in] channel I2Cチャネル(0=内部/1=外部) | |
634 | +//! @attention データ競合(割り込み干渉)に注意する | |
635 | +static void pf_i2c_isr(u4 channel) | |
636 | +{ | |
637 | + NRF_TWIM_Type *dev; | |
638 | + | |
639 | + // オート変数初期化 | |
640 | + dev = pf_i2c_channel_to_dev[channel]; | |
641 | + | |
642 | + // STOPPED | |
643 | + if ((TWIM_EVENTS_STOPPED_EVENTS_STOPPED_Generated << TWIM_EVENTS_STOPPED_EVENTS_STOPPED_Pos) | |
644 | + == dev->EVENTS_STOPPED) | |
645 | + { | |
646 | + dev->EVENTS_STOPPED = TWIM_EVENTS_STOPPED_EVENTS_STOPPED_NotGenerated | |
647 | + << TWIM_EVENTS_STOPPED_EVENTS_STOPPED_Pos; | |
648 | + pf_i2c_isr_stopped(channel); | |
649 | + } | |
650 | + | |
651 | + // ERROR | |
652 | + if ((TWIM_EVENTS_ERROR_EVENTS_ERROR_Generated << TWIM_EVENTS_ERROR_EVENTS_ERROR_Pos) | |
653 | + == dev->EVENTS_ERROR) | |
654 | + { | |
655 | + dev->EVENTS_ERROR = TWIM_EVENTS_ERROR_EVENTS_ERROR_NotGenerated | |
656 | + << TWIM_EVENTS_ERROR_EVENTS_ERROR_Pos; | |
657 | + pf_i2c_isr_error(channel); | |
658 | + } | |
659 | +} | |
660 | + | |
661 | +//! @brief I2C割り込みハンドラ(チャネル0=内部I2Cバス) | |
662 | +//! @attention データ競合(割り込み干渉)に注意する | |
663 | +void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) | |
664 | +{ | |
665 | + pf_i2c_isr(0); | |
666 | +} | |
667 | + | |
668 | +//! @brief I2C割り込みハンドラ(チャネル1=外部I2Cバス) | |
669 | +//! @attention データ競合(割り込み干渉)に注意する | |
670 | +void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void) | |
671 | +{ | |
672 | + pf_i2c_isr(1); | |
673 | +} |
@@ -33,6 +33,9 @@ u4 pf_interrupt_global_disable(void) | ||
33 | 33 | u4 primask; |
34 | 34 | |
35 | 35 | // オート変数初期化 |
36 | + primask = 0; | |
37 | + | |
38 | + // 現在のPRIMASKビットを取得 | |
36 | 39 | primask = (u4)__get_PRIMASK(); |
37 | 40 | |
38 | 41 | // 割り込み禁止 |
@@ -45,7 +48,7 @@ u4 pf_interrupt_global_disable(void) | ||
45 | 48 | //! @param [in] primask pf_interrupt_global_disable()の返り値 |
46 | 49 | void pf_interrupt_global_restore(u4 primask) |
47 | 50 | { |
48 | - // 直前の割り込み禁止状態が割り込み許可の場合のみ | |
51 | + // 直前の状態が割り込み許可の場合のみ | |
49 | 52 | if (0 == primask) |
50 | 53 | { |
51 | 54 | // 割り込み許可 |
@@ -56,7 +59,7 @@ void pf_interrupt_global_restore(u4 primask) | ||
56 | 59 | //! @brief 割り込み番号を取得 |
57 | 60 | //! @param [in] pri 割り込み優先度 |
58 | 61 | //! @return 割り込み番号(priが不正の場合、UARTE1_IRQn) |
59 | -static u4 pf_interrupt_get_irq(PF_INTERRUPT_PRI pri) | |
62 | +static IRQn_Type pf_interrupt_get_irq(PF_INTERRUPT_PRI pri) | |
60 | 63 | { |
61 | 64 | IRQn_Type irq; |
62 | 65 |
@@ -66,11 +69,6 @@ static u4 pf_interrupt_get_irq(PF_INTERRUPT_PRI pri) | ||
66 | 69 | // 割り込み優先度から割り込み番号を取得 |
67 | 70 | switch (pri) |
68 | 71 | { |
69 | - // POWER | |
70 | - case PF_INTERRUPT_PRI_POWER: | |
71 | - irq = POWER_CLOCK_IRQn; | |
72 | - break; | |
73 | - | |
74 | 72 | // UART |
75 | 73 | case PF_INTERRUPT_PRI_UART: |
76 | 74 | irq = UARTE0_UART0_IRQn; |
@@ -81,6 +79,16 @@ static u4 pf_interrupt_get_irq(PF_INTERRUPT_PRI pri) | ||
81 | 79 | irq = TIMER0_IRQn; |
82 | 80 | break; |
83 | 81 | |
82 | + // I2C(内部) | |
83 | + case PF_INTERRUPT_PRI_I2C_INT: | |
84 | + irq = SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn; | |
85 | + break; | |
86 | + | |
87 | + // I2C(外部) | |
88 | + case PF_INTERRUPT_PRI_I2C_EXT: | |
89 | + irq = SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn; | |
90 | + break; | |
91 | + | |
84 | 92 | default: |
85 | 93 | break; |
86 | 94 | } |
@@ -27,10 +27,10 @@ | ||
27 | 27 | #include "pf_led.h" |
28 | 28 | |
29 | 29 | //! @brief LED→GPIO IDテーブル |
30 | -static const PF_GPIO_ID pf_led_gpio_table[PF_LED_ID_MAX] = | |
30 | +static const PF_GPIO_ID pf_led_to_gpio[PF_LED_ID_MAX] = | |
31 | 31 | { |
32 | - PF_GPIO_ID_MAQUEEN_LED_L, //!< PF_LED_ID_MAQUEEN_L | |
33 | - PF_GPIO_ID_MAQUEEN_LED_R, //!< PF_LED_ID_MAQUEEN_R | |
32 | + PF_GPIO_ID_MAQUEEN_LED_L, //!< PF_LED_ID_L | |
33 | + PF_GPIO_ID_MAQUEEN_LED_R, //!< PF_LED_ID_R | |
34 | 34 | }; |
35 | 35 | |
36 | 36 | //! @brief LED情報テーブル |
@@ -44,46 +44,54 @@ static BOOL pf_led_info[PF_LED_ID_MAX] = | ||
44 | 44 | //! @remarks プラットフォーム初期化処理から呼び出すこと |
45 | 45 | void pf_led_init(void) |
46 | 46 | { |
47 | - u4 loop; | |
47 | + PF_LED_ID id; | |
48 | 48 | PF_GPIO_ID gpio; |
49 | 49 | |
50 | 50 | // オート変数初期化 |
51 | - loop = 0; | |
51 | + id = 0; | |
52 | 52 | gpio = PF_GPIO_ID_MAQUEEN_LED_L; |
53 | 53 | |
54 | - for (loop = 0; loop < (u4)PF_LED_ID_MAX; loop++) | |
54 | + // すべてのIDをループ | |
55 | + for (id = 0; id < PF_LED_ID_MAX; id++) | |
55 | 56 | { |
56 | 57 | // LED消灯(GPIOに対し'H'レベルで点灯、'L'レベルで消灯) |
57 | - gpio = pf_led_gpio_table[loop]; | |
58 | + gpio = pf_led_to_gpio[id]; | |
58 | 59 | pf_gpio_output(gpio, FALSE); |
59 | 60 | |
60 | 61 | // LED情報を更新 |
61 | - pf_led_info[loop] = FALSE; | |
62 | + pf_led_info[id] = FALSE; | |
62 | 63 | } |
63 | 64 | } |
64 | 65 | |
65 | -//! @brief LED制御 | |
66 | -//! @param [in] id LEDのID | |
67 | -//! @param [in] ctrl LED制御情報(TRUE=LED点灯/FALSE=LED消灯) | |
68 | -void pf_led_ctrl(PF_LED_ID id, BOOL ctrl) | |
66 | +//! @brief LED定期タスク | |
67 | +//! @remarks プラットフォーム定期タスク(出力系)処理から呼び出すこと | |
68 | +void pf_led_task(void) | |
69 | 69 | { |
70 | + PF_LED_ID id; | |
70 | 71 | PF_GPIO_ID gpio; |
71 | 72 | |
72 | 73 | // オート変数初期化 |
74 | + id = 0; | |
73 | 75 | gpio = PF_GPIO_ID_MAQUEEN_LED_L; |
74 | 76 | |
77 | + // すべてのIDをループ | |
78 | + for (id = 0; id < PF_LED_ID_MAX; id++) | |
79 | + { | |
80 | + // GPIOへ反映 | |
81 | + gpio = pf_led_to_gpio[id]; | |
82 | + pf_gpio_output(gpio, pf_led_info[id]); | |
83 | + } | |
84 | +} | |
85 | + | |
86 | +//! @brief LED制御 | |
87 | +//! @param [in] id LEDのID | |
88 | +//! @param [in] ctrl LED制御情報(TRUE=LED点灯/FALSE=LED消灯) | |
89 | +void pf_led_ctrl(PF_LED_ID id, BOOL ctrl) | |
90 | +{ | |
75 | 91 | // パラメータチェック |
76 | 92 | if (id < PF_LED_ID_MAX) |
77 | 93 | { |
78 | - // 一致チェック | |
79 | - if (ctrl != pf_led_info[id]) | |
80 | - { | |
81 | - // GPIO出力を更新 | |
82 | - gpio = pf_led_gpio_table[id]; | |
83 | - pf_gpio_output(gpio, ctrl); | |
84 | - | |
85 | - // LED情報を更新 | |
86 | - pf_led_info[id] = ctrl; | |
87 | - } | |
94 | + // LED情報を更新 | |
95 | + pf_led_info[id] = ctrl; | |
88 | 96 | } |
89 | 97 | } |
@@ -0,0 +1,288 @@ | ||
1 | +//! @file pf_motor.c | |
2 | +//! @brief プラットフォーム(モータ)実装ファイル | |
3 | + | |
4 | +// The MIT License (MIT) | |
5 | +// Copyright (c) 2023 @xm6_original | |
6 | +// | |
7 | +// Permission is hereby granted, free of charge, to any person obtaining a | |
8 | +// copy of this software and associated documentation files (the "Software"), | |
9 | +// to deal in the Software without restriction, including without limitation | |
10 | +// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | +// and/or sell copies of the Software, and to permit persons to whom the | |
12 | +// Software is furnished to do so, subject to the following conditions: | |
13 | +// | |
14 | +// The above copyright notice and this permission notice shall be included in | |
15 | +// all copies or substantial portions of the Software. | |
16 | +// | |
17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
22 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
23 | +// DEALINGS IN THE SOFTWARE. | |
24 | + | |
25 | +#include "pf_types.h" | |
26 | +#include "pf_interrupt.h" | |
27 | +#include "pf_i2c.h" | |
28 | +#include "pf_motor.h" | |
29 | + | |
30 | +//! @brief モータ速度(デフォルト) | |
31 | +#define PF_MOTOR_DEFAULT_SPEED ((u1)100U) | |
32 | + | |
33 | +//! @brief チャネル(左) | |
34 | +#define PF_MOTOR_CHANNEL_LEFT ((u1)0x00U) | |
35 | + | |
36 | +//! @brief チャネル(左) | |
37 | +#define PF_MOTOR_CHANNEL_RIGHT ((u1)0x02U) | |
38 | + | |
39 | +//! @brief チャネル数 | |
40 | +#define PF_MOTOR_CHANNEL_MAX ((u4)2U) | |
41 | + | |
42 | +//! @brief 回転方向(前回転) | |
43 | +#define PF_MOTOR_MOVE_FORWARD ((u1)0x00U) | |
44 | + | |
45 | +//! @brief 回転方向(後回転) | |
46 | +#define PF_MOTOR_MOVE_BACKWARD ((u1)0x01U) | |
47 | + | |
48 | +//! @brief 動作速度(駆動) | |
49 | +#define PF_MOTOR_SPEED_DRIVE ((u1)0x01U) | |
50 | + | |
51 | +//! @brief 動作速度(停止) | |
52 | +#define PF_MOTOR_SPEED_STOP ((u1)0x00U) | |
53 | + | |
54 | +//! @brief I2Cバッファ要素定義 | |
55 | +typedef enum PF_MOTOR_I2C_Tag | |
56 | +{ | |
57 | + PF_MOTOR_I2C_CHANNEL = 0, //!< チャネル | |
58 | + PF_MOTOR_I2C_MOVE, //!< 回転方向 | |
59 | + PF_MOTOR_I2C_SPEED, //!< 速度 | |
60 | + PF_MOTOR_I2C_MAX, //!< (バッファのサイズを表す) | |
61 | +} PF_MOTOR_I2C; | |
62 | + | |
63 | +//! @brief モータ駆動情報構造体 | |
64 | +typedef struct PF_MOTOR_DIR_INFO_Tag | |
65 | +{ | |
66 | + u1 channel; //!< チャネル | |
67 | + u1 direction; //!< 駆動方向 | |
68 | + u1 speed; //!< 動作速度 | |
69 | +} PF_MOTOR_DIR_INFO; | |
70 | + | |
71 | +//! @brief モータ駆動方向→モータ駆動情報テーブル | |
72 | +static const PF_MOTOR_DIR_INFO pf_motor_dir_to_info[PF_MOTOR_DIR_MAX][PF_MOTOR_CHANNEL_MAX] = | |
73 | +{ | |
74 | + // PF_MOTOR_DIR_FORWARD | |
75 | + { | |
76 | + // LEFT | |
77 | + { | |
78 | + PF_MOTOR_CHANNEL_LEFT, | |
79 | + PF_MOTOR_MOVE_FORWARD, | |
80 | + PF_MOTOR_SPEED_DRIVE, | |
81 | + }, | |
82 | + | |
83 | + // RIGHT | |
84 | + { | |
85 | + PF_MOTOR_CHANNEL_RIGHT, | |
86 | + PF_MOTOR_MOVE_FORWARD, | |
87 | + PF_MOTOR_SPEED_DRIVE, | |
88 | + }, | |
89 | + }, | |
90 | + | |
91 | + // PF_MOTOR_DIR_LEFT | |
92 | + { | |
93 | + // LEFT | |
94 | + { | |
95 | + PF_MOTOR_CHANNEL_LEFT, | |
96 | + PF_MOTOR_MOVE_BACKWARD, | |
97 | + PF_MOTOR_SPEED_DRIVE, | |
98 | + }, | |
99 | + | |
100 | + // RIGHT | |
101 | + { | |
102 | + PF_MOTOR_CHANNEL_RIGHT, | |
103 | + PF_MOTOR_MOVE_FORWARD, | |
104 | + PF_MOTOR_SPEED_DRIVE, | |
105 | + }, | |
106 | + }, | |
107 | + | |
108 | + // PF_MOTOR_DIR_RIGHT | |
109 | + { | |
110 | + // LEFT | |
111 | + { | |
112 | + PF_MOTOR_CHANNEL_LEFT, | |
113 | + PF_MOTOR_MOVE_FORWARD, | |
114 | + PF_MOTOR_SPEED_DRIVE, | |
115 | + }, | |
116 | + | |
117 | + // RIGHT | |
118 | + { | |
119 | + PF_MOTOR_CHANNEL_RIGHT, | |
120 | + PF_MOTOR_MOVE_BACKWARD, | |
121 | + PF_MOTOR_SPEED_DRIVE, | |
122 | + }, | |
123 | + }, | |
124 | + | |
125 | + // PF_MOTOR_DIR_BACKWORD | |
126 | + { | |
127 | + // LEFT | |
128 | + { | |
129 | + PF_MOTOR_CHANNEL_LEFT, | |
130 | + PF_MOTOR_MOVE_BACKWARD, | |
131 | + PF_MOTOR_SPEED_DRIVE, | |
132 | + }, | |
133 | + | |
134 | + // RIGHT | |
135 | + { | |
136 | + PF_MOTOR_CHANNEL_RIGHT, | |
137 | + PF_MOTOR_MOVE_BACKWARD, | |
138 | + PF_MOTOR_SPEED_DRIVE, | |
139 | + }, | |
140 | + }, | |
141 | + | |
142 | + // PF_MOTOR_DIR_STOP | |
143 | + { | |
144 | + // LEFT | |
145 | + { | |
146 | + PF_MOTOR_CHANNEL_LEFT, | |
147 | + PF_MOTOR_MOVE_FORWARD, | |
148 | + PF_MOTOR_SPEED_STOP, | |
149 | + }, | |
150 | + | |
151 | + // RIGHT | |
152 | + { | |
153 | + PF_MOTOR_CHANNEL_RIGHT, | |
154 | + PF_MOTOR_MOVE_FORWARD, | |
155 | + PF_MOTOR_SPEED_STOP, | |
156 | + }, | |
157 | + }, | |
158 | +}; | |
159 | + | |
160 | +//! @brief I2C通信バッファ | |
161 | +static u1 pf_motor_buf[PF_MOTOR_CHANNEL_MAX][PF_MOTOR_I2C_MAX]; | |
162 | + | |
163 | +//! @brief 現在のモータ駆動方向 | |
164 | +static PF_MOTOR_DIR pf_motor_current_dir; | |
165 | + | |
166 | +//! @brief 次回のモータ駆動方向 | |
167 | +static PF_MOTOR_DIR pf_motor_next_dir; | |
168 | + | |
169 | +//! @brief 現在のモータ速度 | |
170 | +static u1 pf_motor_current_speed; | |
171 | + | |
172 | +//! @brief 現在の送信中チャネル | |
173 | +static u4 pf_motor_current_channel; | |
174 | + | |
175 | +//! @brief I2Cからのコールバック関数 | |
176 | +//! @param [in] status 通信ステータス(TRUE=成功/FALSE=失敗) | |
177 | +static void pf_motor_callback(BOOL status) | |
178 | +{ | |
179 | + // 成功の場合 | |
180 | + if (TRUE == status) | |
181 | + { | |
182 | + // 送信中チャネルをインクリメント | |
183 | + pf_motor_current_channel++; | |
184 | + | |
185 | + // 送信中チャネルが最大値に達しているか | |
186 | + if (pf_motor_current_channel < PF_MOTOR_CHANNEL_MAX) | |
187 | + { | |
188 | + // 次の送信をスタート | |
189 | + (void)pf_i2c_send(PF_I2C_ID_MAQUEEN_MOTOR, &pf_motor_buf[pf_motor_current_channel][0], | |
190 | + PF_MOTOR_I2C_MAX); | |
191 | + } | |
192 | + else | |
193 | + { | |
194 | + // すべてのチャネルを送信完了したので、更新 | |
195 | + pf_motor_current_dir = pf_motor_next_dir; | |
196 | + } | |
197 | + } | |
198 | +} | |
199 | + | |
200 | +//! @brief モータ初期化 | |
201 | +//! @remarks プラットフォーム初期化処理から呼び出すこと | |
202 | +void pf_motor_init(void) | |
203 | +{ | |
204 | + // モータ駆動方向: 停止 | |
205 | + pf_motor_current_dir = PF_MOTOR_DIR_STOP; | |
206 | + pf_motor_next_dir = PF_MOTOR_DIR_STOP; | |
207 | + | |
208 | + // モータ速度: デフォルト | |
209 | + pf_motor_current_speed = PF_MOTOR_DEFAULT_SPEED; | |
210 | + | |
211 | + // I2Cコールバック関数を設定 | |
212 | + pf_i2c_callback(PF_I2C_ID_MAQUEEN_MOTOR, pf_motor_callback); | |
213 | +} | |
214 | + | |
215 | +//! @brief モータ駆動情報送信 | |
216 | +static void pf_motor_send(void) | |
217 | +{ | |
218 | + u4 loop; | |
219 | + | |
220 | + // オート変数初期化 | |
221 | + loop = 0; | |
222 | + | |
223 | + // チャネル数ループ | |
224 | + for (loop = 0; loop < PF_MOTOR_CHANNEL_MAX; loop++) | |
225 | + { | |
226 | + // チャネル | |
227 | + pf_motor_buf[loop][PF_MOTOR_I2C_CHANNEL] = | |
228 | + pf_motor_dir_to_info[pf_motor_next_dir][loop].channel; | |
229 | + | |
230 | + // 駆動方向 | |
231 | + pf_motor_buf[loop][PF_MOTOR_I2C_MOVE] = | |
232 | + pf_motor_dir_to_info[pf_motor_next_dir][loop].direction; | |
233 | + | |
234 | + // 動作速度(駆動の場合は現在の速度を設定する) | |
235 | + if (PF_MOTOR_SPEED_STOP == pf_motor_dir_to_info[pf_motor_next_dir][loop].speed) | |
236 | + { | |
237 | + // 停止 | |
238 | + pf_motor_buf[loop][PF_MOTOR_I2C_SPEED] = PF_MOTOR_SPEED_STOP; | |
239 | + } | |
240 | + else | |
241 | + { | |
242 | + // 現在の速度で駆動 | |
243 | + pf_motor_buf[loop][PF_MOTOR_I2C_SPEED] = pf_motor_current_speed; | |
244 | + } | |
245 | + } | |
246 | + | |
247 | + // 送信中チャネルを初期化 | |
248 | + pf_motor_current_channel = 0; | |
249 | + | |
250 | + // 最初のチャネルの送信をスタート | |
251 | + (void)pf_i2c_send(PF_I2C_ID_MAQUEEN_MOTOR, &pf_motor_buf[0][0], PF_MOTOR_I2C_MAX); | |
252 | +} | |
253 | + | |
254 | +//! @brief モータ定期タスク | |
255 | +//! @remarks プラットフォーム定期タスク(出力系)処理から呼び出すこと | |
256 | +void pf_motor_task(void) | |
257 | +{ | |
258 | + u4 enable; | |
259 | + PF_MOTOR_DIR current; | |
260 | + | |
261 | + // オート変数初期化 | |
262 | + enable = 0; | |
263 | + current = PF_MOTOR_DIR_STOP; | |
264 | + | |
265 | + // 現在の駆動方向を取得(グローバル割り込みを禁止して行う) | |
266 | + enable = pf_interrupt_global_disable(); | |
267 | + current = pf_motor_current_dir; | |
268 | + pf_interrupt_global_restore(enable); | |
269 | + | |
270 | + // 駆動方向を比較 | |
271 | + if (current != pf_motor_next_dir) | |
272 | + { | |
273 | + // 一致するまで送信 | |
274 | + pf_motor_send(); | |
275 | + } | |
276 | +} | |
277 | + | |
278 | +//! @brief モータ駆動 | |
279 | +//! @details モータ定期タスクで実際のモータ出力が行われる | |
280 | +//! @param [in] dir モータ駆動方向 | |
281 | +void pf_motor_drive(PF_MOTOR_DIR dir) | |
282 | +{ | |
283 | + // パラメータチェック | |
284 | + if (dir < PF_MOTOR_DIR_MAX) | |
285 | + { | |
286 | + pf_motor_next_dir = dir; | |
287 | + } | |
288 | +} |
@@ -0,0 +1,120 @@ | ||
1 | +//! @file pf_patrol.c | |
2 | +//! @brief プラットフォーム(ラインセンサ)実装ファイル | |
3 | + | |
4 | +// The MIT License (MIT) | |
5 | +// Copyright (c) 2023 @xm6_original | |
6 | +// | |
7 | +// Permission is hereby granted, free of charge, to any person obtaining a | |
8 | +// copy of this software and associated documentation files (the "Software"), | |
9 | +// to deal in the Software without restriction, including without limitation | |
10 | +// the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | +// and/or sell copies of the Software, and to permit persons to whom the | |
12 | +// Software is furnished to do so, subject to the following conditions: | |
13 | +// | |
14 | +// The above copyright notice and this permission notice shall be included in | |
15 | +// all copies or substantial portions of the Software. | |
16 | +// | |
17 | +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
22 | +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
23 | +// DEALINGS IN THE SOFTWARE. | |
24 | + | |
25 | +#include "pf_types.h" | |
26 | +#include "pf_gpio.h" | |
27 | +#include "pf_patrol.h" | |
28 | + | |
29 | +//! @brief ラインセンサ→GPIO IDテーブル | |
30 | +static const PF_GPIO_ID pf_patrol_to_gpio[PF_PATROL_ID_MAX] = | |
31 | +{ | |
32 | + PF_GPIO_ID_MAQUEEN_PATROL_L, //!< PF_PATROL_ID_L | |
33 | + PF_GPIO_ID_MAQUEEN_PATROL_R, //!< PF_PATROL_ID_R | |
34 | +}; | |
35 | + | |
36 | +//! @brief ラインセンサ情報 | |
37 | +static PF_PATROL_COLOR pf_patrol_info[PF_PATROL_ID_MAX]; | |
38 | + | |
39 | +//! @brief ラインセンサ初期化(単一のID) | |
40 | +//! @param [in] id ラインセンサのID | |
41 | +static void pf_patrol_init_id(PF_PATROL_ID id) | |
42 | +{ | |
43 | + // 現在データをWHITEに初期化 | |
44 | + pf_patrol_info[id] = PF_PATROL_COLOR_WHITE; | |
45 | +} | |
46 | + | |
47 | +//! @brief ラインセンサ初期化 | |
48 | +//! @remarks プラットフォーム初期化処理から呼び出すこと | |
49 | +void pf_patrol_init(void) | |
50 | +{ | |
51 | + PF_PATROL_ID id; | |
52 | + | |
53 | + // オート変数初期化 | |
54 | + id = 0; | |
55 | + | |
56 | + // すべてのIDをループ | |
57 | + for (id = 0; id < PF_PATROL_ID_MAX; id++) | |
58 | + { | |
59 | + // 1つのIDを初期化 | |
60 | + pf_patrol_init_id(id); | |
61 | + } | |
62 | +} | |
63 | + | |
64 | +//! @brief ラインセンサ定期タスク(単一のID) | |
65 | +//! @param [in] id ラインセンサのID | |
66 | +static void pf_patrol_task_id(PF_PATROL_ID id) | |
67 | +{ | |
68 | + PF_GPIO_ID gpio; | |
69 | + | |
70 | + // オート変数初期化 | |
71 | + gpio = pf_patrol_to_gpio[id]; | |
72 | + | |
73 | + // 現在のフォトリフレクタ情報を取得(GPIOからの入力が'L'で白色) | |
74 | + if (FALSE == pf_gpio_input(gpio)) | |
75 | + { | |
76 | + // 白色 | |
77 | + pf_patrol_info[id] = PF_PATROL_COLOR_WHITE; | |
78 | + } | |
79 | + else | |
80 | + { | |
81 | + // 黒色 | |
82 | + pf_patrol_info[id] = PF_PATROL_COLOR_BLACK; | |
83 | + } | |
84 | +} | |
85 | + | |
86 | +//! @brief ラインセンサ定期タスク | |
87 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
88 | +void pf_patrol_task(void) | |
89 | +{ | |
90 | + PF_PATROL_ID id; | |
91 | + | |
92 | + // オート変数初期化 | |
93 | + id = 0; | |
94 | + | |
95 | + // すべてのIDをループ | |
96 | + for (id = 0; id < PF_PATROL_ID_MAX; id++) | |
97 | + { | |
98 | + // 1つのIDを処理 | |
99 | + pf_patrol_task_id(id); | |
100 | + } | |
101 | +} | |
102 | + | |
103 | +//! @brief ラインセンサの白黒状態を取得 | |
104 | +//! @param [in] id ラインセンサのID | |
105 | +//! @return 色状態(PF_PATROL_COLOR_WHITE=白色/PF_PATROL_COLOR_BLACK=黒色) | |
106 | +PF_PATROL_COLOR pf_patrol_get(PF_PATROL_ID id) | |
107 | +{ | |
108 | + PF_PATROL_COLOR result; | |
109 | + | |
110 | + // オート変数初期化 | |
111 | + result = PF_PATROL_COLOR_WHITE; | |
112 | + | |
113 | + // パラメータチェック | |
114 | + if (id < PF_PATROL_ID_MAX) | |
115 | + { | |
116 | + result = pf_patrol_info[id]; | |
117 | + } | |
118 | + | |
119 | + return result; | |
120 | +} |
@@ -30,6 +30,9 @@ | ||
30 | 30 | #include "pf_systick.h" |
31 | 31 | #include "pf_power.h" |
32 | 32 | |
33 | +//! @brief VDD電圧低下警告有無フラグ | |
34 | +static BOOL pf_power_warning = FALSE; | |
35 | + | |
33 | 36 | //! @brief インタフェースMCU初期化待ちのためのデモ(アニメーション) |
34 | 37 | //! @details NRF_POWER->RESETREAS==0の場合に限り呼び出される。所要時間1000msで設計している |
35 | 38 | static void pf_power_greetings(void) |
@@ -50,11 +53,10 @@ static void pf_power_greetings(void) | ||
50 | 53 | pf_display_id(PF_DISPLAY_ID_HAPPY); |
51 | 54 | |
52 | 55 | // 460msループ(輝度を上げる) |
53 | - while ((u4)(freerun - base) | |
54 | - <= ((PF_DISPLAY_BRIGHTNESS_MAX - PF_DISPLAY_BRIGHTNESS_MIN) * 5)) | |
56 | + while ((u4)(freerun - base) <= ((PF_DISPLAY_BRIGHTNESS_MAX - PF_DISPLAY_BRIGHTNESS_MIN) * 5)) | |
55 | 57 | { |
56 | 58 | // 目標輝度を算出 |
57 | - target = (u4) (freerun - base); | |
59 | + target = (u4)(freerun - base); | |
58 | 60 | target /= 5; |
59 | 61 | target += PF_DISPLAY_BRIGHTNESS_MIN; |
60 | 62 |
@@ -83,11 +85,10 @@ static void pf_power_greetings(void) | ||
83 | 85 | base += 80; |
84 | 86 | |
85 | 87 | // 460msループ(輝度を下げる) |
86 | - while ((u4) (freerun - base) | |
87 | - <= ((PF_DISPLAY_BRIGHTNESS_MAX - PF_DISPLAY_BRIGHTNESS_MIN) * 5)) | |
88 | + while ((u4)(freerun - base) <= ((PF_DISPLAY_BRIGHTNESS_MAX - PF_DISPLAY_BRIGHTNESS_MIN) * 5)) | |
88 | 89 | { |
89 | 90 | // 目標輝度を算出 |
90 | - target = (u4) (freerun - base); | |
91 | + target = (u4)(freerun - base); | |
91 | 92 | target /= 5; |
92 | 93 | target = PF_DISPLAY_BRIGHTNESS_MAX - target; |
93 | 94 |
@@ -111,22 +112,14 @@ static void pf_power_greetings(void) | ||
111 | 112 | //! @attention Display初期化の後で呼び出すこと |
112 | 113 | void pf_power_init(void) |
113 | 114 | { |
114 | - // 割り込み設定(1) | |
115 | - NVIC_SetPriority(POWER_CLOCK_IRQn, PF_INTERRUPT_PRI_POWER); | |
116 | - NVIC_ClearPendingIRQ(POWER_CLOCK_IRQn); | |
117 | - | |
118 | - // 割り込み有効化(VDD電圧降下警告) | |
119 | - NRF_POWER->INTENSET = POWER_INTENSET_POFWARN_Set | |
120 | - << POWER_INTENSET_POFWARN_Pos; | |
115 | + // VDD電圧低下警告なし | |
116 | + pf_power_warning = FALSE; | |
121 | 117 | |
122 | - // 電源電圧低下警告(VDD、VDDHとも2.8Vで警告) | |
118 | + // VDD電圧低下警告(VDD、VDDHとも2.8Vで警告) | |
123 | 119 | NRF_POWER->POFCON = (POWER_POFCON_POF_Enabled << POWER_POFCON_POF_Pos) |
124 | 120 | | (POWER_POFCON_THRESHOLD_V28 << POWER_POFCON_THRESHOLD_Pos) |
125 | 121 | | (POWER_POFCON_THRESHOLDVDDH_V28 << POWER_POFCON_THRESHOLDVDDH_Pos); |
126 | 122 | |
127 | - // 割り込み設定(2) | |
128 | - NVIC_EnableIRQ(POWER_CLOCK_IRQn); | |
129 | - | |
130 | 123 | // パワーオンリセットの場合、インタフェースMCUの起動待ちのためのデモを行う |
131 | 124 | if (0 == NRF_POWER->RESETREAS) |
132 | 125 | { |
@@ -134,18 +127,22 @@ void pf_power_init(void) | ||
134 | 127 | } |
135 | 128 | } |
136 | 129 | |
137 | -//! @brief Power割り込みハンドラ | |
138 | -//! @attention 割り込み発生以降、Displayの動作が×固定になる | |
139 | -void POWER_CLOCK_IRQHandler(void) | |
130 | +//! @brief Power定期タスク | |
131 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
132 | +void pf_power_task(void) | |
140 | 133 | { |
141 | - // イベントクリア(VDD電圧降下警告) | |
142 | - NRF_POWER->EVENTS_POFWARN = POWER_EVENTS_POFWARN_EVENTS_POFWARN_NotGenerated | |
143 | - << POWER_EVENTS_POFWARN_EVENTS_POFWARN_Pos; | |
144 | - | |
145 | - // 割り込み無効化(VDD電圧降下警告) | |
146 | - NRF_POWER->INTENCLR = POWER_INTENCLR_POFWARN_Clear | |
147 | - << POWER_INTENCLR_POFWARN_Pos; | |
134 | + // VDD電圧低下警告なしの場合 | |
135 | + if (FALSE == pf_power_warning) | |
136 | + { | |
137 | + // POFWARN | |
138 | + if (POWER_EVENTS_POFWARN_EVENTS_POFWARN_Generated << POWER_EVENTS_POFWARN_EVENTS_POFWARN_Pos | |
139 | + == NRF_POWER->EVENTS_POFWARN) | |
140 | + { | |
141 | + // VDD電圧低下警告あり | |
142 | + pf_power_warning = TRUE; | |
148 | 143 | |
149 | - // ディスプレイ表示 | |
150 | - pf_display_powerdown(); | |
144 | + // ディスプレイ表示 | |
145 | + pf_display_powerdown(); | |
146 | + } | |
147 | + } | |
151 | 148 | } |
@@ -28,7 +28,8 @@ | ||
28 | 28 | #include "pf_systick.h" |
29 | 29 | |
30 | 30 | //! @brief フリーランカウンタ[ms] |
31 | -static volatile u4 pf_systick_freerun_ms; | |
31 | +//! @remarks 通常コンテキストで変化を監視するためvolatile修飾を付与する | |
32 | +static volatile u4 pf_systick_freerun_ms; | |
32 | 33 | |
33 | 34 | //! @brief 制御周期カウンタ[ms] |
34 | 35 | static u4 pf_systick_sync_ms; |
@@ -41,7 +42,7 @@ void pf_systick_init(void) | ||
41 | 42 | SysTick->CTRL = 0; |
42 | 43 | |
43 | 44 | // 割り込み優先度を設定 |
44 | - NVIC_SetPriority(SysTick_IRQn, (u4)PF_INTERRUPT_PRI_SYSTICK); | |
45 | + NVIC_SetPriority(SysTick_IRQn, PF_INTERRUPT_PRI_SYSTICK); | |
45 | 46 | |
46 | 47 | // フリーランタイマをリセット |
47 | 48 | pf_systick_freerun_ms = 0; |
@@ -58,8 +59,7 @@ void pf_systick_init(void) | ||
58 | 59 | // ・SysClockタイマ動作 |
59 | 60 | // ・割り込みモードを指定 |
60 | 61 | // ・クロックソースとしてプロセッサクロックを指定 |
61 | - SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk | |
62 | - | SysTick_CTRL_CLKSOURCE_Msk; | |
62 | + SysTick->CTRL = SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk; | |
63 | 63 | |
64 | 64 | // 制御周期カウンタをクリア |
65 | 65 | pf_systick_sync_ms = 0; |
@@ -76,7 +76,7 @@ void pf_systick_sync(void) | ||
76 | 76 | quit = FALSE; |
77 | 77 | freerun = 0; |
78 | 78 | |
79 | - // ループ | |
79 | + // 時間が経過するまでループ | |
80 | 80 | while (FALSE == quit) |
81 | 81 | { |
82 | 82 | // フリーランmsカウンタを取得 |
@@ -127,9 +127,9 @@ void pf_systick_time(PF_SYSTICK_TIME *timebuf) | ||
127 | 127 | |
128 | 128 | // while文が必ず成立するよう条件設定 |
129 | 129 | freerun[1] = freerun[0] + 1; |
130 | - val[0] = val[1] + 1; | |
130 | + val[1] = val[0]; | |
131 | 131 | |
132 | - // 2回読み出してmsが一致するまで続ける | |
132 | + // 2回読み出して、msが一致かつVALの順序が正しくなるまで続ける | |
133 | 133 | while ((freerun[0] != freerun[1]) || (val[0] > val[1])) |
134 | 134 | { |
135 | 135 | // 移動 |
@@ -28,6 +28,12 @@ | ||
28 | 28 | #include "pf_interrupt.h" |
29 | 29 | #include "pf_timer.h" |
30 | 30 | |
31 | +//! @brief Timerチャネル数 | |
32 | +#define PF_TIMER_CHANNEL_MAX ((u4)5U) | |
33 | + | |
34 | +//! @brief コンペア最大数(チャネル0~チャネル4で共通) | |
35 | +#define PF_TIMER_COMPARE_MAX ((u4)4U) | |
36 | + | |
31 | 37 | //! @brief Timer動作 |
32 | 38 | typedef enum PF_TIMER_ACTION_Tag |
33 | 39 | { |
@@ -66,96 +72,46 @@ const PF_TIMER_INIT pf_timer_table[PF_TIMER_ID_MAX] = | ||
66 | 72 | }, |
67 | 73 | }; |
68 | 74 | |
69 | -//! @brief Timer動作情報構造体 | |
70 | -typedef struct PF_TIMER_OPERATION_Tag | |
75 | +//! @brief compares→CLEARビットテーブル | |
76 | +static const u4 pf_timer_clear_table[PF_TIMER_COMPARE_MAX + 1] = | |
71 | 77 | { |
72 | - PF_TIMER_CALLBACK callback; //!< コールバック関数 | |
73 | - u4 cc[4]; //!< コンペア値 | |
74 | - BOOL running; //!< 動作中フラグ | |
75 | -} PF_TIMER_OPERATION; | |
76 | - | |
77 | -//! @brief Timer動作情報テーブル | |
78 | -static PF_TIMER_OPERATION pf_timer_status[PF_TIMER_ID_MAX]; | |
78 | + 0, | |
79 | + TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos, | |
80 | + TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos, | |
81 | + TIMER_SHORTS_COMPARE2_CLEAR_Enabled << TIMER_SHORTS_COMPARE2_CLEAR_Pos, | |
82 | + TIMER_SHORTS_COMPARE3_CLEAR_Enabled << TIMER_SHORTS_COMPARE3_CLEAR_Pos, | |
83 | +}; | |
79 | 84 | |
80 | -//! @brief SHORTSレジスタへの設定値を得る(COMPARE-CLEAR) | |
81 | -//! @param [in] id TimerのID | |
82 | -//! @return SHORTSレジスタへの設定値 | |
83 | -static u4 pf_timer_get_shorts_clear(PF_TIMER_ID id) | |
85 | +//! @brief compares→STOPビットテーブル | |
86 | +static const u4 pf_timer_stop_table[PF_TIMER_COMPARE_MAX + 1] = | |
84 | 87 | { |
85 | - u4 shorts; | |
86 | - | |
87 | - // オート変数初期化 | |
88 | - shorts = 0; | |
89 | - | |
90 | - // コンペア数(1~4)によって分ける | |
91 | - switch (pf_timer_table[id].compares) | |
92 | - { | |
93 | - case 1: | |
94 | - shorts = TIMER_SHORTS_COMPARE0_CLEAR_Enabled | |
95 | - << TIMER_SHORTS_COMPARE0_CLEAR_Pos; | |
96 | - break; | |
97 | - | |
98 | - case 2: | |
99 | - shorts = TIMER_SHORTS_COMPARE1_CLEAR_Enabled | |
100 | - << TIMER_SHORTS_COMPARE1_CLEAR_Pos; | |
101 | - break; | |
102 | - | |
103 | - case 3: | |
104 | - shorts = TIMER_SHORTS_COMPARE2_CLEAR_Enabled | |
105 | - << TIMER_SHORTS_COMPARE2_CLEAR_Pos; | |
106 | - break; | |
107 | - | |
108 | - case 4: | |
109 | - shorts = TIMER_SHORTS_COMPARE3_CLEAR_Enabled | |
110 | - << TIMER_SHORTS_COMPARE3_CLEAR_Pos; | |
111 | - break; | |
112 | - | |
113 | - default: | |
114 | - break; | |
115 | - } | |
116 | - | |
117 | - return shorts; | |
118 | -} | |
88 | + 0, | |
89 | + TIMER_SHORTS_COMPARE0_STOP_Enabled << TIMER_SHORTS_COMPARE0_STOP_Pos, | |
90 | + TIMER_SHORTS_COMPARE1_STOP_Enabled << TIMER_SHORTS_COMPARE1_STOP_Pos, | |
91 | + TIMER_SHORTS_COMPARE2_STOP_Enabled << TIMER_SHORTS_COMPARE2_STOP_Pos, | |
92 | + TIMER_SHORTS_COMPARE3_STOP_Enabled << TIMER_SHORTS_COMPARE3_STOP_Pos, | |
93 | +}; | |
119 | 94 | |
120 | -//! @brief SHORTSレジスタへの設定値を得る(COMPARE-STOP) | |
121 | -//! @param [in] id TimerのID | |
122 | -//! @return SHORTSレジスタへの設定値 | |
123 | -static u4 pf_timer_get_shorts_stop(PF_TIMER_ID id) | |
95 | +//! @brief Timer→割り込み番号テーブル | |
96 | +static const IRQn_Type pf_timer_to_irq[PF_TIMER_CHANNEL_MAX] = | |
124 | 97 | { |
125 | - u4 shorts; | |
126 | - | |
127 | - // オート変数初期化 | |
128 | - shorts = 0; | |
98 | + TIMER0_IRQn, //!< Timer0 | |
99 | + TIMER1_IRQn, //!< Timer1 | |
100 | + TIMER2_IRQn, //!< Timer2 | |
101 | + TIMER3_IRQn, //!< Timer3 | |
102 | + TIMER4_IRQn, //!< Timer4 | |
103 | +}; | |
129 | 104 | |
130 | - // コンペア数(1~4)によって分ける | |
131 | - switch (pf_timer_table[id].compares) | |
132 | - { | |
133 | - case 1: | |
134 | - shorts = TIMER_SHORTS_COMPARE0_STOP_Enabled | |
135 | - << TIMER_SHORTS_COMPARE0_STOP_Pos; | |
136 | - break; | |
137 | - | |
138 | - case 2: | |
139 | - shorts = TIMER_SHORTS_COMPARE1_STOP_Enabled | |
140 | - << TIMER_SHORTS_COMPARE1_STOP_Pos; | |
141 | - break; | |
142 | - | |
143 | - case 3: | |
144 | - shorts = TIMER_SHORTS_COMPARE2_STOP_Enabled | |
145 | - << TIMER_SHORTS_COMPARE2_STOP_Pos; | |
146 | - break; | |
147 | - | |
148 | - case 4: | |
149 | - shorts = TIMER_SHORTS_COMPARE3_STOP_Enabled | |
150 | - << TIMER_SHORTS_COMPARE3_STOP_Pos; | |
151 | - break; | |
152 | - | |
153 | - default: | |
154 | - break; | |
155 | - } | |
105 | +//! @brief Timer動作情報構造体 | |
106 | +typedef struct PF_TIMER_STATUS_Tag | |
107 | +{ | |
108 | + PF_TIMER_CALLBACK callback; //!< コールバック関数 | |
109 | + u4 cc[4]; //!< コンペア値 | |
110 | + BOOL running; //!< 動作中フラグ | |
111 | +} PF_TIMER_STATUS; | |
156 | 112 | |
157 | - return shorts; | |
158 | -} | |
113 | +//! @brief Timer動作情報テーブル | |
114 | +static PF_TIMER_STATUS pf_timer_status[PF_TIMER_ID_MAX]; | |
159 | 115 | |
160 | 116 | //! @brief INTENSETレジスタへの設定値を得る |
161 | 117 | //! @param [in] id TimerのID |
@@ -194,51 +150,6 @@ static u4 pf_timer_get_intenset(PF_TIMER_ID id) | ||
194 | 150 | return intenset; |
195 | 151 | } |
196 | 152 | |
197 | -//! @brief 割り込み番号を得る | |
198 | -//! @param [in] id TimerのID | |
199 | -//! @return 割り込み番号 | |
200 | -static IRQn_Type pf_timer_get_irq(PF_TIMER_ID id) | |
201 | -{ | |
202 | - IRQn_Type irq; | |
203 | - | |
204 | - // オート変数初期化 | |
205 | - irq = TIMER0_IRQn; | |
206 | - | |
207 | - switch (pf_timer_table[id].channel) | |
208 | - { | |
209 | - // TIMER0 | |
210 | - case 0: | |
211 | - irq = TIMER0_IRQn; | |
212 | - break; | |
213 | - | |
214 | - // TIMER1 | |
215 | - case 1: | |
216 | - irq = TIMER1_IRQn; | |
217 | - break; | |
218 | - | |
219 | - // TIMER2 | |
220 | - case 2: | |
221 | - irq = TIMER2_IRQn; | |
222 | - break; | |
223 | - | |
224 | - // TIMER3 | |
225 | - case 3: | |
226 | - irq = TIMER3_IRQn; | |
227 | - break; | |
228 | - | |
229 | - // TIMER4 | |
230 | - case 4: | |
231 | - irq = TIMER4_IRQn; | |
232 | - break; | |
233 | - | |
234 | - // 設定エラー | |
235 | - default: | |
236 | - break; | |
237 | - } | |
238 | - | |
239 | - return irq; | |
240 | -} | |
241 | - | |
242 | 153 | //! @brief Timer初期化(単一のID) |
243 | 154 | //! @param [in] id TimerのID |
244 | 155 | static void pf_timer_init_id(PF_TIMER_ID id) |
@@ -250,18 +161,18 @@ static void pf_timer_init_id(PF_TIMER_ID id) | ||
250 | 161 | |
251 | 162 | // タイマ停止 |
252 | 163 | pf_timer_table[id].dev->TASKS_STOP = TIMER_TASKS_STOP_TASKS_STOP_Trigger |
253 | - << TIMER_TASKS_STOP_TASKS_STOP_Pos; | |
164 | + << TIMER_TASKS_STOP_TASKS_STOP_Pos; | |
254 | 165 | |
255 | 166 | // イベントのショートカット |
256 | 167 | if (PF_TIMER_ACTION_INTERVAL == pf_timer_table[id].action) |
257 | 168 | { |
258 | 169 | // COMPARE[i]に達したらCLEAR |
259 | - pf_timer_table[id].dev->SHORTS = pf_timer_get_shorts_clear(id); | |
170 | + pf_timer_table[id].dev->SHORTS = pf_timer_clear_table[pf_timer_table[id].compares]; | |
260 | 171 | } |
261 | 172 | else |
262 | 173 | { |
263 | 174 | // COMPARE[i]に達したらSTOP |
264 | - pf_timer_table[id].dev->SHORTS = pf_timer_get_shorts_stop(id); | |
175 | + pf_timer_table[id].dev->SHORTS = pf_timer_stop_table[pf_timer_table[id].compares]; | |
265 | 176 | } |
266 | 177 | |
267 | 178 | // 割り込み有効 |
@@ -271,11 +182,10 @@ static void pf_timer_init_id(PF_TIMER_ID id) | ||
271 | 182 | pf_timer_table[id].dev->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; |
272 | 183 | |
273 | 184 | // BITMODE(32bit幅固定) |
274 | - pf_timer_table[id].dev->BITMODE = TIMER_BITMODE_BITMODE_32Bit | |
275 | - << TIMER_BITMODE_BITMODE_Pos; | |
185 | + pf_timer_table[id].dev->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos; | |
276 | 186 | |
277 | 187 | // PRESCALER(1/16固定)クロックソースはPCLK1MHzとなり1[us]ごとにカウントアップする |
278 | - pf_timer_table[id].dev->PRESCALER = 0x00000004U; | |
188 | + pf_timer_table[id].dev->PRESCALER = 4U; | |
279 | 189 | |
280 | 190 | // CC[0]設定 |
281 | 191 | if (pf_timer_table[id].compares >= 1) |
@@ -310,7 +220,7 @@ static void pf_timer_init_id(PF_TIMER_ID id) | ||
310 | 220 | pf_timer_status[id].running = FALSE; |
311 | 221 | |
312 | 222 | // 割り込み設定 |
313 | - irq = pf_timer_get_irq(id); | |
223 | + irq = pf_timer_to_irq[id]; | |
314 | 224 | NVIC_SetPriority(irq, pf_timer_table[id].priority); |
315 | 225 | NVIC_ClearPendingIRQ(irq); |
316 | 226 | NVIC_EnableIRQ(irq); |
@@ -320,16 +230,16 @@ static void pf_timer_init_id(PF_TIMER_ID id) | ||
320 | 230 | //! @remarks プラットフォーム初期化処理から呼び出すこと |
321 | 231 | void pf_timer_init(void) |
322 | 232 | { |
323 | - u4 id; | |
233 | + PF_TIMER_ID id; | |
324 | 234 | |
325 | 235 | // オート変数初期化 |
326 | 236 | id = 0; |
327 | 237 | |
328 | 238 | // すべてのIDをループ |
329 | - for (id = 0; id < (u4)PF_TIMER_ID_MAX; id++) | |
239 | + for (id = 0; id < PF_TIMER_ID_MAX; id++) | |
330 | 240 | { |
331 | 241 | // 1つのIDを初期化 |
332 | - pf_timer_init_id((PF_TIMER_ID)id); | |
242 | + pf_timer_init_id(id); | |
333 | 243 | } |
334 | 244 | } |
335 | 245 |
@@ -342,15 +252,13 @@ void pf_timer_start(PF_TIMER_ID id) | ||
342 | 252 | { |
343 | 253 | // 開始に先立って、クリア |
344 | 254 | pf_timer_table[id].dev->TASKS_CLEAR = |
345 | - TIMER_TASKS_CLEAR_TASKS_CLEAR_Trigger | |
346 | - << TIMER_TASKS_CLEAR_TASKS_CLEAR_Pos; | |
255 | + TIMER_TASKS_CLEAR_TASKS_CLEAR_Trigger << TIMER_TASKS_CLEAR_TASKS_CLEAR_Pos; | |
347 | 256 | |
348 | 257 | // 開始 |
349 | 258 | pf_timer_table[id].dev->TASKS_START = |
350 | - TIMER_TASKS_START_TASKS_START_Trigger | |
351 | - << TIMER_TASKS_START_TASKS_START_Pos; | |
259 | + TIMER_TASKS_START_TASKS_START_Trigger << TIMER_TASKS_START_TASKS_START_Pos; | |
352 | 260 | |
353 | - // 動作中フラグセット | |
261 | + // 動作中フラグセット(割り込み干渉を考慮する必要はない) | |
354 | 262 | pf_timer_status[id].running = TRUE; |
355 | 263 | } |
356 | 264 | } |
@@ -364,9 +272,9 @@ void pf_timer_stop(PF_TIMER_ID id) | ||
364 | 272 | { |
365 | 273 | // 停止 |
366 | 274 | pf_timer_table[id].dev->TASKS_STOP = TIMER_TASKS_STOP_TASKS_STOP_Trigger |
367 | - << TIMER_TASKS_STOP_TASKS_STOP_Pos; | |
275 | + << TIMER_TASKS_STOP_TASKS_STOP_Pos; | |
368 | 276 | |
369 | - // 動作中フラグクリア | |
277 | + // 動作中フラグクリア(割り込み干渉を考慮する必要はない) | |
370 | 278 | pf_timer_status[id].running = FALSE; |
371 | 279 | } |
372 | 280 | } |
@@ -388,7 +296,7 @@ void pf_timer_callback(PF_TIMER_ID id, PF_TIMER_CALLBACK func) | ||
388 | 296 | if (id < PF_TIMER_ID_MAX) |
389 | 297 | { |
390 | 298 | // IDに対応したIRQを取得 |
391 | - irq = pf_timer_get_irq(id); | |
299 | + irq = pf_timer_to_irq[id]; | |
392 | 300 | |
393 | 301 | // 割り込み禁止 |
394 | 302 | enable = NVIC_GetEnableIRQ(irq); |
@@ -421,7 +329,7 @@ void pf_timer_cc(PF_TIMER_ID id, u4 *cc) | ||
421 | 329 | if ((id < PF_TIMER_ID_MAX) && (NULL != cc)) |
422 | 330 | { |
423 | 331 | // IDに対応したIRQを取得 |
424 | - irq = pf_timer_get_irq(id); | |
332 | + irq = pf_timer_to_irq[id]; | |
425 | 333 | |
426 | 334 | // 割り込み禁止 |
427 | 335 | enable = NVIC_GetEnableIRQ(irq); |
@@ -434,8 +342,7 @@ void pf_timer_cc(PF_TIMER_ID id, u4 *cc) | ||
434 | 342 | if (pf_timer_status[id].cc[loop] != cc[loop]) |
435 | 343 | { |
436 | 344 | pf_timer_status[id].cc[loop] = cc[loop]; |
437 | - pf_timer_table[id].dev->CC[loop] = | |
438 | - pf_timer_status[id].cc[loop]; | |
345 | + pf_timer_table[id].dev->CC[loop] = pf_timer_status[id].cc[loop]; | |
439 | 346 | } |
440 | 347 | } |
441 | 348 |
@@ -452,34 +359,31 @@ void pf_timer_cc(PF_TIMER_ID id, u4 *cc) | ||
452 | 359 | static void pf_timer_isr(u4 channel) |
453 | 360 | { |
454 | 361 | PF_TIMER_ID id; |
455 | - u4 loop; | |
456 | 362 | u4 compare; |
457 | 363 | u4 mask; |
458 | 364 | u4 generated; |
459 | 365 | u4 clear; |
460 | 366 | |
461 | 367 | // オート変数初期化 |
462 | - id = PF_TIMER_ID_MAX; | |
463 | - loop = 0; | |
368 | + id = 0; | |
464 | 369 | compare = 0; |
465 | 370 | mask = TIMER_EVENTS_COMPARE_EVENTS_COMPARE_Msk; |
466 | 371 | generated = TIMER_EVENTS_COMPARE_EVENTS_COMPARE_Generated |
467 | - << TIMER_EVENTS_COMPARE_EVENTS_COMPARE_Pos; | |
372 | + << TIMER_EVENTS_COMPARE_EVENTS_COMPARE_Pos; | |
468 | 373 | clear = TIMER_EVENTS_COMPARE_EVENTS_COMPARE_NotGenerated |
469 | - << TIMER_EVENTS_COMPARE_EVENTS_COMPARE_Pos; | |
374 | + << TIMER_EVENTS_COMPARE_EVENTS_COMPARE_Pos; | |
470 | 375 | |
471 | 376 | // チャネル番号からIDを特定する |
472 | - for (loop = 0; loop < (u4)PF_TIMER_ID_MAX; loop++) | |
377 | + for (id = 0; id < PF_TIMER_ID_MAX; id++) | |
473 | 378 | { |
474 | 379 | if (channel == pf_timer_table[id].channel) |
475 | 380 | { |
476 | - id = (PF_TIMER_ID)loop; | |
477 | 381 | break; |
478 | 382 | } |
479 | 383 | } |
480 | 384 | |
481 | 385 | // IDが見つかった場合のみ処理 |
482 | - if (id != PF_TIMER_ID_MAX) | |
386 | + if (id < PF_TIMER_ID_MAX) | |
483 | 387 | { |
484 | 388 | // EVENTS_COMPARE[3]レジスタからコンペア情報を作成 |
485 | 389 | compare <<= 1; |
@@ -39,36 +39,24 @@ | ||
39 | 39 | //! @brief 受信除外文字(この文字は受信できない) |
40 | 40 | #define PF_UART_EMPTY_CODE ((u1)0xFFU) |
41 | 41 | |
42 | -//! @brief UARTエラー情報構造体 | |
43 | -typedef struct PF_UART_ERROR_Tag | |
44 | -{ | |
45 | - u4 overrun_count; //!< オーバーランエラー発生回数 | |
46 | - u4 parity_count; //!< パリティエラー発生回数 | |
47 | - u4 framing_count; //!< フレーミングエラー発生回数 | |
48 | - u4 brk_count; //!< ブレーク条件発生回数 | |
49 | -} PF_UART_ERROR; | |
50 | - | |
51 | -//! @brief UARTエラー情報本体 | |
52 | -static PF_UART_ERROR pf_uart_error; | |
53 | - | |
54 | 42 | //! @brief UARTバッファ管理構造体 |
55 | 43 | typedef struct PF_UART_BUF_Tag |
56 | 44 | { |
57 | - u4 read_pos; //!< 読み取り位置 | |
58 | - u4 write_pos; //!< 書き込み位置 | |
59 | - u4 valid_bytes; //!< 有効バイト数 | |
60 | - u4 overrun_count; //!< オーバーラン発生回数 | |
61 | - u4 uart_process_count; //!< UART動作カウント | |
62 | - u4 uart_read_bytes; //!< 現在のUARTバッファから読み出したバイト数 | |
63 | - u1 buf[PF_UART_BUF_BYTES]; //!< リングバッファ | |
45 | + u4 read_pos; //!< 読み取り位置 | |
46 | + u4 write_pos; //!< 書き込み位置 | |
47 | + u4 valid_bytes; //!< 有効バイト数 | |
48 | + u4 overrun_count; //!< オーバーラン発生回数 | |
49 | + u4 uart_process_count; //!< UART動作カウント | |
50 | + u4 uart_read_bytes; //!< 現在のUARTバッファから読み出したバイト数 | |
51 | + u1 buf[PF_UART_BUF_BYTES]; //!< リングバッファ | |
64 | 52 | } PF_UART_BUF; |
65 | 53 | |
66 | 54 | //! @brief UARTバッファのID |
67 | 55 | typedef enum PF_UART_BUF_ID_Tag |
68 | 56 | { |
69 | - PF_UART_BUF_ID_TXD = 0, //!< 送信バッファ | |
70 | - PF_UART_BUF_ID_RXD, //!< 受信バッファ | |
71 | - PF_UART_BUF_ID_MAX, //!< (IDの個数を表す) | |
57 | + PF_UART_BUF_ID_TXD = 0, //!< 送信バッファ | |
58 | + PF_UART_BUF_ID_RXD, //!< 受信バッファ | |
59 | + PF_UART_BUF_ID_MAX, //!< (IDの個数を表す) | |
72 | 60 | } PF_UART_BUF_ID; |
73 | 61 | |
74 | 62 | //! @brief UARTバッファ本体 |
@@ -77,6 +65,9 @@ static PF_UART_BUF pf_uart_buf[PF_UART_BUF_ID_MAX]; | ||
77 | 65 | //! @brief DMAバッファ本体 |
78 | 66 | static u1 pf_uart_dma[PF_UART_BUF_BYTES]; |
79 | 67 | |
68 | +//! @brief UARTエラー情報本体 | |
69 | +static PF_UART_ERROR pf_uart_rxderr; | |
70 | + | |
80 | 71 | //! @brief UARTバッファ初期化 |
81 | 72 | //! @param [in] id UARTバッファのID |
82 | 73 | static void pf_uart_init_buf(PF_UART_BUF_ID id) |
@@ -104,6 +95,15 @@ static void pf_uart_init_dma(void) | ||
104 | 95 | } |
105 | 96 | } |
106 | 97 | |
98 | +//! @brief UARTエラー情報初期化 | |
99 | +static void pf_uart_init_error(void) | |
100 | +{ | |
101 | + pf_uart_rxderr.overrun = 0; | |
102 | + pf_uart_rxderr.parity = 0; | |
103 | + pf_uart_rxderr.framing = 0; | |
104 | + pf_uart_rxderr.brk = 0; | |
105 | +} | |
106 | + | |
107 | 107 | //! @brief UART送信ポーリング |
108 | 108 | //! @attention 通常コンテキストと、割り込みコンテキストの双方から呼び出される |
109 | 109 | static void pf_uart_poll_txd(void) |
@@ -121,7 +121,7 @@ static void pf_uart_poll_txd(void) | ||
121 | 121 | { |
122 | 122 | // バッファをまたぐか? |
123 | 123 | txd_bytes = sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf) |
124 | - - pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos; | |
124 | + - pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos; | |
125 | 125 | if (pf_uart_buf[PF_UART_BUF_ID_TXD].valid_bytes < txd_bytes) |
126 | 126 | { |
127 | 127 | // バッファをまたがない(valid_bytesの方が小さい) |
@@ -130,19 +130,18 @@ static void pf_uart_poll_txd(void) | ||
130 | 130 | |
131 | 131 | // 送信指示 |
132 | 132 | NRF_UARTE0->TXD.PTR = |
133 | - (u4)&(pf_uart_buf[PF_UART_BUF_ID_TXD].buf[pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos]); | |
133 | + (u4)&(pf_uart_buf[PF_UART_BUF_ID_TXD].buf[pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos]); | |
134 | 134 | NRF_UARTE0->TXD.MAXCNT = txd_bytes; |
135 | 135 | NRF_UARTE0->TASKS_STARTTX = |
136 | - UARTE_TASKS_STARTTX_TASKS_STARTTX_Trigger | |
137 | - << UARTE_TASKS_STARTTX_TASKS_STARTTX_Pos; | |
136 | + UARTE_TASKS_STARTTX_TASKS_STARTTX_Trigger << UARTE_TASKS_STARTTX_TASKS_STARTTX_Pos; | |
138 | 137 | |
139 | 138 | // 1回のUART送信を予約した |
140 | 139 | pf_uart_buf[PF_UART_BUF_ID_TXD].uart_process_count++; |
141 | 140 | |
142 | 141 | // read_posを進める |
143 | 142 | pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos += txd_bytes; |
144 | - pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos &= | |
145 | - (sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf) - 1); | |
143 | + pf_uart_buf[PF_UART_BUF_ID_TXD].read_pos &= (sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf) | |
144 | + - 1); | |
146 | 145 | |
147 | 146 | // valid_bytesを減らす |
148 | 147 | pf_uart_buf[PF_UART_BUF_ID_TXD].valid_bytes -= txd_bytes; |
@@ -154,21 +153,20 @@ static void pf_uart_poll_txd(void) | ||
154 | 153 | //! @attention 通常コンテキストと、割り込みコンテキストの双方から呼び出される |
155 | 154 | static void pf_uart_poll_rxd(void) |
156 | 155 | { |
157 | - while (PF_UART_EMPTY_CODE | |
158 | - != pf_uart_dma[pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes]) | |
156 | + while (PF_UART_EMPTY_CODE != pf_uart_dma[pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes]) | |
159 | 157 | { |
160 | 158 | // 現在の読み取り位置をバッファに挿入する |
161 | 159 | if (pf_uart_buf[PF_UART_BUF_ID_RXD].valid_bytes |
162 | - <= sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf)) | |
160 | + <= sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf)) | |
163 | 161 | { |
164 | 162 | // データ転送 |
165 | 163 | pf_uart_buf[PF_UART_BUF_ID_RXD].buf[pf_uart_buf[PF_UART_BUF_ID_RXD].write_pos] = |
166 | - pf_uart_dma[pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes]; | |
164 | + pf_uart_dma[pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes]; | |
167 | 165 | |
168 | 166 | // write_posを進める |
169 | 167 | pf_uart_buf[PF_UART_BUF_ID_RXD].write_pos++; |
170 | 168 | pf_uart_buf[PF_UART_BUF_ID_RXD].write_pos &= |
171 | - (sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf) - 1); | |
169 | + (sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf) - 1); | |
172 | 170 | |
173 | 171 | // valid_bytesをインクリメント |
174 | 172 | pf_uart_buf[PF_UART_BUF_ID_RXD].valid_bytes++; |
@@ -181,12 +179,12 @@ static void pf_uart_poll_rxd(void) | ||
181 | 179 | |
182 | 180 | // このDMAバッファを受信除外文字に復元する |
183 | 181 | pf_uart_dma[pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes] = |
184 | - PF_UART_EMPTY_CODE; | |
182 | + PF_UART_EMPTY_CODE; | |
185 | 183 | |
186 | 184 | // UARTバッファから読み出したバイト数を進める |
187 | 185 | pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes++; |
188 | 186 | pf_uart_buf[PF_UART_BUF_ID_RXD].uart_read_bytes &= |
189 | - (sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf) - 1); | |
187 | + (sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf) - 1); | |
190 | 188 | } |
191 | 189 | } |
192 | 190 |
@@ -197,22 +195,22 @@ void pf_uart_init(void) | ||
197 | 195 | { |
198 | 196 | // UART無効化 |
199 | 197 | NRF_UARTE0->ENABLE = |
200 | - UARTE_ENABLE_ENABLE_Disabled << UARTE_ENABLE_ENABLE_Pos; | |
198 | + UARTE_ENABLE_ENABLE_Disabled << UARTE_ENABLE_ENABLE_Pos; | |
201 | 199 | |
202 | 200 | // バッファ初期化 |
203 | 201 | pf_uart_init_buf(PF_UART_BUF_ID_TXD); |
204 | 202 | pf_uart_init_buf(PF_UART_BUF_ID_RXD); |
205 | 203 | pf_uart_init_dma(); |
204 | + pf_uart_init_error(); | |
206 | 205 | |
207 | 206 | // イベントのショートカット(ENDRXと同時にSTARTRXを行う) |
208 | - NRF_UARTE0->SHORTS = UARTE_SHORTS_ENDRX_STARTRX_Enabled | |
209 | - << UARTE_SHORTS_ENDRX_STARTRX_Pos; | |
207 | + NRF_UARTE0->SHORTS = UARTE_SHORTS_ENDRX_STARTRX_Enabled << UARTE_SHORTS_ENDRX_STARTRX_Pos; | |
210 | 208 | |
211 | 209 | // 割り込み有効化 |
212 | 210 | NRF_UARTE0->INTEN = (UARTE_INTEN_ENDRX_Enabled << UARTE_INTEN_ENDRX_Pos) |
213 | - | (UARTE_INTEN_ENDTX_Enabled << UARTE_INTEN_ENDTX_Pos) | |
214 | - | (UARTE_INTEN_ERROR_Enabled << UARTE_INTEN_ERROR_Pos) | |
215 | - | (UARTE_INTEN_RXSTARTED_Enabled << UARTE_INTEN_RXSTARTED_Pos); | |
211 | + | (UARTE_INTEN_ENDTX_Enabled << UARTE_INTEN_ENDTX_Pos) | |
212 | + | (UARTE_INTEN_ERROR_Enabled << UARTE_INTEN_ERROR_Pos) | |
213 | + | (UARTE_INTEN_RXSTARTED_Enabled << UARTE_INTEN_RXSTARTED_Pos); | |
216 | 214 | |
217 | 215 | // 割り込み設定 |
218 | 216 | NVIC_SetPriority(UARTE0_UART0_IRQn, PF_INTERRUPT_PRI_UART); |
@@ -220,40 +218,35 @@ void pf_uart_init(void) | ||
220 | 218 | NVIC_EnableIRQ(UARTE0_UART0_IRQn); |
221 | 219 | |
222 | 220 | // 受信エラーをすべてクリア |
223 | - NRF_UARTE0->ERRORSRC = (UARTE_ERRORSRC_OVERRUN_NotPresent | |
224 | - << UARTE_ERRORSRC_OVERRUN_Pos) | |
225 | - | (UARTE_ERRORSRC_PARITY_NotPresent << UARTE_ERRORSRC_PARITY_Pos) | |
226 | - | (UARTE_ERRORSRC_FRAMING_NotPresent << UARTE_ERRORSRC_FRAMING_Pos) | |
227 | - | (UARTE_ERRORSRC_BREAK_NotPresent << UARTE_ERRORSRC_BREAK_Pos); | |
221 | + NRF_UARTE0->ERRORSRC = (UARTE_ERRORSRC_OVERRUN_NotPresent << UARTE_ERRORSRC_OVERRUN_Pos) | |
222 | + | (UARTE_ERRORSRC_PARITY_NotPresent << UARTE_ERRORSRC_PARITY_Pos) | |
223 | + | (UARTE_ERRORSRC_FRAMING_NotPresent << UARTE_ERRORSRC_FRAMING_Pos) | |
224 | + | (UARTE_ERRORSRC_BREAK_NotPresent << UARTE_ERRORSRC_BREAK_Pos); | |
228 | 225 | |
229 | 226 | // RTSピン設定(使用しない) |
230 | - NRF_UARTE0->PSEL.RTS |= (UARTE_PSEL_RTS_CONNECT_Disconnected | |
231 | - << UARTE_PSEL_RTS_CONNECT_Pos); | |
227 | + NRF_UARTE0->PSEL.RTS |= (UARTE_PSEL_RTS_CONNECT_Disconnected << UARTE_PSEL_RTS_CONNECT_Pos); | |
232 | 228 | |
233 | 229 | // TXDピン設定(pf_gpioで管理しているポート番号・ピン番号に接続する) |
234 | - NRF_UARTE0->PSEL.TXD = (pf_gpio_get_pin(PF_GPIO_ID_UART_TXD) | |
235 | - << UARTE_PSEL_TXD_PIN_Pos) | |
236 | - | (pf_gpio_get_port(PF_GPIO_ID_UART_TXD) << UARTE_PSEL_TXD_PORT_Pos) | |
237 | - | (UARTE_PSEL_TXD_CONNECT_Connected << UARTE_PSEL_TXD_CONNECT_Pos); | |
230 | + NRF_UARTE0->PSEL.TXD = (pf_gpio_get_pin(PF_GPIO_ID_UART_TXD) << UARTE_PSEL_TXD_PIN_Pos) | |
231 | + | (pf_gpio_get_port(PF_GPIO_ID_UART_TXD) << UARTE_PSEL_TXD_PORT_Pos) | |
232 | + | (UARTE_PSEL_TXD_CONNECT_Connected << UARTE_PSEL_TXD_CONNECT_Pos); | |
238 | 233 | |
239 | 234 | // CTSピン設定(使用しない) |
240 | - NRF_UARTE0->PSEL.CTS |= (UARTE_PSEL_CTS_CONNECT_Disconnected | |
241 | - << UARTE_PSEL_CTS_CONNECT_Pos); | |
235 | + NRF_UARTE0->PSEL.CTS |= (UARTE_PSEL_CTS_CONNECT_Disconnected << UARTE_PSEL_CTS_CONNECT_Pos); | |
242 | 236 | |
243 | 237 | // RXDピン設定(pf_gpioで管理しているポート番号・ピン番号に接続する) |
244 | - NRF_UARTE0->PSEL.RXD = (pf_gpio_get_pin(PF_GPIO_ID_UART_RXD) | |
245 | - << UARTE_PSEL_RXD_PIN_Pos) | |
246 | - | (pf_gpio_get_port(PF_GPIO_ID_UART_RXD) << UARTE_PSEL_RXD_PORT_Pos) | |
247 | - | (UARTE_PSEL_RXD_CONNECT_Connected << UARTE_PSEL_RXD_CONNECT_Pos); | |
238 | + NRF_UARTE0->PSEL.RXD = (pf_gpio_get_pin(PF_GPIO_ID_UART_RXD) << UARTE_PSEL_RXD_PIN_Pos) | |
239 | + | (pf_gpio_get_port(PF_GPIO_ID_UART_RXD) << UARTE_PSEL_RXD_PORT_Pos) | |
240 | + | (UARTE_PSEL_RXD_CONNECT_Connected << UARTE_PSEL_RXD_CONNECT_Pos); | |
248 | 241 | |
249 | 242 | // ボーレート115200bps(実際のボーレートは115108bps、誤差-0.08%) |
250 | - NRF_UARTE0->BAUDRATE = UARTE_BAUDRATE_BAUDRATE_Baud115200; | |
243 | + NRF_UARTE0->BAUDRATE = UARTE_BAUDRATE_BAUDRATE_Baud115200 << UARTE_BAUDRATE_BAUDRATE_Pos; | |
251 | 244 | |
252 | 245 | // ハードウェアフロー無し、パリティ無し、ストップビット1bit |
253 | 246 | NRF_UARTE0->CONFIG = (UARTE_CONFIG_HWFC_Disabled << UARTE_CONFIG_HWFC_Pos) |
254 | - | (UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos) | |
255 | - | (UARTE_CONFIG_STOP_One << UARTE_CONFIG_STOP_Pos) | |
256 | - | (UARTE_CONFIG_PARITYTYPE_Even << UARTE_CONFIG_PARITYTYPE_Pos); | |
247 | + | (UARTE_CONFIG_PARITY_Excluded << UARTE_CONFIG_PARITY_Pos) | |
248 | + | (UARTE_CONFIG_STOP_One << UARTE_CONFIG_STOP_Pos) | |
249 | + | (UARTE_CONFIG_PARITYTYPE_Even << UARTE_CONFIG_PARITYTYPE_Pos); | |
257 | 250 | |
258 | 251 | // UART有効化 |
259 | 252 | NRF_UARTE0->ENABLE = UARTE_ENABLE_ENABLE_Enabled << UARTE_ENABLE_ENABLE_Pos; |
@@ -262,14 +255,14 @@ void pf_uart_init(void) | ||
262 | 255 | NRF_UARTE0->RXD.PTR = (u4)pf_uart_dma; |
263 | 256 | NRF_UARTE0->RXD.MAXCNT = sizeof(pf_uart_dma); |
264 | 257 | NRF_UARTE0->TASKS_STARTRX = UART_TASKS_STARTRX_TASKS_STARTRX_Trigger |
265 | - << UART_TASKS_STARTRX_TASKS_STARTRX_Pos; | |
258 | + << UART_TASKS_STARTRX_TASKS_STARTRX_Pos; | |
266 | 259 | |
267 | 260 | // 1回のUART受信を予約した |
268 | 261 | pf_uart_buf[PF_UART_BUF_ID_RXD].uart_process_count++; |
269 | 262 | } |
270 | 263 | |
271 | 264 | //! @brief UART定期タスク |
272 | -//! @remarks 定期タスク(出力系)処理から呼び出すこと | |
265 | +//! @remarks プラットフォーム定期タスク(入力系)処理から呼び出すこと | |
273 | 266 | void pf_uart_task(void) |
274 | 267 | { |
275 | 268 | u4 enable; |
@@ -309,16 +302,17 @@ void pf_uart_send(const u1 *buf, u4 bytes) | ||
309 | 302 | { |
310 | 303 | // 送信バッファが一杯? |
311 | 304 | if (pf_uart_buf[PF_UART_BUF_ID_TXD].valid_bytes |
312 | - < sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf)) | |
305 | + < sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf)) | |
313 | 306 | { |
314 | 307 | // 送信バッファへ1バイト挿入 |
315 | - pf_uart_buf[PF_UART_BUF_ID_TXD].buf[pf_uart_buf[PF_UART_BUF_ID_TXD].write_pos] = *buf; | |
308 | + pf_uart_buf[PF_UART_BUF_ID_TXD].buf[pf_uart_buf[PF_UART_BUF_ID_TXD].write_pos] = | |
309 | + *buf; | |
316 | 310 | buf++; |
317 | 311 | |
318 | 312 | // write_posを進める |
319 | 313 | pf_uart_buf[PF_UART_BUF_ID_TXD].write_pos++; |
320 | 314 | pf_uart_buf[PF_UART_BUF_ID_TXD].write_pos &= |
321 | - (sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf) - 1); | |
315 | + (sizeof(pf_uart_buf[PF_UART_BUF_ID_TXD].buf) - 1); | |
322 | 316 | |
323 | 317 | // valid_bytesをインクリメント |
324 | 318 | pf_uart_buf[PF_UART_BUF_ID_TXD].valid_bytes++; |
@@ -360,8 +354,7 @@ u4 pf_uart_recv(u1 *buf, u4 bytes) | ||
360 | 354 | enable = pf_interrupt_local_disable(PF_INTERRUPT_PRI_UART); |
361 | 355 | |
362 | 356 | // 全てのバイト数を処理し終わるまで |
363 | - while ((recv < bytes) | |
364 | - && (pf_uart_buf[PF_UART_BUF_ID_RXD].valid_bytes > 0)) | |
357 | + while ((recv < bytes) && (pf_uart_buf[PF_UART_BUF_ID_RXD].valid_bytes > 0)) | |
365 | 358 | { |
366 | 359 | // 受信バッファへ1バイト転送 |
367 | 360 | *buf = pf_uart_buf[PF_UART_BUF_ID_RXD].buf[pf_uart_buf[PF_UART_BUF_ID_RXD].read_pos]; |
@@ -369,8 +362,8 @@ u4 pf_uart_recv(u1 *buf, u4 bytes) | ||
369 | 362 | |
370 | 363 | // read_posを進める |
371 | 364 | pf_uart_buf[PF_UART_BUF_ID_RXD].read_pos++; |
372 | - pf_uart_buf[PF_UART_BUF_ID_RXD].read_pos &= | |
373 | - (sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf) - 1); | |
365 | + pf_uart_buf[PF_UART_BUF_ID_RXD].read_pos &= (sizeof(pf_uart_buf[PF_UART_BUF_ID_RXD].buf) | |
366 | + - 1); | |
374 | 367 | |
375 | 368 | // valid_bytesをデクリメント |
376 | 369 | pf_uart_buf[PF_UART_BUF_ID_RXD].valid_bytes--; |
@@ -386,6 +379,39 @@ u4 pf_uart_recv(u1 *buf, u4 bytes) | ||
386 | 379 | return recv; |
387 | 380 | } |
388 | 381 | |
382 | +//! @brief UARTエラー情報取得 | |
383 | +//! @param [out] error エラー情報構造体へのポインタ | |
384 | +//! @remarks プラットフォーム内部のエラー情報はクリアされる | |
385 | +void pf_uart_error(PF_UART_ERROR *error) | |
386 | +{ | |
387 | + u4 enable; | |
388 | + | |
389 | + // オート変数初期化 | |
390 | + enable = 0; | |
391 | + | |
392 | + // パラメータチェック | |
393 | + if (NULL != error) | |
394 | + { | |
395 | + // UART割り込み禁止 | |
396 | + enable = pf_interrupt_local_disable(PF_INTERRUPT_PRI_UART); | |
397 | + | |
398 | + // エラー情報を転送 | |
399 | + error->overrun = pf_uart_rxderr.overrun; | |
400 | + error->parity = pf_uart_rxderr.parity; | |
401 | + error->framing = pf_uart_rxderr.framing; | |
402 | + error->brk = pf_uart_rxderr.brk; | |
403 | + | |
404 | + // プラットフォーム内部のエラー情報をクリア | |
405 | + pf_uart_rxderr.overrun = 0; | |
406 | + pf_uart_rxderr.parity = 0; | |
407 | + pf_uart_rxderr.framing = 0; | |
408 | + pf_uart_rxderr.brk = 0; | |
409 | + | |
410 | + // UART割り込み復元 | |
411 | + pf_interrupt_local_restore(PF_INTERRUPT_PRI_UART, enable); | |
412 | + } | |
413 | +} | |
414 | + | |
389 | 415 | //! @brief UART1文字出力 |
390 | 416 | //! @param [in] ch 送信する文字(0xFF以外) |
391 | 417 | void pf_uart_putc(u1 ch) |
@@ -455,11 +481,10 @@ void pf_uart_log(const char *format, ...) | ||
455 | 481 | pf_systick_time(&timebuf); |
456 | 482 | |
457 | 483 | // SysTick時刻をフォーマット |
458 | - pf_uart_log_time(buf, "%05d,%03d,%03d,", timebuf.sec, timebuf.ms, | |
459 | - timebuf.us); | |
484 | + pf_uart_log_time(buf, "%05d,%03d,%03d,", timebuf.sec, timebuf.ms, timebuf.us); | |
460 | 485 | |
461 | 486 | // 本体のフォーマット |
462 | - bytes = (u4) vsnprintf(&buf[14], sizeof(buf) - 16, format, ap); | |
487 | + bytes = (u4)vsnprintf(&buf[14], sizeof(buf) - 16, format, ap); | |
463 | 488 | bytes += 14; |
464 | 489 | |
465 | 490 | // 末尾に改行文字があるか? |
@@ -484,7 +509,7 @@ void pf_uart_log(const char *format, ...) | ||
484 | 509 | |
485 | 510 | //! @brief UART割り込みハンドラ(ENDTX) |
486 | 511 | //! @attention データ競合(割り込み干渉)に注意する |
487 | -static void pf_uart_intr_endtx(void) | |
512 | +static void pf_uart_isr_endtx(void) | |
488 | 513 | { |
489 | 514 | // 1回のUART送信が完了した |
490 | 515 | pf_uart_buf[PF_UART_BUF_ID_TXD].uart_process_count--; |
@@ -496,13 +521,13 @@ static void pf_uart_intr_endtx(void) | ||
496 | 521 | if (0 == pf_uart_buf[PF_UART_BUF_ID_TXD].uart_process_count) |
497 | 522 | { |
498 | 523 | NRF_UARTE0->TASKS_STOPTX = UART_TASKS_STOPTX_TASKS_STOPTX_Trigger |
499 | - << UART_TASKS_STOPTX_TASKS_STOPTX_Pos; | |
524 | + << UART_TASKS_STOPTX_TASKS_STOPTX_Pos; | |
500 | 525 | } |
501 | 526 | } |
502 | 527 | |
503 | 528 | //! @brief UART割り込みハンドラ(ERROR) |
504 | 529 | //! @attention データ競合(割り込み干渉)に注意する |
505 | -static void pf_uart_intr_error(void) | |
530 | +static void pf_uart_isr_error(void) | |
506 | 531 | { |
507 | 532 | u4 overrun; |
508 | 533 | u4 parity; |
@@ -519,34 +544,34 @@ static void pf_uart_intr_error(void) | ||
519 | 544 | if (overrun == (NRF_UARTE0->ERRORSRC & overrun)) |
520 | 545 | { |
521 | 546 | NRF_UARTE0->ERRORSRC &= (u4)(~UART_ERRORSRC_OVERRUN_Msk); |
522 | - pf_uart_error.overrun_count++; | |
547 | + pf_uart_rxderr.overrun++; | |
523 | 548 | } |
524 | 549 | |
525 | 550 | // パリティエラー |
526 | 551 | if (parity == (NRF_UARTE0->ERRORSRC & parity)) |
527 | 552 | { |
528 | 553 | NRF_UARTE0->ERRORSRC &= (u4)(~UART_ERRORSRC_PARITY_Msk); |
529 | - pf_uart_error.parity_count++; | |
554 | + pf_uart_rxderr.parity++; | |
530 | 555 | } |
531 | 556 | |
532 | 557 | // フレーミングエラー |
533 | 558 | if (framing == (NRF_UARTE0->ERRORSRC & framing)) |
534 | 559 | { |
535 | 560 | NRF_UARTE0->ERRORSRC &= (u4)(~UART_ERRORSRC_FRAMING_Msk); |
536 | - pf_uart_error.framing_count++; | |
561 | + pf_uart_rxderr.framing++; | |
537 | 562 | } |
538 | 563 | |
539 | 564 | // ブレーク信号受信 |
540 | 565 | if (brk == (NRF_UARTE0->ERRORSRC & brk)) |
541 | 566 | { |
542 | 567 | NRF_UARTE0->ERRORSRC &= (u4)(~UART_ERRORSRC_BREAK_Msk); |
543 | - pf_uart_error.brk_count++; | |
568 | + pf_uart_rxderr.brk++; | |
544 | 569 | } |
545 | 570 | } |
546 | 571 | |
547 | 572 | //! @brief UART割り込みハンドラ(RXSTARTED) |
548 | 573 | //! @attention データ競合(割り込み干渉)に注意する |
549 | -static void pf_uart_intr_rxstarted(void) | |
574 | +static void pf_uart_isr_rxstarted(void) | |
550 | 575 | { |
551 | 576 | // 受信バッファを再セットできるか? |
552 | 577 | if (pf_uart_buf[PF_UART_BUF_ID_RXD].uart_process_count < 2) |
@@ -561,10 +586,10 @@ static void pf_uart_intr_rxstarted(void) | ||
561 | 586 | |
562 | 587 | //! @brief UART割り込みハンドラ(ENDRX) |
563 | 588 | //! @attention データ競合(割り込み干渉)に注意する |
564 | -static void pf_uart_intr_endrx(void) | |
589 | +static void pf_uart_isr_endrx(void) | |
565 | 590 | { |
566 | 591 | // 受信バッファの再セット |
567 | - pf_uart_intr_rxstarted(); | |
592 | + pf_uart_isr_rxstarted(); | |
568 | 593 | |
569 | 594 | // 1回のUART受信が終了した |
570 | 595 | pf_uart_buf[PF_UART_BUF_ID_RXD].uart_process_count--; |
@@ -578,40 +603,39 @@ static void pf_uart_intr_endrx(void) | ||
578 | 603 | void UARTE0_UART0_IRQHandler(void) |
579 | 604 | { |
580 | 605 | // ENDRX |
581 | - if ((UARTE_EVENTS_ENDRX_EVENTS_ENDRX_Generated | |
582 | - << UARTE_EVENTS_ENDRX_EVENTS_ENDRX_Pos) == NRF_UARTE0->EVENTS_ENDRX) | |
606 | + if ((UARTE_EVENTS_ENDRX_EVENTS_ENDRX_Generated << UARTE_EVENTS_ENDRX_EVENTS_ENDRX_Pos) | |
607 | + == NRF_UARTE0->EVENTS_ENDRX) | |
583 | 608 | { |
584 | 609 | NRF_UARTE0->EVENTS_ENDRX = UARTE_EVENTS_ENDRX_EVENTS_ENDRX_NotGenerated |
585 | - << UARTE_EVENTS_ENDRX_EVENTS_ENDRX_Pos; | |
586 | - pf_uart_intr_endrx(); | |
610 | + << UARTE_EVENTS_ENDRX_EVENTS_ENDRX_Pos; | |
611 | + pf_uart_isr_endrx(); | |
587 | 612 | } |
588 | 613 | |
589 | 614 | // ENDTX |
590 | - if ((UARTE_EVENTS_ENDTX_EVENTS_ENDTX_Generated | |
591 | - << UARTE_EVENTS_ENDTX_EVENTS_ENDTX_Pos) == NRF_UARTE0->EVENTS_ENDTX) | |
615 | + if ((UARTE_EVENTS_ENDTX_EVENTS_ENDTX_Generated << UARTE_EVENTS_ENDTX_EVENTS_ENDTX_Pos) | |
616 | + == NRF_UARTE0->EVENTS_ENDTX) | |
592 | 617 | { |
593 | 618 | NRF_UARTE0->EVENTS_ENDTX = UARTE_EVENTS_ENDTX_EVENTS_ENDTX_NotGenerated |
594 | - << UARTE_EVENTS_ENDTX_EVENTS_ENDTX_Pos; | |
595 | - pf_uart_intr_endtx(); | |
619 | + << UARTE_EVENTS_ENDTX_EVENTS_ENDTX_Pos; | |
620 | + pf_uart_isr_endtx(); | |
596 | 621 | } |
597 | 622 | |
598 | 623 | // ERROR |
599 | - if ((UARTE_EVENTS_ERROR_EVENTS_ERROR_Generated | |
600 | - << UARTE_EVENTS_ERROR_EVENTS_ERROR_Pos) == NRF_UARTE0->EVENTS_ERROR) | |
624 | + if ((UARTE_EVENTS_ERROR_EVENTS_ERROR_Generated << UARTE_EVENTS_ERROR_EVENTS_ERROR_Pos) | |
625 | + == NRF_UARTE0->EVENTS_ERROR) | |
601 | 626 | { |
602 | 627 | NRF_UARTE0->EVENTS_ERROR = UARTE_EVENTS_ERROR_EVENTS_ERROR_NotGenerated |
603 | - << UARTE_EVENTS_ERROR_EVENTS_ERROR_Pos; | |
604 | - pf_uart_intr_error(); | |
628 | + << UARTE_EVENTS_ERROR_EVENTS_ERROR_Pos; | |
629 | + pf_uart_isr_error(); | |
605 | 630 | } |
606 | 631 | |
607 | 632 | // RXSTATRED |
608 | 633 | if ((UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_Generated |
609 | - << UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_Pos) | |
610 | - == NRF_UARTE0->EVENTS_RXSTARTED) | |
634 | + << UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_Pos) == NRF_UARTE0->EVENTS_RXSTARTED) | |
611 | 635 | { |
612 | 636 | NRF_UARTE0->EVENTS_RXSTARTED = |
613 | 637 | UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_NotGenerated |
614 | - << UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_Pos; | |
615 | - pf_uart_intr_rxstarted(); | |
638 | + << UARTE_EVENTS_RXSTARTED_EVENTS_RXSTARTED_Pos; | |
639 | + pf_uart_isr_rxstarted(); | |
616 | 640 | } |
617 | 641 | } |