FTDI Community

Please login or register.

Login with username, password and session length.
Advanced Search  

News:

Welcome to the FTDI Community!

Please read our Welcome Note

Technical Support enquires
please contact the team
@ FTDI Support


New Bridgetek Community is now open

Please note that we have created the Bridgetek Community to discuss all Bridgetek products e.g. EVE, MCU.

Please follow this link and create a new user account to get started.

Bridgetek Community

Author Topic: USBHostHID2.c problem. Packets out of order and hangs at random  (Read 9433 times)

AndersG

  • Newbie
  • *
  • Posts: 13
    • View Profile
USBHostHID2.c problem. Packets out of order and hangs at random
« on: November 15, 2020, 05:23:28 PM »

Hi!

I am trying to adapt USBHostHID2.c for ose as an USB to SPI bridge and have run into problems. Those problems appear even if I have no SPI defined. The problems are:
1. When typing fast, reports from the keyboard go missing or arrive in the wrong order. Ie instead of one press one release, I get two presses followed by two releases.
2. The unit hangs hard after some time. This seems to happen if you type really fast on the keyboard or move the mouse a lot.

I have attached the USBHostHID2.* files, with my additions. This is on the 32-pin VNC2.

Code: [Select]
/*
** Filename: USBHostHID2_iomux.c
**
** Automatically created by Application Wizard 1.4.2
**
** Part of solution USBHostHID2 in project USBHostHID2
**
** Comments:
**
** Important: Sections between markers "FTDI:S*" and "FTDI:E*" will be overwritten by
** the Application Wizard
*/
#include "vos.h"

