Fix set buffer control
This commit is contained in:
parent
fea5fe0b5b
commit
d98bf4c347
|
@ -34,9 +34,12 @@
|
||||||
|
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
|
|
||||||
|
#include "chmtx.h"
|
||||||
#include "rp_fifo.h"
|
#include "rp_fifo.h"
|
||||||
|
|
||||||
#define CMD_RESET 0x00
|
mutex_t cmtx;
|
||||||
|
|
||||||
|
#define CMD_RESET 0x0F
|
||||||
#define CMD_SETUP 0x01
|
#define CMD_SETUP 0x01
|
||||||
#define CMD_READ_SETUP 0x02
|
#define CMD_READ_SETUP 0x02
|
||||||
#define CMD_SET_ADDR 0x03
|
#define CMD_SET_ADDR 0x03
|
||||||
|
@ -45,6 +48,10 @@
|
||||||
#define CMD_BUFF_STATUS 0x06
|
#define CMD_BUFF_STATUS 0x06
|
||||||
#define CMD_EP_DONE 0x07
|
#define CMD_EP_DONE 0x07
|
||||||
#define CMD_DATA_ERROR 0x09
|
#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) {
|
void cmd_send(uint8_t cmd, uint8_t length) {
|
||||||
uint32_t data = (cmd << 24) | (length << 16);
|
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;
|
uint16_t buf_len;
|
||||||
uint32_t buf_ctrl = 0;
|
uint32_t buf_ctrl = 0;
|
||||||
const USBEndpointConfig *epcp = usbp->epc[ep];
|
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 (!(buf_len == 0 && buffer_index == 1)) {
|
||||||
if ((iesp->rxpkts == 1 && buffer_index == 0) ||
|
/* Host only? */
|
||||||
(iesp->rxpkts == 2 && buffer_index == 1)) {
|
//if ((oesp->rxpkts == 1 && buffer_index == 0) ||
|
||||||
|
// (oesp->rxpkts == 2 && buffer_index == 1)) {
|
||||||
/* Last buffer */
|
/* Last buffer */
|
||||||
buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
//buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
||||||
}
|
//}
|
||||||
/* PID */
|
/* PID */
|
||||||
buf_ctrl |= iesp->next_pid ? USB_BUFFER_BUFFER1_DATA_PID : USB_BUFFER_BUFFER0_DATA_PID;
|
buf_ctrl |= oesp->next_pid ? USB_BUFFER_BUFFER0_DATA_PID : 0;
|
||||||
iesp->next_pid ^= 1U;
|
oesp->next_pid ^= 1U;
|
||||||
|
|
||||||
buf_ctrl |= USB_BUFFER_BUFFER0_AVAILABLE |
|
buf_ctrl |= USB_BUFFER_BUFFER0_AVAILABLE |
|
||||||
buf_len;
|
buf_len;
|
||||||
|
|
||||||
iesp->active = true;
|
oesp->active = true;
|
||||||
if (buffer_index) {
|
if (buffer_index) {
|
||||||
buf_ctrl = buf_ctrl << 16;
|
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;
|
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 ?
|
buf_len = epcp->in_maxsize < iesp->txsize - iesp->txlast ?
|
||||||
epcp->in_maxsize : iesp->txsize - iesp->txlast;
|
epcp->in_maxsize : iesp->txsize - iesp->txlast;
|
||||||
|
|
||||||
if (buf_len > 0) {
|
|
||||||
iesp->txlast += buf_len;
|
iesp->txlast += buf_len;
|
||||||
|
|
||||||
if (iesp->txsize <= iesp->txlast) {
|
/* Host only? */
|
||||||
|
//if (iesp->txsize <= iesp->txlast) {
|
||||||
/* Last buffer */
|
/* Last buffer */
|
||||||
buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
//buf_ctrl |= USB_BUFFER_BUFFER0_LAST;
|
||||||
}
|
//}
|
||||||
/* PID */
|
/* 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;
|
iesp->next_pid ^= 1U;
|
||||||
|
|
||||||
/* Copy data into hardware buffer */
|
/* 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) {
|
if (buffer_index) {
|
||||||
buf_ctrl = buf_ctrl << 16;
|
buf_ctrl = buf_ctrl << 16;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return buf_ctrl;
|
return buf_ctrl;
|
||||||
}
|
}
|
||||||
|
@ -342,7 +355,13 @@ static void usb_prepare_in_ep(USBDriver *usbp, usbep_t ep) {
|
||||||
EP_CTRL(ep).IN = ep_ctrl;
|
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;
|
iesp->txcnt = iesp->txlast;
|
||||||
n = iesp->txsize - iesp->txcnt;
|
n = iesp->txsize - iesp->txcnt;
|
||||||
if (n > 0) {
|
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. */
|
/* Transfer not completed, there are more packets to send. */
|
||||||
usb_prepare_in_ep(usbp, ep);
|
usb_prepare_in_ep(usbp, ep);
|
||||||
} else {
|
} else {
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
cmd_send(CMD_EP_DONE, 0);
|
cmd_send(CMD_EP_DONE, 1);
|
||||||
|
data_send((1 << 7) | ep);
|
||||||
#endif
|
#endif
|
||||||
/* Transfer complete */
|
/* Transfer complete */
|
||||||
_usb_isr_invoke_in_cb(usbp, ep);
|
_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. */
|
/* Short packet or all packetes have been received. */
|
||||||
if (oesp->rxpkts <= 0 || n <= epcp->out_maxsize) {
|
if (oesp->rxpkts <= 0 || n <= epcp->out_maxsize) {
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
//cmd_send(CMD_EP_DONE, 0);
|
cmd_send(CMD_EP_DONE, 1);
|
||||||
|
data_send(ep);
|
||||||
#endif
|
#endif
|
||||||
/* Transifer complete */
|
/* Transifer complete */
|
||||||
_usb_isr_invoke_out_cb(usbp, ep);
|
_usb_isr_invoke_out_cb(usbp, ep);
|
||||||
|
@ -426,9 +451,12 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
||||||
/* USB setup packet handling. */
|
/* USB setup packet handling. */
|
||||||
if (ints & USB_INTS_SETUP_REQ) {
|
if (ints & USB_INTS_SETUP_REQ) {
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
cmd_send(CMD_SETUP, 0);
|
//cmd_send(CMD_SETUP, 0);
|
||||||
#endif
|
#endif
|
||||||
USB->CLR.SIESTATUS = USB_SIE_STATUS_SETUP_REC;
|
USB->CLR.SIESTATUS = USB_SIE_STATUS_SETUP_REC;
|
||||||
|
|
||||||
|
usbp->epc[0]->in_state->next_pid = 1U;
|
||||||
|
|
||||||
_usb_isr_invoke_setup_cb(usbp, 0);
|
_usb_isr_invoke_setup_cb(usbp, 0);
|
||||||
|
|
||||||
reset_ep0(usbp);
|
reset_ep0(usbp);
|
||||||
|
@ -437,20 +465,10 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
||||||
/* USB bus reset condition handling. */
|
/* USB bus reset condition handling. */
|
||||||
if (ints & USB_INTS_BUS_RESET) {
|
if (ints & USB_INTS_BUS_RESET) {
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
//cmd_send(CMD_RESET, 0);
|
cmd_send(CMD_RESET, 0);
|
||||||
#endif
|
#endif
|
||||||
USB->CLR.SIESTATUS = USB_SIE_STATUS_BUS_RESET;
|
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);
|
_usb_reset(usbp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +497,8 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
||||||
/* Endpoint events handling.*/
|
/* Endpoint events handling.*/
|
||||||
if (ints & USB_INTS_BUFF_STATUS) {
|
if (ints & USB_INTS_BUFF_STATUS) {
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
//cmd_send(CMD_BUFF_STATUS, 0);
|
cmd_send(CMD_BUFF_STATUS, 1);
|
||||||
|
data_send(USB->BUFSTATUS);
|
||||||
#endif
|
#endif
|
||||||
uint32_t buf_status = USB->BUFSTATUS;
|
uint32_t buf_status = USB->BUFSTATUS;
|
||||||
uint32_t bit = 1U;
|
uint32_t bit = 1U;
|
||||||
|
@ -487,7 +506,10 @@ OSAL_IRQ_HANDLER(RP_USBCTRL_IRQ_HANDLER) {
|
||||||
if (buf_status & bit) {
|
if (buf_status & bit) {
|
||||||
/* Clear flag */
|
/* Clear flag */
|
||||||
USB->SET.BUFSTATUS = bit;
|
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 */
|
/* Finish on the endpoint or transfer remained data */
|
||||||
usb_serve_endpoint(&USBD1, i >> 1U, (i & 1U) == 0);
|
usb_serve_endpoint(&USBD1, i >> 1U, (i & 1U) == 0);
|
||||||
|
|
||||||
|
@ -537,6 +559,9 @@ void usb_lld_init(void) {
|
||||||
*/
|
*/
|
||||||
void usb_lld_start(USBDriver *usbp) {
|
void usb_lld_start(USBDriver *usbp) {
|
||||||
#if RP_USB_USE_USBD1 == TRUE
|
#if RP_USB_USE_USBD1 == TRUE
|
||||||
|
#ifdef USB_DEBUG
|
||||||
|
chMtxObjectInit(&cmtx);
|
||||||
|
#endif
|
||||||
if (&USBD1 == usbp) {
|
if (&USBD1 == usbp) {
|
||||||
if (usbp->state == USB_STOP) {
|
if (usbp->state == USB_STOP) {
|
||||||
/* Reset usb controller */
|
/* Reset usb controller */
|
||||||
|
@ -625,6 +650,9 @@ void usb_lld_reset(USBDriver *usbp) {
|
||||||
/* EP0 initialization.*/
|
/* EP0 initialization.*/
|
||||||
usbp->epc[0] = &ep0config;
|
usbp->epc[0] = &ep0config;
|
||||||
usb_lld_init_endpoint(usbp, 0);
|
usb_lld_init_endpoint(usbp, 0);
|
||||||
|
|
||||||
|
/* Reset device address. */
|
||||||
|
USB->DEVADDRCTRL = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -635,11 +663,14 @@ void usb_lld_reset(USBDriver *usbp) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void usb_lld_set_address(USBDriver *usbp) {
|
void usb_lld_set_address(USBDriver *usbp) {
|
||||||
#ifdef USB_DEBUG
|
/* Set address to hardware here. */
|
||||||
cmd_send(CMD_SET_ADDR, 0);
|
|
||||||
#endif
|
|
||||||
USB->DEVADDRCTRL |= USB_ADDR_ENDP0_ADDRESS_Msk & (usbp->address << USB_ADDR_ENDP0_ADDRESS_Pos);
|
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);
|
reset_ep0(usbp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +693,7 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
||||||
if (ep == 0) {
|
if (ep == 0) {
|
||||||
epcp->in_state->hw_buf = (uint8_t*)&USB_DPSRAM->EP0BUF0;
|
epcp->in_state->hw_buf = (uint8_t*)&USB_DPSRAM->EP0BUF0;
|
||||||
epcp->in_state->buf_size = 64;
|
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->next_pid = 1U;
|
||||||
epcp->in_state->active = false;
|
epcp->in_state->active = false;
|
||||||
epcp->in_state->stalled = 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)usbp;
|
||||||
(void)ep;
|
(void)ep;
|
||||||
#ifdef USB_DEBUG
|
#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);
|
cmd_send(CMD_READ_SETUP, 2);
|
||||||
data_send(*((uint32_t*)USB_DPSRAM->SETUPPACKET));
|
data_send(data1);
|
||||||
data_send(*((uint32_t*)(USB_DPSRAM->SETUPPACKET + 4)));
|
data_send(data2);
|
||||||
#endif
|
#endif
|
||||||
/* Copy data from hardware buffer to user buffer */
|
/* Copy data from hardware buffer to user buffer */
|
||||||
memcpy((void *)buf, (void *)USB_DPSRAM->SETUPPACKET, 8);
|
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 usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
||||||
(void)usbp;
|
(void)usbp;
|
||||||
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
USBOutEndpointState *oesp = usbp->epc[ep]->out_state;
|
||||||
#ifdef USB_DEBUG
|
|
||||||
//cmd_send(CMD_START_OUT, 0);
|
|
||||||
#endif
|
|
||||||
/* Transfer initialization.*/
|
/* Transfer initialization.*/
|
||||||
if (oesp->rxsize == 0) {
|
if (oesp->rxsize == 0) {
|
||||||
/* Special case for zero sized packets.*/
|
/* 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);
|
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. */
|
/* Prepare OUT endpoint. */
|
||||||
usb_prepare_out_ep(usbp, ep);
|
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) {
|
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
||||||
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
USBInEndpointState *iesp = usbp->epc[ep]->in_state;
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
cmd_send(CMD_START_IN, 0);
|
cmd_send(CMD_START_IN, 1);
|
||||||
|
data_send((ep << 24) | iesp->txsize);
|
||||||
#endif
|
#endif
|
||||||
iesp->txlast = 0;
|
iesp->txlast = 0;
|
||||||
|
|
||||||
|
|
|
@ -50,12 +50,12 @@
|
||||||
/**
|
/**
|
||||||
* @brief Address ack handling
|
* @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.
|
* @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. */
|
/* 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)/test/oslib/oslib_test.mk
|
||||||
include $(CHIBIOS)/os/various/pico_bindings/pico-sdk.mk
|
include $(CHIBIOS)/os/various/pico_bindings/pico-sdk.mk
|
||||||
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
include $(CHIBIOS)/os/hal/lib/streams/streams.mk
|
||||||
include $(CHIBIOS)/os/various/shell/shell.mk
|
|
||||||
|
|
||||||
# Define linker script file here
|
# Define linker script file here
|
||||||
LDSCRIPT= $(STARTUPLD)/RP2040_RAM.ld
|
LDSCRIPT = $(STARTUPLD)/RP2040_RAM.ld
|
||||||
#LDSCRIPT= ./RP2040_FLASH.ld
|
#LDSCRIPT = ./RP2040_FLASH.ld
|
||||||
|
|
||||||
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
# C sources that can be compiled in ARM or THUMB mode depending on the global
|
||||||
# setting.
|
# setting.
|
||||||
|
|
|
@ -20,24 +20,49 @@
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
|
|
||||||
#include "rp_fifo.h"
|
#include "rp_fifo.h"
|
||||||
|
|
||||||
#include "chprintf.h"
|
#include "chprintf.h"
|
||||||
|
#include "chmtx.h"
|
||||||
|
|
||||||
|
mutex_t mtx;
|
||||||
|
|
||||||
uint8_t remained_data = 0;
|
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) {
|
void process_command(uint32_t data) {
|
||||||
if (remained_data > 0) {
|
//chMtxLock(&mtx);
|
||||||
remained_data -= 1;
|
|
||||||
chprintf((BaseSequentialStream *)&SIOD0, "0x%X\r\n", data);
|
buffer[next_buffer_index] = data;
|
||||||
} else {
|
next_buffer_index += 1;
|
||||||
uint8_t cmd = (data & 0xFF000000) >> 24;
|
if (next_buffer_index >= BUFFER_LEN) {
|
||||||
uint8_t length = (data & 0xFF0000) >> 16;
|
next_buffer_index = 0;
|
||||||
if (length > 0) {
|
|
||||||
remained_data = length;
|
|
||||||
}
|
|
||||||
chprintf((BaseSequentialStream *)&SIOD0, "%X\r\n", cmd);
|
|
||||||
}
|
}
|
||||||
|
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
|
#endif // USB_DEBUG
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,6 +81,8 @@ void c1_main(void) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
|
chMtxObjectInit(&mtx);
|
||||||
|
//chSemObjectInit(&buff_sem, 0);
|
||||||
/*
|
/*
|
||||||
* Setting up GPIOs.
|
* Setting up GPIOs.
|
||||||
*/
|
*/
|
||||||
|
@ -77,6 +104,57 @@ void c1_main(void) {
|
||||||
* sleeping in a loop (re)spawning a shell.
|
* sleeping in a loop (re)spawning a shell.
|
||||||
*/
|
*/
|
||||||
while (true) {
|
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
|
#ifdef USB_DEBUG
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void process_command(uint32_t message);
|
||||||
|
|
||||||
#define PORT_HANDLE_FIFO_MESSAGE(core, message) \
|
#define PORT_HANDLE_FIFO_MESSAGE(core, message) \
|
||||||
if (core == 0U) { process_command(message); }
|
if (core == 0U) { process_command(message); }
|
||||||
#endif /* USB_DEBUG */
|
#endif /* USB_DEBUG */
|
||||||
|
|
|
@ -17,14 +17,10 @@
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
//#include "chprintf.h"
|
|
||||||
|
|
||||||
#include "usbcfg.h"
|
#include "usbcfg.h"
|
||||||
|
|
||||||
#define LED_GREEN_PIN 25U
|
#define LED_GREEN_PIN 25U
|
||||||
|
|
||||||
//semaphore_t blinker_sem;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Green LED blinker thread, times are in milliseconds.
|
* Green LED blinker thread, times are in milliseconds.
|
||||||
*/
|
*/
|
||||||
|
@ -34,8 +30,7 @@ static THD_FUNCTION(Thread1, arg) {
|
||||||
(void)arg;
|
(void)arg;
|
||||||
chRegSetThreadName("blinker");
|
chRegSetThreadName("blinker");
|
||||||
while (true) {
|
while (true) {
|
||||||
//chSemWait(&blinker_sem);
|
systime_t time = USBD1.state == USB_ACTIVE ? 250 : 1000;
|
||||||
systime_t time = USBD1.state == USB_ACTIVE ? 125 : 1000;
|
|
||||||
chThdSleepMilliseconds(time);
|
chThdSleepMilliseconds(time);
|
||||||
palToggleLine(LED_GREEN_PIN);
|
palToggleLine(LED_GREEN_PIN);
|
||||||
}
|
}
|
||||||
|
@ -45,12 +40,6 @@ static THD_FUNCTION(Thread1, arg) {
|
||||||
* Application entry point.
|
* Application entry point.
|
||||||
*/
|
*/
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
/*
|
|
||||||
* Shared objects initialization.
|
|
||||||
*/
|
|
||||||
//chSemObjectInit(&blinker_sem, 0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System initializations.
|
* System initializations.
|
||||||
* - HAL initialization, this also initializes the configured device drivers
|
* - HAL initialization, this also initializes the configured device drivers
|
||||||
|
@ -61,21 +50,9 @@ int main(void) {
|
||||||
halInit();
|
halInit();
|
||||||
chSysInit();
|
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.
|
* Initializes a USB HID driver.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hidObjectInit(&UHD1);
|
hidObjectInit(&UHD1);
|
||||||
hidStart(&UHD1, &usbhidcfg);
|
hidStart(&UHD1, &usbhidcfg);
|
||||||
|
|
||||||
|
@ -84,8 +61,6 @@ int main(void) {
|
||||||
* Note, a delay is inserted in order to not have to disconnect the cable
|
* Note, a delay is inserted in order to not have to disconnect the cable
|
||||||
* after a reset.
|
* after a reset.
|
||||||
*/
|
*/
|
||||||
//chprintf((BaseSequentialStream *)&SIOD0, "-- Start usb connection\r\n");
|
|
||||||
|
|
||||||
usbDisconnectBus(usbhidcfg.usbp);
|
usbDisconnectBus(usbhidcfg.usbp);
|
||||||
chThdSleepMilliseconds(1000);
|
chThdSleepMilliseconds(1000);
|
||||||
usbStart(usbhidcfg.usbp, &usbcfg);
|
usbStart(usbhidcfg.usbp, &usbcfg);
|
||||||
|
@ -101,15 +76,11 @@ int main(void) {
|
||||||
*/
|
*/
|
||||||
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
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
|
* Normal main() thread activity, in this demo it does nothing except
|
||||||
* sleeping in a loop.
|
* sleeping in a loop.
|
||||||
*/
|
*/
|
||||||
while (true) {
|
while (true) {
|
||||||
/*
|
|
||||||
if (usbhidcfg.usbp->state == USB_ACTIVE) {
|
if (usbhidcfg.usbp->state == USB_ACTIVE) {
|
||||||
uint8_t report;
|
uint8_t report;
|
||||||
size_t n = hidGetReport(0, &report, sizeof(report));
|
size_t n = hidGetReport(0, &report, sizeof(report));
|
||||||
|
@ -118,7 +89,6 @@ int main(void) {
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
hidSetReport(0, &report, n);
|
hidSetReport(0, &report, n);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
chThdSleepMilliseconds(500);
|
chThdSleepMilliseconds(500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue