セクションの複数ページをまとめています。 印刷またはPDF形式で保存...

もとのページに戻る

2025-08-08 現在

TWENETcmpt - AHI互換レイヤー

BLUE / RED シリーズと互換性のある API を提供する GOLD シリーズ向けの互換レイヤー
TWENETライブラリ TWENETcmpt の解説。TWELITE BLUE/RED で利用されていた AHI 関数の一部を TWELITE GOLD で利用できるようにするものです。

TWENETcmpt - AHI互換レイヤー

AHIライブラリの互換性を目的としたライブラリです。

  • TweApps のビルド、動作を目的としており包括的な互換性を達成することは目的としてません。
  • 実装には TWENETmwfライブラリ(fslライブラリにより実装されたC++ライブラリ)を用いています。

以下には、互換レイヤーの諸定義について留意事項を記述しています。

リンク内容
共通・その他諸関数
ADCADC関連のAPI
GPIOGPIO関連のAPI
PWMPWM関連のAPI
I2C (SMBus)I2C関連のAPI
SPISPIバス
Random乱数生成
UARTUART関連のAPI
WDTウォッチドッグタイマー
WTIMERウェイクタイマー、FRWT
OnChipTempチップ内温度センサー(ADC利用)

1 - AHI互換関数

TWENETライブラリ、AHI互換レイヤーの解説
AHI互換関数全般の話題及び特定のペリフェラル等に属さないAHI関数の解説です。

AHI互換関数

AHI 関数群の一部について、ソースコードの互換を目的として実装しています。

以下には AHI 互換関数について記載しています。SPI, I2C などは別ファイルに記載しているものもあります。

一般関数

u32AHI_Init()

uint32 u32AHI_Init();

本来AHIライブラリの初期化を行いますが、本ライブラリでは一部の変数の初期化のみを実施します。

bAHI_SetClockRate(), u8AHI_GetSystemClkRate()

bool_t bAHI_SetClockRate(uint8 u8clk_code);
uint8 u8AHI_GetSystemClkRate();

CPUのクロック速度を設定または設定値の取得を行います。

設定されるクロックは以下のようになります。TWELITE BLUE/REDの設定とは大きく異なるため注意が必要です。

u8clk_codeTWELITE BLUE/REDTWELITE GOLD
04Mhz12Mhz
18Mhz12Mhz
216Mhz32Mhz
332Mhz48Mhz
4..設定有り無視される
  • kFROM1M_to_MAIN_CLKといったクロックも fsl ライブラリ内では設定可能ですが、動作に大きな難があるため設定できないようにしています。
  • デバッガを利用するような場合は、クロック変更に支障が出る場合があります。
  • 規定値は 2、32Mhz (TWELITE GOLD) です。(参考:TWELITE BLUE/REDでは 16MHz)

bAHI_Set32KhzClockMode()

bool_t bAHI_Set32KhzClockMode(uint8 u8mode);

なにもしません。

vAHI_CpuDoze()

static inline void vAHI_CpuDoze() { __WFI(); }

割り込み待ち低電力待機 DOZE 状態に入ります。TWELITE-GOLD では WFI (割り込み待ち) を発効します。

vAHI_SwReset()

static inline void vAHI_SwReset() { NVIC_SystemReset(); }

リセットを行います。

電源関係

u16AHI_PowerStatus()

uint16 u16AHI_PowerStatus();

本関数では、以下のビットマップを報告します。

ビット解説
bit0スリープからの復帰時に 1
bit1RAMが保持されていた場合に 1

POR 時は 0、通常のRAM保持スリープからの復帰は 3 になります。

vAHI_BrownOutConfigure()

static inline void vAHI_BrownOutConfigure(
    uint8       const u8VboSelect,
    bool_t      const bVboRstEn,
    bool_t      const bVboEn,
    bool_t      const bVboIntEnFalling,
    bool_t      const bVboIntEnRising) { ; } // DUMMY FUNC

コンパイルエラー回避のための定義です。この関数は何もしません。

スリープについて

void ToCoNet_vSleep(uint8 u8Device, uint32 u32Periodms, bool_t bPeriodic, bool_t bRamOff)

スリープは TWENET C ライブラリでは ToCoNet_vSleep() 関数を用います。

※ mwxライブラリでは the_twelite.sleep() を用います。

  • bRamOffはTRUEを指定した場合、全てのRAMセグメントを保持しない形でスリープを行います。なお、この場合もJN518x FSL ライブラリ定義のPM_POWER_DOWNを用いPM_DEEP_DOWNは使用しません。

スリープの失敗について(TWELITE GOLD)

TWELITE GOLD では、スリープ遷移の半導体ライブラリ中の手続き(POWER_EnterPowerMode())が稀に失敗し、スリープが行われません。そのため以下の対処を行っています。

  • 半導体ライブラリの手続き失敗時は関数呼び出しからそのまま抜けてしまうが、100usec 相当(DelayLoopN(100))のループ待ちを行った後、再度スリープの手続きを実行します。
  • 上記を3回試行して失敗した場合は ToCoNet_vSleep() は無限ループを呼び出し、通常はウォッチドッグタイマーによるリセットが発生します。当社では、2回または3回の再試行は確認されていませんが、念のため3回までとしています。
  • 上記スリープ手続きが行われた場合、スリープ復帰後 extern uint8 g_twenet_power_down_fails; の値が0以外であれば、上記の再試行が行われていたことを示します。但し、ウォッチドッグタイマーによるリセット時はこの変数は初期化されます。

内部処理用

u32AppApiInit()

uint32
u32AppApiInit(PR_GET_BUFFER prMlmeGetBuffer,
              PR_POST_CALLBACK prMlmeCallback,
              void *pvMlmeParam,
              PR_GET_BUFFER prMcpsGetBuffer,
              PR_POST_CALLBACK prMcpsCallback,
              void *pvMcpsParam);

AppQAPIの初期化処理を行います。

vAHI_RegEvMgr_MW()

void vAHI_RegEvMgr_MW();

TWENETmwfライブラリでのクラスオブジェクトを管理するための管理オブジェクト(mwf::the_sys_ev_manager)を構築します。

vAHI_OnWakeup_MW(), vAHI_OnWakeupRamOff_MW()

void vAHI_OnWakeup_MW(bool_t b_init_2nd);
void vAHI_OnWakeupRamOff_MW(bool_t b_init_2nd);

起床時に実施する手続きです。TWENETmcuのtwenet_main.cの処理を参照してください。

  • TWENETmwf ライブラリ内のクラスオブジェクトの起床時処理mwf::the_sys_ev_manager->on_wakeup()を行います。
  • vAHI_DioOnWakeup_MW()を呼び出します。起床要因のピンを保存します。
  • b_init_2ndがFALSEの場合は始動初期の段階の呼び出しで、TRUEの場合はある程度の初期化が終わった時点(cbAppWarmStart(TRUE)呼び出し前)での呼び出しになります。

vAHI_OnWakeupRamOff_MW()はRAM非保持スリープ復帰時に呼び出されます。

  • b_init_2ndがFALSEの場合は始動初期の段階の呼び出しで、TRUEの場合はある程度の初期化が終わった時点(cbAppWarmStart(TRUE)呼び出し後)での呼び出しになります。

vAHI_OnSleep_MW()

vAHI_OnSleep_MW();

スリープ前に実施する手続きです。

  • TWENETmwf ライブラリ内のクラスオブジェクトのスリープ前処理mwf::the_sys_ev_manager->on_sleep()を行います。
  • vAHI_DioOnSleep_MW()を呼び出します。DIO起床ピンの設定をします。

vAHI_DMAEnable_MW(), vAHI_DMADisable_MW()

void vAHI_DMAEnable_MW();
void vAHI_DMADisable_MW();

DMA機能の有効化と無効化を行います。

vAHI_DMADisable_MW()は何も実行しません。

2 - ADC関連のAHI関数と解説

TWENETライブラリ、ADC関連のAHI関数と解説
TWENETライブラリ、ADC関連のAHI関数と解説です。

