RaspberryPiでttyポートを使う

### FT4232H MINI MODULE 使用上の注意
https://ftdichip.com/products/ft4232h-mini-module/
このボードはVIO入力が開放状態で、VCOMは認識しますがTX/RXで通信できません。VCC3V3をVIOに接続してUART用入出力端子を有効にする必要があります。
```
VCCIO : POWER Input : +3.3V input. I/O interface power supply input.
Failure to connect all VCCIO pins will result in failure of the device. 
```
https://strawberry-linux.com/catalog/items?code=50029
このボードはVIOが有効に接続されています。そのままTX/RXで通信できます。
### ttyポートに直接アクセスするプログラム
```
sudo apt -y install screen
```
コマンド終了は「Ctrl-A k」
参考 https://hirotaka-hachiya.hatenablog.com/entry/2016/05/13/133333
### 複数のFTDIシリアルポートを識別
```
$ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Apr  1 20:55 /dev/ttyUSB0
$ lsusb -v
Bus 001 Device 004: ID 0403:6011 Future Technology Devices International, Ltd FT4232H Quad HS USB-UART/FIFO IC
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x0403 Future Technology Devices International, Ltd
  idProduct          0x6011 FT4232H Quad HS USB-UART/FIFO IC
  bcdDevice            8.00
  iManufacturer           1 FTDI
  iProduct                2 Quad RS232-HS
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0065
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
以下略
$ udevadm info -q all -n /dev/ttyUSB0
P: /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0
M: ttyUSB0
R: 0
U: tty
D: c 188:0
N: ttyUSB0
L: 0
S: serial/by-id/usb-FTDI_Quad_RS232-HS-if00-port0
S: ttyUSB-FTDI0
S: serial/by-path/platform-3f980000.usb-usb-0:1.2:1.0-port0
E: DEVPATH=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0
E: DEVNAME=/dev/ttyUSB0
E: MAJOR=188
E: MINOR=0
E: SUBSYSTEM=tty
E: USEC_INITIALIZED=24290823
E: ID_BUS=usb
E: ID_MODEL=Quad_RS232-HS
E: ID_MODEL_ENC=Quad\x20RS232-HS
E: ID_MODEL_ID=6011
E: ID_SERIAL=FTDI_Quad_RS232-HS
E: ID_VENDOR=FTDI
E: ID_VENDOR_ENC=FTDI
E: ID_VENDOR_ID=0403
E: ID_REVISION=0800
E: ID_TYPE=generic
E: ID_USB_MODEL=Quad_RS232-HS
E: ID_USB_MODEL_ENC=Quad\x20RS232-HS
E: ID_USB_MODEL_ID=6011
E: ID_USB_SERIAL=FTDI_Quad_RS232-HS
E: ID_USB_VENDOR=FTDI
E: ID_USB_VENDOR_ENC=FTDI
E: ID_USB_VENDOR_ID=0403
E: ID_USB_REVISION=0800
E: ID_USB_TYPE=generic
E: ID_USB_INTERFACES=:ffffff:
E: ID_USB_INTERFACE_NUM=00
以下略
```
ttyUSB?の別名デバイスを生成する /dev/ttyUSB-FTDI[0123]
```
$ sudo vi /etc/udev/rules.d/99-ftdi.rules
# FT4232
SUBSYSTEM=="tty",ENV{ID_VENDOR_ID}=="0403",ENV{ID_MODEL_ID}=="6011",ENV{ID_USB_INTERFACE_NUM}=="00",GROUP="dialout",MODE="0660",SYMLINK+="ttyUSB-FTDI0"
SUBSYSTEM=="tty",ENV{ID_VENDOR_ID}=="0403",ENV{ID_MODEL_ID}=="6011",ENV{ID_USB_INTERFACE_NUM}=="01",GROUP="dialout",MODE="0660",SYMLINK+="ttyUSB-FTDI1"
SUBSYSTEM=="tty",ENV{ID_VENDOR_ID}=="0403",ENV{ID_MODEL_ID}=="6011",ENV{ID_USB_INTERFACE_NUM}=="02",GROUP="dialout",MODE="0660",SYMLINK+="ttyUSB-FTDI2"
SUBSYSTEM=="tty",ENV{ID_VENDOR_ID}=="0403",ENV{ID_MODEL_ID}=="6011",ENV{ID_USB_INTERFACE_NUM}=="03",GROUP="dialout",MODE="0660",SYMLINK+="ttyUSB-FTDI3"
```
ルールを反映
```
sudo udevadm trigger
又は
sudo /etc/init.d/udev reload
```
参考

https://qiita.com/kiyonaga/items/182db6b8fc9afb33751c
https://qiita.com/rdonster/items/ecd335abb2d76eec943d
### ttyポートのアクセス権
```
$ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Apr  1 20:55 /dev/ttyUSB0
$ groups
raspi adm dialout cdrom sudo audio video plugdev games users input render netdev gpio i2c spi
```
### ttyポートをプログラムで使う
```
struct ttyctrl {
	int fd;
	struct termios oldtio;
	struct termios newtio;
};
struct ttyctrl m_ttylist[4];
struct ttyctrl& tty = m_ttylist[i];
tty.fd = open(ttyary[i], O_RDWR);
if (0 <= tty.fd) {
	int err = 0;
	const int yes = 1;
	err = ioctl(tty.fd, FIONBIO, &yes);
	err = tcflush(tty.fd, TCIFLUSH);
	err = tcgetattr(tty.fd, &tty.oldtio);
	tty.newtio = tty.oldtio;
	cfmakeraw(&tty.newtio);
	err = cfsetspeed(&tty.newtio, B300);
	err = tcsetattr(tty.fd, TCSANOW, &tty.newtio);
	tty.writing = false;
 }
```
参考
https://mcommit.hatenadiary.com/entry/2017/07/09/210840
https://irobot.csse.muroran-it.ac.jp/html-corner/robotMaker/elements/outlineSerialCommProgramming/index.html
http://archive.linux.or.jp/JF/JFdocs/Serial-Programming-HOWTO-3.html
https://manpages.ubuntu.com/manpages/bionic/ja/man4/tty_ioctl.4.html
### シリアルコンソール
参考
https://www.mikan-tech.net/entry/raspi-serial-console
https://toki-blog.com/pi-serial/
https://raspberrypi-japan.com/enable-port-serial-raspberry-pi-3/
https://scratchpad.jp/raspberry-pi-3-model-b-plus-5/
http://independence-sys.net/main/?p=6035