|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "usb_dev.h" |
|
|
#include "usb_dev.h" |
|
|
#include "usb_rawhid.h" |
|
|
#include "usb_rawhid.h" |
|
|
|
|
|
#include "avr/pgmspace.h" // for PROGMEM, DMAMEM, FASTRUN |
|
|
#include "core_pins.h" // for yield(), millis() |
|
|
#include "core_pins.h" // for yield(), millis() |
|
|
#include <string.h> // for memcpy() |
|
|
#include <string.h> // for memcpy() |
|
|
//#include "HardwareSerial.h" |
|
|
//#include "HardwareSerial.h" |
|
|
|
|
|
|
|
|
static uint8_t txbuffer[RAWHID_TX_SIZE * TX_NUM]; |
|
|
static uint8_t txbuffer[RAWHID_TX_SIZE * TX_NUM]; |
|
|
static uint8_t tx_head=0; |
|
|
static uint8_t tx_head=0; |
|
|
|
|
|
|
|
|
static transfer_t rx_transfer[1] __attribute__ ((used, aligned(32))); |
|
|
|
|
|
static uint8_t rx_buffer[RAWHID_RX_SIZE]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define RX_NUM 4 |
|
|
|
|
|
static transfer_t rx_transfer[RX_NUM] __attribute__ ((used, aligned(32))); |
|
|
|
|
|
DMAMEM static uint8_t rx_buffer[RAWHID_RX_SIZE * RX_NUM] __attribute__ ((aligned(32))); |
|
|
|
|
|
static volatile uint8_t rx_head; |
|
|
|
|
|
static volatile uint8_t rx_tail; |
|
|
|
|
|
static uint8_t rx_list[RX_NUM + 1]; |
|
|
|
|
|
static volatile uint32_t rx_available; |
|
|
|
|
|
static void rx_queue_transfer(int i); |
|
|
|
|
|
static void rx_event(transfer_t *t); |
|
|
extern volatile uint8_t usb_configuration; |
|
|
extern volatile uint8_t usb_configuration; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void rx_event(transfer_t *t) |
|
|
|
|
|
{ |
|
|
|
|
|
//printf("rx\n"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void usb_rawhid_configure(void) |
|
|
void usb_rawhid_configure(void) |
|
|
{ |
|
|
{ |
|
|
printf("usb_rawhid_configure\n"); |
|
|
printf("usb_rawhid_configure\n"); |
|
|
memset(tx_transfer, 0, sizeof(tx_transfer)); |
|
|
memset(tx_transfer, 0, sizeof(tx_transfer)); |
|
|
memset(rx_transfer, 0, sizeof(rx_transfer)); |
|
|
memset(rx_transfer, 0, sizeof(rx_transfer)); |
|
|
tx_head = 0; |
|
|
tx_head = 0; |
|
|
|
|
|
rx_head = 0; |
|
|
|
|
|
rx_tail = 0; |
|
|
usb_config_tx(RAWHID_TX_ENDPOINT, RAWHID_TX_SIZE, 0, NULL); |
|
|
usb_config_tx(RAWHID_TX_ENDPOINT, RAWHID_TX_SIZE, 0, NULL); |
|
|
usb_config_rx(RAWHID_RX_ENDPOINT, RAWHID_RX_SIZE, 0, rx_event); |
|
|
usb_config_rx(RAWHID_RX_ENDPOINT, RAWHID_RX_SIZE, 0, rx_event); |
|
|
//usb_config_rx(RAWHID_RX_ENDPOINT, RAWHID_RX_SIZE, 0, NULL); // why does this not work? |
|
|
|
|
|
usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0); |
|
|
|
|
|
usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0); |
|
|
|
|
|
|
|
|
int i; |
|
|
|
|
|
for (i=0; i < RX_NUM; i++) rx_queue_transfer(i); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
/** Receive **/ |
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
static void rx_queue_transfer(int i) |
|
|
|
|
|
{ |
|
|
|
|
|
void *buffer = rx_buffer + i * RAWHID_RX_SIZE; |
|
|
|
|
|
arm_dcache_delete(buffer, RAWHID_RX_SIZE); |
|
|
|
|
|
//memset(buffer, ) |
|
|
|
|
|
NVIC_DISABLE_IRQ(IRQ_USB1); |
|
|
|
|
|
usb_prepare_transfer(rx_transfer + i, buffer, RAWHID_RX_SIZE, i); |
|
|
|
|
|
usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + i); |
|
|
|
|
|
NVIC_ENABLE_IRQ(IRQ_USB1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void rx_event(transfer_t *t) |
|
|
|
|
|
{ |
|
|
|
|
|
int i = t->callback_param; |
|
|
|
|
|
//printf("rx event i=%d\n", i); |
|
|
|
|
|
// received a packet with data |
|
|
|
|
|
uint32_t head = rx_head; |
|
|
|
|
|
if (++head > RX_NUM) head = 0; |
|
|
|
|
|
rx_list[head] = i; |
|
|
|
|
|
rx_head = head; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int usb_rawhid_recv(void *buffer, uint32_t timeout) |
|
|
int usb_rawhid_recv(void *buffer, uint32_t timeout) |
|
|
{ |
|
|
{ |
|
|
uint32_t wait_begin_at = systick_millis_count; |
|
|
uint32_t wait_begin_at = systick_millis_count; |
|
|
|
|
|
uint32_t tail = rx_tail; |
|
|
while (1) { |
|
|
while (1) { |
|
|
if (!usb_configuration) return -1; // usb not enumerated by host |
|
|
if (!usb_configuration) return -1; // usb not enumerated by host |
|
|
uint32_t status = usb_transfer_status(rx_transfer); |
|
|
|
|
|
if (!(status & 0x80)) break; // transfer descriptor ready |
|
|
|
|
|
if (systick_millis_count - wait_begin_at > timeout) return 0; |
|
|
|
|
|
|
|
|
if (tail != rx_head) break; |
|
|
|
|
|
if (systick_millis_count - wait_begin_at > timeout) { |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
yield(); |
|
|
yield(); |
|
|
} |
|
|
} |
|
|
memcpy(buffer, rx_buffer, RAWHID_RX_SIZE); |
|
|
|
|
|
memset(rx_transfer, 0, sizeof(rx_transfer)); |
|
|
|
|
|
usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0); |
|
|
|
|
|
usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0); |
|
|
|
|
|
|
|
|
// digitalWriteFast(0, LOW); |
|
|
|
|
|
if (++tail > RX_NUM) tail = 0; |
|
|
|
|
|
uint32_t i = rx_list[tail]; |
|
|
|
|
|
rx_tail = tail; |
|
|
|
|
|
|
|
|
|
|
|
memcpy(buffer, rx_buffer + i * RAWHID_RX_SIZE, RAWHID_RX_SIZE); |
|
|
|
|
|
rx_queue_transfer(i); |
|
|
|
|
|
//memset(rx_transfer, 0, sizeof(rx_transfer)); |
|
|
|
|
|
//usb_prepare_transfer(rx_transfer + 0, rx_buffer, RAWHID_RX_SIZE, 0); |
|
|
|
|
|
//usb_receive(RAWHID_RX_ENDPOINT, rx_transfer + 0); |
|
|
return RAWHID_RX_SIZE; |
|
|
return RAWHID_RX_SIZE; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int usb_rawhid_available(void) |
|
|
int usb_rawhid_available(void) |
|
|
{ |
|
|
{ |
|
|
if (!usb_configuration) return 0; |
|
|
if (!usb_configuration) return 0; |
|
|
if (!(usb_transfer_status(rx_transfer) & 0x80)) return RAWHID_RX_SIZE; |
|
|
|
|
|
|
|
|
if (rx_head != rx_tail) return RAWHID_RX_SIZE; |
|
|
|
|
|
//if (!(usb_transfer_status(rx_transfer) & 0x80)) return RAWHID_RX_SIZE; |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|