ADC

AHI の ADC(アナログディジタル変換) 関連の一部について、ソースコードの互換を目的として実装しています。

概要

ADCのハードウェア仕様はモデルによって違いがあります。

TWELITE BLUETWELITE REDTWELITE GOLD
ビット数10bit10bit12bit
フルスケール2470mV2470mV3600mV
チャネル数
(API未サポート)
44 (2)4 (2)

本ライブラリでは ADC0..3 までの4チャネルと Vcc を利用するための処理を記述しています。ただし、変換時間や変換データの互換性まではライブラリでは実施せず、アプリケーションソースで調整する前提です。

なお6ピンまでの変換や、複数チャネルをまとめた ADC、AHIライブラリでは対応せずmwf::the_adcを直接利用するようにしてください。

関連:オンチップ温度センサー

ピン

PIO備考
ADC015
ADC114DIO8と共用
ADC216
ADC317

AHIcmpt_ADC.cpp

本ライブラリ内では、TWELITE BLUE/RED の AHI ライブラリとの違いについて記述します。APIの仕様については、AHIライブラリマニュアルも参照ください。

vAHI_ApConfigure()

void   vAHI_ApConfigure(
    bool_t      bAPRegulator,
    bool_t      bIntEnable,
    uint8       u8SampleSelect,
    uint8       u8ClockDivRatio,
    bool_t      bRefSelect);

ADCの初期化(mwf::the_adcオブジェクトの構築と the_adc->init() 初期化)を行います。

  • bAPRegulatorをTRUEに指定するとADCを有効化します。FALSEにした場合はADCを無効化します。
  • bIntEnableをTRUEに指定するとADC割り込みが有効になります。
  • u8SampleSelectbRefSelectは無視されます。
  • u8ClockDivRatioも現時点では設定が反映されません。
  • bAHI_APRegulatorEnabled()を用いたアナログ回路の安定化待ち処理は必要です。

bAHI_APRegulatorEnabled()

bool_t bAHI_APRegulatorEnabled(void)

ウェイクタイマを用いたFRWTを動作していない場合は(Cライブラリでは標準)、固定時間の待ち処理を行います(300usec)。この場合vAHI_ApConfigure()呼び出し直後に本関数を呼び出すことを推奨します。相応の時間経過後であっても固定時間の待ち処理を行います。

FRWTを有効化している場合は、タイマカウント値に基づき、必要な待ち処理を行います。相応の時間経過後は、本関数内の待ち処理は行いません。

vAHI_APRegisterCallback()

void   vAHI_APRegisterCallback(PR_HWINT_APPCALLBACK prApCallback);

割り込みハンドラを登録します。ADC完了時に呼び出されます。

vAHI_AdcEnable()

void   void   vAHI_AdcEnable(
    bool_t      bContinuous,
    bool_t      bInputRange,
    uint8       u8Source);

ADCの変換設定を行います。

  • bContinuousを選択すると連続変換しますが、内部的な割り込みが変換都度発生するため、パフォーマンス面で注意が必要です。
  • bInputRangeを指定しても、そういったハードウェア機能がないため反映されません。
  • この呼出時にu8Sourceに対応したピンがADC用として設定されます。
  • vAHI_ApConfigure()実行後にbAHI_APRegulatorEnabled()を未実行で待ち処理が実行されなかった場合は、本呼び出しにて待ち処理を行います。

vAHI_AdcDisable()

void   vAHI_AdcDisable(void);

ADCを停止します。

vAHI_AdcStartSample()

 void   vAHI_AdcStartSample(void);

ADCの変換開始を行います。

  • 原則として初期化時は入力状態ですが、厳密には TWENETmcu ライブラリの pinmux.c BOARD_InitPins() の初期化状態が規定値になります。

bAHI_AdcPoll()

bool_t bAHI_AdcPoll(void);

ADC完了待ちを行うポーリング待ち処理while(bAHI_AdcPoll());に使用します。

  • ADC完了の割り込み後、本呼び出しは1度だけ FALSE を返します。

u16AHI_AdcRead(), i16AHI_AdcRead_mv()

uint16 u16AHI_AdcRead(void);
int16 i16AHI_AdcRead_mv(void); // 非AHI独自関数

実行したADC値を読み出します。

  • u16AHI_AdcRead()は ADC 値を 12bit (0..4095) で返します。エラー時は 0xffff を戻します。
  • i16AHI_AdcRead_mv()は AHI ライブラリにはない独自関数で、ADC値を mV で返します。エラー時は -32768 を戻します。

s_adc_int_handler()

static void s_adc_int_handler(uint32_t a1, uint32_t a2);

AHIcmpt_ADC.cpp で定義された静的関数で、ADC完了時に呼び出される割り込みハンドラとして、TWENETの AppQApi に割り込みを伝達します。

  • vAHI_APRegisterCallback()にてコールバック関数が指定されいている場合は、呼び出されません。

実験的な実装

複数チャネル一括処理

// TWELITE GOLD 専用
//   FSLドライバ機能を用いて複数チャネルのADC取得を一括で行う。

// ADC実行(パラメータはvAHI_AdcEnable()と同様)
void   vAHI_AdcEnableSeq(
    bool_t      bContinuous,
    bool_t      bInputRange,
    uint32      u32MaskSource);
// ADC値の読出し
uint16 u16AHI_AdcReadSeq(
	uint8     u8Source
	);
// ADC値の読出し (mV値にて)
int16 i16AHI_AdcReadSeq_mv(
	uint8     u8Source
	);

sensor_driver, adc.c, adc.h

sensor_driver は既存のTWEAppsアプリケーションなどで利用される処理関数群で、センサー処理の抽象化するためのメカニズムを提供しています。adc.c,.hは、sensor_driverでチップ内ADCを動作させるために、一連のコマンド発行、待ち、データ取得といった順序処理を記述したものです。なお TWENETmwx/sensors/legacy 以下には ADC 以外のいくつかのセンサー向けの実装が含まれます。

TWELITE BLUE/REDのプロジェクトをTWELITE GOLDに移行する場合は、App_Twelite/Common に格納された調整済みのファイルを利用下さい。但し、プロジェクトごとに内容が違う場合があるため、修正等が必要になる場合があります。

ソース名内容
adc.cadc処理部分 (ADC値の変換部分は TWELITE GOLD の値域に合わせている)
adc.h定義部
sensor_driver.cセンサー処理抽象化部分
sensor_driver.h定義部

コード例

以下のコード中のコメントを参照してください。

#include "sensor_driver.h"
#include "adc.h"

tsObjData_ADC sObjADC; // ADC管理構造体(データ部)
tsSnsObj sADC; // ADC管理構造体(制御部)
int16 a1,a2,ab; // 結果格納用

...
	// ADC 初期化
	vSnsObj_Init(&sADC);
	vADC_Init(&sObjADC, &sADC, TRUE);
	vADC_WaitInit(); // ハード初期化待ちを行う

...
	// ADC計測したいポートの指定(以下では電源電圧とADC1,2)
	sObjADC.u8SourceMask = TEH_ADC_SRC_VOLT
    	| TEH_ADC_SRC_ADC_1 | TEH_ADC_SRC_ADC_2;

	// ADC開始
	vSnsObj_Process(&sADC, E_ORDER_KICK); // 開始の号令

// ADCの1チャネル処理が終わるのを待って(=E_AHI_DEVICE_ANALOGUE割り込み)
// vSnsObj_Process() を順次呼び出す。
void cbToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) {
	switch (u32DeviceId) {
	case E_AHI_DEVICE_ANALOGUE:
		// ADC完了割り込み
		vSnsObj_Process(&sADC, E_ORDER_KICK);
		if (bSnsObj_isComplete(&sADC)) {
			// 全チャネルの処理が終わった。
			// 値は以下に格納される
			a1=sObjADC.ai16Result[TEH_ADC_IDX_ADC_1]; // ADC1[mV]
			a2=sObjADC.ai16Result[TEH_ADC_IDX_ADC_2]; // ADC2[mV]
			ab=sObjADC.ai16Result[TEH_ADC_IDX_VOLT]; // 電源電圧[mV]

			// ADC開始前の初期状態に戻す
			vSnsObj_Process(&sADC, E_ORDER_KICK);

			// 連続して実行する場合はもう一度E_ORDER_KICK
			vSnsObj_Process(&sADC, E_ORDER_KICK);
		}
		break;

	default:
		break;
	}
}

関数

vSnsObj_Init()

void vSnsObj_Init(tsSnsObj *pSnsObj)

センサー管理構造体を初期化します。vADC_Init()の直前に呼び出します。

vADC_Init()

void vADC_Init(tsObjData_ADC *pData, tsSnsObj *pSnsObj, bool_t bInitAPR)

ADCの初期化を行います。tsObjData構造体(結果格納用)とtsSnsObj構造体(ADC管理)はあらかじめ用意しておきます。

  • bInitAPRはTRUEの場合、ADCハードウェアの初期化を行います。ハードウェアの初期化には若干の時間が必要ですので、必ずvADC_WaitInit()を実行して初期化を待ちます。

vSnsObj_Process()

void vSnsObj_Process(tsSnsObj *pObj, teEvent eEv)

ADC処理の進捗させる。具体的には、ADCの1ポート分の変換完了するたびに本処理を呼び出す。

本処理中で、ADC値の取得と mV値への演算処理が行われ、tsSnsObj構造体中に値が格納される。

本処理は、tsSnsObj構造体で管理される状態遷移に対するイベント処理になる。本処理直後にbSnsObj_isComplete()を呼び出し処理が完了したかを確認する。再び初期状態に戻すには、改めてE_ORDER_KICKを引数として本処理を実行する(つまりADCを再度実行するには完了後にE_ORDER_KICK を2回実行することになる)。

tsObjData_ADC構造体

この構造体には、指定する ADC チャネル、結果として得られる電圧値が含まれます。

  • u8SourceMask:ADC対象のポートを指定するビットマップ。指定したポートがADC対象となる。- TEH_ADC_SRC_VOLT : 電源電圧- TEH_ADC_SRC_ADC_1-4 : ADC1,2,3,4
  • u8InputRangeMask:ADC対象のポートのレンジ(0-Vrefまたは0-2Vref)を指定する。指定したポートは0-Vrefとなる。未指定の場合 0-2Vref となる。
  • ai16Result[]:ADC値を保存する構造体。結果はmV値として格納される。- TEH_ADC_IDX_VOLT : 電源電圧- TEH_ADC_IDX_ADC_1-4: ADC1,2,3,4

3 - DIO (GPIO)関連のAHI関数と解説

TWENETライブラリ、DIO (GPIO)関連のAHI関数と解説
TWENETライブラリ、DIO (GPIO)関連のAHI関数と解説です。

DIO (GPIO)

AHI の DIO (GPIO) 関連の一部について、ソースコードの互換を目的として実装しています。

概要

ピンの割当については TWELITE BLUE/RED とは違うアーキテクチャになっています。ここでは TWELITE BLUE/RED で使用したピンを DIO0..19/DO0..1/ADC0…3、TWELITE GOLD の半導体でのピン名を PIO0..21 と記載します。ピンの詳細は、各モジュール利用の半導体データシートを参照ください。

  • モジュール上のピンの対応が1:1にならない部分がある。
    • PIO0 は DIO11 と DO0 で共用。
    • PIO14 は DIO8 と ADC1 で共用。
  • DIO割り込みについて、以下の相違点がある。
    • DIO0..19まで独立した割り込みが可能であったが、そういった機能は存在しないため GINT (グループ割り込み) 機能を用いて、類似の動作を実現している。(他に独立した割り込みが可能な PINT という機能があるが4ポートまでの利用なので、本ライブラリでは使用していない)
    • ハードウェアの割り込み検出は両エッジのみであるため、いずれかのエッジで内部割込みが発生する。
      • 稼働中(スリープしていない)の場合は、割り込み発生後のピンの状態で AHI の割り込みハンドラを呼び出すか決めているため、両エッジであることは表面的に見えません。
      • スリープ起床でのエッジは指定できません。

ピンの割当

DIODIOPIO備考
DIO0016
DIO1117
DIO2218
DIO3319
DIO447
DIO556
DIO668
DIO779
DIO8814ADC1と共用
DIO9912
DIO10104
DIO11110DO0と共用
DIO121213
DIO13131
DIO141410
DIO151511
DIO161620
DIO171721
DIO18182
DIO19193
DO0 (PROG)0DIO11と共用
DO15
ADC214DIO8と共用
ADC115

AHIcmpt_Dio.cpp - 定義・定数

定義

#define BOARD_GPIO_PORT_MAX_PIN_COUNT 22 // ピン数
#define BOARD_GPIO_PIN_TABLE_SIZE 24     // ピン数22を4の倍数で切り上げたもの

g_twenet_ioport_remap_by_PIOn[]

const uint8 g_twenet_ioport_remap_by_PIOn[BOARD_GPIO_PIN_TABLE_SIZE];

(ライブラリ内部使用)PIO番号をDIO番号に変換するテーブル。

  • 0x80: SPIMISO ピン
  • 0x90: ADC1ピン (アナログ専用)
  • 0xFF: 未使用・未定義

g_twenet_ioport_remap_by_AHIn[]

const uint8 g_twenet_ioport_remap_by_AHIn[BOARD_GPIO_PIN_TABLE_SIZE];

(ライブラリ内部使用)AHI番号からPIO番号を参照するテーブル。

AHIcmpt_Dio.cpp - 定義

変数

uint32 G_TWENET_IOPORT_OUTPUT_BM() = 0;       // 出力ポート一覧のDIOビットマップ
uint32 G_TWENET_IOPORT_INT_ENABLED_BM() = 0;      // 割り込み有効ポート一覧のDIOビットマップ
uint32 G_TWENET_IOPORT_INT_RISING_BM() = 0;       // 立ち上がり割り込み有効のDIOビットマップ
uint32 G_TWENET_IOPORT_INT_FALLING_BM() = 0;      // 立ち下がり割り込み有効のDIOビットマップ
volatile uint32 G_TWENET_IOPORT_INT_STATUS() = 0; // DIO割り込み起床した場合の、起床ピンを記録したDIOビットマップ
uint32 G_TWENET_IOPORT_WAKE_STATUS() = 0;         // 起床時のIO割り込み要因を保存したDIOビットマップ
  • DIOビットマップはビットnがDIOnに対応します (例: DIO0, 3 なら (1UL << 0) | (1UL << 3))

check_pio(), get_pio(), get_dio()

static inline bool check_pio(uint8 u8pio);
static inline uint8 get_pio(const uint8 u8dio);
static inline uint8 get_dio(const uint8 u8pio);
  • check_pio(): 指定された PIO が有効な番号か、また、他のペリフェラルで使用済みかどうかを判定するインライン関数。
  • get_pio(): 指定された DIO 番号に対応する PIO 番号を返します。無効な割当である場合は 0xffを返します。
  • get_dio(): 指定された PIO 番号に対応する DIO 番号を返します。無効な割当である場合は 0xff を返します。

s_gpio_int_handler()

static void s_gpio_int_handler(uint32 bm_pio, uint32 bm_pio_changed, void* p_data);

DIO割り込み発生時に内部的に呼び出される割り込み処理関数。

  • ピンの変化がある場合は __twenet_vAppQApiPostHwIntT() を用いて、AppQAPI 経由で割り込み情報を伝達します。

AHIcmpt_Dio.cpp - AHI関数定義

vAHI_DioSetDirection()

void   vAHI_DioSetDirection(
    uint32      u32Inputs,
    uint32      u32Outputs);

ポートの入出力を設定します。

  • 原則として初期化時は入力状態ですが、厳密には TWENETmcu ライブラリの pinmux.c BOARD_InitPins() の初期化状態が規定値になります。

