2016年10月31日月曜日

mbedのPinDetectをHackしてMCP23S17で使えるようにする。

mbedのチャタリング対策用のライブラリのPinDetectのソースをよく見てみると割込みではなくてポーリングで処理していた。

中で使っているのはDigitalInなのでこれをMCP23S17経由で読み取れるようにしてみた。

MCP23S17のPortB:0だけトグル動作。

mbed repository:
https://developer.mbed.org/users/ryood/code/ExioController_Test/ Revision:4

ExioController_Test/main.cpp
#include "mbed.h"
#include "rtos.h"
#include "ExioMcp23s17.h"
#include "ExioMcp23s17DigitalIn.h"
#include "ExioMcp23s17PinDetect.h"

SPI Spi(PC_12, PC_11, PC_10); // SPI3: mosi, miso, sclk
//SPI Spi(PA_7, PA_6, PA_5); // SPI1:  mosi, miso, sclk

// MExioMcp23s17(int hardwareaddress, SPI& spi, PinName nCs, PinName nReset);
ExioMcp23s17 Exio(0x00, Spi, PD_2, PA_13);

// トグル動作
bool pb0state = false;
void pb0Falled() {
    uint8_t data = Exio.readPort(ExioPortA);
    pb0state = !pb0state;
    if (pb0state) {
        data |= (1 << 0);
    } else {
        data &= ~(1 << 0);
    } 
    Exio.writePort(ExioPortA, data);
}

void pb1Falled() {
    Exio.writePort(ExioPortA, (1 << 1));
}

void pb2Falled() {
    Exio.writePort(ExioPortA, (1 << 2));
}

void pb3Falled() {
    Exio.writePort(ExioPortA, (1 << 3));
}

void pb4Falled() {
    Exio.writePort(ExioPortA, (1 << 4));
}

void pb5Falled() {
    Exio.writePort(ExioPortA, (1 << 5));
}

void pb6Falled() {
    Exio.writePort(ExioPortA, (1 << 6));
}

void pb7Falled() {
    Exio.writePort(ExioPortA, (1 << 7));
}

void ExioMcp23s17PinDetectTest()
{
    printf("\r\n\n*** ExioMcp23s17PinDetect test ***\r\n");
    
    Exio.reset();
    
    // set PORTA as output
    Exio.ioDirection(ExioPortA, 0x00);
    
    // create PORTB pins as inputs via ExioMcp23s17PinDetect
    ExioMcp23s17PinDetect PinB0(Exio, ExioPortB, 0);
    ExioMcp23s17PinDetect PinB1(Exio, ExioPortB, 1);
    ExioMcp23s17PinDetect PinB2(Exio, ExioPortB, 2);
    ExioMcp23s17PinDetect PinB3(Exio, ExioPortB, 3);
    ExioMcp23s17PinDetect PinB4(Exio, ExioPortB, 4);
    ExioMcp23s17PinDetect PinB5(Exio, ExioPortB, 5);
    ExioMcp23s17PinDetect PinB6(Exio, ExioPortB, 6);
    ExioMcp23s17PinDetect PinB7(Exio, ExioPortB, 7);

    // assign callback functions
    PinB0.attach_asserted(&pb0Falled);
    PinB0.setAssertValue(0);
    PinB0.setSampleFrequency();
    
    PinB1.attach_asserted(&pb1Falled);
    PinB1.setAssertValue(0);
    PinB1.setSampleFrequency();
    
    PinB2.attach_asserted(&pb2Falled);
    PinB2.setAssertValue(0);
    PinB2.setSampleFrequency();
    
    PinB3.attach_asserted(&pb3Falled);
    PinB3.setAssertValue(0);
    PinB3.setSampleFrequency();
    
    PinB4.attach_asserted(&pb4Falled);
    PinB4.setAssertValue(0);
    PinB4.setSampleFrequency();
    
    PinB5.attach_asserted(&pb5Falled);
    PinB5.setAssertValue(0);
    PinB5.setSampleFrequency();
    
    PinB6.attach_asserted(&pb6Falled);
    PinB6.setAssertValue(0);
    PinB6.setSampleFrequency();
    
    PinB7.attach_asserted(&pb7Falled);
    PinB7.setAssertValue(0);
    PinB7.setSampleFrequency();
    

    // LED Check (PortA)
    for (int i = 0; i < 8; i++) {
        Exio.writePort(ExioPortA, 1 << i);
        wait(0.1);
    }
    Exio.writePort(ExioPortA, 0x00);
    
    while (true) {
    }
}

