2022/4/7
製品
カテゴリー
タグ
1551 Views
SPI接続においてペリフェラルを使用した高速ドライバ
課題
SPI接続のテストポイントによるオーバーヘッドをより小さくしたい。
解決方法
ペリフェラルを使用したドライバに変更することで、テストポイント出力時のクリック周波数を上げることができ、オーバーヘッドが削減できます。
SSI/CSIを使用できる場合に対応可能です。
<ペリフェラル使用の注意点>
ペリフェラルのポート以外に、汎用ポートが1ポート必要になります。ペリフェラルを使用する場合、下図のようにマイコンによっては8bit毎にCSが切り替わるものがあり、DT+Traceで検知できるデータフォーマットには合致しません。サンプルドライバでは、通常のテストポイントを4byte固定データとして出力するため、SSIのCSラインは使用せず、汎用ポートを使用してCSラインを制御しています。
効果
弊社で提供するサンプルドライバをそのままご使用いただいた場合よりも、オーバーヘッドを削減することができます。
例) CPU: Cortex™M3, CPU_Clock: 50MHz, OS: FreeRTOS
汎用ポートを使用(ノンカスタム):62us
ペリフェラルを使用(カスタム) :10us(約80%削減)
手順
サンプルドライバのダウンロード
対応OS | 接続方式 | 言語 | イベントID出力方式 | ダウンロード |
---|---|---|---|---|
Non-OS/iTron | SPI接続 | C/C++ | イベントID出力ポイント挿入 拡張イベントID出力ポイント挿入 |
ダウンロード |
Include,defineの設定
変更内容のコントロール等に必要なヘッダファイルをIncludeします。
サンプルドライバは、例として"Common.h"をIncludeしています。
削除するか、コメントアウトしてください。
/*=======================================================*/
/* Desc: Header for Port Control */
/*=======================================================*/
#include “Common.h”
/* #include “driverlib/ssi.h” */
各関数の設定
下記の関数内の記述は、サンプルを例にターゲット機器の環境に合わせて変更をしてから使用してください。
-
_TP_BusPortInit関数
最初にテストポイントの出力が行われる際に使用するポートレジスタの設定・初期化を行う関数です。
ターゲット側の初期化処理で定義される場合は、空関数で構いません。static void _TP_BusPortInit(void) { SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA ); SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOD ); SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0); GPIOPinTypeGPIOOutput( GPIO_PORTD_BASE, GPIO_PIN_3 ); /* CS */ GPIOPinWrite( GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_PIN_3); GPIOPinConfigure(0x00000801); /* GPIO_PA2_SSI0CLK */ GPIOPinConfigure(0x00001001); /* GPIO_PA4_SSI0RX */ GPIOPinConfigure(0x00001401); /* GPIO_PA5_SSI0TX */ GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_2); SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_3, SSI_MODE_MASTER, 25000000, 8); SSIEnable(SSI0_BASE); }
-
_TP_BusOutDrv関数
テストポイントのデータ出力を制御する関数です。
CSをLowにした後、_TP_BusOut関数の引数の(16bit)とaddr(16bit)を出力し、CSをHiに戻します。
datとaddrのラッチタイミングは、立ち上がりエッジです。/*=======================================================*/ /* Func: _TP_BusOutDrv */ /* Desc: Test Point Output Function */ /*=======================================================*/ DT_INLINE void _TP_BusOutDrv( DT_UINT addr, DT_UINT dat ) { unsigned long temp; portSetCS(0); /* data part 16bit */ SSIDataPut(SSI0_BASE, dat >> 8); while( SSIBusy(SSI0_BASE) ); /* Transmission waiting */ SSIDataGet(SSI0_BASE, &temp); /* Dummy Read */ SSIDataPut(SSI0_BASE, dat); while( SSIBusy(SSI0_BASE) ); /* Transmission waiting */ SSIDataGet(SSI0_BASE, &temp); /* Dummy Read */ /* address part 16bit */ SSIDataPut(SSI0_BASE, addr >> 8); while( SSIBusy(SSI0_BASE) ); /* Transmission waiting */ SSIDataGet(SSI0_BASE, &temp); /* Dummy Read */ SSIDataPut(SSI0_BASE, addr); while( SSIBusy(SSI0_BASE) ); /* Transmission waiting */ SSIDataGet(SSI0_BASE, &temp); /* Dummy Read */ portSetCS(1); }
-
_TP_BusOutByteDrv関数
1Byte分のデータを出力するための処理を記述します。
通常のテストポイント以外の高速テストポイント出力、変数値出力やイベントIDにおいて実行される関数です。/*=======================================================*/ /* Func: _TP_BusOutByteDrv */ /* Desc: Byte Data Output Function */ /*=======================================================*/ DT_INLINE void _TP_BusOutByteDrv( DT_UINT dat ) { unsigned long temp; SSIDataPut(SSI0_BASE, dat); while( SSIBusy(SSI0_BASE) ); /* Transmission waiting */ SSIDataGet(SSI0_BASE, &temp); /* Dummy Read */ }