vAHI_DioSetOutput()

void   vAHI_DioSetOutput( // u32On:HIGH, u32Off::LOW
    uint32      u32On,
    uint32      u32Off);

ポートの出力状態を変更します。u32OnはHIGHレベルに変更するDIOビットマップ、u32offはLOWレベルに変更するDIOビットマップです。

  • 複数のピンを指定した場合はピンの変化は同時では有りません。
    • 内部実装として、ループ内で1ピンずつ設定されるためです。

vAHI_DioSetPullup()

void   vAHI_DioSetPullup(
    uint32      u32On,
    uint32      u32Off);

プルアップ状態を設定します。

  • 原則としてプルアップ有りの設定ですが、厳密には TWENETmcu ライブラリの pinmux.c BOARD_InitPins() の初期化状態が規定値になります。

u32AHI_DioReadInput()

uint32 u32AHI_DioReadInput(void);

すべてのポートの状態を一度に取得します。

  • 戻り値が全ポートの状態を示すビットマップで1になっているビットがHIGHレベル、0がLOWレベルです。
  • 存在しないDIO番号やペリフェラルなどで使用中のポートの値は未定義です。

vAHI_DioWakeEnable()

void   vAHI_DioWakeEnable(
    uint32      u32Enable,
    uint32      u32Disable);

DIO割り込みを開始します。u32Enableには割り込み処理を追加するDIOビットマップ、u32Disableには割り込み処理を除外するDIOビットマップを指定します。加えて割り込みを有効にしたピンに対して vAHI_DioWakeEdge() により割り込みエッジを指定する必要があります。

  • 入力設定ピンでないピン(出力ピンや他のペリフェラル機能が割り当てられているピン)を指定した時の振る舞いは未定です。

vAHI_DioWakeEdge()

void   vAHI_DioWakeEdge(
    uint32      u32Rising,
    uint32      u32Falling);

割り込みピンの設定を行います。この呼び出しでは、指定したピンに対して立ち上がり立ち下がり設定を一度に行います。追加や削除は出来ないことに注意してください。

本関数名には Wake が含まれますが、稼働中の割り込みの処理と、スリープ復帰の処理の両方を設定します。

  • 動作原理上 u32Risingu32Fallingに同一ピンを指定した場合は、双方のエッジで割り込みが発生します。(ただし、AHIでの有効な設定ではないため、動作検証外とします)
  • 割り込み動作中はvAHI_DioWakeEnable()が内部的に呼び出され再設定されます。
  • 入力設定ピンでないピン(出力ピンや他のペリフェラル機能が割り当てられているピン)を指定した時の振る舞いは未定です。
  • スリープ復帰時の割り込みエッジは、両エッジになります。

u32AHI_DioWakeStatus()

uint32 u32AHI_DioWakeStatus(void);

DIO割り込み起床時の起床要因となったピンのビットマップを返します。

  • 内部的には、呼び出し時の__twenet_ioport_int_statusの値を返します。呼び出し後は0にセットされます。

bAHI_DoEnableOutputs()

static inline bool_t bAHI_DoEnableOutputs(bool_t bEnableDO) {
	return bAHI_DoEnableOutputsEx_MW(bEnableDO, bEnableDO);
}

DO0,DO1ピンを出力設定にします。

  • DO0/DO1 双方ともに出力設定にします。
  • 片側だけを設定したい場合は bAHI_DoEnableOutputsEx_MW() を呼び出します。
    • DO1 (PIO5) は、始動時にプログラムモードへの遷移判定(ISP_ENT)をするピンに割り当てられているため、ハードウェア設計上留意が必要なピンです。特別な理由がなければ、別のピンを利用することを推奨します。
  • DO0(PIO0) は DIO11 にも割り当てられているため、両方利用している場合はコードの調整(片側の制御を除外する)が必要です。

vAHI_DoSetDataOut()

void vAHI_DoSetDataOut(
    uint8       u8On,
    uint8       u8Off);

DO0(PIO0),DO1(PIO1)に対して出力設定を行います。

  • DO0がbit0 (0x1)、DO1がbit1 (0x2) のビットマップで指定します。
  • u8On にビットを設定すると HIGH レベル、u8off に指定すると LOW レベルになります。

vAHI_DoSetPullup()

 void vAHI_DoSetPullup(
    uint8       u8On,
    uint8       u8Off);

なにもしません。

AHIcmpt_Dio.cpp - AHI拡張API

末尾に _MW がつく関数は、AHI ライブラリには存在しない独自拡張です。

bAHI_DoEnableOutputsEx_MW()

bool_t bAHI_DoEnableOutputsEx_MW(
    bool_t bEnableDO0, bool_t bEnableDO1);

DO0, DO1 を出力用に設定する。bAHI_DoEnableOutputs()が2ポート双方を設定するために追加した関数。

vAHI_DioInterruptDisablePinsIntWhenChanged_MW(), vAHI_DioInterruptReavtivate_MW()

void vAHI_DioInterruptDisablePinsIntWhenChanged_MW(bool_t bSet);
void vAHI_DioInterruptReavtivate_MW();

割り込み判定されたピンの割り込みを一時的に停止する。

bSetをTRUEとして呼び出すと、DIO割り込みが発生した時点で、その割り込み対象ピンの割り込みは一時的に停止します。チャタリングが多いメカボタンなどの入力の場合この設定を有効にして、割り込み発生から一定時間経過後に vAHI_DioInterruptReavtivate_MW() を呼び出し割り込みを再開します。

vAHI_DioOnSleep_MW()

void vAHI_DioOnSleep_MW();

内部的な処理関数でユーザは呼び出しを行いません。スリープ前の DIO 割り込み関係の処理を行います。具体的には DIO 起床ピンの設定を行います。

vAHI_DioOnWakeup_MW()

void vAHI_DioOnWakeup_MW(bool_t b_init_2nd);

内部的な処理関数でユーザは呼び出しを行いません。起床時の DIO 割り込み関係の処理を行います。起床要因となったピンを保存します。

b_init_2ndfalseの呼び出しは、WarmMain()処理のごく初期の段階で呼び出され、起床要因の特定などの処理が行われます。つづいてcbAppWarmStart(TRUE)の呼び出しの直前にtrueでの呼び出しを行います。

vAHI_DioRetentionRelease_MW()

void vAHI_DioRetentionRelease_MW();

スリープ復帰後の DIO 出力状態保持を解除する。本関数は RAM OFF スリープ復帰時かつcbAppColdStart()内で使用します。

JN518Xでは、DIO出力状態を保持するためのレジスタ設定 (SYSCON->RETENTIONCTRL) を行ってからスリープします。出力設定を行ったDIOピンはレジスタ設定時の出力状態を維持し、スリープ復帰後もレジスタ設定を変更しない限り出力状態が保持されます。本関数を呼び出すことで出力保持が解除されます。

スリープ前の状態と同じ設定にするには本関数呼び出し前vAHI_DioSetDirection()vAHI_DioSetOutput()を行い、明示的に出力設定を行っておきます。DIOの内部レジスタはスリープ時にクリアされるためです。

cbAppColdStart()呼び出し後は、TWENETmcuライブラリ内の処理として、本関数と同じ処理を実行します。不用意なポートのHI/LO遷移を避けたい場合は、cbAppColdStart()内でポートの出力設定を行うようにしてください。

その他

本ライブラリを利用しない場合の留意事項

本ライブラリ中の関数は呼び出さないようにしてください。呼び出しを行わない場合であっても、本ライブラリは TWENETmcu, TWENETlib ライブラリと依存性があります。