int main()
{
    ExioMcp23s17PinDetectTest();
}

2016年10月30日日曜日

I/OエキスパンダーのMCP23S17をNucleo F401RE(mbed)で使ってみる。 その2

MCP23S17からの割込みが効かないとプログラミングに制約が出るのでもう少し。

前回割り込みが効かなかったのはプログラミングのミスだったと思う。mbedのMCP23S17用のライブラリもhttps://developer.mbed.org/users/stjo2809/code/MCP23S17/に変更して割込みのテストをしてみた。こちらのLibraryはhttps://developer.mbed.org/users/romilly/code/MCP23S17/より低レベルというかレジスタ操作のラッパーという感じだ。

配線図


割込み線(MCP23S17 -> Nucreo)をPA_14に割り当て、ResetをPA_13に割り当てた。Resetは別に使わなくてもいい。

(追記:2016.11.09)

起動時にResetを掛けておかないとMCP23S17がうまく動作しないようです。

(/追記)

mbed repository:
https://developer.mbed.org/users/ryood/code/Nucleo_MCP23S17_Test/ Revision:3

/*
 * MCP23S17 Test
 *
 * MCP23S17 Library:
 * https://developer.mbed.org/users/stjo2809/code/MCP23S17/
 *
 * mbed:  rev 121
 * mbed-rtos: rev 117
 *
 * Created: 2016.10.28
 *
 */

#include "mbed.h"
#include "rtos.h"
#include "MCP23S17.h"

SPI Spi(PC_12, PC_11, PC_10); // SPI3: mosi, miso, sclk
//SPI Spi(PA_7, PA_6, PA_5); // SPI1:  mosi, miso, sclk

InterruptIn Mcp23s17Int(PA_14);

// MCP23S17(int hardwareaddress, SPI& spi, PinName nCs, PinName nReset);
MCP23S17 Mcp23s17(0x00, Spi, PD_2, PA_13);

void dataChanged()
{
    char data = Mcp23s17.intcapb();
    wait_us(1);
    Mcp23s17.gpioa(data);
}

int main()
{
    printf("\r\n\n*** MCP23S17 Test ***\r\n");

    // Reset MCP23S17
    Mcp23s17.reset();
    
    // PORTA output
    Mcp23s17.iodira(0x00);

    // PORTB input
    Mcp23s17.iodirb(0xFF);
    // PORTB pull-up
    Mcp23s17.gppub(0xFF);
    // PORTB invert polarity
    Mcp23s17.ipolb(0xFF);
    // PORTB enable on change interrupt
    Mcp23s17.gpintenb(0xFF);
    
    // Attach the callback function
    Mcp23s17Int.rise(&dataChanged);
    
    // LED Check
    for (int i = 0; i < 8; i++) {
        Mcp23s17.gpioa(1 << i);
        wait(0.1);
    }
    Mcp23s17.gpioa(0x00);
    
    while (true) {
    }
}

SPI信号


MOSI

ch1:sck ch2:mosi

拡大

2byte目と3byte目の間で一瞬MOSIがLになっている。SPI Mode 0の場合SCKの立ち上がりで評価するので問題ないが、高速な場合誤動作するかも?

MISO

ch1:sck ch2:miso

拡大


MISOが無出力のとき、Lレベルがふらふらしているので、Pull-Downしておいた方が良さそう。

MISO 10kΩでPull-down

MISO 3.3kΩでPull-down

3.3kΩの方が多少きれい。3.3V駆動でロジック・レベルがHの時3.3V/3.3kΩ=1mA消費することになる。

CS

ch1:sck ch2:cs
char data = Mcp23s17.intcapb();
Mcp23s17.gpioa(data);
と読み込み、書き込みを連続した状態で測定。(Read:3byte、Write:3byte)誤動作の可能性があるので間にウェイトを入れた方が良さそう。

Interrupt

ch1:sck ch2:intb

Active-highに設定しているのでPinの状態に変化があった時INTBがHになり、INTCAPBを読み込んだ時Lに戻るのでこれで良さそう。

メモ:


