Skip to content
Permalink
Browse files

samples: intel_s1000: tuning driver for audio app

Add a tuning interface driver to send receive tuning/control
commands over a USB transport.

Signed-off-by: Sathish Kuttan <sathish.k.kuttan@intel.com>
  • Loading branch information...
sathishkuttan authored and nashif committed Jun 28, 2019
1 parent 3adf7e0 commit 881971ad2678a0a833122f607908b58b7eb2585f
Showing with 122 additions and 0 deletions.
  1. +122 −0 samples/boards/intel_s1000_crb/audio/src/tuning_driver.c
@@ -0,0 +1,122 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#define LOG_LEVEL LOG_LEVEL_INF
#include <logging/log.h>
LOG_MODULE_REGISTER(tuning);

#include <misc/byteorder.h>

#include <string.h>
#include <zephyr.h>

#include "audio_core.h"
#include "usb_transport.h"

static void tun_drv_process_command(u8_t *data, u32_t len);

/* Buffer size in "words" for the tuning commands and replies */
#define TUN_DRV_CMD_MAX_WORDS (264)
#define TUN_DRV_CMD_MAX_BYTES (TUN_DRV_CMD_MAX_WORDS << 2)

#define TUN_DRV_ALERT_Q_LEN ((TUN_DRV_CMD_MAX_BYTES +\
USB_TPORT_HID_REPORT_DATA_LEN - 1) /\
USB_TPORT_HID_REPORT_DATA_LEN)

static struct {
/* room for transport header */
union usb_hid_report_hdr header;

/* command buffer for the tuning interface */
u8_t buffer[TUN_DRV_CMD_MAX_BYTES];

/* length of valid data in the buffer */
u32_t len;

/* index into the buffer where incoming data is copied */
u32_t index;
} __packed command_buffer;

/* Allocate a synchronization semaphore */
K_SEM_DEFINE(tun_drv_sem, 0, 1);

static int tun_drv_io_thread(void);

K_THREAD_DEFINE(tun_drv_io_thread_id, TUN_DRV_IO_THREAD_STACK_SIZE,
tun_drv_io_thread, NULL, NULL, NULL, TUN_DRV_IO_THREAD_PRIORITY,
0, K_NO_WAIT);

static int tun_drv_io_thread(void)
{
LOG_INF("Starting tuning driver I/O thread ...");

/* initialize the audio core's tuning interface */
audio_core_tuning_interface_init((u32_t *)command_buffer.buffer,
TUN_DRV_CMD_MAX_WORDS);

/* initialize the tuning transport protocol driver */
usb_transport_init(tun_drv_process_command);

while (true) {
k_sem_take(&tun_drv_sem, K_FOREVER);

/* notify audio core on tuning command reception */
audio_core_notify_tuning_cmd();
}
}

int tun_drv_packet_handler(void)
{
int ret = 0;
u32_t len;
u32_t first_word;

if (audio_core_is_tuning_reply_ready() == false) {
return ret;
}

first_word = *((u32_t *)command_buffer.buffer);
len = (first_word >> 16) << 2;

ret = usb_transport_send_reply(command_buffer.buffer, len);
if (ret) {
LOG_ERR("usb_transport_send_reply error %d", ret);
}
return ret;
}

static void tun_drv_process_command(u8_t *data, u32_t len)
{
u32_t first_word;

if (command_buffer.len == 0) {
/* extract command length */
first_word = *((u32_t *)data);
command_buffer.len = (first_word >> 16) << 2;

/* ensure total length does not exceed max */
if (command_buffer.len > TUN_DRV_CMD_MAX_BYTES) {
command_buffer.len = TUN_DRV_CMD_MAX_BYTES;
}
}

if ((command_buffer.index + len) >= command_buffer.len) {
len = command_buffer.len - command_buffer.index;
}

if (len) {
/* copy the received data into the tuning packet buffer */
memcpy(&command_buffer.buffer[command_buffer.index], data, len);
command_buffer.index += len;
}

if (command_buffer.index == command_buffer.len) {
/* reset index and length */
command_buffer.index = command_buffer.len = 0;
/* notify tuning driver thread */
k_sem_give(&tun_drv_sem);
}
}

0 comments on commit 881971a

Please sign in to comment.
You can’t perform that action at this time.