依存関係を解消するためには以下を参考にしてください。

  • スリープ手続きを行う際の割り込みピンに関する部分
    • vAHI_DioOnSleep_MW(), vAHI_DioOnWakeup_MW() を調整する必要があります。
      • この2つの関数は TWENETcmpt 内の vAHI_OnSleep_MW(), vAHI_OnWakeup_MW()から呼び出されます。
    • vAHI_OnSleep_MW()関数は、ソース非開示のTWENETlibライブラリに依存しています。
      • vAHI_DioOnSleep_MW()__twenet_ioport_int_status に割り込み起床判定を行う PIO ビットマップを指定します。ToCoNet_vSleep()内で反映され、適切にスリープ実行されます。
    • vAHI_OnWakeup_MW(), vAHI_DioOnWakeup_MW() は、TWENETmcuライブラリソース中で呼び出されます。必要に応じて処理を変更してください。

4 - Timer (PWM)関連のAHI関数と解説

TWENETライブラリ、Timer (PWM)関連のAHI関数と解説
TWENETライブラリ、Timer (PWM)関連のAHI関数と解説です。

Timer (PWM)

AHI の Timer 関連の API の一部について、ソースコード互換を取る目的で実装しています。

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 ID01234
SMD PIN##1216131519
AHI DIO##1011121317
PIO##4013121
PWM channel40219

標準で DO1,2 を利用した場合

AHI TIMER ID01234
SMD PIN##12161219
AHI DIO##1011DO0DO117
PIO##400521
PWM channel400N/A9
  • TIMER_1, TIMER_2 の割当が衝突します。
  • TIMER_3 の出力ピンにはハードウェアタイマーの機能がありません。

副割当

AHI TIMER ID01234
SMD PIN##678910
AHI DIO##45678
PIO##768914
PWM channel76891

副割当で DO1,2 を利用した場合

AHI TIMER ID01234
SMD PIN##671910
AHI DIO##45DO0DO18
PIO##760514
PWM channel760N/A1
  • 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を呼び出した場合の振る舞いは未定義です。
  • 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_???)を用いた手続きをまとめたクラスライブラリです。

5 - SMBUS(I2C)関連の手続きを定義したSMBus.c,hの解説

TWENETライブラリ、SMBUS(I2C)関連の手続きを定義したSMBus.c,hの解説
TWENETライブラリ、SMBUS(I2C)関連の手続きを定義したSMBus.c,hの解説です。

SMBUS(I2C)

TWENETを用いたサンプルコードやアプリコードの多くは、I2Cバスの利用は、AHIライブラリ内の低レベル手続きは直接用いず、読み書き手続きを簡素化したSMBus.c, .h定義関数群を用いています。

以下に、利用する関数名を列挙します。

void vSMBusInit(void);
void vSMBusInit_setClk(uint32 u32Clk);
void vSMBusDeInit();
void vSMBusDeInit(void);
bool_t bSMBusWrite(uint8 u8Address, uint8 u8Command,
						  uint8 u8Length, uint8* pu8Data);
bool_t bSMBusSequentialRead(uint8 u8Address, uint8 u8Length,
		   uint8* pu8Data);

SMBus.c SMBus.h

I2C の代表的な手続きをまとめた関数群でTWENETmwx/source/sensors/legacy にソースコードを格納しています。

※TWENETmwx ライブラリをリンクしない場合(Cプロジェクト)は、このソースコードをコピーして利用します。

vSMBusInit()

void vSMBusInit(void);

I2Cバスを初期化します。使用するピンはDIO14(CLK),15(DATA)で、クロック周波数は100Kbpsです。

vSMBusInit_setClk(uint32)

void vSMBusInit_setClk(uint32 u32Clk);

vSMBusInit()の替わりに本関数を用いることで、u32clkに対応するクロックにてI2Cバスを初期化します。

  • u32clk>=7かつu32clk>=255の場合⇒クロック周波数320000ul/(u32clk+1)を指定して初期化します。例えば31を指定すると、100KHz、7を指定すると400kHzとなります。
  • u32clk >= 12500かつu32clk <= 400000u32clkを指定して初期化します。
  • それ以外⇒未定義