ベースマシンはNucleo2台使いをやめてI/Oエクスパンダ―でI/Oピンを増やす方向で。SPI通信の割込みが効かなくなる原因追及に疲れたし(^q^; 細かい実験用にNucleoを1台空けたい。

mbedのクラスが使えなくなるので、タクトスイッチ(トグル動作)、ロータリーエンコーダー、キーパッドの読み取りを自前で書かないとダメか(@@;

2016年10月28日金曜日

I/OエキスパンダーのMCP23S17をNucleo F401RE(mbed)で使ってみる。

I/OエキスパンダーのMCP23S17をNucleo F401RE(mbed)で使ってみる。

ライブラリはRomilly CockingさんのMCP23S17 https://developer.mbed.org/users/romilly/code/MCP23S17/を使った。

配線図


配線はArduinoの場合とほぼ同じ。Nucleo F401REにはSPIが3つあるのでSPI3を使ってみた。

mbed:
https://developer.mbed.org/users/ryood/code/Nucleo_MCP23S17_Test/ Revision:2

/*
 * MCP23S17 Test
 *
 * https://developer.mbed.org/users/romilly/code/MCP23S17/
 *
 * mbed:  rev 121
 * mbed-rtos: rev 117
 *
 * Created: 2016.10.28
 *
 */

#include "mbed.h"
#include "rtos.h"
#include "MCP23S17.h"

#define OPCODE (0x40)

SPI Spi(PC_12, PC_11, PC_10); // SPI3: mosi, miso, sclk
//SPI Spi(PA_7, PA_6, PA_5); // SPI1:  mosi, miso, sclk

// MCP23S17(SPI& spi, PinName ncs, char writeOpcode);
MCP23S17 Mcp23s17(Spi, PD_2, OPCODE);

int main()
{
    printf("\r\n\n*** MCP23S17 Test ***\r\n");

    // PORTA output
    Mcp23s17.direction(PORT_A, 0x00);

    // PORTB input
    Mcp23s17.direction(PORT_B, 0xFF);
    // PORTB pull-up
    Mcp23s17.configurePullUps(PORT_B, 0xFF);
    
    // LED Check
    for (int i = 0; i < 8; i++) {
        Mcp23s17.write(PORT_A, (1 << i));
        wait(0.2);
    }
    Mcp23s17.write(PORT_A, 0x00);
    
    while (true) {
        char data = ~Mcp23s17.read(PORT_B);
        Mcp23s17.write(PORT_A, data);
        
        //printf("%02x\r\n", data);
    }
}

メモ:

ポーリングだとSPI3を使っても動作できたが、割り込みは試してみたがうまく動かせなかった。MCP23S17から割込み信号が出力されない。

ポーリングで動作させてもオシロのプローブをSCK/MOSIあたりにあてるとLEDがふんわりと明るくなって点滅する。外せば正常。


I/OエキスパンダーのMCP23S17をArduinoで使ってみる。

Nucleo64を使っても入出力ピンが足りなくなりそうなので、IOエキスパンダーのMCP23S17を仕入れてみた。まずはArduinoでテスト。

「真夜中の工作室」さんの記事「きむ茶工房ガレージハウス」さんの記事を参考にした。MCP23008/MCP23S08は8bitバージョンで日本語のDATASHEETがあるので、こちらも参考にした。

配線図

<追記:20170920> ブレッドボード図のArduinoの10番ピン~13番ピンがずれていたのをご指摘いただいたので修正しました。 </追記>


GPAとGPBで8bitずつ使うのが簡単そうなので、GPAをLED表示、GPBをタクトスイッチの入力として使った。また、INTA/INTBという割り込み線が用意されているので、これをArduinoの外部割込みのINT0(D2)につないで、タクトスイッチを押したときに割込みを発生させて、割込み処理ルーチン内でLEDを点灯させるようにした。

ソースコードは「真夜中の工作室」さんのものを元にした。ArduinoのSPIライブラリを使っていないので、素のAVRその他にも移植しやすいと思う。

Arduinoのスケッチ


/*
  EXIO-SPI Test
  MCP23S17
  CS:LowActive
  MSB first
  SCK rising

  2016.10.28 created
*/

//SPI IF
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//Interrupt
#define INTPIN 2

//MCP23S17 Device OPCODE
#define HWADDW 0x40
#define HWADDR 0x41

volatile byte address = 0;
volatile byte data = 0;

//SPI 関数
byte spi_transfer(volatile byte data)
{
  SPDR = data;                    // Start the transmission

  while (!(SPSR & (1 << SPIF)))   // Wait the end of the transmission
  {
  };

  return SPDR;                    // return the received byte
}

void setup()
{
  //--------------------------------------------------------------
  //pinmode 設定
  
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK, OUTPUT);
  pinMode(SLAVESELECT, OUTPUT);
  digitalWrite(SLAVESELECT, HIGH); //disable device

  //--------------------------------------------------------------
  //SPI設定
  
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on rising edge of clk,system clock/2 rate (fastest)
  SPCR = 0x50;
  SPSR = 0x01; // SPI2X:1

  //--------------------------------------------------------------
  //MCP23S17 初期化
  
  // IOCON(0x0A):0x20
  //  BANK  :0
  //  MIRROR:0
  //  SEQOP :1
  //  DISSLW:0
  //  HAEN  :0
  //  ODR   :0
  //  INTPOL:0
  //  -     :0
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);   //send MSByte address first
  address = 0x0A;
  spi_transfer(address);   //send MSByte address first
  data = 0x20;
  spi_transfer(data);      //send MSByte DATA
  digitalWrite(SLAVESELECT, HIGH); //release chip

  // GPA -----------------------------------------------
  // Set as outputs
  // IODIRA(0x00): 1:input 0:output
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);   //send MSByte address first
  address = 0x00;
  spi_transfer(address);   //send MSByte address first
  data = 0x00;
  spi_transfer(data);      //send MSByte DATA
  digitalWrite(SLAVESELECT, HIGH); //release chip

  // GPB -----------------------------------------------
  // Set as inputs
  // IODIRB(0x01): 1:input 0:output
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);   //send MSByte address first
  address = 0x01;
  spi_transfer(address);   //send MSByte address first
  data = 0xFF;
  spi_transfer(data);      //send MSByte DATA
  digitalWrite(SLAVESELECT, HIGH); //release chip

  // Pull-up
  // GPPUB(0x0D): 1:pull-up enable 0:pull-up disable
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);   //send MSByte address first
  address = 0x0D;
  spi_transfer(address);   //send MSByte address first
  data = 0xFF;
  spi_transfer(data);      //send MSByte DATA
  digitalWrite(SLAVESELECT, HIGH); //release chip
  
  // 入力ピンの論理値を反転
  // IPOLB(0x03): 1:opposite 0:same 
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);   //send MSByte address first
  address = 0x03;
  spi_transfer(address);   //send MSByte address first
  data = 0xFF;
  spi_transfer(data);      //send MSByte DATA
  digitalWrite(SLAVESELECT, HIGH); //release chip
  
  // Interrupt-on-change enable
  // GPINTENB(0x05): 1:enable 0:disable
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);   //send MSByte address first
  address = 0x05;
  spi_transfer(address);   //send MSByte address first
  data = 0xFF;
  spi_transfer(data);      //send MSByte DATA
  digitalWrite(SLAVESELECT, HIGH); //release chip
  
  //--------------------------------------------------------------
  //外部割込み
  pinMode(INTPIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INTPIN), dataChanged, FALLING); 
  
  Serial.begin(9600);
  Serial.println("*** MCP23S17 Interrupt Test ***");
  
  // LED Check
  for (int i = 0; i < 8; i++) {
    // Write data (LED)
    // GPIOA(0x12)
    digitalWrite(SLAVESELECT, LOW);
    spi_transfer(HWADDW);
    spi_transfer(0x12);
    spi_transfer(1 << i);
    digitalWrite(SLAVESELECT, HIGH);
    delay(100);
  }
  // Write data (LED)
  // GPIOA(0x12)
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);
  spi_transfer(0x12);
  spi_transfer(0x00);
  digitalWrite(SLAVESELECT, HIGH);
}

void dataChanged() {
  // Read data (SW)
  // INTCAPB(0x11)
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDR);
  spi_transfer(0x11);
  data = spi_transfer(0x00);
  digitalWrite(SLAVESELECT, HIGH);
  
  // Write data (LED)
  // GPIOA(0x12)
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(HWADDW);
  spi_transfer(0x12);
  spi_transfer(data);
  digitalWrite(SLAVESELECT, HIGH);
}

void loop() {
}

メモ:


SPIの送受信のところが冗長だが、関数にまとめると動作しなくなったので深追いせずにそのままべた書き。

DATASHEETを読むと、冒頭から「BANK」とか「Sequencial mode」とか出てきてややこしい。BANKは8bit版のMCP23008/MCP23S08にはないのでMCP23S17の英文のDATASHEETを読まないとわからない。

Addressというのがデバイスごとのアドレス(15Pin~17PinのA0~A2で設定)と、レジスタ・アドレスがあるがBANKやSequencialの説明にあるアドレスは、レジスタ・アドレスのもの。

設定で大事なのはIOCONで8bit版とも違っているのでここをいじる時は注意が必要。

データの送受信は
1byte目 0b0100(固定) | デバイス・アドレス:3bit | R/W:1bit
2byte目 レジスタ・アドレス
3byte目 送受信データ
という手順で行う。受信の場合はMasterからダミーデータを送信して受信した。

