ここを観に来る人はすでにXiaoについていろいろと調べていることでしょう。基本としてXiaoはUART、I2C、SPIが各1portづつ使用できる。
ところがCPUの機能SERCOMを使用すると3portを好きに割り当てられる。(SPIは使用する端子数が多いので2portまで)
ここではSERCOMの設定とIDEのメニューで変更できるように記述を掲載したいと思います。
このやり方を見つけるのにここのサイトを参考にしました。
次の3つのファイルを書き換えます。
C:\Users\ユーザー名\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.7.9\variants\XIAO_m0\variant.h
/* * SPI Interfaces */ #define SPI_INTERFACES_COUNT 0 #ifndef DNO_SERCOM0_INTERFACE #ifndef DSERCOM0_I2C #ifndef DSERCOM0_USART //#ifdef DSERCOM0_SPI // SPI interface for QSPI flash #define PIN_SPI_MISO (9u) #define PIN_SPI_SCK (8u) #define PIN_SPI_MOSI (10u) #define PERIPH_SPI sercom0 #define PAD_SPI_TX SPI_PAD_2_SCK_3 // MOSI / SCK #define PAD_SPI_RX SERCOM_RX_PAD_1 // MISO static const uint8_t SS = 4; static const uint8_t MOSI = PIN_SPI_MOSI; static const uint8_t MISO = PIN_SPI_MISO; static const uint8_t SCK = PIN_SPI_SCK; //#endif #endif #endif #endif #ifndef DNO_SERCOM2_INTERFACE #ifndef DSERCOM2_I2C #ifndef DSERCOM2_USART //#ifdef DSERCOM2_SPI // SPI interface for QSPI flash #define PIN_SPI_MISO1 (5u) #define PIN_SPI_SCK1 (3u) #define PIN_SPI_MOSI1 (2u) #define PERIPH_SPI sercom2 #define PAD_SPI_TX SPI_PAD_2_SCK_3 // MOSI / SCK #define PAD_SPI_RX SERCOM_RX_PAD_1 // MISO static const uint8_t SS2 = 1; static const uint8_t MOSI2 = PIN_SPI_MOSI1; static const uint8_t MISO2 = PIN_SPI_MISO1; static const uint8_t SCK2 = PIN_SPI_SCK1; //#endif #endif #endif #endif /* * Wire Interfaces */ #define WIRE_INTERFACES_COUNT 0 #ifndef DNO_SERCOM2_INTERFACE #ifndef DSERCOM2_SPI #ifndef DSERCOM2_USART //#ifdef DSERCOM2_I2C // "external" public i2c_1 interface #define PIN_WIRE_SDA (4u) #define PIN_WIRE_SCL (5u) #define PERIPH_WIRE sercom2 #define WIRE_IT_HANDLER SERCOM2_Handler static const uint8_t SDA = PIN_WIRE_SDA; static const uint8_t SCL = PIN_WIRE_SCL; //#endif #endif #endif #endif #ifndef DNO_SERCOM0_INTERFACE #ifndef DSERCOM0_SPI #ifndef DSERCOM0_USART //#ifdef DSERCOM0_I2C // "external" public i2c_1 interface #define PIN_WIRE1_SDA (1u) #define PIN_WIRE1_SCL (9u) #define PERIPH_WIRE sercom0 #define WIRE_IT_HANDLER SERCOM0_Handler static const uint8_t SDA1 = PIN_WIRE1_SDA; static const uint8_t SCL1 = PIN_WIRE1_SCL; //#endif #endif #endif #endif #ifndef DNO_SERCOM4_INTERFACE #ifndef DSERCOM4_USART //#ifdef DSERCOM4_I2C // "external" public i2c_1 interface #define PIN_WIRE2_SDA (6u) #define PIN_WIRE2_SCL (7u) #define PERIPH_WIRE sercom4 #define WIRE_IT_HANDLER SERCOM4_Handler static const uint8_t SDA2 = PIN_WIRE2_SDA; static const uint8_t SCL2 = PIN_WIRE2_SCL; //#endif #endif #endif // USB // --- #define PIN_USB_HOST_ENABLE (14ul) #define PIN_USB_DM (15ul) #define PIN_USB_DP (16ul) // I2S Interfaces // -------------- #define I2S_INTERFACES_COUNT 3 // Serial ports // ------------ #ifdef __cplusplus #include "SERCOM.h" #include "Uart.h" // Instances of SERCOM extern SERCOM sercom0; extern SERCOM sercom1; extern SERCOM sercom2; extern SERCOM sercom3; extern SERCOM sercom4; extern SERCOM sercom5; #ifndef DNO_SERCOM4_INTERFACE #ifndef DSERCOM4_I2C //#ifdef DSERCOM4_USART extern Uart Serial1; #define PIN_SERIAL1_TX (6ul) #define PIN_SERIAL1_RX (7ul) #define PAD_SERIAL1_TX (UART_TX_PAD_0) #define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) //#endif #endif #endif #ifndef DNO_SERCOM0_INTERFACE #ifndef DSERCOM0_I2C #ifndef DSERCOM0_SPI //#ifdef DSERCOM0_USART extern Uart Serial2; #define PIN_SERIAL2_TX (10ul) #define PIN_SERIAL2_RX (8ul) #define PAD_SERIAL2_TX (UART_TX_PAD_2) #define PAD_SERIAL2_RX (SERCOM_RX_PAD_3) //#endif #endif #endif #endif #ifndef DNO_SERCOM2_INTERFACE #ifndef DSERCOM2_I2C #ifndef DSERCOM2_SPI //#ifdef DSERCOM2_USART extern Uart Serial3; #define PIN_SERIAL3_TX (4ul) #define PIN_SERIAL3_RX (5ul) #define PAD_SERIAL3_TX (UART_TX_PAD_0) #define PAD_SERIAL3_RX (SERCOM_RX_PAD_1) //#endif #endif #endif #endif #endif // __cplusplus // These serial port names are intended to allow libraries and architecture-neutral // sketches to automatically default to the correct port name for a particular type // of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, // the first hardware serial port whose RX/TX pins are not dedicated to another use. // // SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor // // SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial // // SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library // // SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. // // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX // pins are NOT connected to anything by default. #define SERIAL_PORT_USBVIRTUAL SerialUSB #define SERIAL_PORT_MONITOR SerialUSB #ifndef DNO_SERCOM4_INTERFACE #define SERIAL_PORT_HARDWARE Serial1 #define SERIAL_PORT_HARDWARE_OPEN Serial1 #endif // Alias Serial to SerialUSB #define Serial SerialUSB
この記述で動作させた際、ALT-SERCOM0(PAD0,PAD1)に割り当てたUARTが上手く動作しませんでした。調査はしてないのですが、ALT-SERCOM0とSERCOM0が干渉したのではないかと思っています。なので現在はSERCOM0はPAD2,PAD3に割り当てています。
I2CとSPIについては未検証です。どなたか検証したら結果教えてください。
あぁ、やっぱり動作確認しなければいけませんね。UARTも動かなくなってました。記述を修正しました(2020/12/02)。申し訳ありません!!
C:\Users\ユーザー名\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.7.9\variants\XIAO_m0\variant.cpp
// Multi-serial objects instantiation SERCOM sercom0( SERCOM0 ) ; SERCOM sercom1( SERCOM1 ) ; SERCOM sercom2( SERCOM2 ) ; SERCOM sercom3( SERCOM3 ) ; SERCOM sercom4( SERCOM4 ) ; SERCOM sercom5( SERCOM5 ) ; #ifndef DNO_SERCOM4_INTERFACE #ifndef DSERCOM4_I2C //#ifdef DSERCOM4_USART Uart Serial1(&sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX); void SERCOM4_Handler() { Serial1.IrqHandler(); } //#endif #endif #endif #ifndef DNO_SERCOM0_INTERFACE #ifndef DSERCOM0_I2C #ifndef DSERCOM0_SPI //#ifdef DSERCOM0_USART Uart Serial2(&sercom0, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); void SERCOM0_Handler() { Serial2.IrqHandler(); } //#endif #endif #endif #endif #ifndef DNO_SERCOM2_INTERFACE #ifndef DSERCOM2_I2C #ifndef DSERCOM2_SPI //#ifdef DSERCOM2_USART Uart Serial3(&sercom2, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX); void SERCOM2_Handler() { Serial3.IrqHandler(); } //#endif #endif #endif #endif
この記述にしてから動作確認していないので面倒くさい人は少しおまちください。近日中に動作報告をこのページに載せる予定です。
C:\Users\ユーザー名\AppData\Local\Arduino15\packages\Seeeduino\hardware\samd\1.7.9\boards
# Copyright (c) 2014-2015 Arduino LLC. All right reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA : : : menu.sercom0 = SERCOM0 menu.sercom2 = SERCOM2 menu.sercom4 = SERCOM4 : : : # Seeed XIAO M0 (SAMD21) # ------------------------------ seeed_XIAO_m0.name=Seeeduino XIAO seeed_XIAO_m0.vid.0=0x2886 seeed_XIAO_m0.pid.0=0x802F seeed_XIAO_m0.vid.1=0x2886 seeed_XIAO_m0.pid.1=0x002F seeed_XIAO_m0.upload.tool=bossac seeed_XIAO_m0.upload.protocol=sam-ba seeed_XIAO_m0.upload.maximum_size=262144 seeed_XIAO_m0.upload.offset=0x2000 seeed_XIAO_m0.upload.use_1200bps_touch=true seeed_XIAO_m0.upload.wait_for_upload_port=true seeed_XIAO_m0.upload.native_usb=true seeed_XIAO_m0.build.mcu=cortex-m0plus seeed_XIAO_m0.build.f_cpu=48000000L seeed_XIAO_m0.build.usb_product="Seeed XIAO M0" seeed_XIAO_m0.build.usb_manufacturer="Seeed" seeed_XIAO_m0.build.board=SEEED_XIAO_M0 seeed_XIAO_m0.build.core=arduino seeed_XIAO_m0.build.extra_flags= -DARDUINO_SAMD_ZERO -D__SAMD21__ -D__SAMD21G18A__ -DARM_MATH_CM0PLUS -DSEEED_XIAO_M0 {build.usb_flags} {sercom0_flag} {sercom2_flag} {sercom4_flag} seeed_XIAO_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld seeed_XIAO_m0.build.openocdscript=openocd_scripts/XIAO_m0.cfg seeed_XIAO_m0.build.variant=XIAO_m0 seeed_XIAO_m0.build.variant_system_lib= seeed_XIAO_m0.build.vid=0x2886 seeed_XIAO_m0.build.pid=0x802F seeed_XIAO_m0.bootloader.tool=openocd seeed_XIAO_m0.bootloader.file=XIAOM0/bootloader-XIAO_m0-v3.7.0-33-g90ff611-dirty.bin seeed_XIAO_m0.menu.usbstack.arduino=Arduino seeed_XIAO_m0.menu.usbstack.tinyusb=TinyUSB seeed_XIAO_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB seeed_XIAO_m0.menu.debug.off=Off seeed_XIAO_m0.menu.debug.on=On seeed_XIAO_m0.menu.debug.on.build.flags.debug=-g -DDEBUG=1 seeed_XIAO_m0.menu.sercom2.include1=USART seeed_XIAO_m0.menu.sercom2.include1.sercom2_flag=-DSERCOM2_USART seeed_XIAO_m0.menu.sercom2.include2=I2C seeed_XIAO_m0.menu.sercom2.include2.sercom2_flag=-DSERCOM2_I2C seeed_XIAO_m0.menu.sercom2.include3=SPI seeed_XIAO_m0.menu.sercom2.include3.sercom2_flag=-DSERCOM2_SPI seeed_XIAO_m0.menu.sercom2.exclude4=None seeed_XIAO_m0.menu.sercom2.exclude4.sercom2_flag=-DNO_SERCOM2_INTERFACE seeed_XIAO_m0.menu.sercom0.include5=USART seeed_XIAO_m0.menu.sercom0.include5.sercom0_flag=-DSERCOM0_USART seeed_XIAO_m0.menu.sercom0.include6=I2C seeed_XIAO_m0.menu.sercom0.include6.sercom0_flag=-DSERCOM0_I2C seeed_XIAO_m0.menu.sercom0.include7=SPI seeed_XIAO_m0.menu.sercom0.include7.sercom0_flag=-DSERCOM0_SPI seeed_XIAO_m0.menu.sercom0.exclude8=None seeed_XIAO_m0.menu.sercom0.exclude8.sercom0_flag=-DNO_SERCOM0_INTERFACE seeed_XIAO_m0.menu.sercom4.include9=USART seeed_XIAO_m0.menu.sercom4.include9.sercom4_flag=-DSERCOM4_USART seeed_XIAO_m0.menu.sercom4.include10=I2C seeed_XIAO_m0.menu.sercom4.include10.sercom4_flag=-DSERCOM4_I2C seeed_XIAO_m0.menu.sercom4.exclude11=None seeed_XIAO_m0.menu.sercom4.exclude11.sercom4_flag=-DNO_SERCOM4_INTERFACE
ここまで入れるとarduinoIDEのメニューがSSのようになります。

となれば成功です。
ハードウェアで実装できるUARTは3portが限界。しかしソフトウェアシリアルを使用すれば最大5ポートとして使用できます。これはスケッチ例にあるのでここでは説明しませんが、このソフトウェアシリアルは「listen()」しているポートしか読み書きできないのでよく使い方を考える必要があります。
私は5portはあきらめて完全動作する4portハブとして使用しています。