※ 実際の周波数は、ハードウェアのクロックディバイザに対応し近傍の周波数が選択されます。具体的な計算方法についてはソースコードを参照 (TWELITE GOLDの場合は NXP の FSL ライブラリの仕様を参照ください。

// TWELITE GOLDの実装
PUBLIC void  TWENET_smbus_vSMBusInit_setClk(uint32_t u32clk)
{
    ...
	if (u32clk >= 7 && u32clk <= 255) { // given by divisor
		u32clk = 3200000ul / (u32clk + 1);
	}

	if (u32clk < 12500ul || u32clk > 400000ul) {
		u32clk = 100000ul;
	}

	// initialize the I2C
    //...以下、呼び出し先関数の実装
      _conf.baudRate_bps = u32clk;
      I2C_MasterGetDefaultConfig(&_conf); // FSLライブラリ関数
}

// TWELITE BLUE/RED の実装
void vSMBusInit_setClk(uint32 u32Clk)
{
    /* convert clock to clock devisor */
    if (u32Clk > 255) {
    	u32Clk = (3200000UL / u32Clk) - 1;
    }
    if (u32Clk < 7 || u32Clk > 255) u32Clk = 31; // set 100kHz

    /* run bus at specified value */
    vAHI_SiMasterConfigure(TRUE, FALSE, u32Clk);
    // 16/[(PreScaler + 1) x 5]MHz
    //		--> 31:100KHz, 7:400KHz, 47:66Khz
}

vSMBusDeInit()

void vSMBusDeInit();

I2Cバスの利用を停止します。

  • TWELITE BLUE/RED はvAHI_SiMasterDisable()を呼び出します。
  • TWELITE GOLDはI2Cバスの利用の停止と、DIO14,15ピンを TWENET ライブラリ初期化時の設定 (入力ポート、プルアップ) に戻します。

bSMBusWrite()

bool_t bSMBusWrite(
	uint8 u8Address,
    uint8 u8Command,
	uint8 u8Length,
    uint8* pu8Data)

I2Cバスへの書き込みを行います。

  • u8Address⇒I2Cバスのデバイスアドレスを指定します。
  • u8Command⇒書き込み時のコマンド(最初の転送バイト)を指定します。
  • u8Length⇒続くバイト数。0の場合はコマンドのみの転送です。1以上を指定した場合はpu8Dataの定義が必須です。
  • pu8Data⇒転送するバイト列を格納したメモリ領域へのポインタを指定します。

転送が成功した場合は TRUE を戻し、失敗した場合は FALSE を戻します。

bSMBusSequentialRead()

bool_t bSMBusSequentialRead(
    uint8 u8Address,
    uint8 u8Length,
	uint8* pu8Data)

I2Cバスの読み込みを行います。

  • u8Address⇒I2Cバスのデバイスアドレスを指定します。
  • u8Length⇒読み出すバイト数(1以上)を指定します。
  • pu8Data⇒読み出すバイト列を格納するメモリ領域へのポインタを指定します。

転送が成功した場合は TRUE を戻し、失敗した場合は FALSE を戻します。

その他

スリープ時の取り扱い

  • TWELITE BLUE/REDは、スリープ復帰時にハードウェアの再初期化を行う必要があります。vSMBusDeInit()を呼び出さない場合のピンの状態は未定義(またはJN516x のペリフェラル仕様書に基づく)ですが、再度vSMBusInit() vSMBusInit_setClk() の呼び出しを行うことで初期化することができます。
  • TWELITE GOLDは、以下の振る舞いをします。
    • RAM ON(通常)スリープ時:スリープ手続きを行った時点で、I2Cバスが初期化されていた場合は、スリープ復帰時に再初期化を行います。I2Cバスが使用されていない場合は、通常の汎用IOのスリープ復帰時の手続きとなります。
    • RAM OFF(ディープ)スリープ時:スリープ復帰時にTWENETによるピンの初期化(入力ピン、プルアップ)行います。

TWELITE GOLD の実装

AHIライブラリ互換関数は用意せず SMBus.c,h に対応する関数を実装しています。

// TWENETcmptライブラリ内での実装
PUBLIC void TWENET_smbus_vSMBusInit(void);
PUBLIC void TWENET_smbus_vSMBusDeInit(void);
PUBLIC void TWENET_smbus_vSMBusInit_setClk(uint32 u32clk);
PUBLIC bool_t  TWENET_smbus_bSMBusWrite(uint8 u8Address,
    uint8 u8Command, uint8 u8Length, uint8* pu8Data);
PUBLIC bool_t TWENET_smbus_bSMBusSequentialRead(uint8 u8Address,
    uint8 u8Length,  uint8* pu8Data);

// SMBus.hで inline 定義により上記関数群を呼び出す
static inline void vSMBusInit(void) {
	TWENET_smbus_vSMBusInit();
}
static inline void vSMBusInit_setClk(uint32 u32Clk) {
	TWENET_smbus_vSMBusInit_setClk(u32Clk);
}
static inline void vSMBusDeInit() {
	TWENET_smbus_vSMBusDeInit();
}
static inline void vSMBusDeInit(void) {
	TWENET_smbus_vSMBusInit();
}
static inline bool_t bSMBusWrite(uint8 u8Address, uint8 u8Command,
						  uint8 u8Length, uint8* pu8Data) {
	return TWENET_smbus_bSMBusWrite(u8Address, u8Command, u8Length, pu8Data);
}
static inline bool_t bSMBusSequentialRead(uint8 u8Address, uint8 u8Length,
		   uint8* pu8Data) {
	return TWENET_smbus_bSMBusSequentialRead(u8Address, u8Length, pu8Data);
}

6 - SPI関連のAHI関数と解説

TWENETライブラリ、SPI関連のAHI関数と解説
TWENETライブラリ、SPI関連のAHI関数と解説です。

SPI

SPI関連のAHI互換関数の実装です。

SPIの対応については、以下のピンを利用します。

信号名ピン名(PIO番号)解説
SCKSPLCLK=DIO11(PIO0)クロック信号
このピンはSPICLK, DIO11共用になっています
MOSIDIO18(PIO2)SPIMOSIです。TWELITE 側が出力、外部SPIデバイス側が入力です。
MISOSPIMISO(PIO5)SPIMISOです。TWELITE 側が入力、外部SPIデバイス側が出力です。
SEL0DIO19(PIO3)
SEL1DIO0(PIO16)
SEL2DIO1(PIO17)

副割り当てのピン (vAHI_SpiSetLocation_MW(FALSE)により設定)を用いた場合は、以下となります。

信号名ピン名(PIO番号)解説
SCKADC1(PIO15)クロック信号
MOSIDIO1(PIO17)SPIMOSIです。TWELITE 側が出力、外部SPIデバイス側が入力です。
MISODIO2(PIO18)SPIMISOです。TWELITE 側が入力、外部SPIデバイス側が出力です。
SEL0DIO0(PIO16)
SEL1DIO8=ADC2(PIO14)このピンはDIO8, ADC2共用になっています
SEL2DIO12(PIO13)

SPIはハードウェアの機能を用い動作するため、ピンの振る舞い(特に転送していないときの HIGH/LOW の状態など)には一部違いが出ます。

  • 実装は、ブロッキング転送を用いています。コードの互換性を維持するため、転送APIの直後にポーリング待ちコードを含めるようにしてください(bAHI_SpiPollBusy(), vAHI_SpiWaitBusy())。

vAHI_SpiConfigure()

void   vAHI_SpiConfigure(
    uint8       u8SlaveEnable,
    bool_t      bLsbFirst,
    bool_t      bPolarity,
    bool_t      bPhase,
    uint8       u8ClockDivider,
    bool_t      bInterruptEnable,
    bool_t      bAutoSlaveSelect);

SPIの初期化を行います。

  • bInterruptEnableには対応してません。パラメータは無視されます。

vAHI_SpiDisable()

void vAHI_SpiDisable(void);

SPIの利用停止をします。

vAHI_SpiSelect()

void   vAHI_SpiSelect(
    uint8       u8SlaveMask)

SPIのSELECTピンを選択します。

  • vAHI_SpiConfigure()bAutoSlaveSelectがTRUE設定の場合は、制御対象のピンを指定します。この呼出時点ではピンの制御は行いません。
  • vAHI_SpiConfigure()bAutoSlaveSelectがFALSE設定の場合は、SELECTピンの制御(対象品のみをLOW,それ以外はHIGH) します。

vAHI_SpiStop()

PUBLIC void   vAHI_SpiStop(void);

SELECTピンを解除します。vAHI_SpiSelect(0)と同じ処理です。

vAHI_SpiStartTransfer()

void vAHI_SpiStartTransfer(
    uint8       u8CharLen,
    uint32      u32Out);

void   vAHI_SpiStartTransfer32(uint32 u32Out)
void   vAHI_SpiStartTransfer16(uint16 u16Out)
void   vAHI_SpiStartTransfer8(uint8 u8Out)

SPI転送を実行します。

  • この処理はブロッキングで実行されます。
  • 8の倍数ビット数でない場合は、転送が2~3回に分割されます。
  • 32bit指定時は、エンディアンの違いによるメモリ上のバイト配置にかかわらず、数値の上位のバイトから下位のバイトの順に送信されます。結果として、BLUEとGOLDでは転送波形が同じになります。

AHI_SpiReadTransfer

static inline uint32 u32AHI_SpiReadTransfer32(void);
static inline uint16 u16AHI_SpiReadTransfer16(void);
static inline uint8  u8AHI_SpiReadTransfer8(void);

転送完了後に呼び出し、読み出した値を返す。

bAHI_SpiPollBusy()

bool_t bAHI_SpiPollBusy(void);
inline void vAHI_SpiWaitBusy(void) { while(bAHI_SpiPollBusy()); }

常に FALSE を返します。転送APIがブロッキング転送を行うためです。

bAHI_SpiTransferBlocking_MW()

bool_t bAHI_SpiTransferBlocking_MW(
    uint8       *au8tx,
	uint8       *au8rx,
	uint8		u8len);

バイト単位の転送を行います。au8tx が送信データの配列、au8rxが受信データの配列、u8lenが転送バイト数です。

  • 配列の先頭から順に転送されるため、LSBから順に転送する場合は、バイト順も LSB 側のバイトを先に格納しておく必要があります。受信データも同様です。

vAHI_SpiWaitBusy()

void vAHI_SpiWaitBusy(void);

速やかに return します。

vAHI_SpiSetLocation_MW()

void vAHI_SpiSetLocation_MW(bool_t bLocation);

使用するピンの組み合わせを変更します。既定のピンを用いる場合は本関数の呼び出しは不要ですが、副割り当てピンを用いる場合はvAHI_SpiConfigure()関数呼び出し前に本関数を呼び出します。

  • bLocation == FALSE (デフォルト)→既定のピン割り当てを用います。
  • bLocation == TRUE →副割り当てピンを用います。

その他

転送の分割

vAHI_SpiStartTransfer()では8bitの整数倍(8,16,24,32bit)以外の転送を行う場合は、内部的に転送を2分割して行います。そのため、1回目と2回目の転送の間、波形は一定時間保持されることになります。

スリープ復帰時の振る舞い

RAM保持スリープ直前にSPIバスが初期化済みである場合は、復帰時に初期化状態を復元します。RAM非保持スリープの場合は、通常の始動時のDIO初期化が行われます。

BLUE/REDとのコード互換性を高めたい場合はスリープ前に vAHI_SpiDisable()を明示的に呼び出すようにしてください。

7 - Random(乱数)関連のAHI関数と解説

TWENETライブラリ、Random(乱数)関連のAHI関数と解説
TWENETライブラリ、Random(乱数)関連のAHI関数と解説です。

Random(乱数)

乱数生成関連のAHI 互換関数の実装。

vAHI_Start|StopRandomNumberGenerator()

void vAHI_StartRandomNumberGenerator(bool_t const bMode, bool_t const bIntEn);
void vAHI_StopRandomNumberGenerator(void);

乱数生成を開始・停止します。

u16AHI_ReadRandomNumber()

uint16 u16AHI_ReadRandomNumber(void);

16bitの乱数値を読み出します。

  • 乱数生成が開始されていない場合は57005を戻します。

u32AHI_ReadRandomNumber_MW()

uint32 u32AHI_ReadRandomNumber_MW(void);

(TWELITE GOLD 専用関数)32bitの乱数値を読み出します。

  • 乱数生成が開始されていない場合は3735928559を返します。

vAHI_ReinitRandomNumberGenerator_MW()

void vAHI_ReinitRandomNumberGenerator_MW();

(TWELITE GOLD 専用関数)乱数生成デバイスの再初期化を行います。

8 - UART関連のAHI関数と解説

TWENETライブラリ、UART関連のAHI関数と解説
TWENETライブラリ、UART関連のAHI関数と解説です。

UART

UARTの利用は TWENETutils にある serial.c,.h および uart.c,.h を用います。ここでは、TWELITE GOLD で特有の振る舞いをするAHI互換関数について解説します。

  • UART1を用いる場合は、vAHI_UartSetLocation() または vAHI_UartSetLocationByPio_MW() を呼び出し、事前に割り当てポートを指定する必要があります。
  • UART0 は使用にあたりUART1のような特別な手続きは必要ありません。

vAHI_UartSetLocation()

void vAHI_UartSetLocation(uint8_t u8port, bool_t bSel);

UART のポート割り当てを指定します。

  • UART0 の割り当てには影響しません。規定のポート(DIO6,7)から変更できません。
  • UART1 の割り当ては以下の2種類が可能です。
  • UART1を利用する場合は必ず本館数を呼び出す必要があります。
  • UART1 の他の割り当てを行うには vAHI_UartSetLocationEx_MW() を用いてください。
bSelTXRX
FALSEDIO14(PIO10)DIO15(PIO11)
TRUEDIO11(PIO0)*1DIO13(PIO1)

*1 規定のSPICLKピンと重複します。

vAHI_UartSetLocationByPio_MW()

void vAHI_UartSetLocationByPio_MW(uint8_t u8port, uint8 u8TxPort, uint8 u8RxPort)

UART のポート割り当てを行います。u8portE_AHI_UART_1を指定します。TXポートとRXポートのPIO番号を、u8TxPortu8RxPortで指定します。

設定可能なPIO番号(DIO番号)

  • TX : 0(DO0,DIO11) 6(DIO5) 10(DIO14) 20(DIO16)
  • RX : 7(DIO4) 1(DIO13) 11(DIO15) 19(DIO13)

vAHI_UartDisable()

void vAHI_UartDisable(uint8_t u8port)

u8portで指定するUARTポートを利用停止します。ピンの状態は起動直後の初期化状態(TWENETmcu/board/pin_mux.cでの定義)に戻ります。

9 - WatchDog(WDT)関連のAHI関数と解説

TWENETライブラリ、WatchDog(WDT)関連のAHI関数と解説
TWENETライブラリ、WatchDog(WDT)関連のAHI関数と解説です。

WatchDog(WDT)

vAHI_WatchdogStart()

void vAHI_WatchdogStart(uint8 u8Prescale);

ウォッチドッグタイマーを利用開始します。

  • タイムアウト時間はおおよその値を設定している。具体的にはタイムアウトはu8Prescale == 0の場合8ms, それ以外は((1UL<<(u8Prescale-1)) + 1) * 8msとしてthe_wwdt->init()を呼び出している。
  • 値域外の値 u8Presacale > 12を指定した場合は、u8Prescale = 10(約4秒) とする。
  • -DDEBUGでコンパイルするデバッグ時はこの処理は実行されず、WDTは停止したままとします。

vAHI_WatchdogStop()

void vAHI_WatchdogStop();

TWELITE GOLD では、いったん稼働したウォッチドッグの停止を行うことが出来ません。本関数は、ウォッチドッグタイマーのタイムアウトを変更する際に以下のように呼び出します。

...
vAHI_WatchdogStop(); // 一旦停止API(実際は停止しない)を呼び出す
vAHI_WatchdogStart(12); // 約16秒に再設定する

vAHI_WatchdogRestart()

void   vAHI_WatchdogRestart();

ウォッチドッグタイマーのタイムアウトまでに呼び出します。

  • -DDEBUGでコンパイルするデバッグ時はこの処理は実行されません。

10 - WakeTimer(ウェイクタイマー)関連のAHI関数と解説

TWENETライブラリ、WakeTimer(ウェイクタイマー)関連のAHI関数と解説

WakeTimer(ウェイクタイマー)

vAHI_WakeTimer関連の互換関数の実装です。

ウェイクタイマーは2系統あり、スリープ中問わずカウンタが動作します。カウンタは減算式で値が0になったときに割り込みが発生します。またウェイクタイマーは、動作し続ける特性から起動時からの経過時間を計る時計として利用することもできます。時計として利用するための手続きをまとめた FRWT(FreeRunning WTimer)関数軍も用意しています。

  • タイマーはE_AHI_WAKE_TIMER_0 の場合41ビット、E_AHI_WAKE_TIMER_1 の場合28ビットです。後者は BLUE/RED(JN516x) と仕様が違いますので注意してください(カウンタ値として時間差分を計算する場合は、最大値が 0x0FFFFFFF である点に注意してください。例えばct1からct2の間の経過カウントを計算する場合は (((ct2 << 4) - (ct1 << 4)) >> 4)のように計算します)
  • 本ライブラリでは 32ビットを超えるタイマー値を扱う関数は用意していません。
  • mwxライブラリやいくつかのアプリケーションでは、タイマーの1系統(E_AHI_WAKE_TIMER_0を動作しつづけて時間計測をするための処理(Free Running WTimer:FRWTAPI)を行います。

vAHI_WakeTimerEnable()

void vAHI_WakeTimerEnable(uint8 u8Timer,
						  bool_t bIntEnable)

タイマーを初期化する。

vAHI_WakeTimerStart()

void vAHI_WakeTimerStart(uint8 u8Timer, uint32 u32Count)

タイマーを開始する。u32countはカウンター値を指定する。TWELITE GOLD の場合、1秒後に割り込みを発生させたい場合は 32768 (32KHz 水晶振動子の周波数) を指定する。

vAHI_WakeTimerStop()

void vAHI_WakeTimerStop(uint8 u8Timer)

タイマーを停止する。

u32AHI_WakeTimerCalibrate()

uint32 u32AHI_WakeTimerCalibrate(void);

ウェイクタイマーのキャリブレーション値 10000を返します。

  • 本来は精度の低いRCタイマーで 10000 に対して±30%程度の値になりますが、TWELITE GOLDでは32KHz水晶によるタイマー回路が含まれるため、この水準でのキャリブレーションは不要です。無条件で 10000 を返します。

u32AHI_WakeTimerRead()

uint32 u32AHI_WakeTimerRead(uint8 dev)

カウンタ値を返します。起床割り込みはカウンタが0になったときに発生します。その後もカウンタは減算を続けます(0の次はカウンタの最大値)。

u8AHI_WakeTimerStatus()

uint8 u8AHI_WakeTimerStatus(void)

タイマーの稼働状況のビットマップを返す。E_AHI_WAKE_TIMER_0の場合 E_AHI_WAKE_TIMER_MASK_0 (1)E_AHI_WAKE_TIMER_1の場合E_AHI_WAKE_TIMER_MASK_1 (2) が設定されます。

u8AHI_WakeTimerFiredStatus()

uint8 u8AHI_WakeTimerFiredStatus()

起床直後に使用し、起床要因が WTIMER の場合、0 以外の値が戻ります。

  • E_AHI_WAKE_TIMER_0 の場合、E_AHI_WAKE_TIMER_MASK_0 (1) が戻ります。
  • E_AHI_WAKE_TIMER_1 の場合、E_AHI_WAKE_TIMER_MASK_1 (2) が戻ります。

Free Running WTimer (FRWT)

WAKE TIMER を1系統(原則E_AHI_WAKE_TIMER_0)用い、実行し続けることによりリアルタイムカウンタとして用います。スリープ状態を問わず時間を計測することができます。

グローバル変数

G_TWENET_FREE_RUNNING_WTIMER_ENABLED()

uint8_t G_TWENET_FREE_RUNNING_WTIMER_ENABLED() // MACRO

この辺数は cbAppColdStart(FALSE) 呼び出しで設定します。0x80を指定することで E_AHI_WAKE_TIMER_0 をFRWTとして動作させます。WAKE TIMER のカウンタは時間の経過とともに減算されますが、FRWTは加算します。

  • mwxライブラリでは、自動的にE_AHI_WAKE_TIMER_0によるFRWTが設定されます。

g_twenet_free_running_wtimer_boot_tick

uint32_t g_twenet_free_running_wtimer_boot_tick

スリープ復帰直後(RAM保持)のカウント値を保存します。TWENETライブラリ中からvAHI_FRWTSetBootCount_MW()が呼び出されることにより設定されます。

vAHI_FRWTStart_MW()

void vAHI_FRWTStart_MW(uint8_t u8Timer)

本関数はTWENETライブラリ中で用いるため、原則としてユーザプログラムでは使用しません。グローバル変数G_TWENET_FREE_RUNNING_WTIMER_ENABLED()の設定によりFRWTを起動させます。

u32AHI_FRWTGetCurrentCount_MW()

uint32 u32AHI_FRWTGetCurrentCount_MW()

FRWTのカウント値(32000カウント/秒) を返す。

u32AHI_FRWTGetCurrentCount_msec_MW()

uint32 u32AHI_FRWTGetCurrentCount_msec_MW(uint32* dec_part)

現在のFRWTをミリ秒で返す。

  • dec_partNULLまたはuint32変数へのポインタを指定します。指定された場合は 1/10 ミリ秒の値 (0..9) を返します。

u32AHI_FRWTConvertCount_msec_MW()

static inline uint32 u32AHI_FRWTConvertCount_msec_MW(uint32 ct, uint32* dec_part) {
	// note: see wtimer::freerun_ct_convert_msec()
	uint64_t v = 1000ull * ct;
	if(dec_part) *dec_part = (10*(v & 32767)) >> 15;
	return (uint32)(v >> 15);
}

FRWTのカウント値をミリ秒に変換します。dec_partは指定された場合は 1/10 ミリ秒の値(0..9)を返します。

i32AHI_FRWTCompareCount_MW()

int32 i32AHI_FRWTCompareCount_MW(uint32 val_past, uint32 val_now)

FRWTのカウント値の比較を行います。val_nowがより最近の値、val_pastがより過去の値を指定し、この場合は正の値のカウント値を戻します。

i32AHI_FRWTCompareCount_msec_MW()

int32 i32AHI_FRWTCompareCount_msec_MW(uint32 val_past, uint32 val_now)

FRWTのカウント値の比較を行います。val_nowがより最近の値、val_pastがより過去の値を指定し、この場合は正の値のミリ秒を戻します。

vAHI_FRWTSetBootCount_MW()

void vAHI_FRWTSetBootCount_MW()

本関数はTWENETライブラリ中で用いるため、原則としてユーザプログラムでは使用しません

スリープ起床時(RAM保持、ウォームブート)に、FRWTカウント値を保存するために用います。

uint32 u32AHI_FRWTGetBootCount_MW()

uint32 u32AHI_FRWTGetBootCount_MW()

スリープ起床時(RAM保持、ウォームブート)に、FRWTカウント値を返します。

u32AHI_FRWTGetBootCount_msec_MW()

uint32 u32AHI_FRWTGetBootCount_msec_MW()

スリープ起床時(RAM保持、ウォームブート)に、FRWTカウント値をミリ秒に変換して返します。

11 - Onchip temp sensor (温度センサー)関連のAHI関数と解説

TWENETライブラリ、Onchip temp sensor (温度センサー)関連のAHI関数と解説

Onchip temp sensor (温度センサー)

TWELITE GOLDでは、内部チップ中に温度センサーが実装されています。このセンサー値は、無線MAC層の初期化のパラメータとして用いられます。

MAC層の初期化時の温度センサーの取り扱い

  • 温度センサーの値が取得できない場合は20℃として初期化します。
  • スリープ復帰時にG_TWENET_CHIPSENSOR_ADC_INTERVAL_MS()ミリ秒以上経過している場合は、スリープ起床時(RAM保持)に再度温度計測を行い、センサー値をもとにMACの再初期化を行う。

グローバル変数

uint8 G_TWENET_CHIPSENSOR_AUTO_ON_BOOT()
  // 変数アクセス用のマクロ

温度センサーの取得を自動で行うための設定用変数。cbAppColdStart(FALSE)中で設定する。

設定値内容備考
0温度センサーの取得を自動で行わない。MAC層の温度補正は固定値 (20℃で行う)
1温度センサーの取得を自動で行う。
uint8_t G_TWENET_CHIPSENSOR_ADC_TIMES_SCALER()
  // 変数アクセス用のマクロ

温度センサーのADC回数に対応するスケーラー値を指定します。

設定値ADC回数
01
12
24
38
int32 G_TWENET_CHIPSENSOR_TEMP128TH()
  // 変数アクセス用のマクロ

TWENETライブラリ内で計測されたチップセンサーの温度(℃ の128倍値)が格納される。

int16 g_twenet_chipsensor_volt_on_boot;

TWENETライブラリ内で計測された電圧値[mV]。温度センサー計測時に同時に計測された値が格納される。

uint32 G_TWENET_CHIPSENSOR_ADC_INTERVAL_MS()
  = (10*60*1000ul)
  // 変数アクセス用のマクロ

この変数で指定された期間内は温度センサーの取得を省略する。cbAppColdStart(FALSE)中で設定する。

uint8 g_twemet_chipsensor_capture_this_time;

ブート時に温度測定を行うか否かを判定した内部フラグ。

bAHI_AdcTemp_Measure_MW()

bool_t bAHI_AdcTemp_Measure_MW(
    int32 *i32temp_128th,
    int16 *i16volt_mv,
    uint8 adc_times_scaler,
    bool_t bTurnOnSensor)

温度センサーの計測を行います。

  • i32temp_128thは温度計測結果を返すint32がたの変数へのポインタ。
  • i16volt_mvは同時に計測される電源電圧[mV]値。
  • adc_times_scalerは温度センサーのADC回数に対応するスケーラー値を指定します。設定値は G_TWENET_CHIPSENSOR_ADC_TIMES_SCALER()の解説を参照してください。
  • bTurnOnSensorTRUEを設定すると、関数呼び出し内で温度センサーの電源を投入し必要な待ち処理を行います。FALSEを指定した場合は、事前にvAHI_AdcTemp_TurnOn_MW()を行い必要な待ち時間を経過している必要があります。

vAHI_AdcTemp_TurnOn_MW()

void vAHI_AdcTemp_TurnOn_MW()

温度センサーの電源を投入する。この呼び出し後 100μ秒 の待ち時間が必要です。

uint32 u32AHI_AdcTemp_GetCaptTick_MW()

uint32 u32AHI_AdcTemp_GetCaptTick_MW()

最後に温度センサー値を取得した FRWT 時刻を32KHzカウント値で返す。

uint32 u32AHI_AdcTemp_GetCaptTick_msec_MW()

uint32 u32AHI_AdcTemp_GetCaptTick_msec_MW()

最後に温度センサー値を取得した FRWT 時刻をミリ秒で返す。

u32AHI_AdcTemp_ElapsedFromCapt_msec_MW(), u32AHI_AdcTemp_TickrefFromCapt_msec_MW()

uint32 u32AHI_AdcTemp_ElapsedFromCapt_msec_MW()
uint32 u32AHI_AdcTemp_TickrefFromCapt_msec_MW(uint32 tick_ref)

最後に温度計測してからの経過時間をミリ秒で返す。