0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

nRF connect SDK:USB CDC ACM

Last updated at Posted at 2021-11-30

サンプルプロジェクトはあるのだが・・・

プロジェクト選択画面では出てこないのですが、USB CDC ACMのサンプルプロジェクトはSDKの中にすでにあります。
image.png
ここですね。
image.png
ところがこのプロジェクトを選択していざコンパイルすると・・・エラーで止まってしまいます(おいw)。Output Logを見てみるとLinkerあたりで失敗しているようです。

仕方がないので自分で作る

ソースコード自体はほぼ問題なく使えるっぽいので、こういう困ったときはhello_worldプロジェクトをベースに少しずつ切り貼りしていって組み立てます。

main.c
/*
 * Copyright (c) 2012-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

# include <zephyr.h>
# include <sys/printk.h>
# include <device.h>
# include <drivers/uart.h>
# include <logging/log.h>
# include <usb/usb_device.h>
# include <sys/ring_buffer.h>

LOG_MODULE_REGISTER(cdc_acm_echo, LOG_LEVEL_INF);

# define RING_BUF_SIZE 1024
uint8_t ring_buffer[RING_BUF_SIZE];
struct ring_buf ringbuf;

static void interrupt_handler(const struct device *dev, void *user_data)
{
    ARG_UNUSED(user_data);

    while (uart_irq_update(dev) && uart_irq_is_pending(dev)) {
        if (uart_irq_rx_ready(dev)) {
            int recv_len, rb_len;
            uint8_t buffer[64];
            size_t len = MIN(ring_buf_space_get(&ringbuf),sizeof(buffer));

            recv_len = uart_fifo_read(dev, buffer, len);

            rb_len = ring_buf_put(&ringbuf, buffer, recv_len);
            if (rb_len < recv_len) {
                LOG_ERR("Drop %u bytes", recv_len - rb_len);
            }

            LOG_DBG("tty fifo -> ringbuf %d bytes", rb_len);

            uart_irq_tx_enable(dev);
        }

        if (uart_irq_tx_ready(dev)) {
            uint8_t buffer[64];
            int rb_len, send_len;

            rb_len = ring_buf_get(&ringbuf, buffer, sizeof(buffer));
            if (!rb_len) {
                LOG_DBG("Ring buffer empty, disable TX IRQ");
                uart_irq_tx_disable(dev);
                continue;
            }

            send_len = uart_fifo_fill(dev, buffer, rb_len);
            if (send_len < rb_len) {
                LOG_ERR("Drop %d bytes", rb_len - send_len);
            }

            LOG_DBG("ringbuf -> tty fifo %d bytes", send_len);
        }
    }
}

void main(void)
{
    const struct device *dev;
    uint32_t baudrate;
    int ret;

    printk("Hello World! %s\n", CONFIG_BOARD);

    dev = device_get_binding("CDC_ACM_0");
    if (!dev) {
        printk("CDC ACM device not found");
        return;
    }

    ret = usb_enable(NULL);
    if (ret != 0) {
        printk("Failed to enable USB");
        return;
    }

    ring_buf_init(&ringbuf, sizeof(ring_buffer), ring_buffer);

    ret = uart_line_ctrl_get(dev, UART_LINE_CTRL_BAUD_RATE, &baudrate);
    if (ret) {
        printk("Failed to get baudrate, ret code %d", ret);
    } else {
        printk("Baudrate detected: %d", baudrate);
    }

    uart_irq_callback_set(dev, interrupt_handler);

    /* Enable rx interrupts */
    uart_irq_rx_enable(dev);
}
prj.conf
# USB
CONFIG_USB=y
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_CDC_ACM=y
CONFIG_USB_CDC_ACM_DEVICE_COUNT=1

# SERIAL
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_UART_LINE_CTRL=y

単純なエコーバックするプロジェクトができました。これをベースにUSB CDC ACMを使ったプロジェクトが作れそうです。
image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?