void iomux_setup(void)
{
/* FTDI:SIO IOMux Functions */
unsigned char packageType;

packageType = vos_get_package_type();
if (packageType == VINCULUM_II_32_PIN)
{
// Debugger to pin 11 as Bi-Directional.
vos_iomux_define_bidi(199, IOMUX_IN_DEBUGGER, IOMUX_OUT_DEBUGGER);
// GPIO_Port_A_1 to pin 12 as Input.
vos_iomux_define_input(12, IOMUX_IN_GPIO_PORT_A_1);
// GPIO_Port_A_2 to pin 14 as Input.
vos_iomux_define_input(14, IOMUX_IN_GPIO_PORT_A_2);
// GPIO_Port_A_3 to pin 15 as Input.
vos_iomux_define_input(15, IOMUX_IN_GPIO_PORT_A_3);
// UART_TXD to pin 23 as Output.
vos_iomux_define_output(23, IOMUX_OUT_UART_TXD);
// UART_RXD to pin 24 as Input.
vos_iomux_define_input(24, IOMUX_IN_UART_RXD);
// UART_RTS_N to pin 25 as Output.
vos_iomux_define_output(25, IOMUX_OUT_UART_RTS_N);
// UART_CTS_N to pin 26 as Input.
vos_iomux_define_input(26, IOMUX_IN_UART_CTS_N);
// SPI_Slave_0_CLK to pin 29 as Input.
//vos_iomux_define_input(29, IOMUX_IN_SPI_SLAVE_0_CLK);
// SPI_Slave_0_MOSI to pin 30 as Input.
//vos_iomux_define_input(30, IOMUX_IN_SPI_SLAVE_0_MOSI);
// SPI_Slave_0_MISO to pin 31 as Output.
//vos_iomux_define_output(31, IOMUX_OUT_SPI_SLAVE_0_MISO);
// SPI_Slave_0_CS to pin 32 as Input.
//vos_iomux_define_input(32, IOMUX_IN_SPI_SLAVE_0_CS);
//
// SPI Master
//
// SPI_Slave_0_CLK to pin 29 as output. IO8 ie J1 11
vos_iomux_define_output(29, IOMUX_OUT_SPI_MASTER_CLK);
// SPI_Slave_0_MOSI to pin 30 as output. IO 9, ie J1-12
vos_iomux_define_output(30, IOMUX_OUT_SPI_MASTER_MOSI);
// SPI_Slave_0_MISO to pin 31 as input. IO 10 ie J2-12
vos_iomux_define_input(31, IOMUX_IN_SPI_MASTER_MISO);
// SPI_Slave_0_CS to pin 32 as output. IO 11 ie J2-11
vos_iomux_define_output(32, IOMUX_OUT_SPI_MASTER_CS_0);
}
if (packageType == VINCULUM_II_48_PIN)
{
// Debugger to pin 11 as Bi-Directional.
vos_iomux_define_bidi(199, IOMUX_IN_DEBUGGER, IOMUX_OUT_DEBUGGER);
// PWM_1 to pin 12 as Output.
vos_iomux_define_output(12, IOMUX_OUT_PWM_1);
// PWM_2 to pin 13 as Output.
vos_iomux_define_output(13, IOMUX_OUT_PWM_2);
// PWM_3 to pin 14 as Output.
vos_iomux_define_output(14, IOMUX_OUT_PWM_3);
// UART_RI to pin 46 as Input.
vos_iomux_define_input(46, IOMUX_IN_UART_RI);
// UART_DCD to pin 45 as Input.
vos_iomux_define_input(45, IOMUX_IN_UART_DCD);
// GPIO_Port_A_4 to pin 48 as Input.
vos_iomux_define_input(48, IOMUX_IN_GPIO_PORT_A_4);
// UART_TXD to pin 31 as Output.
vos_iomux_define_output(31, IOMUX_OUT_UART_TXD);
// UART_RXD to pin 32 as Input.
vos_iomux_define_input(32, IOMUX_IN_UART_RXD);
// UART_RTS_N to pin 33 as Output.
vos_iomux_define_output(33, IOMUX_OUT_UART_RTS_N);
// UART_CTS_N to pin 34 as Input.
vos_iomux_define_input(34, IOMUX_IN_UART_CTS_N);
// UART_DTR_N to pin 35 as Output.
vos_iomux_define_output(35, IOMUX_OUT_UART_DTR_N);
// UART_DSR_N to pin 36 as Input.
vos_iomux_define_input(36, IOMUX_IN_UART_DSR_N);
// UART_DCD to pin 37 as Input.
vos_iomux_define_input(37, IOMUX_IN_UART_DCD);
// UART_RI to pin 38 as Input.
vos_iomux_define_input(38, IOMUX_IN_UART_RI);
// UART_TX_Active to pin 41 as Output.
vos_iomux_define_output(41, IOMUX_OUT_UART_TX_ACTIVE);
// SPI_Slave_0_CLK to pin 15 as Input.
vos_iomux_define_input(15, IOMUX_IN_SPI_SLAVE_0_CLK);
// SPI_Slave_0_MOSI to pin 16 as Input.
vos_iomux_define_input(16, IOMUX_IN_SPI_SLAVE_0_MOSI);
// SPI_Slave_0_MISO to pin 18 as Output.
vos_iomux_define_output(18, IOMUX_OUT_SPI_SLAVE_0_MISO);
// SPI_Slave_0_CS to pin 19 as Input.
vos_iomux_define_input(19, IOMUX_IN_SPI_SLAVE_0_CS);
// SPI_Master_CLK to pin 20 as Output.
vos_iomux_define_output(20, IOMUX_OUT_SPI_MASTER_CLK);
// SPI_Master_MOSI to pin 21 as Output.
vos_iomux_define_output(21, IOMUX_OUT_SPI_MASTER_MOSI);
// SPI_Master_MISO to pin 22 as Input.
vos_iomux_define_input(22, IOMUX_IN_SPI_MASTER_MISO);
// SPI_Master_CS_0 to pin 23 as Output.
vos_iomux_define_output(23, IOMUX_OUT_SPI_MASTER_CS_0);

}
if (packageType == VINCULUM_II_64_PIN)
{
// Debugger to pin 11 as Bi-Directional.
vos_iomux_define_bidi(199, IOMUX_IN_DEBUGGER, IOMUX_OUT_DEBUGGER);
// FIFO_Data_0 to pin 15 as Bi-Directional.
vos_iomux_define_bidi(15, IOMUX_IN_FIFO_DATA_0, IOMUX_OUT_FIFO_DATA_0);
// FIFO_Data_1 to pin 16 as Bi-Directional.
vos_iomux_define_bidi(16, IOMUX_IN_FIFO_DATA_1, IOMUX_OUT_FIFO_DATA_1);
// FIFO_Data_2 to pin 17 as Bi-Directional.
vos_iomux_define_bidi(17, IOMUX_IN_FIFO_DATA_2, IOMUX_OUT_FIFO_DATA_2);
// FIFO_Data_3 to pin 18 as Bi-Directional.
vos_iomux_define_bidi(18, IOMUX_IN_FIFO_DATA_3, IOMUX_OUT_FIFO_DATA_3);
// FIFO_Data_4 to pin 19 as Bi-Directional.
vos_iomux_define_bidi(19, IOMUX_IN_FIFO_DATA_4, IOMUX_OUT_FIFO_DATA_4);
// FIFO_Data_5 to pin 20 as Bi-Directional.
vos_iomux_define_bidi(20, IOMUX_IN_FIFO_DATA_5, IOMUX_OUT_FIFO_DATA_5);
// FIFO_Data_6 to pin 22 as Bi-Directional.
vos_iomux_define_bidi(22, IOMUX_IN_FIFO_DATA_6, IOMUX_OUT_FIFO_DATA_6);
// FIFO_Data_7 to pin 23 as Bi-Directional.
vos_iomux_define_bidi(23, IOMUX_IN_FIFO_DATA_7, IOMUX_OUT_FIFO_DATA_7);
// FIFO_RXF_N to pin 24 as Output.
vos_iomux_define_output(24, IOMUX_OUT_FIFO_RXF_N);
// FIFO_TXE_N to pin 25 as Output.
vos_iomux_define_output(25, IOMUX_OUT_FIFO_TXE_N);
// FIFO_RD_N to pin 26 as Input.
vos_iomux_define_input(26, IOMUX_IN_FIFO_RD_N);
// FIFO_WR_N to pin 27 as Input.
vos_iomux_define_input(27, IOMUX_IN_FIFO_WR_N);
// FIFO_OE_N to pin 28 as Input.
vos_iomux_define_input(28, IOMUX_IN_FIFO_OE_N);
// UART_DSR_N to pin 29 as Input.
vos_iomux_define_input(29, IOMUX_IN_UART_DSR_N);
// UART_DCD to pin 31 as Input.
vos_iomux_define_input(31, IOMUX_IN_UART_DCD);
// UART_RI to pin 32 as Input.
vos_iomux_define_input(32, IOMUX_IN_UART_RI);
// UART_TXD to pin 39 as Output.
vos_iomux_define_output(39, IOMUX_OUT_UART_TXD);
// UART_RXD to pin 40 as Input.
vos_iomux_define_input(40, IOMUX_IN_UART_RXD);
// UART_RTS_N to pin 41 as Output.
vos_iomux_define_output(41, IOMUX_OUT_UART_RTS_N);
// UART_CTS_N to pin 42 as Input.
vos_iomux_define_input(42, IOMUX_IN_UART_CTS_N);
// UART_DTR_N to pin 43 as Output.
vos_iomux_define_output(43, IOMUX_OUT_UART_DTR_N);
// UART_DSR_N to pin 44 as Input.
vos_iomux_define_input(44, IOMUX_IN_UART_DSR_N);
// UART_DCD to pin 45 as Input.
vos_iomux_define_input(45, IOMUX_IN_UART_DCD);
// UART_RI to pin 46 as Input.
vos_iomux_define_input(46, IOMUX_IN_UART_RI);
// UART_TX_Active to pin 47 as Output.
vos_iomux_define_output(47, IOMUX_OUT_UART_TX_ACTIVE);
// SPI_Slave_0_CLK to pin 51 as Input.
vos_iomux_define_input(51, IOMUX_IN_SPI_SLAVE_0_CLK);
// SPI_Slave_0_MOSI to pin 52 as Input.
vos_iomux_define_input(52, IOMUX_IN_SPI_SLAVE_0_MOSI);
// SPI_Slave_0_MISO to pin 55 as Output.
vos_iomux_define_output(55, IOMUX_OUT_SPI_SLAVE_0_MISO);
// SPI_Slave_0_CS to pin 56 as Input.
vos_iomux_define_input(56, IOMUX_IN_SPI_SLAVE_0_CS);
// SPI_Slave_1_CLK to pin 57 as Input.
vos_iomux_define_input(57, IOMUX_IN_SPI_SLAVE_1_CLK);
// SPI_Slave_1_MOSI to pin 58 as Input.
vos_iomux_define_input(58, IOMUX_IN_SPI_SLAVE_1_MOSI);
// SPI_Slave_1_MISO to pin 59 as Output.
vos_iomux_define_output(59, IOMUX_OUT_SPI_SLAVE_1_MISO);
// SPI_Slave_1_CS to pin 60 as Input.
vos_iomux_define_input(60, IOMUX_IN_SPI_SLAVE_1_CS);
// SPI_Master_CLK to pin 61 as Output.
vos_iomux_define_output(61, IOMUX_OUT_SPI_MASTER_CLK);
// SPI_Master_MOSI to pin 62 as Output.
vos_iomux_define_output(62, IOMUX_OUT_SPI_MASTER_MOSI);
// SPI_Master_MISO to pin 63 as Input.
vos_iomux_define_input(63, IOMUX_IN_SPI_MASTER_MISO);
// SPI_Master_CS_0 to pin 64 as Output.
vos_iomux_define_output(64, IOMUX_OUT_SPI_MASTER_CS_0);

}

/* FTDI:EIO */
}


Code: [Select]
/*
** Filename: USBHostHID2.h
**
** Automatically created by Application Wizard 1.4.2
**
** Part of solution USBHostHID2 in project USBHostHID2
**
** Comments:
**
** Important: Sections between markers "FTDI:S*" and "FTDI:E*" will be overwritten by
** the Application Wizard
*/

#ifndef _USBHostHID2_H_
#define _USBHostHID2_H_

#include "vos.h"

//#define USE_SPI 1

/* FTDI:SHF Header Files */
#include "USB.h"
#include "USBHost.h"
#include "ioctl.h"
#include "UART.h"
#include "string.h"
#include "errno.h"
/* FTDI:EHF */

/* FTDI:SDC Driver Constants */
#define VOS_DEV_USBHOST_1 0
#define VOS_DEV_USBHOST_2 1
#define VOS_DEV_UART 2



#ifdef USE_SPI
#include "SPIMaster.h"
#define VOS_DEV_SPI_MASTER 3
#define VOS_NUMBER_DEVICES 4
#else
#define VOS_NUMBER_DEVICES 3
#endif
/* FTDI:EDC */

/* FTDI:SXH Externs */
/* FTDI:EXH */

#endif                                 /* _USBHostHID2_H_ */
Logged
/AndersG

AndersG

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: USBHostHID2.c problem. Packets out of order and hangs at random
« Reply #1 on: November 15, 2020, 05:24:15 PM »

