動作環境
ホストOS: Ubuntu 18.04 LTS
ボード: STM32F769 Discovery Kit (以下、STM32F769)
RTOS: Zephyr 2.1.0-rc1
touchLCD: gen4-uLCD-35DT
Workshop 4 IDE v4.5.0.17 (on Windows 10 Pro)
概要
- Zephyr + STM32F769でのUART送受信の練習
- tty_init()
- tty_write()
- tty_read()
- gen4-uLCD-35DT(シリアルスレーブモード)
- UART送信して文字を描く ('9')
- UART受信する (ACK[0x06])
準備
gen4-uLCD-35DTの準備
- gen4-uLCD-35DTはWorkshop 4 IDEにてシリアルスレーブモードにしておく
- baud rate: 115200 bpsで設定
- ZephyrではSTM32F769のUART_6は115200bpsがデフォルト設定
- baud rate: 115200 bpsで設定
Zephyrの準備
- UART_6
- default: 115200 bps
- プロジェクトのprj.conf
- 下記のようにしておく
prj.conf
CONFIG_GPIO=y
CONFIG_SERIAL=y
# for tty_init()
CONFIG_CONSOLE_SUBSYS=y
CONFIG_CONSOLE_GETCHAR=y
配線
gen4-uLCD-35DTはFFCケーブルを介してgen4-IBに接続する。
そして、以下のように配線をする。
- STM32F769 D0(RX) <-> gen4-IB RX
- STM32F769 D1(TX) <-> gen4-IB TX
- STM32F769 GND <-> gen4-IB GND
- 5V電源(*1) PWR <-> gen4-IB +5V
- 5V電源(*1) GND <-> gen4-IB GND
*1) 5V出力(1A)のスイッチングACアダプタ
実装
src/main.c
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
# include <zephyr.h>
# include <sys/printk.h>
# include <tty.h>
# include <device.h>
# include <drivers/gpio.h>
// added 2019-11-23
# include <uart.h>
# include <console.h>
//#include <tty.h>
# include <string.h>
# define LED_PORT DT_ALIAS_LED0_GPIOS_CONTROLLER
# define LED DT_ALIAS_LED0_GPIOS_PIN
# define SLEEP_TIME_MSEC 1000
# define BARCODE_UART_PORT "UART_6"
static struct device *uart_dev;
static struct tty_serial ard_serial; // Arduino connector (UART_6) = D0, D1 of CN13 on STM32F769I Discovery
int uart_init()
{
struct uart_config uart_cfg;
int ret;
uart_dev = device_get_binding(BARCODE_UART_PORT);
if (uart_dev == NULL) {
printk("Failed to get %s\n", BARCODE_UART_PORT);
return -1;
}
ret = uart_config_get(uart_dev, &uart_cfg);
if (!ret) {
printk("\n======== [%s] ========\n", BARCODE_UART_PORT);
printk("[%s] uart_config.baudrate=%d\n", BARCODE_UART_PORT, uart_cfg.baudrate);
printk("[%s] uart_config.parity=%d\n", BARCODE_UART_PORT, uart_cfg.parity);
printk("[%s] uart_config.stop_bits=%d\n", BARCODE_UART_PORT, uart_cfg.stop_bits);
printk("[%s] uart_config.data_bits=%d\n", BARCODE_UART_PORT, uart_cfg.data_bits);
printk("[%s] uart_config.flow_ctrl=%d\n", BARCODE_UART_PORT, uart_cfg.flow_ctrl);
} else {
printk("uart_config_get() error\n");
return -1;
}
tty_init(&ard_serial, uart_dev);
return 0;
}
static unsigned char calc_checksum(unsigned char *ptr, int size)
{
if (ptr == NULL) {
return 0x00;
}
unsigned char code = 0;
for(int idx=0; idx < size; idx++) {
code ^= ptr[idx];
}
return code;
}
static void touchLCD_dispChar()
{
// Target: 4D systesms (Serial slave mode) gen4-uLCD-35DT
// Reference: DIABLO16 SERIAL COMMANDS (Rev. 2.1)
// page 16 > 5.1.2. Put Character
//
unsigned char txbuf[20] = { 0 };
unsigned char rxbuf[20] = { 0 };
int pos = 0;
int ret;
txbuf[pos++] = 0xFF;
txbuf[pos++] = 0xFE;
txbuf[pos++] = 0x00;
txbuf[pos++] = 0x39;
ret = tty_write(&ard_serial, txbuf, pos);
ret = tty_read(&ard_serial, rxbuf, 1);
printk("rx:%02X\n", rxbuf[0]);
}
void main(void)
{
u32_t cnt = 0;
struct device *dev;
printk("Hello World! %s\n", CONFIG_BOARD);
dev = device_get_binding(LED_PORT);
gpio_pin_configure(dev, LED, GPIO_DIR_OUT);
uart_init();
while (1) {
// 1. display on touchLCD
touchLCD_dispChar();
// 2. LED Blink
gpio_pin_write(dev, LED, cnt % 2);
cnt++;
// 3. wait
k_sleep(SLEEP_TIME_MSEC);
}
}
実行手順
3つのターミナルで実施した。
最初はgen4-uLCD-35DTの電源を抜いておく(起動直後のスプラッシュスクリーンを表示するため、プログラムが走らないwest debug時に電源を入れるため)。
プロジェクトのルートは~/Zephyr_191116/zephyrproject/
としてセットアップしている。
-
- STM32F769をUSB接続しておく
- ST-LinkのUSB接続
-
- ターミナル1:デバッグ用のシリアル接続をする
sudo screen /dev/ttyACM0 115200
-
- ターミナル2:プログラムをビルド
cd ~/Zephyr_191116/zephyrproject/
west build -p auto -b stm32f769i_disco zephyr/samples/basic/wrk_uart_191123
-
- ターミナル2:プログラム書き込み
west flash
-
- ターミナル3:デバッグ実行開始
cd ~/Zephyr_191116/zephyrproject/
west debug
-
- gen4-uLCD-35DTの電源を接続
- 3秒待って、初期画面を表示 (4D Systems...の文字が表示される)
-
- ターミナル3:デバッグ継続
- 停止しながらデバッグ
(gdb) break main.c:main
-
(gbd) c
- 下記まで実行される
94 printk("Hello World! %s\n", CONFIG_BOARD);
- 下記まで実行される
-
(gbd) n
- 繰り返してtouchLCD_dispChar()の実行を3回繰り返す
終了手順
-
- ターミナル3:デバッグ接続 (west debug)
- q[Enter]
- y
-
- ターミナル2:デバッグ用シリアル (screen)
- ctrl-a, k
- y
動作の様子
以下は、printk()デバッグ用のターミナルの出力。
***** Booting Zephyr OS build v2.1.0-rc1-141-g3cc5bda2fa10 *****
Hello World! stm32f769i_disco
======== [UART_6] ========
[UART_6] uart_config.baudrate=115200
[UART_6] uart_config.parity=0
[UART_6] uart_config.stop_bits=1
[UART_6] uart_config.data_bits=3
[UART_6] uart_config.flow_ctrl=0
rx:06
rx:06
rx:06
touchLCDには以下のように表示される。
コマンドを送信して、gen4-uLCD-35DTが受信成功したというACK[0x06]をSTM32F769にて受信できている。