Seeeduino XIAO 후면 패드를 GPIO로 사용



Seeeduino XIAO 뒷면에는 6 개의 패드가 있으며, 그 중 SWCLK (PA30) 및 SWDIO (PA31)는 GPIO 핀으로 사용할 수 있습니다.

TL;DR



보드 라이브러리 1.7.6 현재는 pinMode 또는 digitalWrite를 사용할 수 없습니다.
대신 레지스터를 직접 설정해야 합니다. digitalRead 도 마찬가지입니다.

pa30_pa31.ino
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의 경우 두 가지 추가 GPIO 핀을 사용할 수있는 이점이 큽니다.

pinMode 및 digitalWrite



서두에서 알 수 있듯이 불행히도 pinModedigitalWrite는 사용할 수 없습니다. 이상적으로 Arduino는 다음과 같은 스케치가 될 것입니다.

pa30_pa31_ideal.ino
// 注意: このスケッチは動作しない

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 의 핀 번호등의 대응표가 정의되고 있습니다.

variant.cpp(발췌)
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에 해당하는 엔트리가 없습니다.
pinModedigitalWrite 는 이 엔트리를 바탕으로, 지정된 핀 번호에 해당하는 포트명이나 속성을 참조해 적절한 레지스터를 설정합니다. 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에 대한 자세한 내용은 내부 구현을 참조하십시오.

좋은 웹페이지 즐겨찾기