見出し画像

M5 CapsuleでUSB Hostを試す

準備

  • M5 Capsuleの5Vin-GNDに5V電源を供給する

プログラム

以下の記事で利用したプログラムを流用して、「USBメモリを差すとLEDの色が赤から緑に変わるサンプルを作成

#include <Arduino.h>
#include <Adafruit_NeoPixel.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_intr_alloc.h"
#include "usb/usb_host.h"

#define DAEMON_TASK_PRIORITY 2
#define CLASS_TASK_PRIORITY 3
#define INPUT_TASK_PRIORITY 4
#define CLIENT_NUM_EVENT_MSG 5
#define DELAY_DAEMON 500
#define DELAY_CLIENT 500
#define DELAY_INPUT 500

static const char *TAG_DAEMON = "DAEMON";
static const char *TAG_CLASS = "CLASS";

#define NUM_OF_LEDS 1
#define NEOPIXELS_PIN 21

Adafruit_NeoPixel pixels(NUM_OF_LEDS, NEOPIXELS_PIN, NEO_GRB + NEO_KHZ800);

typedef enum
{
    DAEMON_READY = 1,
    STOP_BUTTON_IS_PRESSED = 1 << 1
} app_event_t;

typedef struct
{
    usb_host_client_handle_t client_hdl;
    uint8_t dev_addr;
    usb_device_handle_t dev_hdl;
} class_driver_t;

static void daemon_task(void *arg)
{
    EventGroupHandle_t app_event = (EventGroupHandle_t)arg;
    usb_host_config_t host_config = {
        .skip_phy_setup = false,
        .intr_flags = ESP_INTR_FLAG_LEVEL1,
    };
    usb_host_install(&host_config);
    xEventGroupSetBits(app_event, DAEMON_READY);
    bool no_clients = 0;
    while (no_clients == 0)
    {
        uint32_t event_flags;
        usb_host_lib_handle_events(DELAY_DAEMON, &event_flags);
        if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS)
        {
            no_clients = 1;
        }
        if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE)
        {
        }
    }
    usb_host_uninstall();
    vTaskDelete(NULL);
}

static void client_event_cb(const usb_host_client_event_msg_t *event_msg, void *arg)
{
    class_driver_t *driver_obj = (class_driver_t *)arg;
    switch (event_msg->event)
    {
    case USB_HOST_CLIENT_EVENT_NEW_DEV:
        if (driver_obj->dev_addr == 0)
        {
            driver_obj->dev_addr = event_msg->new_dev.address;
            usb_host_device_open(driver_obj->client_hdl, driver_obj->dev_addr, &driver_obj->dev_hdl);
            usb_device_info_t dev_info;
            usb_host_device_info(driver_obj->dev_hdl, &dev_info);
            pixels.setPixelColor(0, pixels.Color(0, 255, 0));
            pixels.show();
        }
        break;
    case USB_HOST_CLIENT_EVENT_DEV_GONE:
        if (driver_obj->dev_hdl != NULL)
        {
            usb_host_device_close(driver_obj->client_hdl, driver_obj->dev_hdl);
        }
        break;
    }
}

static void class_driver_task(void *arg)
{
    EventGroupHandle_t app_event = (EventGroupHandle_t)arg;
    EventBits_t event = xEventGroupWaitBits(app_event, DAEMON_READY, pdTRUE, pdFALSE, portMAX_DELAY);
    class_driver_t driver_obj = {0};
    usb_host_client_config_t client_config = {
        .is_synchronous = false,
        .max_num_event_msg = CLIENT_NUM_EVENT_MSG,
        .async = {
            .client_event_callback = client_event_cb,
            .callback_arg = (void *)&driver_obj,
        },
    };
    usb_host_client_register(&client_config, &driver_obj.client_hdl);

    while (1) {
        esp_err_t e = usb_host_client_handle_events(driver_obj.client_hdl, portMAX_DELAY);
    }

    if (driver_obj.dev_hdl != NULL)
    {
        usb_host_device_close(driver_obj.client_hdl, driver_obj.dev_hdl);
    }
    usb_host_client_deregister(driver_obj.client_hdl);
    usb_host_device_free_all();
    vTaskDelete(NULL);
}

void setup()
{
    EventGroupHandle_t app_events = xEventGroupCreate();

    uint32_t color = pixels.Color(255, 0, 0);
    pixels.setPixelColor(0, color);
    pixels.show();

    xTaskCreatePinnedToCore(daemon_task,
                            "daemon",
                            4096,
                            (void *)app_events,
                            DAEMON_TASK_PRIORITY,
                            NULL,
                            0);

    xTaskCreatePinnedToCore(class_driver_task,
                            "class_driver",
                            4096,
                            (void *)app_events,
                            CLASS_TASK_PRIORITY,
                            NULL,
                            0);
}

void loop()
{
    delay(1000);
}

platformio.ini

[env:m5stack-stamps3]
platform = espressif32
board = m5stack-stamps3
framework = arduino
build_flags = 
	-D ARDUINO_USB_MODE=0
	-D ARDUINO_USB_CDC_ON_BOOT=0
lib_deps = adafruit/Adafruit NeoPixel@^1.12.2


USBメモリを差してLEDの色が緑に変わることを確認!


USB MIDIデバイス

  • USB MIDIデバイスを使った場合でも無事に動作することが確認できた

USB MIDIを認識するとLEDが緑から青に変わる

環境

  • PlatformIO Core 6.1.15, Home 3.4.4

    • platform

      • espressif32

    • board:

      • m5stack-stamps3

    • framework:

      • arduino

    • Libs

      • adafruit/Adafruit NeoPixel@^1.12.2


USB Hostを使ってしまうと、シリアルでデバッグ出力ができない(する方法がみつけられていない)、他の通信手段(Bluetooth、WiFiなど)を使って、デバッグ出力する方法を模索する

この記事が気に入ったらサポートをしてみませんか?