Code: [Select]
/*
** Filename: USBHostHID2.c
**
** Automatically created by Application Wizard 1.4.2
**
** Part of solution USBHostHID2 in project USBHostHID2
**
** Comments:
**
** Important: Sections between markers "FTDI:S*" and "FTDI:E*" will be overwritten by
** the Application Wizard
*/

#include "USBHostHID2.h"
//#define USE_SPI

/* FTDI:STP Thread Prototypes */
vos_tcb_t *tcbFIRMWARE;

void firmware();
/* FTDI:ETP */

/* FTDI:SDH Driver Handles */
VOS_HANDLE hUSBHOST_1; // USB Host Port 1
VOS_HANDLE hUSBHOST_2; // USB Host Port 2
VOS_HANDLE hUART; // UART Interface Driver
#ifdef USE_SPI
VOS_HANDLE hSPI_MASTER; // SPIMaster Interface Driver
#endif
/* FTDI:EDH */
// use our own driver handles to simplify code later
VOS_HANDLE hUsb[2];

/* Declaration for IOMUx setup function */
void iomux_setup(void);

/* Main code - entry point to firmware */
void main(void)
{
/* FTDI:SDD Driver Declarations */
// UART Driver configuration context
uart_context_t uartContext;
// USB Host configuration context
usbhost_context_t usbhostContext;
/* FTDI:EDD */
#ifdef USE_SPI
// SPI Master configuration context
spimaster_context_t spimContext;
#endif
/* FTDI:SKI Kernel Initialisation */
vos_init(50, VOS_TICK_INTERVAL, VOS_NUMBER_DEVICES);
vos_set_clock_frequency(VOS_48MHZ_CLOCK_FREQUENCY);
vos_set_idle_thread_tcb_size(512);
/* FTDI:EKI */

iomux_setup();

/* FTDI:SDI Driver Initialisation */
// Initialise UART
uartContext.buffer_size = VOS_BUFFER_SIZE_128_BYTES;
uart_init(VOS_DEV_UART,&uartContext);
//
// SPI
#ifdef USE_SPI
spimContext.buffer_size = VOS_BUFFER_SIZE_128_BYTES;
spimaster_init(VOS_DEV_SPI_MASTER,&spimContext);
#endif

// Initialise USB Host
usbhostContext.if_count = 8;
usbhostContext.ep_count = 16;
usbhostContext.xfer_count = 2;
usbhostContext.iso_xfer_count = 2;
usbhost_init(VOS_DEV_USBHOST_1, VOS_DEV_USBHOST_2, &usbhostContext);
/* FTDI:EDI */

/* FTDI:SCT Thread Creation */
tcbFIRMWARE = vos_create_thread_ex(20, 4096, firmware, "Application", 0);
/* FTDI:ECT */

vos_start_scheduler();

main_loop:
goto main_loop;
}

/* FTDI:SSP Support Functions */

unsigned char usbhost_connect_state(VOS_HANDLE hUSB)
{
unsigned char connectstate = PORT_STATE_DISCONNECTED;
usbhost_ioctl_cb_t hc_iocb;

if (hUSB)
{
hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_GET_CONNECT_STATE;
hc_iocb.get        = &connectstate;
vos_dev_ioctl(hUSB, &hc_iocb);

    // repeat if connected to see if we move to enumerated
if (connectstate == PORT_STATE_CONNECTED)
{
vos_dev_ioctl(hUSB, &hc_iocb);
}
}
return connectstate;
}

/* FTDI:ESP */

void open_drivers(void)
{
/* Code for opening and closing drivers - move to required places in Application Threads */
/* FTDI:SDA Driver Open */
hUSBHOST_1 = vos_dev_open(VOS_DEV_USBHOST_1);
hUSBHOST_2 = vos_dev_open(VOS_DEV_USBHOST_2);
hUART = vos_dev_open(VOS_DEV_UART);
#ifdef USE_SPI
hSPI_MASTER = vos_dev_open(VOS_DEV_SPI_MASTER);
#endif
/* FTDI:EDA */
}

void attach_drivers(void)
{
/* FTDI:SUA Layered Driver Attach Function Calls */
/* FTDI:EUA */
}

void close_drivers(void)
{
/* FTDI:SDB Driver Close */
vos_dev_close(hUSBHOST_1);
vos_dev_close(hUSBHOST_2);
vos_dev_close(hUART);
#ifdef USE_SPI
vos_dev_close(hSPI_MASTER);
#endif
/* FTDI:EDB */
}

/* Application Threads */

void message(char *msg)
{
vos_dev_write(hUART, (unsigned char *) msg, strlen(msg), NULL);
}

void number(unsigned char val)
{
char letter;
unsigned char nibble;

nibble = (val >> 4) + '0';

if (nibble > '9')
nibble += ('A' - '9' - 1);

vos_dev_write(hUART, &nibble, 1, NULL);
nibble = (val & 15) + '0';

if (nibble > '9')
nibble += ('A' - '9' - 1);

vos_dev_write(hUART, &nibble, 1, NULL);
}

void spinumber(unsigned char val)
{
#ifdef USE_SPI
char letter;
unsigned char nibble;

nibble = (val >> 4) + '0';

if (nibble > '9')
nibble += ('A' - '9' - 1);

vos_dev_write(hSPI_MASTER, &nibble, 1, NULL);
nibble = (val & 15) + '0';

if (nibble > '9')
nibble += ('A' - '9' - 1);

vos_dev_write(hSPI_MASTER, &nibble, 1, NULL);
#endif
}

vos_semaphore_list_t *sem_list;        // pointer to semaphore list

