Fix set buffer control
This commit is contained in:
parent
fea5fe0b5b
commit
d98bf4c347
|
@ -34,9 +34,12 @@
|
|||
|
||||
#ifdef USB_DEBUG
|
||||
|
||||
#include "chmtx.h"
|
||||
#include "rp_fifo.h"
|
||||
|
||||
#define CMD_RESET 0x00
|
||||
mutex_t cmtx;
|
||||
|
||||
#define CMD_RESET 0x0F
|
||||
#define CMD_SETUP 0x01
|
||||
#define CMD_READ_SETUP 0x02
|
||||
#define CMD_SET_ADDR 0x03
|
||||
|
@ -45,6 +48,10 @@
|
|||
#define CMD_BUFF_STATUS 0x06
|
||||
#define CMD_EP_DONE 0x07
|
||||
#define CMD_DATA_ERROR 0x09
|
||||
#define CMD_PREP_IN_EP 0x0A
|
||||
#define CMD_PREP_OUT_EP 0x0B
|
||||
#define CMD_SET_ADDR_HW 0x0C
|
||||
#define CMD_EP_NEXT 0x0D
|
||||
|
||||
void cmd_send(uint8_t cmd, uint8_t length) {
|
||||
uint32_t data = (cmd << 24) | (length << 16);
|
||||
|
@ -204,24 +211,25 @@ uint32_t usb_prepare_out_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t buffer_i
|
|||
uint16_t buf_len;
|
||||
uint32_t buf_ctrl = 0;
|
||||
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||
USBOutEndpointState *iesp = usbp->epc[ep]->out_state;
|
||||
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||
|
||||
buf_len = epcp->out_maxsize < iesp->rxsize ? epcp->out_maxsize : iesp->rxsize;
|
||||
buf_len = epcp->out_maxsize < oesp->rxsize ? epcp->out_maxsize : oesp->rxsize;
|
||||
|
||||
if (!(buf_len == 0 && buffer_index == 1)) {
|
||||
if ((iesp->rxpkts == 1 && buffer_index == 0) ||
|
||||
(iesp->rxpkts == 2 && buffer_index == 1)) {
|
||||
/* Host only? */
|
||||
//if ((oesp->rxpkts == 1 && buffer_index == 0) ||
|
||||
// (oesp->rxpkts == 2 && buffer_index == 1)) {
|
||||
/* Last buffer */
|
||||
buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
||||
}
|
||||
//buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
||||
//}
|
||||
/* PID */
|
||||
buf_ctrl |= iesp->next_pid ? USB_BUFFER_BUFFER1_DATA_PID : USB_BUFFER_BUFFER0_DATA_PID;
|
||||
iesp->next_pid ^= 1U;
|
||||
buf_ctrl |= oesp->next_pid ? USB_BUFFER_BUFFER0_DATA_PID : 0;
|
||||
oesp->next_pid ^= 1U;
|
||||
|
||||
buf_ctrl |= USB_BUFFER_BUFFER0_AVAILABLE |
|
||||
buf_len;
|
||||
|
||||
iesp->active = true;
|
||||
oesp->active = true;
|
||||
if (buffer_index) {
|
||||
buf_ctrl = buf_ctrl << 16;
|
||||
}
|
||||
|
@ -257,7 +265,13 @@ static void usb_prepare_out_ep(USBDriver *usbp, usbep_t ep) {
|
|||
EP_CTRL(ep).OUT = ep_ctrl;
|
||||
}
|
||||
|
||||
BUF_CTRL(ep).OUT |= buf_ctrl;
|
||||
BUF_CTRL(ep).OUT = buf_ctrl;
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_PREP_OUT_EP, 2);
|
||||
data_send(ep_ctrl);
|
||||
data_send(buf_ctrl);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,15 +288,15 @@ static uint32_t usb_prepare_in_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t bu
|
|||
buf_len = epcp->in_maxsize < iesp->txsize - iesp->txlast ?
|
||||
epcp->in_maxsize : iesp->txsize - iesp->txlast;
|
||||
|
||||
if (buf_len > 0) {
|
||||
iesp->txlast += buf_len;
|
||||
|
||||
if (iesp->txsize <= iesp->txlast) {
|
||||
/* Host only? */
|
||||
//if (iesp->txsize <= iesp->txlast) {
|
||||
/* Last buffer */
|
||||
buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
||||
}
|
||||
//buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
||||
//}
|
||||
/* PID */
|
||||
buf_ctrl |= iesp->next_pid ? USB_BUFFER_BUFFER1_DATA_PID : USB_BUFFER_BUFFER0_DATA_PID;
|
||||
buf_ctrl |= iesp->next_pid ? USB_BUFFER_BUFFER0_DATA_PID : 0;
|
||||
iesp->next_pid ^= 1U;
|
||||
|
||||
/* Copy data into hardware buffer */
|
||||
|
@ -298,7 +312,6 @@ static uint32_t usb_prepare_in_ep_buffer(USBDriver *usbp, usbep_t ep, uint8_t bu
|
|||
if (buffer_index) {
|
||||
buf_ctrl = buf_ctrl << 16;
|
||||
}
|
||||
}
|
||||
|
||||
return buf_ctrl;
|
||||
}
|
||||
|
@ -342,7 +355,13 @@ static void usb_prepare_in_ep(USBDriver *usbp, usbep_t ep) {
|
|||
EP_CTRL(ep).IN = ep_ctrl;
|
||||
}
|
||||
|
||||
BUF_CTRL(ep).IN |= buf_ctrl;
|
||||
BUF_CTRL(ep).IN = buf_ctrl;
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_PREP_IN_EP, 2);
|
||||
data_send(ep_ctrl);
|
||||
data_send(buf_ctrl);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -362,11 +381,16 @@ static void usb_serve_endpoint(USBDriver *usbp, usbep_t ep, bool is_in) {
|
|||
iesp->txcnt = iesp->txlast;
|
||||
n = iesp->txsize - iesp->txcnt;
|
||||
if (n > 0) {
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_EP_NEXT, 1);
|
||||
data_send((1 << 7) | ep);
|
||||
#endif
|
||||
/* Transfer not completed, there are more packets to send. */
|
||||
usb_prepare_in_ep(usbp, ep);
|
||||
} else {
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_EP_DONE, 0);
|
||||
cmd_send(CMD_EP_DONE, 1);
|
||||
data_send((1 << 7) | ep);
|
||||
#endif
|
||||
/* Transfer complete */
|
||||
_usb_isr_invoke_in_cb(usbp, ep);
|
||||
|
@ -391,7 +415,8 @@ static void usb_serve_endpoint(USBDriver *usbp, usbep_t ep, bool is_in) {
|
|||
/* Short packet or all packetes have been received. */
|
||||
if (oesp->rxpkts <= 0 || n <= epcp->out_maxsize) {
|
||||
#ifdef USB_DEBUG
|
||||
//cmd_send(CMD_EP_DONE, 0);
|
||||
cmd_send(CMD_EP_DONE, 1);
|
||||
data_send(ep);
|
||||
#endif
|
||||
/* Transifer complete */
|
||||
_usb_isr_invoke_out_cb(usbp, ep);
|
||||
|
@ -426,9 +451,12 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
|||
/* USB setup packet handling. */
|
||||
if (ints & USB_INTS_SETUP_REQ) {
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_SETUP, 0);
|
||||
//cmd_send(CMD_SETUP, 0);
|
||||
#endif
|
||||
USB->CLR.SIESTATUS = USB_SIE_STATUS_SETUP_REC;
|
||||
|
||||
usbp->epc[0]->in_state->next_pid = 1U;
|
||||
|
||||
_usb_isr_invoke_setup_cb(usbp, 0);
|
||||
|
||||
reset_ep0(usbp);
|
||||
|
@ -437,20 +465,10 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
|||
/* USB bus reset condition handling. */
|
||||
if (ints & USB_INTS_BUS_RESET) {
|
||||
#ifdef USB_DEBUG
|
||||
//cmd_send(CMD_RESET, 0);
|
||||
cmd_send(CMD_RESET, 0);
|
||||
#endif
|
||||
USB->CLR.SIESTATUS = USB_SIE_STATUS_BUS_RESET;
|
||||
|
||||
/* Reset device address. */
|
||||
USB->DEVADDRCTRL = 0;
|
||||
|
||||
/* Reset all endpoint. */
|
||||
/*
|
||||
for (int i = 1; i < USB_ENDOPOINTS_NUMBER; i++) {
|
||||
reset_endpoint(usbp, i, true);
|
||||
reset_endpoint(usbp, i, false);
|
||||
}
|
||||
*/
|
||||
_usb_reset(usbp);
|
||||
}
|
||||
|
||||
|
@ -479,7 +497,8 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
|||
/* Endpoint events handling.*/
|
||||
if (ints & USB_INTS_BUFF_STATUS) {
|
||||
#ifdef USB_DEBUG
|
||||
//cmd_send(CMD_BUFF_STATUS, 0);
|
||||
cmd_send(CMD_BUFF_STATUS, 1);
|
||||
data_send(USB->BUFSTATUS);
|
||||
#endif
|
||||
uint32_t buf_status = USB->BUFSTATUS;
|
||||
uint32_t bit = 1U;
|
||||
|
@ -487,7 +506,10 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
|||
if (buf_status & bit) {
|
||||
/* Clear flag */
|
||||
USB->SET.BUFSTATUS = bit;
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
//cmd_send(CMD_BUFF_STATUS, 1);
|
||||
//data_send(((i >> 1U) << 16) | (i & 1U));
|
||||
#endif
|
||||
/* Finish on the endpoint or transfer remained data */
|
||||
usb_serve_endpoint(&USBD1, i >> 1U, (i & 1U) == 0);
|
||||
|
||||
|
@ -537,6 +559,9 @@ void usb_lld_init(void) {
|
|||
*/
|
||||
void usb_lld_start(USBDriver *usbp) {
|
||||
#if RP_USB_USE_USBD1 == TRUE
|
||||
#ifdef USB_DEBUG
|
||||
chMtxObjectInit(&cmtx);
|
||||
#endif
|
||||
if (&USBD1 == usbp) {
|
||||
if (usbp->state == USB_STOP) {
|
||||
/* Reset usb controller */
|
||||
|
@ -625,6 +650,9 @@ void usb_lld_reset(USBDriver *usbp) {
|
|||
/* EP0 initialization.*/
|
||||
usbp->epc[0] = &ep0config;
|
||||
usb_lld_init_endpoint(usbp, 0);
|
||||
|
||||
/* Reset device address. */
|
||||
USB->DEVADDRCTRL = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -635,11 +663,14 @@ void usb_lld_reset(USBDriver *usbp) {
|
|||
* @notapi
|
||||
*/
|
||||
void usb_lld_set_address(USBDriver *usbp) {
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_SET_ADDR, 0);
|
||||
#endif
|
||||
/* Set address to hardware here. */
|
||||
USB->DEVADDRCTRL |= USB_ADDR_ENDP0_ADDRESS_Msk & (usbp->address << USB_ADDR_ENDP0_ADDRESS_Pos);
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_SET_ADDR, 1);
|
||||
data_send(usbp->address);
|
||||
#endif
|
||||
|
||||
reset_ep0(usbp);
|
||||
}
|
||||
|
||||
|
@ -662,7 +693,7 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
|||
if (ep == 0) {
|
||||
epcp->in_state->hw_buf = (uint8_t*)&USB_DPSRAM->EP0BUF0;
|
||||
epcp->in_state->buf_size = 64;
|
||||
USB->SET.SIECTRL = USB_SIE_CTRL_EP0_DOUBLE_BUF;
|
||||
USB->SET.SIECTRL = USB_EP_BUFFER_IRQ_EN;
|
||||
epcp->in_state->next_pid = 1U;
|
||||
epcp->in_state->active = false;
|
||||
epcp->in_state->stalled = false;
|
||||
|
@ -808,9 +839,11 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
|||
(void)usbp;
|
||||
(void)ep;
|
||||
#ifdef USB_DEBUG
|
||||
uint32_t data1 = *((uint32_t*)USB_DPSRAM->SETUPPACKET);
|
||||
uint32_t data2 = *((uint32_t*)(USB_DPSRAM->SETUPPACKET + 4));
|
||||
cmd_send(CMD_READ_SETUP, 2);
|
||||
data_send(*((uint32_t*)USB_DPSRAM->SETUPPACKET));
|
||||
data_send(*((uint32_t*)(USB_DPSRAM->SETUPPACKET + 4)));
|
||||
data_send(data1);
|
||||
data_send(data2);
|
||||
#endif
|
||||
/* Copy data from hardware buffer to user buffer */
|
||||
memcpy((void *)buf, (void *)USB_DPSRAM->SETUPPACKET, 8);
|
||||
|
@ -827,9 +860,7 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
|||
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
||||
(void)usbp;
|
||||
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||
#ifdef USB_DEBUG
|
||||
//cmd_send(CMD_START_OUT, 0);
|
||||
#endif
|
||||
|
||||
/* Transfer initialization.*/
|
||||
if (oesp->rxsize == 0) {
|
||||
/* Special case for zero sized packets.*/
|
||||
|
@ -839,6 +870,10 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
|||
usbp->epc[ep]->out_maxsize);
|
||||
}
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_START_OUT, 1);
|
||||
data_send((ep << 24) | oesp->rxsize | (oesp->rxpkts << 16));
|
||||
#endif
|
||||
/* Prepare OUT endpoint. */
|
||||
usb_prepare_out_ep(usbp, ep);
|
||||
}
|
||||
|
@ -854,7 +889,8 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
|||
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
||||
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
||||
#ifdef USB_DEBUG
|
||||
cmd_send(CMD_START_IN, 0);
|
||||
cmd_send(CMD_START_IN, 1);
|
||||
data_send((ep << 24) | iesp->txsize);
|
||||
#endif
|
||||
iesp->txlast = 0;
|
||||
|
||||
|
|
|
@ -50,12 +50,12 @@
|
|||
/**
|
||||
* @brief Address ack handling
|
||||
*/
|
||||
#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_HW
|
||||
#define USB_SET_ADDRESS_ACK_HANDLING USB_SET_ADDRESS_ACK_SW
|
||||
|
||||
/**
|
||||
* @brief This device requires the address change after the status packet.
|
||||
*/
|
||||
#define USB_SET_ADDRESS_MODE USB_EARLY_SET_ADDRESS
|
||||
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
CC=gcc
|
||||
CFLAGS = -Wall -Wextra -O2 -g
|
||||
|
||||
SRCS = $(wildcard *.c)
|
||||
OBJS = $(SRCS:%.c=%.o)
|
||||
EXE = test-usb-hid
|
||||
|
||||
all: $(EXE)
|
||||
|
||||
$(EXE): $(OBJS)
|
||||
|
||||
-include $(subst .c,.d,$(SRCS))
|
||||
|
||||
%.d: %.c
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -MM -MF $@ -MP -MT $(subst .c,.o,$<) $<
|
||||
|
||||
clean:
|
||||
rm -f $(EXE)
|
||||
rm -f $(OBJS)
|
||||
rm -f $(subst .c,.d,$(SRCS))
|
||||
rm -f *~
|
||||
|
||||
.PHONY: clean all
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2014 Guillaume Duc <guillaume@guiduc.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/hidraw.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define USB_HID_IN_REPORT_SIZE 1
|
||||
#define USB_HID_OUT_REPORT_SIZE 1
|
||||
|
||||
struct usb_hid_in_report_s
|
||||
{
|
||||
uint8_t sequence_number;
|
||||
};
|
||||
|
||||
struct usb_hid_out_report_s
|
||||
{
|
||||
uint8_t sequence_number;
|
||||
};
|
||||
|
||||
static uint8_t usb_hid_in_report_buf[USB_HID_IN_REPORT_SIZE];
|
||||
// +1 for the report index
|
||||
static uint8_t usb_hid_out_report_buf[USB_HID_OUT_REPORT_SIZE + 1];
|
||||
|
||||
static struct usb_hid_in_report_s *usb_hid_in_report =
|
||||
(struct usb_hid_in_report_s *) usb_hid_in_report_buf;
|
||||
|
||||
static struct usb_hid_out_report_s *usb_hid_out_report =
|
||||
(struct usb_hid_out_report_s *) (&usb_hid_out_report_buf[1]);
|
||||
|
||||
static int usb_hid_fd;
|
||||
static uint8_t wkup_pb_old_value = 0;
|
||||
|
||||
static void
|
||||
read_in_report ()
|
||||
{
|
||||
int res, i;
|
||||
|
||||
printf ("read()\n");
|
||||
res = read (usb_hid_fd, usb_hid_in_report_buf, USB_HID_IN_REPORT_SIZE);
|
||||
if (res < 0)
|
||||
{
|
||||
perror ("read");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("read() read %d bytes:\t", res);
|
||||
for (i = 0; i < res; i++)
|
||||
printf ("%02hhx ", usb_hid_in_report_buf[i]);
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
send_out_report ()
|
||||
{
|
||||
int res;
|
||||
|
||||
usb_hid_out_report_buf[0] = 0;
|
||||
|
||||
res =
|
||||
write (usb_hid_fd, usb_hid_out_report_buf, USB_HID_OUT_REPORT_SIZE + 1);
|
||||
if (res < 0)
|
||||
{
|
||||
perror ("write");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
usb_hid_out_report->sequence_number++;
|
||||
}
|
||||
|
||||
static void
|
||||
usb_hid_init (const char *dev_name)
|
||||
{
|
||||
int i, res;
|
||||
int desc_size = 0;
|
||||
char buf[256];
|
||||
|
||||
struct hidraw_report_descriptor rpt_desc;
|
||||
struct hidraw_devinfo info;
|
||||
|
||||
usb_hid_fd = open (dev_name, O_RDWR);
|
||||
|
||||
if (usb_hid_fd < 0)
|
||||
{
|
||||
perror ("Unable to open device");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memset (&rpt_desc, 0x0, sizeof (rpt_desc));
|
||||
memset (&info, 0x0, sizeof (info));
|
||||
memset (buf, 0x0, sizeof (buf));
|
||||
|
||||
// Get Report Descriptor Size
|
||||
res = ioctl (usb_hid_fd, HIDIOCGRDESCSIZE, &desc_size);
|
||||
if (res < 0)
|
||||
perror ("HIDIOCGRDESCSIZE");
|
||||
else
|
||||
printf ("Report Descriptor Size: %d\n", desc_size);
|
||||
|
||||
// Get Report Descriptor
|
||||
rpt_desc.size = desc_size;
|
||||
res = ioctl (usb_hid_fd, HIDIOCGRDESC, &rpt_desc);
|
||||
if (res < 0)
|
||||
{
|
||||
perror ("HIDIOCGRDESC");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Report Descriptor:\n");
|
||||
for (i = 0; i < rpt_desc.size; i++)
|
||||
printf ("%02hhx ", rpt_desc.value[i]);
|
||||
puts ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s /dev/hidrawX\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset (usb_hid_out_report_buf, 0, sizeof (usb_hid_out_report_buf));
|
||||
|
||||
usb_hid_init (argv[1]);
|
||||
usb_hid_out_report->sequence_number = 4;
|
||||
send_out_report ();
|
||||
|
||||
while (1)
|
||||
{
|
||||
read_in_report ();
|
||||
|
||||
if (usb_hid_in_report->sequence_number == 40)
|
||||
{
|
||||
usb_hid_out_report->sequence_number = usb_hid_in_report->sequence_number / 2;
|
||||
send_out_report ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close (usb_hid_fd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
SUBSYSTEM=="usb", ATTR{idVendor}=="0179", ATTR{idProduct}=="0002", MODE:="0666"
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0179", ATTRS{idProduct}=="0002", MODE:="0666"
|
|
@ -116,11 +116,10 @@ include $(CHIBIOS)/test/rt/rt_test.mk
|
|||
include $(CHIBIOS)/test/oslib/oslib_test.mk
|
||||
include $(CHIBIOS)/os/various/pico_bindings/pico-sdk.mk
|
||||
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
||||
include $(CHIBIOS)/os/various/shell/shell.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT= $(STARTUPLD)/RP2040_RAM.ld
|
||||
#LDSCRIPT= ./RP2040_FLASH.ld
|
||||
LDSCRIPT = $(STARTUPLD)/RP2040_RAM.ld
|
||||
#LDSCRIPT = ./RP2040_FLASH.ld
|
||||
|
||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
|
|
|
@ -20,24 +20,49 @@
|
|||
#ifdef USB_DEBUG
|
||||
|
||||
#include "rp_fifo.h"
|
||||
|
||||
#include "chprintf.h"
|
||||
#include "chmtx.h"
|
||||
|
||||
mutex_t mtx;
|
||||
|
||||
uint8_t remained_data = 0;
|
||||
|
||||
#define BUFFER_LEN 32
|
||||
|
||||
uint32_t buffer[BUFFER_LEN] = {
|
||||
0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
|
||||
0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U};
|
||||
uint8_t current_buffer_index = 0;
|
||||
uint8_t next_buffer_index = 0;
|
||||
uint8_t remained_len = 0;
|
||||
|
||||
void process_command(uint32_t data) {
|
||||
if (remained_data > 0) {
|
||||
remained_data -= 1;
|
||||
chprintf((BaseSequentialStream *)&SIOD0, "0x%X\r\n", data);
|
||||
} else {
|
||||
uint8_t cmd = (data & 0xFF000000) >> 24;
|
||||
uint8_t length = (data & 0xFF0000) >> 16;
|
||||
if (length > 0) {
|
||||
remained_data = length;
|
||||
}
|
||||
chprintf((BaseSequentialStream *)&SIOD0, "%X\r\n", cmd);
|
||||
//chMtxLock(&mtx);
|
||||
|
||||
buffer[next_buffer_index] = data;
|
||||
next_buffer_index += 1;
|
||||
if (next_buffer_index >= BUFFER_LEN) {
|
||||
next_buffer_index = 0;
|
||||
}
|
||||
remained_len += 1;
|
||||
|
||||
//chMtxUnlock(&mtx);
|
||||
}
|
||||
|
||||
#define CMD_RESET 0x0F
|
||||
#define CMD_SETUP 0x01
|
||||
#define CMD_READ_SETUP 0x02
|
||||
#define CMD_SET_ADDR 0x03
|
||||
#define CMD_START_IN 0x04
|
||||
#define CMD_START_OUT 0x05
|
||||
#define CMD_BUFF_STATUS 0x06
|
||||
#define CMD_EP_DONE 0x07
|
||||
#define CMD_DATA_ERROR 0x09
|
||||
#define CMD_PREP_IN_EP 0x0A
|
||||
#define CMD_PREP_OUT_EP 0x0B
|
||||
#define CMD_SET_ADDR_HW 0x0C
|
||||
#define CMD_EP_NEXT 0x0D
|
||||
|
||||
#endif // USB_DEBUG
|
||||
|
||||
/**
|
||||
|
@ -56,6 +81,8 @@ void c1_main(void) {
|
|||
chSysUnlock();
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
chMtxObjectInit(&mtx);
|
||||
//chSemObjectInit(&buff_sem, 0);
|
||||
/*
|
||||
* Setting up GPIOs.
|
||||
*/
|
||||
|
@ -77,6 +104,57 @@ void c1_main(void) {
|
|||
* sleeping in a loop (re)spawning a shell.
|
||||
*/
|
||||
while (true) {
|
||||
chThdSleepMilliseconds(200);
|
||||
#ifdef USB_DEBUG
|
||||
chMtxLock(&mtx);
|
||||
if (remained_len > 0) {
|
||||
const uint32_t data = buffer[current_buffer_index];
|
||||
current_buffer_index += 1;
|
||||
if (current_buffer_index >= BUFFER_LEN) {
|
||||
current_buffer_index = 0;
|
||||
}
|
||||
remained_len -= 1;
|
||||
|
||||
if (remained_data > 0) {
|
||||
remained_data -= 1;
|
||||
chprintf((BaseSequentialStream *)&SIOD0, "0x%X", data);
|
||||
if (remained_data) {
|
||||
chprintf((BaseSequentialStream *)&SIOD0, ", ");
|
||||
} else {
|
||||
chprintf((BaseSequentialStream *)&SIOD0, "\r\n");
|
||||
}
|
||||
} else {
|
||||
uint8_t cmd = (data & 0xFF000000) >> 24;
|
||||
uint8_t length = (data & 0xFF0000) >> 16;
|
||||
if (length > 0) {
|
||||
remained_data = length;
|
||||
}
|
||||
const char *text = NULL;
|
||||
switch (cmd) {
|
||||
case CMD_RESET: text = "Reset\r\n"; break;
|
||||
case CMD_SETUP: text = "Setup req\r\n"; break;
|
||||
case CMD_READ_SETUP: text = "Read setup data: "; break;
|
||||
case CMD_SET_ADDR: text = "Set address: "; break;
|
||||
case CMD_START_IN: text = "Start in: "; break;
|
||||
case CMD_START_OUT: text = "Start out: "; break;
|
||||
case CMD_EP_DONE: text = "Endpoint done: "; break;
|
||||
case CMD_BUFF_STATUS: text = "Buffer status: "; break;
|
||||
case CMD_PREP_IN_EP: text = "Prepare IN endpoint: "; break;
|
||||
case CMD_PREP_OUT_EP: text = "Prepare OUT endpoint: "; break;
|
||||
case CMD_SET_ADDR_HW: text = "Set address to hw: "; break;
|
||||
case CMD_DATA_ERROR: text = "Data error\r\n"; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (text) {
|
||||
chprintf((BaseSequentialStream *)&SIOD0, text);
|
||||
} else {
|
||||
chprintf((BaseSequentialStream *)&SIOD0, "%X\r\n", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
chMtxUnlock(&mtx);
|
||||
#else
|
||||
chThdSleepMilliseconds(50);
|
||||
#endif // USB_DEBUG
|
||||
}
|
||||
}
|
||||
|
|
|
@ -814,6 +814,10 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
#ifdef USB_DEBUG
|
||||
#include <stdint.h>
|
||||
|
||||
extern void process_command(uint32_t message);
|
||||
|
||||
#define PORT_HANDLE_FIFO_MESSAGE(core, message) \
|
||||
if (core == 0U) { process_command(message); }
|
||||
#endif /* USB_DEBUG */
|
||||
|
|
|
@ -17,14 +17,10 @@
|
|||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
//#include "chprintf.h"
|
||||
|
||||
#include "usbcfg.h"
|
||||
|
||||
#define LED_GREEN_PIN 25U
|
||||
|
||||
//semaphore_t blinker_sem;
|
||||
|
||||
/*
|
||||
* Green LED blinker thread, times are in milliseconds.
|
||||
*/
|
||||
|
@ -34,8 +30,7 @@ static THD_FUNCTION(Thread1, arg) {
|
|||
(void)arg;
|
||||
chRegSetThreadName("blinker");
|
||||
while (true) {
|
||||
//chSemWait(&blinker_sem);
|
||||
systime_t time = USBD1.state == USB_ACTIVE ? 125 : 1000;
|
||||
systime_t time = USBD1.state == USB_ACTIVE ? 250 : 1000;
|
||||
chThdSleepMilliseconds(time);
|
||||
palToggleLine(LED_GREEN_PIN);
|
||||
}
|
||||
|
@ -45,12 +40,6 @@ static THD_FUNCTION(Thread1, arg) {
|
|||
* Application entry point.
|
||||
*/
|
||||
int main(void) {
|
||||
|
||||
/*
|
||||
* Shared objects initialization.
|
||||
*/
|
||||
//chSemObjectInit(&blinker_sem, 0);
|
||||
|
||||
/*
|
||||
* System initializations.
|
||||
* - HAL initialization, this also initializes the configured device drivers
|
||||
|
@ -61,21 +50,9 @@ int main(void) {
|
|||
halInit();
|
||||
chSysInit();
|
||||
|
||||
/*
|
||||
palSetLineMode(0U, PAL_MODE_ALTERNATE_UART);
|
||||
palSetLineMode(1U, PAL_MODE_ALTERNATE_UART);
|
||||
*/
|
||||
/*
|
||||
* Activates the UART0 SIO driver using the default configuration.
|
||||
*/
|
||||
/*
|
||||
sioStart(&SIOD0, NULL);
|
||||
sioStartOperation(&SIOD0, NULL);
|
||||
*/
|
||||
/*
|
||||
* Initializes a USB HID driver.
|
||||
*/
|
||||
|
||||
hidObjectInit(&UHD1);
|
||||
hidStart(&UHD1, &usbhidcfg);
|
||||
|
||||
|
@ -84,8 +61,6 @@ int main(void) {
|
|||
* Note, a delay is inserted in order to not have to disconnect the cable
|
||||
* after a reset.
|
||||
*/
|
||||
//chprintf((BaseSequentialStream *)&SIOD0, "-- Start usb connection\r\n");
|
||||
|
||||
usbDisconnectBus(usbhidcfg.usbp);
|
||||
chThdSleepMilliseconds(1000);
|
||||
usbStart(usbhidcfg.usbp, &usbcfg);
|
||||
|
@ -101,15 +76,11 @@ int main(void) {
|
|||
*/
|
||||
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
||||
|
||||
//BaseSequentialStream *chp = &SIOD0;
|
||||
//chprintf((BaseSequentialStream *)&SIOD0, "-- Started in c0\r\n");
|
||||
|
||||
/*
|
||||
* Normal main() thread activity, in this demo it does nothing except
|
||||
* sleeping in a loop.
|
||||
*/
|
||||
while (true) {
|
||||
/*
|
||||
if (usbhidcfg.usbp->state == USB_ACTIVE) {
|
||||
uint8_t report;
|
||||
size_t n = hidGetReport(0, &report, sizeof(report));
|
||||
|
@ -118,7 +89,6 @@ int main(void) {
|
|||
if (n > 0)
|
||||
hidSetReport(0, &report, n);
|
||||
}
|
||||
*/
|
||||
chThdSleepMilliseconds(500);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue