14. SPI
SPIオブジェクトは、SPI通信機能を提供する組み込みオブジェクトです。
機能概要:
- SPIマスタモード機能を提供します。
制限事項:
- SPIインスタンスの書き込み及び読み出しメソッドはブロック型処理となります。
特に、低い通信速度設定で、一度に大きなサイズのデータを読み書きした場合、通信が完了するまでの間、長いブロック時間が発生することになりますので、留意願います。
Abstracts
Methods()/Properties | Summary | Version | Note |
---|---|---|---|
new SPI() | SPIインスタンスを生成します。 | 01.00.00+ |
{SPI} Instance
Methods()/Properties | Summary | Version | Note |
---|---|---|---|
.open() | 通信を開始します。 | 01.00.00+ | |
.close() | 通信を終了します。 | 01.00.00+ | |
.write() | データを書き込みます。 | 01.00.00+ | |
.read() | データを読み込みます。 | 01.00.00+ | |
.writeRead() | データ書き込み後にデータを読み込みます。 | 01.00.00+ | |
.writeReadFullDup() | データ書き込みと同時にデータを読み込みます。(全二重通信) | 01.00.00+ | |
.readAndCompare() | 指定されたターゲット値が得られるまでデータ読み込みを繰り返します。 | 01.00.00+ | |
.setChipSelect() | チップセレクト信号を手動制御します。 | 01.00.00+ |
Details
new SPI(nodeNo)
SPIインスタンスを生成します。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
nodeNo | number | mandatory | 使用するSPIインタフェースのノード番号を指定します。 Pinoutを参照してください。 | |
return | {SPI} | - | {SPI} : 生成された{SPI} |
.open(baudrate,clkmode,bitorder,csmode)
通信を開始します。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
baudrate | number | mandatory | 通信速度 0: 20Mbps 1: 10Mbps 2: 5Mbps 3: 2.5Mbps 4: 1.25Mbps 5: 0.625Mbps 6: 0.3125Mbps 7: 0.15625Mbps | |
clkmode | number | mandatory | クロックモード 0: アイドル時Lowレベル/立ち上がりエッジサンプリング 1: アイドル時Lowレベル/立ち下がりエッジサンプリング 2: アイドル時Highレベル/立ち下がりエッジサンプリング 3: アイドル時Highレベル/立ち上がりエッジサンプリング クロックモード詳細を参照してください。 | |
bitorder | number | mandatory | ビットオーダー 0: MSB first 1: LSB first | |
csmode | number | mandatory | チップセレクトモード 0: 自動 (アイドル時Highレベル、アクティブ時Lowレベルに自動制御されます。各書き込み及び読み込みメソッドが実行されている間、Lowレベルとなります) 1: 手動 (.setChipSelect()を使用して、チップセレクト信号を制御します。但し、SPIオープン時及びクローズ時は、強制的にHighレベルが設定されます) | |
return | boolean | - | true: 成功 false: 失敗 |
クロックモード詳細
.close()
通信を終了します。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
return | boolean | - | true: 成功 false: 失敗 |
.write(buff)
データを書き込みます。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
buff | ArrayBuffer | mandatory | 書き込みデータ 指定可能なデータサイズは1~4096バイトとなります。 | ArrayBufferサイズ分、書き込まれます。 |
return | boolean | - | true: 成功 false: 失敗 | パラメータ異常の場合、例外が発生します。 |
データ長が1バイトの時はUint8Arrayを用いて以下のようにします。
var buff = new ArrayBuffer(1);
var arr = new Uint8Array(buff);
arr[0] = your_data;
var ret = spi.write(buff);
.read(len[,dummyData])
データを読み込みます。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
len | number | mandatory | 読み込みデータ長を指定します。 設定範囲: 1~4096 | |
dummyData | number | optional | 読み込み時に送信されるダミーデータを指定します。 設定範囲: 0x00~0xFF デフォルト値は0xFFです。 | |
return | Arraybuffer | - | 読み込んだデータ 読み込みに失敗した場合は、サイズが0となります。 | パラメータ異常の場合、例外が発生します。 |
.writeRead(buff,len[,dummyData])
データ書き込み後にデータを読み込みます。
尚、チップセレクトモードが自動の場合、チップセレクト信号は、書き込み開始から読み込み完了するまでの間、Lowレベルが維持されます。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
buff | ArrayBuffer | mandatory | 書き込みデータ 指定可能なデータサイズは1~4096バイトとなります。 | ArrayBufferサイズ分、書き込まれます。 |
len | number | mandatory | 読み込みデータ長を指定します。 設定範囲: 1~4096 | |
dummyData | number | optional | 読み込み時に送信されるダミーデータを指定します。 設定範囲: 0x00~0xFF デフォルト値は0xFFです。 | |
return | Arraybuffer | - | 読み込んだデータ 書き込み又は読み込みに失敗した場合は、サイズが0となります。 | パラメータ異常の場合、例外が発生します。 |
.writeReadFullDup(buff)
データ書き込みと同時にデータを読み込みます。(全二重通信)
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
buff | ArrayBuffer | mandatory | 書き込みデータ 指定可能なデータサイズは1~4096バイトとなります。 | ArrayBufferサイズ分、書き込まれます。 |
return | Arraybuffer | - | 読み込んだデータ データサイズは書き込みデータ長と同じになります。 書き込み又は読み込みに失敗した場合は、サイズが0となります。 | パラメータ異常の場合、例外が発生します。 |
.readAndCompare(targetValue,dataMask,readTimeout[,dummyData])
指定されたターゲット値が得られるまでデータ読み込みを繰り返します。
読み出された1バイトデータはdataMask
でAND演算され、targetValue
と比較されます。
尚、チップセレクトモードが自動の場合、チップセレクト信号は、1バイトデータ読み出し毎に、Lowレベルになります。
尚、ターゲット値が検出されるまで全ての処理がブロックされます。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
targetValue | number | mandatory | ターゲット値 1バイトのターゲットデータを指定します。 設定範囲: 0x00~0xFF | |
dataMask | number | mandatory | データマスク 1バイトのデータマスクを指定します。 設定範囲: 0x00~0xFF | |
readTimeout | number | mandatory | 検出処理タイムアウト時間[ms] 設定範囲: 1~100 最大100msまで検出処理を継続できます。 | |
dummyData | number | optional | 読み込み時に送信されるダミーデータを指定します。 設定範囲: 0x00~0xFF デフォルト値は0xFFです。 | |
return | boolean | - | 検出結果 true: 検出 false: 未検出 (タイムアウト発生) | パラメータ異常の場合、例外が発生します。 |
.setChipSelect(sts)
チップセレクト信号を手動制御します。
チップセレクトモードを手動に設定した場合のみ、制御可能です。
Name | Type | M/O | Summary | Note |
---|---|---|---|---|
sts | boolean | mandatory | true: アクティブ (Lowレベル出力) false: アイドル (Highレベル出力) | |
return | boolean | - | true: 成功 false: 失敗 | SPIがオープンされていない場合もしくはチップセレクトモードが自動設定の場合、失敗となります。 |
オブジェクトの使用例
Sample 1
コマンドデータ0x9Fを書き込み、次に3バイト読み込むサンプルです。
チップセレクト信号の自動制御を使用します。
var NODE_NO = 1;
var SPI_DUMMY = 0xFF;
var spi = new SPI(NODE_NO);
if(!(spi instanceof SPI)) {
throw new TypeError("spi is not SPI Instance");
}
if(!spi.open(1,3,0,0)) { //10Mbps,Mode3,MSB,Auto
print('spi open error');
while(1); //Infinite loop
};
var sendCmdAndRecvRsp = function(cmd,len) {
var buf = new ArrayBuffer(1);
var arr = new Uint8Array(buf);
arr[0] = cmd;
return spi.writeRead(buf,len,SPI_DUMMY); //ArrayBuffer
}
var COMMAND = 0x9F;
var RECVLEN = 3;
var rBuf = sendCmdAndRecvRsp(COMMAND,RECVLEN);
if(!rBuf.byteLength) {
print('command error');
} else {
var rArr = new Uint8Array(rBuf);
for(var i=0; i<rArr.length; i++) {
print(i + ':' + '0x' + rArr[i].toString(16));
}
}
spi.close();
Sample 2
コマンドデータ0x9Fを書き込み、次に3バイト読み込むサンプルです。
チップセレクト信号の手動制御を使用します。
var NODE_NO = 1;
var SPI_DUMMY = 0xFF;
var spi = new SPI(NODE_NO);
if(!(spi instanceof SPI)) {
throw new TypeError("spi is not SPI Instance");
}
if(!spi.open(1,3,0,1)) { //10Mbps,Mode3,MSB,Manual
print('spi open error');
while(1); //Infinite loop
};
var sendCmdAndRecvRsp = function(cmd,len) {
var buf = new ArrayBuffer(1);
var arr = new Uint8Array(buf);
arr[0] = cmd;
var rbuf;
spi.setChipSelect(true); //chip select manual control
if(spi.write(buf)) {
rbuf = spi.read(len,SPI_DUMMY); //ArrayBuffer
} else {
rbuf = new ArrayBuffer(0); //write error
}
spi.setChipSelect(false); //chip select manual control
return rbuf;
}
var COMMAND = 0x9F;
var RECVLEN = 3;
var rBuf = sendCmdAndRecvRsp(COMMAND,RECVLEN);
if(!rBuf.byteLength) {
print('command error');
} else {
var rArr = new Uint8Array(rBuf);
for(var i=0; i<rArr.length; i++) {
print(i + ':' + '0x' + rArr[i].toString(16));
}
}
spi.close();
Sample 3
全二重通信のサンプルです。
コマンドデータ0x9Fとダミーデータ3バイトを書き込み、同時にデータを読み込みます。
var NODE_NO = 1;
var SPI_DUMMY = 0xFF;
var spi = new SPI(NODE_NO);
if(!(spi instanceof SPI)) {
throw new TypeError("spi is not SPI Instance");
}
if(!spi.open(1,3,0,0)) { //10Mbps,Mode3,MSB,Auto
print('spi open error');
while(1); //Infinite loop
};
var sendCmdAndRecvRsp = function(cmd) {
var buf = new ArrayBuffer(4);
var arr = new Uint8Array(buf);
arr[0] = cmd;
arr[1] = SPI_DUMMY;
arr[2] = SPI_DUMMY;
arr[3] = SPI_DUMMY;
return spi.writeReadFullDup(buf); //ArrayBuffer
}
var COMMAND = 0x9F;
var rBuf = sendCmdAndRecvRsp(COMMAND);
if(!rBuf.byteLength) {
print('command error');
} else {
var rArr = new Uint8Array(rBuf);
for(var i=0; i<rArr.length; i++) {
print(i + ':' + '0x' + rArr[i].toString(16));
}
}
spi.close();
Sample 4
コマンドデータを書き込み、次にステータスレジスタを確認して、準備完了を待つサンプルです。
数ミリ秒間のポーリング監視を行う場合、.readAndCompare()が有効です。
var NODE_NO = 1;
var SPI_DUMMY = 0xFF;
var spi = new SPI(NODE_NO);
if(!(spi instanceof SPI)) {
throw new TypeError("spi is not SPI Instance");
}
if(!spi.open(1,3,0,1)) { //10Mbps,Mode3,MSB,Manual
print('spi open error');
while(1); //Infinite loop
};
var sendCmd = function(cmd) {
var buf = new ArrayBuffer(1);
var arr = new Uint8Array(buf);
arr[0] = cmd;
spi.setChipSelect(true); //chip select manual control
var ret = spi.write(buf);
spi.setChipSelect(false); //chip select manual control
return ret;
}
var checkStatus = function(target,data_mask,timeout_ms) {
var cmd = 0x05; //read status
var buf = new ArrayBuffer(1);
var arr = new Uint8Array(buf);
arr[0] = cmd;
var ret = false;
spi.setChipSelect(true); //chip select manual control
if(spi.write(buf)) {
ret = spi.readAndCompare(target,data_mask,timeout_ms,SPI_DUMMY);
if(!ret) print('timeout!');
}
spi.setChipSelect(false); //chip select manual control
return ret;
}
var COMMAND;
var TARGET_BIT = 0x02;
var TIMEOUT_MS = 100;
COMMAND = 0x06;
if(!sendCmd(COMMAND)) print('command error');
//Wait for bit 1 of the status register to become 1.
print('status: ' + checkStatus(0x02,TARGET_BIT,TIMEOUT_MS));
COMMAND = 0x04;
if(!sendCmd(COMMAND)) print('command error');
//Wait for bit 1 of the status register to become 0.
print('status: ' + checkStatus(0x00,TARGET_BIT,TIMEOUT_MS));
spi.close();
Updated: 2021-08-23