void firmware(void)
{
// test buffer
char buf[64];
char *eol = "\r\n";
char replybuf[64];

unsigned char i;
unsigned short len;
unsigned short written;
unsigned char status;
unsigned char n, m;
unsigned char ch;
unsigned int replylen;

// device handle
usbhost_device_handle_ex ifDev;
// endpoint handles
usbhost_ep_handle_ex epInt[2], epCtrl[2];
// endpoint maxPacketLength values
unsigned char maxPack[2];

// completion semaphore and set semaphore list
vos_semaphore_t semRead;
vos_semaphore_t endpointSem[2];

// Host Controller ioctl request block
usbhost_ioctl_cb_t hc_iocb;
usbhost_ioctl_cb_vid_pid_t hc_ioctVidPid;

// interrupt endpoint transfer descriptor
usbhost_xfer_t xfer[2];

// UART ioctl request block
common_ioctl_cb_t uart_iocb;
#ifdef USE_SPI
// SPI Master ioctl request block
common_ioctl_cb_t spim_iocb;
#endif

// host controller device descriptor
usb_deviceRequest_t desc_dev;

// endpoint information
usbhost_ioctl_cb_ep_info_t epInfo;

epInt[0] = NULL;
epCtrl[0] = NULL;
epInt[1] = NULL;
epCtrl[1] = NULL;

open_drivers();
hUsb[0] = hUSBHOST_1;
hUsb[1] = hUSBHOST_2;

//uart_iocb.ioctl_code = VOS_IOCTL_COMMON_ENABLE_DMA;
//uart_iocb.set.param = DMA_ACQUIRE_AS_REQUIRED;
//vos_dev_ioctl(hUART, &uart_iocb);

// set baud rate
uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_BAUD_RATE;
uart_iocb.set.uart_baud_rate = UART_BAUD_115200;
vos_dev_ioctl(hUART, &uart_iocb);

// set flow control
uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_FLOW_CONTROL;
uart_iocb.set.param = UART_FLOW_RTS_CTS;
vos_dev_ioctl(hUART, &uart_iocb);

// set data bits
uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_DATA_BITS;
uart_iocb.set.param = UART_DATA_BITS_8;
vos_dev_ioctl(hUART, &uart_iocb);

// set stop bits
uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_STOP_BITS;
uart_iocb.set.param = UART_STOP_BITS_1;
vos_dev_ioctl(hUART, &uart_iocb);

// set parity
uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_PARITY;
uart_iocb.set.param = UART_PARITY_NONE;
vos_dev_ioctl(hUART, &uart_iocb);
#ifdef USE_SPI
// set clock phase
spim_iocb.ioctl_code = VOS_IOCTL_SPI_MASTER_SCK_CPHA;
spim_iocb.set.param = SPI_MASTER_SCK_CPHA_0;
vos_dev_ioctl(hSPI_MASTER, &spim_iocb);
// set clock polarity
spim_iocb.ioctl_code = VOS_IOCTL_SPI_MASTER_SCK_CPOL;
spim_iocb.set.param = SPI_MASTER_SCK_CPOL_0;
vos_dev_ioctl(hSPI_MASTER, &spim_iocb);
// set data order
spim_iocb.ioctl_code = VOS_IOCTL_SPI_MASTER_DATA_ORDER;
spim_iocb.set.param = SPI_MASTER_DATA_ORDER_MSB;
vos_dev_ioctl(hSPI_MASTER, &spim_iocb);
// enable DMA
spim_iocb.ioctl_code = VOS_IOCTL_COMMON_ENABLE_DMA;
spim_iocb.set = DMA_ACQUIRE_AND_RETAIN;
vos_dev_ioctl(hSPI_MASTER, &spim_iocb);
// set clock rate
spim_iocb.ioctl_code = VOS_IOCTL_SPI_MASTER_SET_SCK_FREQUENCY;
spim_iocb.set.spi_master_sck_freq = 300000; // /10
vos_dev_ioctl(hSPI_MASTER, &spim_iocb);
// set auto toggle
spim_iocb.ioctl_code = VOS_IOCTL_SPI_MASTER_AUTO_TOGGLE_SS;
spim_iocb.set.param = SPI_MASTER_SS_AUTO_TOGGLE_ENABLE_SS_0;
vos_dev_ioctl(hSPI_MASTER, &spim_iocb);
#endif
message("Starting...\r\n");
#ifdef USE_SPI
message("With SPI...\r\n");
//vos_dev_write(hSPI_MASTER, "With SPI...\r\n", 13, NULL);
#endif
do
{
vos_delay_msecs(100);

// check if USB port 1 is configured already
for (i = 0; i < 2; i++)
{
if (epCtrl[i] == NULL)
{
// user ioctl to see if selected USB port available
if (usbhost_connect_state(hUsb[i]) == PORT_STATE_ENUMERATED)
{
message("Enumeration complete Port ");
number(i);
message(eol);

// user ioctl to find first hub device
hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_NEXT_HANDLE;
// find first device interface
hc_iocb.handle.dif = NULL;
// hc_iocb.set = &hc_ioctVidPid;
hc_iocb.get = &ifDev;
status = vos_dev_ioctl(hUsb[i], &hc_iocb);

if (status != USBHOST_OK)
{
message("No Device Found - code ");
number(status);
message(eol);
break;
}

// user ioctl to find control endpoint on this device
hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_CONTROL_ENDPOINT_HANDLE;
hc_iocb.handle.dif = ifDev;
hc_iocb.get = &epCtrl[i];

status = vos_dev_ioctl(hUsb[i], &hc_iocb);

if (status != USBHOST_OK)
{
message("No Control Endpoint Found - code ");
number(status);
message(eol);
break;
}

// user ioctl to find first interrupt endpoint on this device
hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_INT_IN_ENDPOINT_HANDLE;
hc_iocb.handle.dif = ifDev;
hc_iocb.get = &epInt[i];
status = vos_dev_ioctl(hUsb[i], &hc_iocb);

if (status != USBHOST_OK)
{
message("No interrupt Endpoint Found - code ");
number(status);
message(eol);
break;
}

// user ioctl to find interrupt endpoint on this device
hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_ENDPOINT_INFO;
hc_iocb.handle.ep = epInt[i];
hc_iocb.get = &epInfo;

status = vos_dev_ioctl(hUsb[i], &hc_iocb);

if (status != USBHOST_OK)
{
message("Interrupt Endpoint Info Not Found - code ");
number(status);
message(eol);
break;
}

maxPack[i] = epInfo.max_size;

desc_dev.bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
USB_BMREQUESTTYPE_CLASS |
USB_BMREQUESTTYPE_INTERFACE;
desc_dev.bRequest = 0x0a; // USB_HID_REQUEST_CODE_SET_IDLE
desc_dev.wValue = 0; // Repeat rate here
desc_dev.wIndex = 0;
desc_dev.wLength = 0;

hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_SETUP_TRANSFER;
hc_iocb.handle.ep = epCtrl[i];
hc_iocb.set = &desc_dev;

vos_dev_ioctl(hUsb[i], &hc_iocb);


message("Init complete Port ");
number(i);
message(eol);
}
}
}

if (epCtrl[0] && epCtrl[1])
{
sem_list = (vos_semaphore_list_t *) vos_malloc(VOS_SEMAPHORE_LIST_SIZE(2));
sem_list->next = NULL;     // initialise semaphore list
sem_list->siz = 2;         // 2 semaphores (1 for each device endpoint)
sem_list->flags = VOS_SEMAPHORE_FLAGS_WAIT_ANY;

// initialise semaphore
vos_init_semaphore(&endpointSem[0], 0);
vos_init_semaphore(&endpointSem[1], 0);

n = -1;

memset(xfer, 0, sizeof(xfer));

xfer[0].buf = buf;
xfer[0].ep = epInt[0];
xfer[0].s = &endpointSem[0];
// Do not block on completion... we will wait on the sempaphore later
xfer[0].flags = USBHOST_XFER_FLAG_NONBLOCKING | USBHOST_XFER_FLAG_ROUNDING;

xfer[1].buf = buf;
xfer[1].s = &endpointSem[1];
xfer[1].ep = epInt[1];
xfer[1].flags = USBHOST_XFER_FLAG_NONBLOCKING | USBHOST_XFER_FLAG_ROUNDING;

while (1)
{
// Start or restart each endpoint transfer
if (n != 1)
{
sem_list->list[0] = &endpointSem[0];
xfer[0].len = maxPack[0];
xfer[0].cond_code = USBHOST_CC_NOTACCESSED;
status = vos_dev_read(hUsb[0], (unsigned char *) &xfer[0], sizeof(usbhost_xfer_t), NULL);

if (status != USBHOST_OK)
{
message("Port 00 Read Failed - code ");
number(status);
message(eol);
break;
}
}

if (n != 0)
{
sem_list->list[1] = &endpointSem[1];
xfer[1].len = maxPack[1];
xfer[1].cond_code = USBHOST_CC_NOTACCESSED;

status = vos_dev_read(hUsb[1], (unsigned char *) &xfer[1], sizeof(usbhost_xfer_t), NULL);

if (status != USBHOST_OK)
{
message("Port 01 Read Failed - code ");
number(status);
message(eol);
break;
}
}

// Wait on a key press from either endpoint...
n = vos_wait_semaphore_ex(sem_list);

// Display data received
message("Port ");
number(n);
message(" Data: ");

// Display the data from the keyboard...
if (n == 0)
{
//  sem0 has signalled
replybuf[0] = 0x13;
replybuf[1] = (unsigned char) xfer[0].len;
replylen = 2;
for (i = 0; i < xfer[0].len; i++)
{
number(buf[i]);
ch = buf[i];
replybuf[replylen++] = (ch >> 4); // MSB
replybuf[replylen++] = (ch & 0x0f); // LSB
}
replybuf[replylen++] = 0x14;
#ifdef USE_SPI
vos_dev_write(hSPI_MASTER, (unsigned char *)replybuf, (uint16)replylen, NULL);
#endif
}
else if (n == 1)
{
// sem1 has signalled
replybuf[0] = 0x13;
replybuf[1] = (unsigned char)xfer[1].len;
replylen = 2;
for (i = 0; i < xfer[1].len; i++)
{
number(buf[i]);
ch = buf[i];
replybuf[replylen++] = (ch >> 4); // MSB
replybuf[replylen++] = (ch & 0x0f); // LSB
}
replybuf[replylen++] = 0x14;
#ifdef USE_SPI
vos_dev_write(hSPI_MASTER, (unsigned char *)replybuf, (uint16) replylen, NULL);
#endif
}

message(eol);
}
}
}
while (1);
}

