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

もとのページに戻る

2025-08-08 現在

TWENETutils - TWENET ユーティリティ

一般的なアルゴリズムやペリフェラルの手続きを内包するライブラリ
このライブラリは一般的なアルゴリズムやペリフェラルの手続きなどが含まれます。

TWENETutils - TWENET ユーティリティ

このライブラリは一般的なアルゴリズムやペリフェラルの手続きなどが含まれます。libTWENETutils.a に相当します。

1 - utils.h

始動関数 main(), WarmMain()
utils.h をインクルードすることで利用できるマクロ・関数を紹介します。

utils.h

utils.h をインクルードすることで利用できるマクロ・関数を紹介します。

S_OCTET(x)

1バイトをメモリを書き込む。

uint8 *q = &sTx.au8Data[0];

S_OCTET(0x12); 
S_BE_WORD(0x1234);
S_BE_DWORD(0x12345678);

uint8 *q をローカル変数として宣言しておき、データを読み込みたい領域のポインタとしておく。代入演算子の評価後 q++ が実行される。

S_BE_WORD(x)

2バイトをメモリを書き込む。

uint8 *q = &sTx.au8Data[0];

S_OCTET(0x12); 
S_BE_WORD(0x1234);
S_BE_DWORD(0x12345678);

uint8 *q をローカル変数として宣言しておき、データを読み込みたい領域のポインタとしておく。代入演算子の評価後 q+=2 が実行される。

BE はビッグエンディアン、LE はリトルエンディアン。

S_BE_DWORD(x)

4バイトをメモリを書き込む。

uint8 *q = &sTx.au8Data[0];

S_OCTET(0x12); 
S_BE_WORD(0x1234);
S_BE_DWORD(0x12345678);

uint8 *q をローカル変数として宣言しておき、データを読み込みたい領域のポインタとしておく。代入演算子の評価後 q+=4 が実行される。

BE はビッグエンディアン、LE はリトルエンディアン。

G_OCTET()

1バイトメモリを読み込み uint8 型の変数に値を格納する。

uint8 *p = &sRx.au8Data[0];

uint8 u8data1 = OCTET(); 
uint16 u16data2 = G_BE_WORD();
uint32 u32data3 = G_BE_DWORD();

uint8 *p をローカル変数として宣言しておき、データを読み込みたい領域のポインタとしておく。=演算子の評価後 p++ が実行される。

G_BE_WORD()

2バイトメモリを読み込み uint16 型の変数に値を格納する。

uint8 *p = &sRx.au8Data[0];

uint8 u8data1 = OCTET(); 
uint16 u16data2 = G_BE_WORD();
uint32 u32data3 = G_BE_DWORD();

uint8 *p をローカル変数として宣言しておき、データを読み込みたい領域のポインタとしておく。=演算子の評価後 p+=2 が実行される。

BE はビッグエンディアン、LE はリトルエンディアン。

G_BE_DWORD()

1バイトメモリを読み込み uint8 型の変数に値を格納する。

uint8 *p = &sRx.au8Data[0];

uint8 u8data1 = OCTET(); 
uint16 u16data2 = G_BE_WORD();
uint32 u32data3 = G_BE_DWORD();

uint8 *p をローカル変数として宣言しておき、データを読み込みたい領域のポインタとしておく。=演算子の評価後 p+=4 が実行される。

BE はビッグエンディアン、LE はリトルエンディアン。

ENCODE_VOLT(x)

2000~3600 の値を 8bit 値に変換します。

  • 1.95~2.80V は 5mV 刻み
  • 2.81~3.65V は 10mV 刻み
// utils.h の定義
#define ENCODE_VOLT(m) \
	(m < 1950 ? 0 : \
		(m > 3650 ? 255 : \
			(m <= 2802 ? ((m-1950+2)/5) : ((m-2800-5)/10+171)) ))
...
uint16 u16Volt = 2860;
uint8 u8Volt_enc = ENCODE_VOLT(u16Volt);
uint16 u16Volt_dec = DECODE_VOLT(u8Volt_Enc);

2000~2800 の値は 5 刻み、2800~は10 刻みで 8bit 値に割り当てます。

DECODE_VOLT(x)

ENCODE_VOLT() により得られた8bit値を元の値に戻します。

  • 1.95~2.80V は 5mV 刻み
  • 2.81~3.65V は 10mV 刻み
// utils.h の定義
#define DECODE_VOLT(i) \
	(i <= 170 ? (1950+i*5) : (2800+(i-170)*10) )
...
uint16 u16Volt = 2860;
uint8 u8Volt_enc = ENCODE_VOLT(u16Volt);
uint16 u16Volt_dec = DECODE_VOLT(u8Volt_Enc);

2000~2800 の値は 5 刻み、2800~は10 刻みで 8bit 値に割り当てます。

vPortAsInput(c)

ポートcを入力に設定する

#define vPortAsInput(c) vAHI_DioSetDirection(1UL << (c), 0)

vPortAsOutput(c)

ポートcを出力に設定する

#define vPortAsOutput(c) vAHI_DioSetDirection(0, 1UL << (c))

vPortSetHi(c)

ポートcをHi状態にする

#define vPortSetHi(c) vAHI_DioSetOutput(1UL << (c), 0)

vPortSetLo(c)

ポートcをLo状態にする

#define vPortSetLo(c) vAHI_DioSetOutput(0, 1UL << (c))

vPortSet_TrueAsLo(c, s)

ポート c を s が TRUE なら Lo, FALSE なら Hi に設定する

#define vPortSet_TrueAsLo(c, s)  vAHI_DioSetOutput((s) ? \
    0 : 1UL << (c), s ? 1UL << (c) : 0)

bPortRead(c)

ポート c を読み出す。Loレベルなら TRUE が返る

#define bPortRead(c) ((u32AHI_DioReadInput() & \
    (1UL<<(c))) ? FALSE : TRUE)

u32PortReadBitmap()

ポート c を読み出す。Loレベルなら TRUE が返る。

#define u32PortReadBitmap() (u32AHI_DioReadInput())

ビットマップの1がHi,0がLoとなります。

bPortCheckBitmap(bitmap, c)

読みだしたビットマップのポート c に対応するビットがLoレベルならTRUEを返す。

#define bPortCheckBitmap(bitmap, c) \
    (bitmap & (1UL<<(c))) ? FALSE : TRUE)

vPortDisablePullup(c)

ポート c のプルアップを停止する。

#define vPortDisablePullup(c) vAHI_DioSetPullup(0x0, 1UL << (c))

_C

switch でスコープを定義したい場合 _C { … } と記述している。

#define _C if(1)
// for example

switch(c) {
case 1:
  _C {
    uint8 u8work;
    ; // work
  } break;
default:
}

LB

改行コード (CRLF) 文字列です。

2バイトの文字列リテラルですので、vPutChar() では利用できません。

#define LB "\r\n"

vWait()関数

ループによる時間待ちを行います。

void vWait(uint32 c) {
	static volatile uint32 u32ct = 0;
	while (c-- > 0)
		u32ct++;
}

処理内容はソースコードの通りです。

vAnalogueConfig(), vAnalogueDisable()

ADC機能の初期化と停止を行う手続きをまとめています。既存コードの互換性を目的としています。

void vAnalogueConfig(void) {
#if defined(JN516x)
	if (!bAHI_APRegulatorEnabled()) {
		vAHI_ApConfigure(E_AHI_AP_REGULATOR_ENABLE,
				E_AHI_AP_INT_DISABLE,
				E_AHI_AP_SAMPLE_4,
				E_AHI_AP_CLOCKDIV_1MHZ,
				E_AHI_AP_INTREF);

		while (!bAHI_APRegulatorEnabled())
			;
	}
#elif defined(CPU_JN518X)
#endif

void vAnalogueDisable(void) {
#if defined(JN516x)
	vAHI_ApConfigure(E_AHI_AP_REGULATOR_DISABLE,
			E_AHI_AP_INT_DISABLE,
			E_AHI_AP_SAMPLE_4,
			E_AHI_AP_CLOCKDIV_1MHZ,
			E_AHI_AP_INTREF);
#elif defined(CPU_JN518X)
#endif
}

その他マクロ定義

// 64bit mac address
#define MAC_EXT_ADDR_TO_64BIT(ext) ((uint64)(ext.u32L) | (((uint64)(ext.u32H)) << 32))

// TIME COMPARE
#define u32TimeDiff(ref, now) (now - ref < 0x7FFFFFFF ? now - ref : )

// IO settings
#define vPortSetHi(c) vAHI_DioSetOutput(1UL << (c), 0)
#define vPortSetLo(c) vAHI_DioSetOutput(0, 1UL << (c))
#define vPortSet_TrueAsLo(c, s)  vAHI_DioSetOutput((s) ? 0 : 1UL << (c), s ? 1UL << (c) : 0)
#define vPortAsInput(c) vAHI_DioSetDirection(1UL << (c), 0)
#define vPortAsOutput(c) vAHI_DioSetDirection(0, 1UL << (c))
#define bPortRead(c) ((u32AHI_DioReadInput() & (1UL<<(c))) ? FALSE : TRUE) // Lo as True
#define u32PortReadBitmap() (u32AHI_DioReadInput())
#define bPortCheckBitmap(bitmap, c) ((bitmap & (1UL<<(c))) ? FALSE : TRUE)
#define vPortDisablePullup(c) vAHI_DioSetPullup(0x0, 1UL << (c))

#if defined(JN516x) || defined(CPU_JN518X)
#define PORT_KIT_SW1 2
#define PORT_KIT_SW2 3
#define PORT_KIT_SW3 10
#define PORT_KIT_SW4 9
#define PORT_KIT_LED1 17
#define PORT_KIT_LED2 13
#define PORT_KIT_LED3 12
#define PORT_KIT_LED4 11
#endif

#define PORT_KIT_SW1_MASK (1UL << PORT_KIT_SW1)
#define PORT_KIT_SW2_MASK (1UL << PORT_KIT_SW2)
#define PORT_KIT_SW3_MASK (1UL << PORT_KIT_SW3)
#define PORT_KIT_SW4_MASK (1UL << PORT_KIT_SW4)
#define PORT_KIT_SW_ALL2_MASK (PORT_KIT_SW1_MASK | PORT_KIT_SW2_MASK)
#define PORT_KIT_SW_ALL4_MASK (PORT_KIT_SW1_MASK | PORT_KIT_SW2_MASK | PORT_KIT_SW3_MASK | PORT_KIT_SW4_MASK)

#define PORT_KIT_LED1_MASK (1UL << PORT_KIT_LED1)
#define PORT_KIT_LED2_MASK (1UL << PORT_KIT_LED2)
#define PORT_KIT_LED3_MASK (1UL << PORT_KIT_LED3)
#define PORT_KIT_LED4_MASK (1UL << PORT_KIT_LED4)
#define PORT_KIT_LED_ALL2_MASK (PORT_KIT_LED1_MASK | PORT_KIT_LED2_MASK)
#define PORT_KIT_LED_ALL4_MASK (PORT_KIT_LED1_MASK | PORT_KIT_LED2_MASK | PORT_KIT_LED3_MASK | PORT_KIT_LED4_MASK)

// UART related
#define WAIT_UART_OUTPUT(P) SERIAL_vFlush(P)

// IO clock (on JN514x, IO runs at 16Mhz regardless of CPU clock.
#if defined(JN516x)
#define u32IO_FREQ_HZ 16000000UL
#elif defined(CPU_JN518X)
//#define u32IO_FREQ_HZ 32000000UL
#define u32IO_FREQ_HZ 16000000UL
#endif

void vAnalogueConfig(void);
void vAnalogueDisable(void);

void vWait(uint32 c);

2 - Timerライブラリ

Timerライブラリ
Timerライブラリを紹介します。

Timerライブラリ

tsTimerContext

Timer ライブラリで用いる設定用の構造体。

  • 0クリアすること。
  • 静的に確保すること。
名前解説
uint8u8Deviceタイマーデバイスを指定する (E_AHI_DEVICE_TIMER0 .. 4)。
uint16u16Hzタイマー周波数を Hz で指定する。
uint8u8PreScale16Mhz クロックに対するプリスケールを設定する。
bool_tbPWMOutTRUE なら PWM 出力を行う。
bool_tbDisableIntTRUE なら割り込みを禁止する。

vTimerConfig()

解説

Timer の初期化を行う。

引数

名前詳細
tsTimerContextpsTCタイマー設定の構造体。

戻り値

なし

サンプル

tsTimerContext sTimerApp; // global or static allocation

// set 64ticks/sec
memset(&sTimerApp, 0, sizeof(tsTimerContext));
sTimerApp.u8Device = E_AHI_DEVICE_TIMER0;
sTimerApp.u16Hz = 64;
sTimerApp.u8PreScale = 4; // 15625ct@2^4

vTimerStart()

解説

Timer を開始する。

本関数は、既に開始済みのTimerについても呼び出し可能です。Duty 比の変更を行う場合などに利用します。

引数

名前詳細
tsTimerContextpsTCタイマー設定の構造体。

戻り値

なし

サンプル

// initialize and start
vTimerConfig(&sTimerApp); // initialize
vTimerStart(&sTimerApp); // start

// change duty
sTimerPWM.u16Duty = 256; // set new duty ratio
vTimerStart(&sTimerPWM); // just start again to change duty

vTimerStop()

解説

Timer の動作を停止する。

引数

名前詳細
tsTimerContextpsTCタイマー設定の構造体。
戻り値

なし。

サンプル

// just stop the timer
vTimerStop(&sTimerApp);
...
// restart
vTimerStart(&sTimerApp);
...
// now, disable timer completely
vTimerStop(&sTimerApp);
vTimerDisable(&sTimerApp);

vTimerDisable()

Timer を破棄する。

引数

名前詳細
tsTimerContextpsTCタイマー設定の構造体。

戻り値

なし

サンプル

// just stop the timer
vTimerStop(&sTimerApp);
...
// restart
vTimerStart(&sTimerApp);
...
// now, disable timer completely
vTimerStop(&sTimerApp);
vTimerDisable(&sTimerApp);

3 - fprintf ライブラリ

fprintf ライブラリ
fprintfの簡易的な実装です。

fprintf ライブラリ

fprintfの簡易的な実装です。

参考

tsFILE

vfPrintf() vPutChar() で指定する出力先を定義した構造体。

メンバー
名前詳細
uint8u8Deviceシリアルポート (E_AHI_UART_0 または E_AHI_UART_1 を指定する)
bool_t (*) (uint8 u8Device, uint8 u8Char)bPutChar出力用の関数ポインタ。SERIAL ライブラリ用には SERIAL_bTxChar() が準備されているので、これを指定する。

{% hint style=“info” %} SERIAL_bTxChar() は、u8Char として渡されたバイトを SERIAL ライブラリ内の FIFO キューに投入します。

独自に出力関数を準備することで、UART 以外への文字列の出力にも利用できます。 {% endhint %}

サンプルコード
#include "serial.h"
#include "fprintf.h"

tsFILE sSerStream;
tsSerialPortSetup sSerPort;

void vSerialInit(uint32 u32Baud, tsUartOpt *pUartOpt) {
	// initialize sSerPort
	...
	SERIAL_vInit(&sSerPort);

	// for vfPrintf()
	sSerStream.bPutChar = SERIAL_bTxChar;
	sSerStream.u8Device = E_AHI_UART_0;
}

void vSerOut() {
    vfPrintf(&sSerStream, "HELLO!");
}

以下は、キャラクタ LCD の出力コードとして利用した一例です。

#include "serial.h"
#include "fprintf.h"

tsFILE sLcdStream;

// handle LCD display
PUBLIC bool_t LCD_bTxChar(uint8 u8Device, uint8 u8Data) {
	int i;

	switch (u8Data) {
	case '\n':
	...
}

void vInitHardware() {
    /* Initialise the LCD */
    vLcdReset(3, 0);

    /* register for vfPrintf() */
    sLcdStream.bPutChar = LCD_bTxChar;
    sLcdStream.u8Device = 0xFF;
}

void vSomeOutput() {
    vfPrintf(&sLcdStream, "Hello World!\n");
}

vfPrintf()

解説

tsFILE 構造体の示す出力先(UART)に printf 書式にて出力する。

引数

名前詳細
tsFILE*psStream出力先
const char *pcFormat出力書式
可変引数
対応する書式
s文字列
d整数(32bitまで)
u符号なし整数(32bitまで)
x16進数。a-f は小文字。
X16進数。A-Fは大文字。
bbit列

戻り値

なし。

サンプル

void cbToCoNet_vMain(void) {
	while (!SERIAL_bRxQueueEmpty(sSerPort.u8SerialPort)) {
		int16 i16Char;
		i16Char = SERIAL_i16RxChar(sSerPort.u8SerialPort);
		vfPrintf(&sSerStream, "\n\r## [%c] --> ", i16Char);
	    SERIAL_vFlush(sSerStream.u8Device);
		...
	}
}

vPutChar()

解説

tsFILE 構造体の示す出力先(UART)に1バイト出力する。

引数

名前詳細
tsFILE*psStream出力先
uint8u8Char出力バイト

戻り値

なし

サンプル

#define IS_ASC(c) ((c) >= 0x20 && (c) <= 0x7e)

void cbToCoNet_vRxEvent(tsRxDataApp *pRx) {
	uint8 u8i;
	vfPrintf(&sSerStream, LB"RX(len=%d):[", pRx->u8Len);
	for (i = 0; i < pRx->u8Len; i++) {
		uint8 c = pRx->auData[i];
		vPutChar(&sSerStream, IS_ASC(c) ? c : '.');
	}
}