hidapi Windows 8.1 hid_write fail - qt5

hw : lpc1549 eval board with usb hid test firmware ...
endpoint size 64 bytes
endpoint intr reads out-report buf and displays len and data in hex ...
copies out_report into in_report buf and echoes back with write funct and len
host :
using qt5 , libusb-1.0.19 wingw32 dll and hidapi code
hid test code issues all your api calls (except write and read) sucessfully in linux, win7 and win8.1
test code issues hid_write followed by hid_read and get's data back properly in linux
i am not using the, by hidapi hid_write mandatory flagged Report ID, since the nxp firmware and keil software do not use it (as far as i could figure out) ...
my linux sw sends and receives a defined 64 byte pattern or smaller len) correctly and byte [0] is part of this pattern ... out and in byte [0] data is intentionally different and correct received
running the keil hid client under windows succeeds to properly communicate with the lpc1549 firmware, even they only transfer and echo one byte ...
my firmware has the endpoint size changed to 64 bytes (i hope my changes are correct) and the keil hid client works with it in windows so my assumption is that my descriptors are correct ... hopefully
host sw kububtu 14.04
hid_write len = 17, device 17 bytes received, 17 bytes indicated as received ... all seems to work properly
host sw with hidapi in win 8.1
hid_write len = 17 bytes shows up on device with 16 bytes correct and the rest is 0, but the read indicates a received len of 64 ... i issued a write of 17, received 16 correctly, but was indicated as 64 received
also win 8.1 throws a blank system32/cmd prompt window up ... why ???
the same hangs on win7 and only a hid_write len = 0 succeeds ... popping the same cmd prompt ... received len = 64, but no data transferred (as it would make sense with len = 0)
i can not single step or breakpoints since qt debugger get's segment fault upon app loading
also i link in my qt app to the hidapi "windows/hid.c" code and it is now part my code
sorry for my rather complicated description
why is a Report ID mandatory if it's not being used ... it would be a waste of one byte and if uint32_t alignment is required it would be a waste of about 7 % of the 64 bytes data
why does the keil hid client written in c++ msvs work correctly with my fw and hidapi not
would the functioning of the keil hid client indicate that my fw and my descriptors and report len are correct
What would cause an empty cmd prompt popping up?
What could i be doing wrong (a whole hidapi based app is correctly communicating with a complete usb based firmware pgm, not just the described test code)?

after a couple of days a few things got clear
the ReportID seems to be something in windows and on the host side only ... the firmware is not effected on my setup
also what was not to clear initially is that the ReportID is in addition to the max of 64 report bytes
so i create a buffer with 1 + 64 bytes = 65 ... the 1st one is zero since i do not use the ReportID mechanism and the remaining 64 are normally used
the write call data size needs to be therefore 1 + whatever the reportsize is in the usb hid descriptor endpoint side
in linux there is no ReportID on hid what i could see
next : make sure the data length specified in the write call on the host as well on the device match exactly the endpoint size definitions, otherwise no data gets across either direction and your software might hang (wait forever) on the read on the other end
i hope this might help others to get a better pict of the windows end of the hidapi hid_write calls

Alan Ott wrote me the following
http://www.signal11.us/oss/hidapi/hidapi/doxygen/html/group__API.html#gad14ea48e440cf5066df87cc6488493af
There is always a report ID. You must always send a report ID in HIDAPI, but it will not be sent to the device if the report ID is 0.

Related

PC set Capabilities.InputReportByteLength to one more that USB device packet size - why?

I am playing around with a PIC16F1455, using the USB port based on this article: https://www.codeproject.com/Tips/530836/Csharp-USB-HID-Interface
I send data to the port, and I set the packet size (Configuration descriptor) to 8 bytes.
However, the PC sees the Capabilities.InputReportByteLength as 9 bytes
And when I receive I get 9 bytes, the first one always being 00, followed by the 8 bytes I send from my device.
Can anyone tell me why this happens?
And this first 00, what is this used for?
Can I put something real there?

How is value of Program Counter incremented?

I am creating a Primitive Virtual Machine which is kind of inspired by LC-3 VMs but a 32-bit version. I am feeding the machine set of instructions. After executing the first instruction, how will the PC know the location of the second instruction.
Is there a particular method to store the instructions in memory in a systematic way so that PC knows the address of the next instruction
Example - All instructions are stored in a linear way as in memory[0] = instruction1, memory[1] = instruction2 etc.
Thank you for the help.
It depends on whether your Processor architecture is RISC or CISC. In the context you asked, A CISC processor has instructions whose size vary, say from 1 to 14 bytes, like for Intel processors. If it is RISC, each instruction size is fixed, say 4 byte, like for ARM processors. All the instruction of a program are stored, in sequence, in main memory. It is the processor control unit that decides how much to increment the PC. Instructions from the main memory would be read in sequence.
So say in CISC architecture, a single 8 byte read from main memory, can contain up to 8 '1 byte' instructions, e.g., repetitive 'inc ax' instruction in Intel processors. After sending the first instruction for decode, the control unit will increment PC by 1. But, at other extreme, there could be a instruction like 'add REG , [BASE+INDEX+OFFSET]' , which can take 13 bytes to store all the information (opcode + REG id + base address + index + some offset) that is there in the instruction. For such instruction, two memory read operation would be required to fetch the full instruction. After sending it for decode, the control unit will increment the PC by 13.
For RISC it is simple. Increment PC by size (2,4,...) of instructions.
Only exception is when there is branch. In that case, PC value is reset at usually the execute stage.
Instructions and data are generally grouped (segmented in some processor architecture) and stored separately. A code segment will end with some kind of return or exit instruction. If PC is set to some memory address where data is stored, the control unit of the processor will process it as instruction. After all both data and instructions are nothing but a sequence of bits! The control unit will not be able to differentiate. It is usually the role of OS or programmer (if there is no OS, like on micro-controllers) to prevent such anomaly.

