How can I transfer data to HID if it has not OUT Endpoint - hid

I am trying to implement data exchange with some HID device. I managed to implement reading from this device using libusb_interrupt_transfer function, but I do not know how to implement sending a buffer to the HID, because device has not OUT endpoint. How can I transfer data to HID? Descriptor of device looks like this:
Bus 001 Device 074: ID 16d0:8080 MCS
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x16d0 MCS
idProduct 0x8080
bcdDevice 2.03
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.11
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 32
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 5

If the device doesn't have an OUT endpoint, the only way to send data to the device is using control transfers using default control endpoint (EP0).
There are HID class specific control requests mentioned in the HID Specification document. However, SET_* requests aren't mandatory, so your HID device may not support them.
There can be also vendor specific control requests, but there is no way to guess them, so they need to be documented by the device vendor.

Related

Why does my esp32 keep rebooting problem?

This is my problem:
Brownout detector was triggered
ets Jun 8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5008
ho 0 tail 12 room 4
load:0x40078000,len:10600
ho 0 tail 12 room 4
load:0x40080400,len:5684
entry 0x400806bc
I want to make some web server on my ESP32

PCIe DMA aarch64 0x10 Translation Fault

I'm trying to write a PCIe driver to DMA pages from the host memory to an FPGA. My host setup is Cavium ThunderX2 and my FPGAs are Xilinx Alveo U50.
A DMA from/to the host causes the ARM SMMU v3.4 to throw an event 0x10 Translation fault. I'm using dma_map_single(..) and dma_alloc_coherent(..) Linux APIs to map the virtual address of the page to a DMA-capable address.
Further inspecting the event records, Context Descriptor, and Stream Table Entries, I have the following information.
Type of Fault - F_TRANSLATION (Translation Fault)
S2 == 0 (Stage 1 Fault - Virtual Address -> Intermediate Physical Address stage)
Class of Fault = TT/TTD (Translation Table Descriptor Fetch)
PnU == Underprivileged Access
T0SZ == 5'b01000 (16); T1SZ == 5'b00000 (IGNORED because EPD1 == 1)
VAS == 49 bits (Virtual Address Size)
TG0 == 00 (4 kB page granule size)
EPD0 == 0 (Stage 1 page table walk enabled)
EPD1 == 1 (Stage 2 is bypassed)
TB0/1 == 0 (Top byte ignore disabled)
IPS == 44 bits (Input Address size)
SMMU Config = 3'b101 (Stage 1 translation enabled, Stage 2 bypassed)
Sample Virtual and DMA address of the page obtained -
Virtual Address - 0xFFFF--- (64-bit value)
DMA Address - 0x9F733CA000 (looks within the range defined by T0SZ and compliant with the IPS)
I'm unable to figure why I'm getting a Stage 1 translation fault when everything looks fine. Technically, I should be getting a Stage 2 fault since it is bypassed and the input address should translate through the TTB0.
P.S. I'm a newbie to ARM v8. Let me know if you need additional information in the comments.
Attached is a picture of the fault F_TRANSLATION.
I was able to fix the issue. There was a synchronization lapse between the IOMMU and the DMA mapping. There were no valid descriptors found for the mapped DMA addresses in the SMMU.
I used dma_alloc_coherent(SZ_2M) to get a buffer region and use IOMMU domain ops to map the IOVA to the SMMU.
int ret = iommu_domain->ops->map(domain, IOVA, size, phys_addr, PROT)
Now the SMMU is able to fetch and translate the IOVA.
For some reason, dma_map_single(..) doesn't work with my current implementation. I have to investigate why a streaming DMA API doesn't work.

SocketCAN - device state "STOPPED"

I use a Raspberry Pi with the PiCAN board which uses a MCP2515 CAN controller.
I use SocketCAN to read and write CAN messages via an application I wrote.
After running a few weeks without a problem the controller is now in the state "STOPPED".
What is the difference between the state STOPPED and BUS-OFF?
Does a device enter the BUS-OFF state if too many error occure on the CAN bus and the device enters the STOPPED state if you set the device down (ip link set canX down)?
Are there any other ways how the device may enter the state STOPPED? I wasn't able to find a way how my application might have set the device down.
ip -details -statistics link show can0
3: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10
link/can promiscuity 0
can state STOPPED restart-ms 100
bitrate 250000 sample-point 0.875
tq 250 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 8000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 146 139 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
787700920 151606570 24 0 24 0
TX: bytes packets errors dropped carrier collsns
6002905 5895301 0 0 0 0
You need to familiarize your self with ERROR ACTIVE, ERROR PASSIVE, and BUS OFF error states of CAN bus devices, and when is it needed to manually restart CAN communication.
All relevant info can be found at one of these links:
http://www.can-wiki.info/doku.php?id=can_faq:can_faq_erors
http://www.port.de/cgi-bin/CAN/CanFaqErrors

How to add more FLAG of reason cause reboot with watchdog in Linux?

I'm using iMX8MM with Yocto. I'm trying to figure out the reason cause reboot with Watchdog.
I find out watchdog.h and there are a lot of FLAGs:
#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */
#define WDIOF_FANFAULT 0x0002 /* Fan failed */
#define WDIOF_EXTERN1 0x0004 /* External relay 1 */
#define WDIOF_EXTERN2 0x0008 /* External relay 2 */
#define WDIOF_POWERUNDER 0x0010 /* Power bad/power fault */
#define WDIOF_CARDRESET 0x0020 /* Card previously reset the CPU */
#define WDIOF_POWEROVER 0x0040 /* Power over voltage */
#define WDIOF_SETTIMEOUT 0x0080 /* Set timeout (in seconds) */
#define WDIOF_MAGICCLOSE 0x0100 /* Supports magic close char */
#define WDIOF_PRETIMEOUT 0x0200 /* Pretimeout (in seconds), get/set */
#define WDIOF_KEEPALIVEPING 0x8000 /* Keep alive ping reply */
But when I check with command, I get only 4 FLAGs:
$ wdctl
Device: /dev/watchdog
Identity: imx2+ watchdog [version 0]
Timeout: 60 seconds
Pre-timeout: 0 seconds
FLAG DESCRIPTION STATUS BOOT-STATUS
KEEPALIVEPING Keep alive ping reply 1 0
MAGICCLOSE Supports magic close char 0 0
PRETIMEOUT Pretimeout (in seconds) 0 0
SETTIMEOUT Set timeout (in seconds) 0 0
How do I get more of FLAG to use?
The macros(flags) you are seeing in the watchdog.h is the complete list. However, the application utility (here wdctl) is reading the driver capabilities implementation from the kernel.
Another flag you are seeing WDIOF_OVERHEAT and others should be supported by the kernel driver then and then only it will be available to the wdctl list.
Looking at the source code of the wdctl is working in the following way. It is calling the read_watchdog_from_device API to get the implemented flags(Environmental monitoring).
Please check for the flags in the corresponding driver from the i.MX8MM watchdog imx2_wdt.c.
References: https://github.com/karelzak/util-linux/blob/master/sys-utils/wdctl.c
https://www.kernel.org/doc/Documentation/watchdog/watchdog-api.txt
This is how I solve the issue above.
Find all file concert about imx2+ watchdog package.
Modified by adding more flags as watchdog.h file.
Access menuconfig in Yocto and turn on some options in Watchdog sections. This action makes sure that bitbake recognize the changing in driver.
Rebuild and generate OS image.

OLED on Zedboard

I am very new to zedboard. I have a zedboard running an Ubuntu image. I am trying to write a driver to run the OLED on the board. On board start-up the OLED on the board shows some display(Xilinx logo), therefore I am assuming it already has a driver. I have the following questions:
a) How is the OLED in the zedboard internally connected, is it through SPI, GPIOs or the PL. If it's through SPI/GPIOs then which pins?
b) Any tutorial or documentation that I can follow to create userspace drivers using SPI/GPIO for the OLED in the zedboard?
c) I have a redhat desktop, is there any SDk I can use to develop userspace drivers for the zedboard from my redhat desktop.
I have seen a lot of materials on the zedboard but none of them talks about how the OLED is internally connected. In one document it shows that it's connected to the PL. If that's the case then how can I write userspace drivers using the PL on the zedboard? I will be coding using C.
Appreciate your help and thanks in advance!
a) How is the OLED in the zedboard internally connected, is it through SPI, GPIOs or the PL. If it's through SPI/GPIOs then which pins?
First or second result for the web search "zedboard oled pdf" - http://zedboard.org/sites/default/files/ZedBoard_HW_UG_v1_1.pdf
then search for "oled" in it (page numbers of the pdf file, not printed in document):
page3: 2.4.4 OLED...... ... ...... 19
page4: 128x32 OLED Display
page5: ZYNQ XC7Z020-CSG484 OLED <- bus_of_5 -> 128x32 OLED
page20: 2.4.4 OLED
An Inteltronic/Wisechip UG-2832HSWEG04 OLED Display is used on the ZedBoard. This
provides a 128x32 pixel, passive-matrix, monochrome display. The display size is 30mm x11.5mm x 1.45mm. Table 11 - OLED Connections ... Interface
oled_pin symb EPP_pin Function
9 RES# U9 Power Reset for Controller and Driver
8 CS# N/C Chip Select – Pulled Down on Board
10 D/C# U10 Data/Command Control
11 SCLK AB12 Serial Clock Input Signal
12 SDIN AA12 Serial Data Input Signal
So, we know model of OLED UG-2832HSWEG04 (datasheet http://www.adafruit.com/datasheets/UG-2832HSWEG04.pdf with low-level details on data interface) and data connection; this is OLED with 1 serial data input and 1 serial clock.
Pinout pdf is http://www.xilinx.com/support/documentation/user_guides/ug865-Zynq-7000-Pkg-Pinout.pdf (too long to read), but there is shorter version of pin list in txt format: http://www.xilinx.com/support/packagefiles/z7packages/xc7z020clg484pkg.txt
Device/Package xc7z020clg484 9/18/2012 10:07:35
Pin Pin Name Memory Byte Group Bank VCCAUX Group Super Logic Region I/O Type
AA12 IO_L7P_T1_13 1 13 NA NA HR
AB12 IO_L7N_T1_13 1 13 NA NA HR
HR means "3.3V-capable high-range (HR) banks", both data pins are from "bank 13". Pin name is IO_* so it "supports both input, as well as output functionality", and is part of "PL Pins" (PL = programmable logic = FPGA). Default Zedboard firmware of FPGA part gives access to this pin to the ARM part of chip with linux kernel (PS = processing system = ARM) by routing it to some internal processing_system GPIO pin via system.ucf file like:
NET processing_system7_0_GPIO_pin[5] LOC = AB12 | IOSTANDARD="LVCMOS25"; # "OLED-SCLK"
NET processing_system7_0_GPIO_pin[6] LOC = AA12 | IOSTANDARD="LVCMOS25"; # "OLED-SDIN"
Then the GPIO pins are registered in devicetree (dts) https://github.com/Digilent/linux-digilent/blob/master/arch/arm/boot/dts/digilent-zed.dts in zed_oled group:
zed_oled {
compatible = "dglnt,pmodoled-gpio";
/* GPIO Pins */
vbat-gpio = <&ps7_gpio_0 55 0>;
vdd-gpio = <&ps7_gpio_0 56 0>;
res-gpio = <&ps7_gpio_0 57 0>;
dc-gpio = <&ps7_gpio_0 58 0>;
/* SPI-GPIOs */
spi-bus-num = <2>;
spi-speed-hz = <4000000>;
spi-sclk-gpio = <&ps7_gpio_0 59 0>;
spi-sdin-gpio = <&ps7_gpio_0 60 0>;
};
b) Any tutorial or documentation that I can follow to create userspace drivers using SPI/GPIO for the OLED in the zedboard?
According to Avnet's Getting Started pdf, "Demo 2 – OLED Display" scetion on page 17 (web searched as "zedboard oled") http://zedboard.org/sites/default/files/documentations/GS-AES-Z7EV-7Z020-G-14.1-V6%5B1%5D.pdf#page=17 there is kernel driver pmodoled-gpio.ko (on screenshot it reported as "pmodoled-gpio-spi"), so OLED is driven with GPIO pins.
There are two helper scripts: unload_oled to remove the kernel module and load_oled to insert it into kernel. Driver will create special device file /dev/zed_oled to work with display from user-space and load_oled also displays the /root/logo.bin file using this zed_oled interface.
Typical usage of zed_oled is like cat yourfile.bin > /dev/zed_oled, for example http://people.mech.kuleuven.be/~lin.zhang/notes/emebedded-linux/zedboard-oled-display.html and better http://zedboard.org/content/zedboard-oled
The .bin file format. ... The screen is written to right to left, top to bottom with each pixel being represented by a bit within one of the bytes within the .bin file. Bits are read-in top down 8 pixels then move over 1 pixel and write the next 8 bits and continue until you are at the end of the row. Then move down 8 pixels and do this again 3 more times.
You can do writes from C application, check code from http://www.cnblogs.com/popo0904/p/3853144.html (you can use online web translation services to read the text)
Documentation on the kernel module PmodOLED used in standard zedboard demo: https://github.com/Digilent/linux-digilent/blob/master/Documentation/pmods/pmodoled.txt
The driver provides a 512 Byte display buffer for the display of PmodOLED.
The Whole screen is divided into four lines, each of them is 128 bits wide
and 8 bits high, as shown in the figure below.
+--------------------------...----------------------------+
+ Line 4 +
+--------------------------...----------------------------+
+ Line 3 +
+--------------------------...----------------------------+
+ Line 2 +
+--------------------------...----------------------------+ MSB (bit 7)
+ Line 1 +
+--------------------------...----------------------------+ LSB (bit 0)
byte 127 byte 0
Users can perform read and write functions to the device node to access the data
inside the display buffer.
And there is source code of the dirver: https://github.com/Digilent/linux-digilent/blob/06b388903e5459687ba2538ae3895ffe29e2e39e/drivers/pmods/pmodoled-gpio.c
c) I have a redhat desktop, is there any SDk I can use to develop userspace drivers for the zedboard from my redhat desktop.
The standard driver is kernel-space for this OLED on ZEDboard, you can use it from precompiled ZEDboard firmware. Or you can build the kernel according to zedboard instructions, all in-kernel drivers will be built too (if enabled in kernel configuration): http://zedboard.org/content/creating-linux-kernel-image-boot-zc702-sd-card-slot