ATmega328でSC16IS750を使う

GPIO制御


このモジュールにはプログラムから制御できるGPIOポートが8ポートあります。
そこで、GPIOポートの制御を試してみます。


使用するのは前回と同じこちらの ライブラリです。
GPIOに関する機能としては以下の関数を持っています。

void pinMode(uint8_t pin, uint8_t i_o)
指定したpin_number(0-7)のINPUT(=0)/OUTPUT(=1)を設定

void digitalWrite(uint8_t pin, uint8_t value);
指定したpin_number(0-7)のHIGH/LOWを設定

uint8_t digitalRead(uint8_t pin);
指定したpin_number(0-7)のHIGH/LOWを読み込み

uint8_t GPIOGetPortState(void);
8ビットデータでGPIO0〜7のHIGH/LOWを読み込み

void SetPinInterrupt(uint8_t io_int_ena);
8ビットデータでGPIO0〜7の入力割り込みを設定
割り込みが発生するとIRQがHIGH→LOWになる

void ModemPin(uint8_t gpio);
GPIO4〜7の4ビットをModemコントロールライン(RI、CD、DTR、DSR)として使うかどうかの指定
gpio=0 GPIO4〜7の4ビットをModemピンとして使う
gpio=1 GPIO4〜7の4ビットをGPIOとして使う
特に指定しなくてもGPIO4〜7の4つのポートはGPIOとして使えます

void GPIOLatch(uint8_t latch);
Latch機能の有効/無効の切り替え



今回はSPIを使い、以下のコードでGPIO7に繋いだLEDがLチカすることを確認しました。
#include <SPI.h>
#include <Wire.h>
#include <SC16IS750.h>
#include <string.h>

SC16IS750 spiuart = SC16IS750(SC16IS750_PROTOCOL_SPI,6);

//Pin 6 should be connected to CS of the module.

#define GPIO 7
 
void setup()
{
  Serial.begin(115200);
  Serial.println("Start testing");
  // UART to Serial Bridge Initialization
  spiuart.begin(9600);               //baudrate setting
  Serial.println("BAUDRATE SET");
  if (spiuart.ping()!=1) {
      Serial.println("Device not found");
      while(1);
  } else {
      Serial.println("Device found");
  }
  Serial.println("Start serial communication");

  spiuart.pinMode(GPIO, OUTPUT);
}

void loop()
{
  spiuart.digitalWrite(GPIO, HIGH);
  delay(1000);
  spiuart.digitalWrite(GPIO, LOW);
  delay(1000);
}



GPIOを入力として使う場合、データシートの13. Static characteristicsにGPIO0からGPIO7のHIGH-level input voltageは5.5Vと書かれていますので、
この電圧まで入力することができます。
以下のコードでGPIO0〜3に繋いだボタンの値を読めることを確認しました。
#include <SPI.h>
#include <Wire.h>
#include <SC16IS750.h>
#include <string.h>

SC16IS750 spiuart = SC16IS750(SC16IS750_PROTOCOL_SPI,6);

//Pin 6 should be connected to CS of the module.

#define  GPIO0 0
#define  GPIO1 1
#define  GPIO2 2
#define  GPIO3 3

void setup()
{
  Serial.begin(115200);
  Serial.println("Start testing");
  // UART to Serial Bridge Initialization
  spiuart.begin(9600);               //baudrate setting
  Serial.println("BAUDRATE SET");
  if (spiuart.ping()!=1) {
      Serial.println("Device not found");
      while(1);
  } else {
      Serial.println("Device found");
  }
  Serial.println("Start serial communication");

  spiuart.pinMode(GPIO0, INPUT);
  spiuart.pinMode(GPIO1, INPUT);
  spiuart.pinMode(GPIO2, INPUT);
  spiuart.pinMode(GPIO3, INPUT);
}

void loop()
{
  uint8_t value = spiuart.GPIOGetPortState();
  Serial.print("value = ");
  Serial.println(value,HEX);
  if ( (value & 0x01) == 0x01) Serial.println("GPIO0 ON");
  if ( (value & 0x02) == 0x02) Serial.println("GPIO1 ON");
  if ( (value & 0x04) == 0x04) Serial.println("GPIO2 ON");
  if ( (value & 0x08) == 0x08) Serial.println("GPIO3 ON");
  delay(1000);
}



入力割り込みもできるはずなんですが、色々試しましたが成功していません。
データシートによると、レジスターを設定することで、GPIOの値に変化が有るとIRQピンの出力がLOWになると書かれています。
Schematicによると、IRQピンは内部でPullUpされているはずなんですが、テスターで当たってみてもPullUp抵抗は見当たりま せん。
そこで、IRQピンを1K抵抗でPullUpしてみましたが、ボタンを押してもIRQピンの出力レベルに変化が有りません。
正しく動くようになったら追記します。

<追記>
ボードの配線をテスターで当たったら理由が分かりました。
チップのIRQピンからボード上のPullUp抵抗まで結線されていますが、その先がどこにも繋がっていません。
つまり、モジュールのIRQピンはN/Cです。
これではどのような割り込みも拾えません。
</追記>

続く...