Seeeduino XIAO の背面には 6 つのパッドがあり、そのうち SWCLK (PA30) と SWDIO (PA31) は GPIO ピンとして使用できます。
TL;DR
ボードライブラリ 1.7.6 時点では pinMode
や digitalWrite
は使えません。
代わりにレジスタを直接設定する必要があります。digitalRead
も同様です。
void setup() {
// instead of pinMode(PA30, OUTPUT) and pinMode(PA31, OUTPUT)
(&(PORT->Group[PORTA]))->PINCFG[30].reg = (uint8_t)(PORT_PINCFG_INEN);
(&(PORT->Group[PORTA]))->PINCFG[31].reg = (uint8_t)(PORT_PINCFG_INEN);
(&(PORT->Group[PORTA]))->DIRSET.reg = (1 << 30);
(&(PORT->Group[PORTA]))->DIRSET.reg = (1 << 31);
}
void loop() {
// instead of digitalWrite(PA30, HIGH) and digitalWrite(PA31, HIGH)
(&(PORT->Group[PORTA]))->OUTSET.reg = (1 << 30);
(&(PORT->Group[PORTA]))->OUTSET.reg = (1 << 31);
delay(1000);
// instead of digitalWrite(PA30, LOW) and digitalWrite(PA31, LOW)
(&(PORT->Group[PORTA]))->OUTCLR.reg = (1 << 30);
(&(PORT->Group[PORTA]))->OUTCLR.reg = (1 << 31);
delay(1000);
}
SWCLK/SWDIO パッド
SWD用に用意されたパッドです。Seeeduino XIAO では基板背面に配置されています。上記の XIAO の回路図(該当部分のみ抜粋)からわかるとおり、これらのパッドに繋がっているピンは PA30, PA31 という PORTA の GPIO として利用できます。
他の背面パッドと同様に直接はんだづけしない限りは利用機会は少ないでしょう。しかし、利用できる物理ピン数が限られている XIAO にとって、追加で 2 つも GPIO ピンが使えるメリットは大きいです。
pinMode と digitalWrite
冒頭で示したとおり、残念ながら pinMode
と digitalWrite
は使えません。理想では、Arduino であれば以下のようなスケッチになるはずです。
// 注意: このスケッチは動作しない
void setup() {
pinMode(PA30, OUTPUT);
pinMode(PA31, OUTPUT);
}
void loop() {
digitalWrite(PA30, HIGH);
digitalWrite(PA31, HIGH);
delay(1000);
digitalWrite(PA30, HIGH);
digitalWrite(PA31, HIGH);
delay(1000);
}
実際にはどちらの関数も正しく動作しません。原因は variant.cpp にあります。
variant.cpp には Arduino で指定するピン番号と SAMD21G18 のピン番号などの対応表が定義されています。
const PinDescription g_APinDescription[]=
{
// 0..10 - Digitabl & Analog pins
{ PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0]
{ PORTA, 4, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // ADC/AIN[4]
{ PORTA, 10, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel18, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_10 },
{ PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel19, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_11 },
// ... (snip) ...
// 14..16 - USB
// --------------------
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE } // USB/DP
} ;
この対応表には PA30, PA31 にあたるエントリがありません。
pinMode
と digitalWrite
はこのエントリをもとに、指定されたピン番号に該当するポート名や属性を参照し適切なレジスタを設定します。PA30, PA31 のエントリがないために適切なレジスタが判明せず動作しません。
レジスタを直接設定
variant.cpp は対応していませんが PA30, PA31 に相当するレジスタは存在します。
pinMode(PA30, OUTPUT)
に対応する指定は以下になります。
(&(PORT->Group[PORTA]))->PINCFG[30].reg = (uint8_t)(PORT_PINCFG_INEN);
(&(PORT->Group[PORTA]))->DIRSET.reg = (1 << 30);
digitalWrite(PA30, HIGH)
および digitalWrite(PA30, LOW)
に対応する指定は以下になります。
(&(PORT->Group[PORTA]))->OUTSET.reg = (1 << 30); // HIGH
(&(PORT->Group[PORTA]))->OUTCLR.reg = (1 << 30); // LOW
PA31 も同様です。
これ以外のピンモードや digitalRead
については 内部実装 を参照してください。