Timer (PWM)関連のAHI関数と解説
Timer (PWM)
AHI の Timer 関連の API の一部について、ソースコード互換を取る目的で実装しています。
- この実装は完全な互換性を保つことを目的とはしていません。
- 本書記述時点で判明している留意点などを記載します。
- 内部の実装は予告なく変更される場合があります。
- 解説中のパラメータについても、留意が必要な部分のみ記述しています。省略部分は、原典の AHI ライブラリマニュアルを参照ください。
AHI APIについて
vAHI_TimerFineGrainDIOControl()
void vAHI_TimerFineGrainDIOControl(uint8 u8BitMask)
出力ピンを無効化するビットマスクを指定します。TIMER_0 … TIMER_4 に対応するビットのみ有効です。
vAHI_TimerEnable()
実行前に本関数を呼び出します。vAHI_TimerEnable()
のパラメータで出力を有効化していても、ピンを無効化設定されている場合は、出力無効化として取り扱います。
vAHI_TimerAssignPIOPin_MW()
void vAHI_TimerAssignPIOPin_MW(
uint8 u8_timer_id,
uint8 u8_pin_id)
TWELITE GOLD専用です。
指定したタイマーデバイス(u8_timer_id
)で使用するピンをPIO番号で指定します。
PIO番号には特定のPWMチャネルが紐づいています。またPWMが使用できないPIO番号もあります。指定方法によっては、重複したPWMチャネルを利用するといった矛盾した設定になる場合があります。PIO番号とPWMチャネルの割り当てについては、ピン配置表などを参照してください。
u8_timer_id
は、対象のタイマーデバイス (E_AHI_DEVICE_TIMER0-4
)を指定します。vAHI_TimerFineGrainDIOControl()
の設定も有効ですが、出力の有無はvAHI_TImerEnable()
のbOutputEnable
で出力の制御を行います。- 出力を行わずタイマー割り込みのみを利用する場合でも、利用するPWMチャネルに対応したピン番号を指定します。
本ライブラリの独自関数です。
vAHI_TimerEnable()
void vAHI_TimerEnable(
uint8 u8_timer_id,
uint8 u8Prescale,
bool_t bIntRiseEnable,
bool_t bIntPeriodEnable,
bool_t bOutputEnable)
タイマーを有効化します。
bIntRiseEnable==TRUE
の場合はbIntPeriodEnable==TRUE
として取り扱います。bOutputEnable==TRUE
の設定が行われてもvAHI_TimerFineGrainDIOControl()
でピンが無効化されている場合はFALSE
として取り扱います。- すでに有効化したタイマーIDに対して、再度本関数を呼び出した場合の動作は不定です。
ハードウェア資源に矛盾がある場合
TWELITE BLUE/RED とのハードウェアの差異から、すべてのタイマーデバイスを同じように利用できるわけではありません。詳しくは後述のピン割当を参照してください。
- PWM出力が有効になっている場合は、ソフトウェアでのPWM出力エミュレーションを行います。
- PWM出力が無効になっている場合は、目的がタイマー割り込みと限定されるため、空いているPWM3またはPWM5をピン出力無しで利用します。
- 上記割当を行ったかどうかを調べるAPIや手続きは用意していません。
vAHI_TimerDisable()
void vAHI_TimerDisable(uint8 u8_timer_id)
タイマーを無効化します。
- 出力ポートは入力(プルアップは設定変更しない)に戻します。
vAHI_TimerConfigure()
void vAHI_TimerConfigure(
uint8 u8_timer_id,
bool_t bInvertPwmOutput,
bool_t bGateDisable)
タイマーの設定を変更します。
bInvertPwmOutput
の設定を行います。bGateDisable
は無視されます。
vAHI_TimerStartRepeat()
void vAHI_TimerStartRepeat(
uint8 u8_timer_id,
uint16 u16Hi,
uint16 u16Lo)
タイマーを開始します。
- この関数はタイマー動作中にも呼び出すことができ、PWMのDUTY設定を変更する目的で使用できます。
vAHI_TimerStop()
void vAHI_TimerStop(uint8 u8_timer_id)
タイマーを停止します。
vAHI_TimerSetLocation()
void vAHI_TimerSetLocation(
uint8 u8Timer,
bool_t bLocation,
bool_t bLocationOverridePWM3andPWM2)
ピンの割当変更を行います。
vAHI_TimerEnable()
実行前に本関数を呼び出します。
vAHI_TimerXRegisterCallback
PUBLIC void vAHI_Timer0RegisterCallback(
PR_HWINT_APPCALLBACK prTimer0Callback);
PUBLIC void vAHI_Timer1RegisterCallback(
PR_HWINT_APPCALLBACK prTimer1Callback);
PUBLIC void vAHI_Timer2RegisterCallback(
PR_HWINT_APPCALLBACK prTimer2Callback);
PUBLIC void vAHI_Timer3RegisterCallback(
PR_HWINT_APPCALLBACK prTimer3Callback);
PUBLIC void vAHI_Timer4RegisterCallback(
PR_HWINT_APPCALLBACK prTimer4Callback);
割り込みハンドラの登録関数は実装されていません。AppQAPIにより割り込みハンドラが呼び出されます。
独自に割り込みハンドラの定義を行う場合は、以下のWEAK
定義のハンドラ関数を実装します。実装についてはAHIcmpt_TImers.cpp
の実装を参考にしてください。少なくともPWM_ClearStatusFlags(PWM, kPWM_PwmX);
を呼び出しておく必要があります。
WEAK void PWM0_DriverIRQHandler(void); // MONO WIRELESS, DEFINED AS WEAK FUNCTION.
WEAK void PWM1_DriverIRQHandler(void);
WEAK void PWM2_DriverIRQHandler(void);
WEAK void PWM3_DriverIRQHandler(void);
WEAK void PWM4_DriverIRQHandler(void);
WEAK void PWM5_DriverIRQHandler(void);
WEAK void PWM6_DriverIRQHandler(void);
WEAK void PWM7_DriverIRQHandler(void);
WEAK void PWM8_DriverIRQHandler(void);
WEAK void PWM9_DriverIRQHandler(void);
上記以外の関数
void vAHI_TimerClockSelect(
uint8 u8Timer,
bool_t bExternalClock,
bool_t bInvertClock);
void vAHI_TimerStartSingleShot(
uint8 u8Timer,
uint16 u16Hi,
uint16 u16Lo);
関数定義なし、または、何もしないダミー関数です。
出力ピンについて
- 出力ピンは
vAHI_TimerEnabled()
呼び出し時に PWM 用途として初期化されます。 - 出力ピンは
vAHI_TimerDisable()
呼び出し時に、入力ポート (プルアップ設定は設定を変えない) として最初期化します。
割り込みについて
周期途中の出力変化点での割り込みには対応しません。周期ごとの割り込みのみに対応します。
割り込みハンドラ
割り込みハンドラは、TWENET 標準の cbToCoNet_u8HwInt()
, cbToCoNet_vHwEvent()
のみに対応します。別途ハンドラを登録することはできません。
個別のハンドラを定義したい場合はPWMx_IRQHandler()
関数を別途定義します。この場合、定義されたハンドラから TWENET へのイベント通知は行いません。
ピン割当
ピン割当は TIMER_ID 毎に個別に設定できますが、TWELITE BLACK ではハードウェアの違いから、割当が困難な場合があります。
標準
AHI TIMER ID | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
SMD PIN## | 12 | 16 | 13 | 15 | 19 |
AHI DIO## | 10 | 11 | 12 | 13 | 17 |
PIO## | 4 | 0 | 13 | 1 | 21 |
PWM channel | 4 | 0 | 2 | 1 | 9 |
標準で DO1,2 を利用した場合
AHI TIMER ID | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
SMD PIN## | 12 | 16 | 1 | 2 | 19 |
AHI DIO## | 10 | 11 | DO0 | DO1 | 17 |
PIO## | 4 | 0 | 0 | 5 | 21 |
PWM channel | 4 | 0 | 0 | N/A | 9 |
- TIMER_1, TIMER_2 の割当が衝突します。
- TIMER_3 の出力ピンにはハードウェアタイマーの機能がありません。
副割当
AHI TIMER ID | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
SMD PIN## | 6 | 7 | 8 | 9 | 10 |
AHI DIO## | 4 | 5 | 6 | 7 | 8 |
PIO## | 7 | 6 | 8 | 9 | 14 |
PWM channel | 7 | 6 | 8 | 9 | 1 |
副割当で DO1,2 を利用した場合
AHI TIMER ID | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
SMD PIN## | 6 | 7 | 1 | 9 | 10 |
AHI DIO## | 4 | 5 | DO0 | DO1 | 8 |
PIO## | 7 | 6 | 0 | 5 | 14 |
PWM channel | 7 | 6 | 0 | N/A | 1 |
- TIMER_3 の出力ピンにはハードウェアタイマーの機能がありません。
その他
ピン割り当てに矛盾が出たときの振る舞い
- PWM出力設定をしている場合で矛盾が出たピン(そもそもPWM機能がないものなど)は、ソフトウェアでのエミュレーションになります。
- ソフトウェアでのエミュレーションはシステムタイマー(SysTick)の割り込み処理下で16クロックを1周期として出力を制御します。1Khz で動作する場合は 1000/16 = 約62Hz の PWM 周期です。
- PWM出力設定をしない場合で矛盾が出たピン(PWM デバイス番号の衝突)は、空いている PWM3 または PWM5 を割り当てます。ピン出力なしの場合でもPWM割り込みは動作します。
本ライブラリのPWM機能を利用しない場合
- AHI のタイマー関連の API (
?AHI_Timer???
) を呼び出さないようにしてください。- 当該APIを呼び出すことで、AHI互換のための処理オブジェクトを生成します。この状態で
fsl_pwm.h
に定義されるAPIを呼び出した場合の振る舞いは未定義です。
- 当該APIを呼び出すことで、AHI互換のための処理オブジェクトを生成します。この状態で
PWM0_IRQHandler()
…PWM9_IRQHandler()
を別途定義してください。これらはweak
リンク指定されているので、アプリケーションで定義したweak
指定のないものが優先してリンクされます。
スリープ復帰時の振る舞い
- RAM保持スリープ時は、スリープ直前の PWM 出力状態の状態を復元します。RAM非保持の場合は、通常のDIO初期化を実施します。
関連AHI API
void vAHI_TimerFineGrainDIOControl(
uint8 u8BitMask);
PUBLIC void vAHI_TimerConfigure(
uint8 u8Timer,
bool_t bInvertPwmOutput,
bool_t bGateDisable);
PUBLIC void vAHI_TimerEnable(
uint8 u8Timer,
uint8 u8Prescale,
bool_t bIntRiseEnable,
bool_t bIntPeriodEnable,
bool_t bOutputEnable);
PUBLIC void vAHI_TimerDisable(
uint8 u8Timer);
PUBLIC void vAHI_TimerClockSelect(
uint8 u8Timer,
bool_t bExternalClock,
bool_t bInvertClock);
PUBLIC void vAHI_TimerStartRepeat(
uint8 u8Timer,
uint16 u16Hi,
uint16 u16Lo);
PUBLIC void vAHI_TimerStop(
uint8 u8_timer_id);
PUBLIC void vAHI_TimerSetLocation(
uint8 u8Timer,
bool_t bLocation,
bool_t bLocationOverridePWM3andPWM2);
※ マクロで関数名が再定義されているものもあります。
※ utils.h のタイマーライブラリも上記APIを利用します。
ハンドラー定義例
最小限の手続きを含めた定義です。
void PWM0_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm0); }
void PWM1_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm1); }
void PWM2_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm2); }
void PWM3_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm3); }
void PWM4_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm4); }
void PWM5_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm5); }
void PWM6_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm6); }
void PWM7_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm7); }
void PWM8_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm8); }
void PWM9_IRQHandler(void) { PWM_ClearStatusFlags(PWM, kPWM_Pwm9); }
- この関数定義を行うとTWENETへの割り込み・イベント伝達は行われません。
本ライブラリの実装について
AHIcmpt_Timer.cpp
には主要な実装コードが含まれます。上記コードは
_periph_pwm.hpp
,_periph_pwm.cpp
を引用しています。これらはプラットフォームドライバ(driver/fs_???
)を用いた手続きをまとめたクラスライブラリです。