I2C版のMCP23017も慣れれば使えそうだが、さらにややこしそうな感じだ。通信速度も速いので線数が許すなら最初はSPI版の方が楽かも。

SPI/I2C経由でI/Oを16bit拡張するならATMega328Pやピンコンパチで値段の安いATMega88VをSlaveとして使うという手もある。

2016年10月26日水曜日

SPI バス・バッファ(TC74HC541)基板の設計

回路図

基板図

部品並べ

SPI信号を補強するバス・バッファと8bitの状態表示用のLEDを載せた。

2016年10月23日日曜日

ベースマシン SequencerのSPI出力にバッファ(TC74HC541)を入れてみる。


UI Controller <-> SequncerのSPI通信でハマっているが、SequencerからDCO、DCF、DCAをコントロールするのにもSPIを使っている。こちらはMISOはなく、Master->Slaveの一方通行なので多少気が楽だ。

以前かんたんにテストしたTC74HC541を使ってバッファリングしてみた(参考:「高速バッファICのTC74HC541の出力波形を見てみる。」)


配線図


波形が細かいSCKとMOSIにだけ、ダンピング抵抗を入れてみた。各Slave用のCSやDCAで使っているMCP4922のLDACは波形荒いし配線がめんどくさいので今回は端折った。

SPI信号波形


バッファからの出力付近(ブレッドボード上)で測定。

バッファなし

ch1: MOSI ch2:SOK

74HC541(ダンピング抵抗なし)

74HC541(ダンピング抵抗33Ω)

Slave(PSoC4 DCO)付近で測定。

74HC541(ダンピング抵抗33Ω)

メモ:

バッファリングの効果絶大。

74HC541が強力なのか33Ω程度のダンピング抵抗は入れても入れなくてあまり変わらないようだ。


ベースマシン ファームウェアを少し修正

UI Controller(SPI Master)の初期化時にSequencer(SPI Slave)にリセットをかけるシーケンスを追加。

UI ControllerとSequencerに共通な定義を"BaseMachineCommon.h"として分離。

UI Controller
https://developer.mbed.org/users/ryood/code/BaseMachine_UI_Controller/

Sequencer
https://developer.mbed.org/users/ryood/code/BaseMachine_Sequencer/ Revision:43

Github:
https://github.com/ryood/BaseMachine

SPIのダンピング抵抗値


Master Master側 Slave側 Slave
SCK 33Ω SCK
MISO 47Ω MISO
MOSI 33Ω MOSI
CS 33Ω CS
INT 47Ω INT

メモ:

SPIの信号線にダンピング抵抗を入れて波形を整えてみたが、Master側がMOSIMISOを拾わなくなることがある。条件は不明。一旦動作しなくなるとResetをかけてもダメな場合があり、SPIのケーブルを挿し直したりすれば治る。オシロのプローブをあてても確実ではなくなった。

MISO(Slave->Master)の動作だけが不安定な様で、これがうまく動かないとシーケンス再生中にLCDに今演奏しているステップが表示できなくなる。この機能を諦めればMISOはなくても良いので現状のままで進めてみる。

Slave->Masterへの通信はファームウェア・レベルでまだ色々試せるし、最悪I2Cや自前の信号線を用意することも考えておく。

発生条件がよくわからないので、この問題にこだわっているとなかなかやる気が出ない(^q^;

2016年10月20日木曜日

ベースマシン UI ControllerとSequencerのSPI通信でSequencer(Slave)の近くにダンピング抵抗を入れてみる。

UI Controller(Master)側のシールド上で抵抗を入れたり、コンデンサを入れたりいろいろしてみたが、長時間動作させたりRESETしたりすると通信がうまくいかなくなる場合がある。

オシロのプローブを当てるとほとんどの場合動作するので原因特定が難しい。思いつきだが、Sequencer(Slave)の出力ピンの近くにダンピング抵抗を入れてようすをみることにした。

Nucleo BoardのMorphoヘッダはオスなので、オス - <メス-抵抗-オス> - メスという風になるように抵抗を加工した。


QIピンのオスとメスを抵抗に直に圧着して、熱圧縮チューブで絶縁した。

ピンヘッダとピンソケットを1Pinに分割してはんだ付けすれば同じようにできるが、QIピンのメリットは
ピンヘッダやピンソケット(のプラスチック部分)に比べて細いのでピンが混み合っているところでも挿せる。
デメリットは
値段が高い。
慣れないととうまく圧着できないし、慣れてもたまにミスるので結構な出費になります。
QIピンは専用?のカバーが売っているので使ってるが、1Pの場合は熱圧縮チューブでカバーしたほうが扱いやすいと思う。

Sequencer(Slave)のMorpho Headerに挿したようす


Sequencer(Slave)のSPIのMISOとSlave->Masterへの割り込み線にだけダンピング抵抗を入れた。

MISO信号波形


Master側の入力部分で測定した。

ダンピング抵抗なし


ch1:MISO ch2:SCK

ダンピング抵抗 47Ω


ダンピング抵抗 100Ω


ダンピング抵抗 220Ω


MISO信号波形(拡大)


ダンピング抵抗なし

ch1:MISO ch2:SCK

ダンピング抵抗 47Ω

ダンピング抵抗 100Ω

ダンピング抵抗 220Ω

Slave->Master割り込み線


ファームウェアを変更してH/Lの間にwait_us(1)を入れてみた。波形の幅が広くなったので適当でよさそう。

ダンピング抵抗なし

ch1:Interrupt(Slave->Master)

ダンピング抵抗47Ω


PSoC DCOにショットキーバリアダイオードで電源の逆接続対策をしてみる。

ダイオードで電源の逆接続に対策する実験」で試したのをPSoC4 DCOに施してみた。


回路図

基板図

Github:
https://github.com/ryood/PSoC4_DCO/tree/master/PSoC%204%20Prototyping%20Kit%20DCO

2016年10月16日日曜日

ベースマシン UI Controller ダンピング抵抗用シールドの製作


回路図

基板図

ダンピング抵抗はピンソケットを使って差し替えられるようにした。シールドを載せるとNucleoボード上のリセットボタンが押せなくなるので、シールド上にリセットボタンを付けた。

Master側からSlaveにリセットをかけられるようにResetボタンとは別にSlaveのReset端子につなぐGPIOを1本割り当てた。

配線図

UI Controller(SPI Master)

Sequencer(SPI Slave)


SPI信号波形


ダンピング抵抗はすべて33Ωにして測定


MISO

ch1:MISO(ダンピング抵抗のSlave側) ch2:sck


ch1:MISO(ダンピング抵抗のMaster側) ch2:sck

MOSI

ch1:MOSI(ダンピング抵抗のSlave側) ch2:sck

CS

ch1:CS(ダンピング抵抗のSlave側) ch2:sck

Slave->Master Interrupt

ch1:Interupt(ダンピング抵抗のSlave側)


ch1:Interupt(ダンピング抵抗のMaster側)

メモ:


Masterの出力の近くにダンピング抵抗を入れてSCK、MOSI、CSは波形がきれいになったようだ。(参考「ベースマシン UI ControllerとSequencerのSPIの信号線にダンピング抵抗を入れてみる。のSPI信号の波形」

MISOとInterruptはSlaveからの出力なのでMasterの近くに抵抗を入れてもやはりあまり効果がない。Sequencer(Slave)の近くに抵抗を入れるのは少々難しそうなので、波形なまるのを覚悟のうえでもっと抵抗値をあげてみる?ケーブルを加工してダンピング抵抗を入れてみる?

まだときどきSlave->Masterの通信がうまくいかない。オシロスコープのプローブをあてておくと動作することが多い。ノイズや振動の影響で読み取りをミスってるのかなあ??プローブ内のCR類がたまたま、うまい具合に波形を整形してくれているのか。

ToDo:


UI Controller <-> Sequencer間のSPI通信の信頼性をあげる。

Sequencer→DCO、DCF、DCAのSPI信号を補強する(こちらも動作があやしい感じのときがある)。現状でもSlaveが3つあるので(CSがインアクティブの時はSlave側はHiZになってると思うが)余裕をもってドライブできるようにバッファICを入れてみる。

Sequencerのファームウェアを点検して休符時にブツブツ言うのを修正する。Durationが短いときにブツブツ言うようだ。←めんどくさい(TqT;

4x4キーパッドを使ってシーケンスの切り替えができるようにする。

やりたいことはいろいろあるが、安定して使えないと楽器として使えないので安定度を上げるのが最優先だ。