Logged
/AndersG

AndersG

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: USBHostHID2.c problem. Packets out of order and hangs at random
« Reply #2 on: November 16, 2020, 07:55:22 PM »

Removing all the UART stuff led to a marked improvement.

Next task is to adapt the code so that it does not require both USB ports to be connected.
Logged
/AndersG

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 892
    • View Profile
Re: USBHostHID2.c problem. Packets out of order and hangs at random
« Reply #3 on: November 18, 2020, 04:36:38 PM »

Hello,

We have tried this and can’t get it to fail.

We copied and pasted your supplied code, compiled it and tested.

We cannot get it to fail even with the SPI turned on.

The #define USE_SPI is in the wrong place in the code though. Should be in this order:

#define USE_SPI
#include "USBHostHID2.h"

This is unlikely to be the cause though.

> instead of one press one release, I get two presses followed by two releases.

You will, as there may be key presses that overlap... i.e. F key down, G key down, F key up, G key up.

Maybe some other community users will be able to help you further.

Best Regards,
FTDI Community
Logged

AndersG

  • Newbie
  • *
  • Posts: 13
    • View Profile
Re: USBHostHID2.c problem. Packets out of order and hangs at random
« Reply #4 on: November 18, 2020, 06:33:18 PM »

Well, in this case it was the same key, but removing UART fixed it. It now works as advertised.
Logged
/AndersG

FTDI Community

  • Administrator
  • Hero Member
  • *****
  • Posts: 892
    • View Profile
Re: USBHostHID2.c problem. Packets out of order and hangs at random
« Reply #5 on: November 23, 2020, 10:13:30 PM »

Hello,

You need something connected to the UART with CTS / RTS flow control signals.
Or set it to UART_FLOW_NONE.
At some point it writes enough to the UART to be waiting for a flow control event.

// set flow control
uart_iocb.ioctl_code = VOS_IOCTL_UART_SET_FLOW_CONTROL;
uart_iocb.set.param = UART_FLOW_RTS_CTS;
vos_dev_ioctl(hUART, &uart_iocb);

Best Regards,
FTDI Community
Logged