First
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
#include "command_handler.h"
|
||||
#include "led.h"
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(command_handler, LOG_LEVEL_INF);
|
||||
|
||||
int command_handler(struct command_message_t *msg) {
|
||||
if (msg == NULL) {
|
||||
LOG_ERR("Received NULL message pointer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
LOG_DBG("Processing command: %d, length: %d", msg->command, msg->length);
|
||||
|
||||
switch (msg->command) {
|
||||
case COMMAND_ERROR: {
|
||||
LOG_WRN("Received COMMAND_ERROR");
|
||||
break;
|
||||
}
|
||||
|
||||
case LED: {
|
||||
// Toggle LED with the LED command
|
||||
led_toggle();
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
LOG_WRN("Unknown command received: %d", msg->command);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef COMMAND_HANDLER_H
|
||||
#define COMMAND_HANDLER_H
|
||||
|
||||
|
||||
#include "command_message.h"
|
||||
|
||||
/**
|
||||
* @brief Process received command message
|
||||
*
|
||||
* @param msg Command message to process
|
||||
* @return 0 on success, negative errno on failure
|
||||
*/
|
||||
int command_handler(struct command_message_t *msg);
|
||||
|
||||
|
||||
#endif // COMMAND_HANDLER_H
|
||||
@@ -0,0 +1,73 @@
|
||||
#include "command_message.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(command_message, LOG_LEVEL_INF);
|
||||
|
||||
void command_message_init(struct command_message_t *msg) {
|
||||
memset(msg, 0, sizeof(struct command_message_t));
|
||||
msg->prefix = COMMAND_PREFIX;
|
||||
msg->id = COMMAND_ID;
|
||||
}
|
||||
|
||||
void command_create_message(struct command_message_t *msg, uint8_t length, commands_e command, uint8_t data[160]) {
|
||||
// Ensure length doesn't exceed available space
|
||||
if (length > sizeof(msg->data) - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
command_message_init(msg);
|
||||
msg->length = length;
|
||||
msg->command = command;
|
||||
|
||||
// Copy the data
|
||||
if (data != NULL) {
|
||||
for (int i = 0; i < msg->length; i++) {
|
||||
msg->data[i] = data[i];
|
||||
}
|
||||
}
|
||||
msg->crc = command_calculate_crc(msg);
|
||||
}
|
||||
|
||||
uint8_t command_calculate_crc(struct command_message_t *msg) {
|
||||
uint32_t sum = 0;
|
||||
uint8_t crc = 0;
|
||||
|
||||
uint8_t *byte_ptr = (uint8_t *)msg;
|
||||
|
||||
for (int i = 0; i < (sizeof(struct command_message_t) - sizeof(msg->data) + msg->length) - 1; i++) {
|
||||
sum += byte_ptr[i];
|
||||
}
|
||||
|
||||
crc = 0x100 - (sum & 0xff);
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
void command_create_ack(struct command_message_t *msg) {
|
||||
command_create_message(msg, 0, COMMAND_ACK, NULL);
|
||||
}
|
||||
|
||||
void command_create_nack(struct command_message_t *msg) {
|
||||
command_create_message(msg, 0, COMMAND_NACK, NULL);
|
||||
}
|
||||
|
||||
void command_log(struct command_message_t *msg) {
|
||||
if (msg->length > sizeof(msg->data) - 1) {
|
||||
LOG_ERR("Message length too long: %d", msg->length);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_INF("Prefix: %d\n\r", msg->prefix);
|
||||
LOG_INF("Length: %d\n\r", msg->length);
|
||||
LOG_INF("COMMAND_ID: %d\n\r", msg->id);
|
||||
LOG_INF("Command: %d\n\r", msg->command);
|
||||
LOG_INF("Data:\n\r");
|
||||
|
||||
for (int i = 0; i < msg->length; i++) {
|
||||
LOG_INF("%d", msg->data[i]);
|
||||
}
|
||||
|
||||
LOG_INF("CRC: %d\n\r", msg->crc);
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#ifndef COMMAND_MESSAGE_H
|
||||
#define COMMAND_MESSAGE_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define COMMAND_PREFIX 0x69
|
||||
#define COMMAND_ID 0x00
|
||||
|
||||
typedef enum {
|
||||
COMMAND_ERROR,
|
||||
COMMAND_ACK,
|
||||
COMMAND_NACK,
|
||||
LED,
|
||||
} commands_e;
|
||||
|
||||
struct command_message_t {
|
||||
uint8_t prefix;
|
||||
uint8_t length;
|
||||
uint8_t id;
|
||||
uint8_t command;
|
||||
uint8_t crc;
|
||||
uint8_t data[160];
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* @brief Initialize command message to default state
|
||||
*
|
||||
* @param msg Message to initialize
|
||||
*/
|
||||
void command_message_init(struct command_message_t *msg);
|
||||
|
||||
/**
|
||||
* @brief Create command message with data and CRC
|
||||
*
|
||||
* @param msg Message to populate
|
||||
* @param length Data length in bytes
|
||||
* @param command Command type
|
||||
* @param data Data payload
|
||||
*/
|
||||
void command_create_message(struct command_message_t *msg, uint8_t length, commands_e command, uint8_t data[160]);
|
||||
|
||||
/**
|
||||
* @brief Calculate CRC for command message
|
||||
*
|
||||
* @param msg Message to calculate CRC for
|
||||
* @return CRC value
|
||||
*/
|
||||
uint8_t command_calculate_crc(struct command_message_t *msg);
|
||||
|
||||
/**
|
||||
* @brief Create ACK command message
|
||||
*
|
||||
* @param msg Message to populate
|
||||
*/
|
||||
void command_create_ack(struct command_message_t *msg);
|
||||
|
||||
/**
|
||||
* @brief Create NACK command message
|
||||
*
|
||||
* @param msg Message to populate
|
||||
*/
|
||||
void command_create_nack(struct command_message_t *msg);
|
||||
|
||||
/**
|
||||
* @brief Print the command with LOG
|
||||
*
|
||||
* @param msg Message to calculate CRC for
|
||||
*/
|
||||
void command_log(struct command_message_t *msg);
|
||||
|
||||
|
||||
#endif // COMMAND_MESSAGE_H
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "led.h"
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
|
||||
LOG_MODULE_REGISTER(led, LOG_LEVEL_INF);
|
||||
|
||||
#define LED0_NODE DT_ALIAS(led0)
|
||||
static const struct gpio_dt_spec led0_gpio = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
|
||||
static int led0_state = 0;
|
||||
|
||||
int led_init() {
|
||||
int ret;
|
||||
|
||||
if (!device_is_ready(led0_gpio.port)) {
|
||||
LOG_ERR("LED0 GPIO device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure_dt(&led0_gpio, GPIO_OUTPUT_INACTIVE);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to configure LED0 GPIO: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Turn it off
|
||||
ret = gpio_pin_set_dt(&led0_gpio, 0);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to initialize LED");
|
||||
return ret;
|
||||
}
|
||||
|
||||
LOG_INF("LED driver initialized (LED0: GPIO %d)", led0_gpio.pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int led_set(int state) {
|
||||
led0_state = state ? 1 : 0;
|
||||
|
||||
int ret = gpio_pin_set_dt(&led0_gpio, led0_state);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to set LED0: %d", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int led_toggle() {
|
||||
return led_set(!led0_state);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef LED_H
|
||||
#define LED_H
|
||||
|
||||
|
||||
int led_init();
|
||||
int led_set(int state);
|
||||
int led_toggle();
|
||||
|
||||
|
||||
#endif // LED_H
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#include "led.h"
|
||||
#include "usb.h"
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
|
||||
|
||||
|
||||
int main(void) {
|
||||
int ret;
|
||||
|
||||
ret = usb_init();
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to enable USB");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = led_init();
|
||||
if (ret != 0) {
|
||||
LOG_ERR("Failed to enable LED");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
#include "usb.h"
|
||||
#include "usb_conf.h"
|
||||
#include "command_handler.h"
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
LOG_MODULE_REGISTER(usb, LOG_LEVEL_DBG);
|
||||
|
||||
// DEVICE
|
||||
const struct device *const uart_dev = DEVICE_DT_GET_ONE(zephyr_cdc_acm_uart);
|
||||
static struct usbd_context *usb_context;
|
||||
|
||||
// THREAD
|
||||
static struct k_thread usb_thread_data;
|
||||
static k_tid_t usb_thread_id = NULL;
|
||||
#define USB_THREAD_STACK_SIZE 2048
|
||||
K_THREAD_STACK_DEFINE(usb_thread_stack, USB_THREAD_STACK_SIZE);
|
||||
|
||||
// RX BUFFER
|
||||
#define RX_BUF_SIZE 4
|
||||
struct rx_buffer_t {
|
||||
int current_read;
|
||||
int current_write;
|
||||
struct k_sem semaphore;
|
||||
struct command_message_t buffer[RX_BUF_SIZE];
|
||||
};
|
||||
|
||||
static struct rx_buffer_t rx_buf;
|
||||
|
||||
|
||||
static void interrupt_handler(const struct device *dev, void *user_data) {
|
||||
ARG_UNUSED(user_data);
|
||||
|
||||
while (true) {
|
||||
uart_irq_update(dev);
|
||||
|
||||
if (uart_irq_is_pending(dev) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (uart_irq_rx_ready(dev)) {
|
||||
size_t len = sizeof(struct command_message_t);
|
||||
|
||||
int recv_len = uart_fifo_read(dev, (uint8_t *)&rx_buf.buffer[rx_buf.current_write], len);
|
||||
if (recv_len < 0) {
|
||||
LOG_ERR("Failed to read UART FIFO");
|
||||
recv_len = 0;
|
||||
};
|
||||
|
||||
rx_buf.current_write += 1;
|
||||
|
||||
if (rx_buf.current_write >= RX_BUF_SIZE) {
|
||||
rx_buf.current_write = 0;
|
||||
rx_buf.current_read = (RX_BUF_SIZE - 1);
|
||||
}
|
||||
else {
|
||||
rx_buf.current_read = (rx_buf.current_write - 1);
|
||||
}
|
||||
|
||||
// Give semaphore for usb read thread
|
||||
k_sem_give(&rx_buf.semaphore);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_thread(void *p1, void *p2, void *p3) {
|
||||
ARG_UNUSED(p1);
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
LOG_INF("USB command processing thread started");
|
||||
|
||||
while (1) {
|
||||
// Wait forever for the rx semaphore
|
||||
k_sem_take(&rx_buf.semaphore, K_FOREVER);
|
||||
|
||||
int read_index = rx_buf.current_read;
|
||||
|
||||
// Check the prefix
|
||||
if (rx_buf.buffer[read_index].prefix != COMMAND_PREFIX) {
|
||||
LOG_ERR("COMMAND_PREFIX does not match: %d", rx_buf.buffer[read_index].prefix);
|
||||
|
||||
// Send NACK
|
||||
struct command_message_t nack_buf;
|
||||
command_create_nack(&nack_buf);
|
||||
usb_send_command(&nack_buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check the CRC
|
||||
uint8_t calculated_crc = command_calculate_crc(&rx_buf.buffer[read_index]);
|
||||
if (calculated_crc != rx_buf.buffer[read_index].crc) {
|
||||
LOG_ERR("CRC does not match:");
|
||||
LOG_ERR("Calculated CRC: %d", calculated_crc);
|
||||
LOG_ERR("Received CRC: %d", rx_buf.buffer[read_index].prefix);
|
||||
|
||||
// Send NACK
|
||||
struct command_message_t nack_buf;
|
||||
command_create_nack(&nack_buf);
|
||||
usb_send_command(&nack_buf);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
int ret = command_handler(&rx_buf.buffer[read_index]);
|
||||
if (ret == 0) {
|
||||
// Send ACK
|
||||
struct command_message_t ack_buf;
|
||||
command_create_ack(&ack_buf);
|
||||
usb_send_command(&ack_buf);
|
||||
}
|
||||
else {
|
||||
// Send NACK
|
||||
struct command_message_t nack_buf;
|
||||
command_create_nack(&nack_buf);
|
||||
usb_send_command(&nack_buf);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INF("USB command processing thread exiting");
|
||||
}
|
||||
|
||||
int usb_init() {
|
||||
rx_buf.current_read = 0;
|
||||
rx_buf.current_write = 0;
|
||||
k_sem_init(&rx_buf.semaphore, 1, 1);
|
||||
memset(rx_buf.buffer, 0, sizeof(rx_buf.buffer));
|
||||
|
||||
int ret;
|
||||
|
||||
if (!device_is_ready(uart_dev)) {
|
||||
LOG_ERR("CDC ACM device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
usb_context = usb_device_init(NULL);
|
||||
if (usb_context == NULL) {
|
||||
LOG_ERR("Failed to initialize USB device");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!usbd_can_detect_vbus(usb_context)) {
|
||||
ret = usbd_enable(usb_context);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to enable device support");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
k_msleep(100);
|
||||
|
||||
uart_irq_callback_set(uart_dev, interrupt_handler);
|
||||
uart_irq_rx_enable(uart_dev);
|
||||
|
||||
usb_thread_id = k_thread_create(
|
||||
&usb_thread_data,
|
||||
usb_thread_stack,
|
||||
K_THREAD_STACK_SIZEOF(usb_thread_stack),
|
||||
usb_thread,
|
||||
NULL, NULL, NULL,
|
||||
5,
|
||||
0,
|
||||
K_NO_WAIT
|
||||
);
|
||||
|
||||
if (usb_thread_id == NULL) {
|
||||
LOG_ERR("Failed to create USB thread");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_send_command(struct command_message_t *msg) {
|
||||
int ret = 0;
|
||||
|
||||
if (!device_is_ready(uart_dev)) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
// Message size: prefix + length + id + command + crc + data
|
||||
size_t msg_size = 5 + msg->length;
|
||||
uint8_t *msg_bytes = (uint8_t *)msg;
|
||||
|
||||
/* uart_poll_out blocks until sent, ensuring data integrity */
|
||||
for (size_t i = 0; i < msg_size; i++) {
|
||||
uart_poll_out(uart_dev, msg_bytes[i]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef USB_H
|
||||
#define USB_H
|
||||
|
||||
|
||||
#include "command_message.h"
|
||||
|
||||
|
||||
int usb_init();
|
||||
int usb_send_command(struct command_message_t *msg);
|
||||
|
||||
|
||||
#endif // USB_H
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
#include "usb_conf.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/usb/usbd.h>
|
||||
#include <zephyr/usb/bos.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
LOG_MODULE_REGISTER(usb_conf, LOG_LEVEL_DBG);
|
||||
|
||||
/* By default, do not register the USB DFU class DFU mode instance. */
|
||||
static const char *const blocklist[] = {
|
||||
"dfu_dfu",
|
||||
NULL,
|
||||
};
|
||||
|
||||
/*
|
||||
* Instantiate a context named my_usb_context using the default USB device
|
||||
* controller, the Zephyr project vendor ID, and the sample product ID.
|
||||
* Zephyr project vendor ID must not be used outside of Zephyr samples.
|
||||
*/
|
||||
USBD_DEVICE_DEFINE(my_usb_context,
|
||||
DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
|
||||
CONFIG_USBD_VID, CONFIG_USBD_PID);
|
||||
|
||||
USBD_DESC_LANG_DEFINE(my_usb_lang);
|
||||
USBD_DESC_MANUFACTURER_DEFINE(my_usb_mfr, CONFIG_USBD_MANUFACTURER);
|
||||
USBD_DESC_PRODUCT_DEFINE(my_usb_product, CONFIG_USBD_PRODUCT);
|
||||
IF_ENABLED(CONFIG_HWINFO, (USBD_DESC_SERIAL_NUMBER_DEFINE(my_usb_serial)));
|
||||
|
||||
USBD_DESC_CONFIG_DEFINE(fs_cfg_desc, "FS Configuration");
|
||||
USBD_DESC_CONFIG_DEFINE(hs_cfg_desc, "HS Configuration");
|
||||
|
||||
static const uint8_t attributes = (IS_ENABLED(CONFIG_USBD_SELF_POWERED) ?
|
||||
USB_SCD_SELF_POWERED : 0) |
|
||||
(IS_ENABLED(CONFIG_USBD_REMOTE_WAKEUP) ?
|
||||
USB_SCD_REMOTE_WAKEUP : 0);
|
||||
|
||||
/* Full speed configuration */
|
||||
USBD_CONFIGURATION_DEFINE(sample_fs_config,
|
||||
attributes,
|
||||
CONFIG_USBD_MAX_POWER, &fs_cfg_desc);
|
||||
|
||||
/* High speed configuration */
|
||||
USBD_CONFIGURATION_DEFINE(sample_hs_config,
|
||||
attributes,
|
||||
CONFIG_USBD_MAX_POWER, &hs_cfg_desc);
|
||||
|
||||
#if CONFIG_SAMPLE_USBD_20_EXTENSION_DESC
|
||||
/*
|
||||
* This does not yet provide valuable information, but rather serves as an
|
||||
* example, and will be improved in the future.
|
||||
*/
|
||||
static const struct usb_bos_capability_lpm bos_cap_lpm = {
|
||||
.bLength = sizeof(struct usb_bos_capability_lpm),
|
||||
.bDescriptorType = USB_DESC_DEVICE_CAPABILITY,
|
||||
.bDevCapabilityType = USB_BOS_CAPABILITY_EXTENSION,
|
||||
.bmAttributes = 0UL,
|
||||
};
|
||||
|
||||
USBD_DESC_BOS_DEFINE(my_usb_usbext, sizeof(bos_cap_lpm), &bos_cap_lpm);
|
||||
#endif
|
||||
|
||||
static void usb_fix_code_triple(struct usbd_context *uds_ctx, const enum usbd_speed speed) {
|
||||
/* Always use class code information from Interface Descriptors */
|
||||
if (IS_ENABLED(CONFIG_USBD_CDC_ACM_CLASS) ||
|
||||
IS_ENABLED(CONFIG_USBD_CDC_ECM_CLASS) ||
|
||||
IS_ENABLED(CONFIG_USBD_CDC_NCM_CLASS) ||
|
||||
IS_ENABLED(CONFIG_USBD_MIDI2_CLASS) ||
|
||||
IS_ENABLED(CONFIG_USBD_AUDIO2_CLASS) ||
|
||||
IS_ENABLED(CONFIG_USBD_VIDEO_CLASS)) {
|
||||
/*
|
||||
* Class with multiple interfaces have an Interface
|
||||
* Association Descriptor available, use an appropriate triple
|
||||
* to indicate it.
|
||||
*/
|
||||
usbd_device_set_code_triple(uds_ctx, speed,
|
||||
USB_BCC_MISCELLANEOUS, 0x02, 0x01);
|
||||
} else {
|
||||
usbd_device_set_code_triple(uds_ctx, speed, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_context *usb_device_setup(usbd_msg_cb_t msg_cb) {
|
||||
int err;
|
||||
|
||||
err = usbd_add_descriptor(&my_usb_context, &my_usb_lang);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to initialize language descriptor (%d)", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = usbd_add_descriptor(&my_usb_context, &my_usb_mfr);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to initialize manufacturer descriptor (%d)", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = usbd_add_descriptor(&my_usb_context, &my_usb_product);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to initialize product descriptor (%d)", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IF_ENABLED(CONFIG_HWINFO, (
|
||||
err = usbd_add_descriptor(&my_usb_context, &my_usb_serial);
|
||||
))
|
||||
if (err) {
|
||||
LOG_ERR("Failed to initialize SN descriptor (%d)", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (USBD_SUPPORTS_HIGH_SPEED &&
|
||||
usbd_caps_speed(&my_usb_context) == USBD_SPEED_HS) {
|
||||
err = usbd_add_configuration(&my_usb_context, USBD_SPEED_HS,
|
||||
&sample_hs_config);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to add High-Speed configuration");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = usbd_register_all_classes(&my_usb_context, USBD_SPEED_HS, 1,
|
||||
blocklist);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to add register classes");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
usb_fix_code_triple(&my_usb_context, USBD_SPEED_HS);
|
||||
}
|
||||
|
||||
err = usbd_add_configuration(&my_usb_context, USBD_SPEED_FS,
|
||||
&sample_fs_config);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to add Full-Speed configuration");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = usbd_register_all_classes(&my_usb_context, USBD_SPEED_FS, 1, blocklist);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to add register classes");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
usb_fix_code_triple(&my_usb_context, USBD_SPEED_FS);
|
||||
usbd_self_powered(&my_usb_context, attributes & USB_SCD_SELF_POWERED);
|
||||
|
||||
if (msg_cb != NULL) {
|
||||
err = usbd_msg_register_cb(&my_usb_context, msg_cb);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to register message callback");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_SAMPLE_USBD_20_EXTENSION_DESC
|
||||
(void)usbd_device_set_bcd_usb(&my_usb_context, USBD_SPEED_FS, 0x0201);
|
||||
(void)usbd_device_set_bcd_usb(&my_usb_context, USBD_SPEED_HS, 0x0201);
|
||||
|
||||
err = usbd_add_descriptor(&my_usb_context, &my_usb_usbext);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to add USB 2.0 Extension Descriptor");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return &my_usb_context;
|
||||
}
|
||||
|
||||
struct usbd_context *usb_device_init(usbd_msg_cb_t msg_cb) {
|
||||
int err;
|
||||
|
||||
if (usb_device_setup(msg_cb) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = usbd_init(&my_usb_context);
|
||||
if (err) {
|
||||
LOG_ERR("Failed to initialize device support");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &my_usb_context;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef USB_CONF_H
|
||||
#define USB_CONF_H
|
||||
|
||||
|
||||
#include <zephyr/usb/usbd.h>
|
||||
|
||||
struct usbd_context *usb_device_setup(usbd_msg_cb_t msg_cb);
|
||||
struct usbd_context *usb_device_init(usbd_msg_cb_t msg_cb);
|
||||
|
||||
|
||||
#endif // USB_CONF_H
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "zbus_channels.h"
|
||||
#include "command_message.h"
|
||||
|
||||
|
||||
ZBUS_CHAN_DEFINE(
|
||||
in_command_chan,
|
||||
struct command_message_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ZBUS_OBSERVERS_EMPTY,
|
||||
ZBUS_MSG_INIT(0)
|
||||
);
|
||||
|
||||
ZBUS_CHAN_DEFINE(
|
||||
out_command_chan,
|
||||
struct command_message_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ZBUS_OBSERVERS_EMPTY,
|
||||
ZBUS_MSG_INIT(0)
|
||||
);
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef ZBUS_CHANNELS_H
|
||||
#define ZBUS_CHANNELS_H
|
||||
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/zbus/zbus.h>
|
||||
|
||||
#include "command_message.h"
|
||||
|
||||
|
||||
ZBUS_CHAN_DECLARE(in_command_chan);
|
||||
ZBUS_CHAN_DECLARE(out_command_chan);
|
||||
|
||||
|
||||
#endif // ZBUS_CHANNELS_H
|
||||
Reference in New Issue
Block a user