Read variable length messages over SPI using Low Level (LL) api on STM32 MCU

My system is composed by an STM32NUCLEO board and a slave device connected over SPI. The slave device sends commands with a variable length: possible lengths are 4, 8, 10, 14 bits.
I'm trying to detect these messages on my nucleo board using the LL APIs and interrupts.
The solution I'm currently working on is based on setting the SPI with a data-width of 4 bits (SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_4BIT) and then counting the number of words (1 word = 4 bits) that I receive. In this way, if I receive 1 word then it means that I have received a 4 bit command, 2 word --> 8 bit command. If I receive 3 words, it should mean that I have received a 10bit command (2 bits should be discarded), and so on.
Unfortunately, I have noticed that the LL APIs provides functions only for reading 8 bits or 16 bits at a time and currently I'm having issue in receiving a 4 bit command, since the function LL_SPI_ReceiveData8 expects to receive 8 bits.
Here is my implementation for the IRQ handler and for the callback:
IRQ Handler:
void SPI1_IRQHandler(void)
{
/* Check RXNE flag value in ISR register */
if(LL_SPI_IsActiveFlag_RXNE(SPI1))
{
/* Call function Slave Reception Callback */
SPI1_Rx_Callback();
}
/* Check STOP flag value in ISR register */
else if(LL_SPI_IsActiveFlag_OVR(SPI1))
{
/* Call Error function */
SPI1_TransferError_Callback();
}
}
Callback
void SPI1_Rx_Callback(void)
{
/* Read character in Data register.
RXNE flag is cleared by reading data in DR register */
aRxBuffer[ubReceiveIndex++] = LL_SPI_ReceiveData8(SPI1);
}
As said before in my opinion, the problem seems that I'm using the LL_SPI_ReceiveData8 function to read since I could not find something like LL_SPI_ReceiveData4.
Do you have some suggestions?
Furthermore, is it possible to set the SPI to use 2 bit datawidth instead of 4? Something like SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_2BIT: in this way it should be easier to detect the commands since 4, 8, 10 and 14 are multiples of 2.
Thank you.
With the new information about the used controller:
It supports SPI data transfer length between 4 and 16 bit. So your fist try seems not so bad.
Your "problem" is that there is no 4 bit read function. This is caused by the receive data register that will always contain 16 bit but there are only 4 bit valid data in your case. the other bits are '0'.
Your callback function
aRxBuffer[ubReceiveIndex++] = LL_SPI_ReceiveData8(SPI1);
will write values from 0..15 to the aRxBuffer and you don't need a
ReceiveData4() to get your answer :-)
So also the Reference manual for the STM32L4 series Reference Manual at page 1193ff.
The minimal addresable chunk of data is byte. So even if you receive the 4 bits the read value is 8 bits.
BTW wht is this secret slave device which have varing word length?

Confused by the report ID when using HIDAPI through USB

I am a USB HID newbie and I am trying to use the HIDAPI for my application.
I have a question about using HIDAPI (in Visual Studio) regarding the report ID.
When I try to use the HIDAPI and connect to the Microchip Custom Demo,
I am confused about this aspect: The 65-byte report does not make sense to me!
Even if I don't want to set a report ID, I need to set the first byte to 0 and send the 65-byte buffer to the device, but I only receive 64 bytes of data from the Microchip device (because the report is 64 bytes long).
It looks like:
**Host** **Device**
*write_hid*
65 byte --------------->
*read_hid*
<------------------ 64byte
However, it seems weird to me.
Isn't the report that is sent or received always 64 bytes? Because the specifications say the report should have a 64-byte maximum and be sent every 1 ms.
If the answer is yes, why does the API maintain 65 bytes for 1-byte report ID?
Is the report ID contained in the 64 bytes?
The 65-byte data length does not make sense to me.
If your application does not include a Report ID in the HID descriptor, then there shouldn't be a Report ID prepended.
As you can see in the documentation of hid_write, HIDAPI should only send 64-bytes if the first byte is 0 (i.e. there is no Report ID):
unsigned char data[65];
buf[0] = 0; /* Single report */
// Fill report starting at buf[1]
hid_write(device, data, sizeof(data));
When looking at the source code for the libusb implementation, you can see that the Report ID is correctly stripped. On Windows however, the data is passed straight to Windows. I don't know Windows programming, but perhaps this makes a difference. Try testing this on Linux instead.

lpc1788 ssp (SPI) - proc to proc communication

I would like to send string of chars from one proc (master) to another (slave) and then read string from a slave.
Currently im mixing up the arduino and LPC1788, using lpc as master and arduino as slave.
LPC sent's the string correctly which is received by the arduino in ISR. In loop function i check if all of the chars are received and then try to send string back. On LPC side ISR is not working for some reason. I have set SR as
SR = (1<<TNF) | (1<<RNE);
So i have put delay after sending the string from LPC and then initiate read from arduino.
What i see on LA for sending the string is:
but reading of string from Arduino looks odd (string should be "Pong\n", it is not always P that i received... it varies)
i guess majority of problem is within the sync of sending and reading of SPI buffer. How do i achieve that without functional ISR on LPC?
The SPI specification states that the CS (SSEL) line should be active during a frame and become inactive in between. NXP interpreted this as a word being one frame. This means that the CS as generated by the SSP block (the same goes for the legacy SPI) is only active during one transaction of up to 16 bits.
Note also that there is always a gap in between the words/frames being sent. So even when you fill the FIFO or use DMA you will see 16 clock pulses, a short delay and then 16 more pulses.
When using a GPIO pin as SSEL, please note you have to wait for SSEL assertion or de-assertion until the peripheral is idle.