Post Reply 
USBOpen(), USBSend() and USBRecv()
04-28-2023, 11:24 PM (This post was last modified: 04-28-2023 11:57 PM by matalog.)
Post: #1
USBOpen(), USBSend() and USBRecv()
I have a HP Prime connected to a UMFT260EV1A, bought from Farnell:https://uk.farnell.com/ftdi/umft260ev1a/...derack-GLB

The HP Prime recognises it, when I enter USBOpen() it returns {{1027,24624}}.

I have JP7 connected at pins 2-3 and JP9 connected at pins 1-2. That is DCNF0 low and DCNF1 high.

That should set it to solely UART connection.

I have an FTDI232 device that I have set the 3.3V jumper on, and it is connected to my PC, then RealTerm - it is also connected to the RXD (TO TXD of FT260) and TXD (TO RXD of FT260) of the FT260.

If I enter USBOpen(1027,24624) it returns {64,64} as expected, but everytime I try USBSend(45) (for example) it returns "Error:Invalid Input".

USBRecv returns {}.

I have not changed the EEPROM in the FT260, and assumed that I would have been able to communicate with the calculator easier.

BTW, I have always been using Serial 19200 as I though nothing else would work.

The strangest thing though - If I follow the steps in this thread: https://www.hpmuseum.org/forum/thread-17848.html And perform :

Code:
EXPORT ft260_EEPROMrdall()  // TEST - dump ft260 ROM in L5 at once
BEGIN
LOCAL x, sts;
PRINT();
L5:={};
UClr();
ft260_open(); 
ft260_i2cSend(ft260,{0});       // start at reg 0
x:=256;
sts:=ft260_i2cReadReq(ft260,x); // read request #C2h, 256 bytes ...
IF TYPE(sts)=6 AND SIZE(sts)>0 THEN 
  L5:=SETBASE(R→B(sts),0);
END;
PRINT("I2C "+ STRING(L5));
UClose();
RETURN L5;
END;

Then the calculator actually returns the codes (numbers of ascii) that were transmitted from PC To Calculator.


Does anyone have any tips or ideas to help me ?
Find all posts by this user
Quote this message in a reply
04-29-2023, 02:47 AM (This post was last modified: 04-29-2023 02:11 PM by gehakte_bits.)
Post: #2
RE: USBOpen(), USBSend() and USBRecv()
See the help text of USBSend:
USBSend({data}) is the format to send data using the HID interface.
i.e. USBSend({240, 4, 65, 66, 67,68})

Per the FT260 User guide manual
4.6.2 UART Write Request:
Byte 0 0xF0 Report ID (240)
Byte 1 length (04)
Byte 2..5 actual data 'ABCD' (65,66,67,68)

A PC typically expects RS232 levels, sometimes 0~5V will do, so I don't know if 0/3.3V will be properly recognized. You might need a proper RS232 level converter.

ft260_EEPROMrdall() dumps the FT260 internal EEPROM (#C2h I2C Read Request), it is not using the serial port to your PC.
The data you see is from the FT260 HID buffer, after a USBRecv(). The first byte indicates what port it came from (probably 0xf0 up to 0xff in your case as from the UART)

Good job - you are almost there!
Find all posts by this user
Quote this message in a reply
04-29-2023, 05:36 PM
Post: #3
RE: USBOpen(), USBSend() and USBRecv()
(04-29-2023 02:47 AM)gehakte_bits Wrote:  See the help text of USBSend:
USBSend({data}) is the format to send data using the HID interface.
i.e. USBSend({240, 4, 65, 66, 67,68})

Per the FT260 User guide manual
4.6.2 UART Write Request:
Byte 0 0xF0 Report ID (240)
Byte 1 length (04)
Byte 2..5 actual data 'ABCD' (65,66,67,68)

A PC typically expects RS232 levels, sometimes 0~5V will do, so I don't know if 0/3.3V will be properly recognized. You might need a proper RS232 level converter.

ft260_EEPROMrdall() dumps the FT260 internal EEPROM (#C2h I2C Read Request), it is not using the serial port to your PC.
The data you see is from the FT260 HID buffer, after a USBRecv(). The first byte indicates what port it came from (probably 0xf0 up to 0xff in your case as from the UART)

Good job - you are almost there!

Great, I have now got the sends working fine. I can send data from the calculator through the serial port.

What do you have to do on the FT260 side, to receive some data through serial port?

Is a USBSend() required before USBRecv() will work?
Find all posts by this user
Quote this message in a reply
04-29-2023, 10:00 PM
Post: #4
RE: USBOpen(), USBSend() and USBRecv()
Okay, now I think I am understanding better that data is being received, although I don't fully understand why it is in the way that it is. I have still not modified any settings, this is all 19200, N,8,1.

The Prime always returns a list of size 64. I wasn't expecting that. It does return the correct results, but not in the way I was expecting. The results are the first bytes in a 64 long list.

For example, I send from PC: "3,1,4,1"

And the HP Prime, after entering USBRecv, returns a list {240,1,3,x,x,x,x....}. Then after entering another USBRecv, I get {240,3,1,4,1,x,x,x,x....}. That is the full amount of numbers that I sent. "3,1,4,1". Although, I expected that I would receive {240,4,3,1,4,1,x,x,x,x....}, all in one go.

Is there any logic to what size the FT260 will return for each "chunk of data" received? Is it something to do with the speed at which the PC is sending it?

Another example, with similar input on PC "3,1,4,1" twice, I sent the same chunk "3,1,4,1" two times, and it resulted in 8 single receives of {240,1,3,xxxx....},{240,1,1,x,x,x,x....},{240,1,4,x,x,x,x....},{240,1,1,x,x,x,x.​...},{240,1,3,x,x,x,x....}... etc.

Is there a way for the FT260 to gather these altogether instead if spreading them over so many receive reports?
Find all posts by this user
Quote this message in a reply
04-30-2023, 03:17 PM
Post: #5
RE: USBOpen(), USBSend() and USBRecv()
The USBOpen returning ({64,64}) tells you the block size the FT260 USB-HID device will do. So the Prime will receive 64 bytes at once. The USB HID interface speed is 64Kbyte/s, so 64 bytes (1 block) per 1 msec.

Since you are sending serial data at 19200 N,8,1, it takes 33 ms to fill that block of 64 bytes. One can wait until the block is filled, introducing a lot of latency (when/how long do you wait for small packet frames << 64 bytes?) or send the data as fast as possible (at 19200 N,8,1 about 1~2 bytes every 1 msec, you see that in your steady state).
(Ignoring things like OS delays, USB suspend-wake delays)

The HID device is not going to wait, in order to reduce latency for its interfaces, and to hide the knowledge of the end-of-data for each and every possible application, leaving it up to the receiver to re-assemble the user data, based on opcode and/or packet length. So 'the way' is to have fun coding the re-assembly of the received packets (or break up data you send...) at the application layers.

If you have a faster interface (i.e. I2C) you see it fills the full 64 bytes:
((wr) request (0xc2) to I2C-device (0x50) read (0x06) 256 bytes (0x0100)
((RD) read opcode (0xde/0xd3), size (4 * 0x3c + 0x10), actual data cropped...)

wr C2 50 06 00 01 00 00 00 00
RD DE 3C 08 30 60 00 00 A0 40
RD DE 3C 00 30 00 10 03 46 00
RD DE 3C 00 00 00 00 00 00 00
RD DE 3C 00 00 00 00 00 00 00
RD D3 10 00 00 00 00 00 00 00
Find all posts by this user
Quote this message in a reply
04-30-2023, 08:37 PM (This post was last modified: 04-30-2023 09:34 PM by matalog.)
Post: #6
RE: USBOpen(), USBSend() and USBRecv()
Thanks again, I am going to try and receive a report, could you possibly help with what you can of these:

[Image: Get%20Report.png?dl=1]

I assume that these should be:

Byte 0 : 161
Byte 1 : 01
Byte 3 : 03
Byte 4 : 161 (For System Status)
Byte 5 : Interface - I'm not sure that the device expects here
Byte 6 : Interface
Byte 7 : Report Length - I'm not sure how this length should be ordered - surely there is not a report longer than 255 bytes.
Byte 8 : Report Length.


And the likes of this:
[Image: Set%20Report.png?dl=1]

Is this set with a Set Report?

Where is "request" entered - "request" is mentioned in byte 1?

Or is this data just sent to the device as USBSend({161,66,0,75,0,0}) (I tried this and it didn't seem to work.
Find all posts by this user
Quote this message in a reply
04-30-2023, 11:51 PM
Post: #7
RE: USBOpen(), USBSend() and USBRecv()
Following this with some interest. I've always wanted a simple way for an app to be able to send and receive data without CK. You may recall https://github.com/BeatSkip/PrimeDev which I wish would have kept going, it showed a ton of promise and opened the door wide open to a lot of innovative improvements of not just managing the calculator, but also installing apps, letting apps work with external devices, etc.

Curious what functionality specifically you're interested in?
Visit this user's website Find all posts by this user
Quote this message in a reply
05-01-2023, 02:23 AM
Post: #8
RE: USBOpen(), USBSend() and USBRecv()
1) The Interrupt-only reports are the only ones supported by the HP Prime:
0xB1(UART-RX interrupts), 0xC2(I2C dumps), 0xD0-0xDE(I2C R/W) 0xF0~0xFE(UART-RX/TX).

2) Examine your receiving example outputs: they only contain data following the HID Report Structure per 4.2 of User Gude FT260 (AN_394). All other setup packet stuff is hidden/taken care of by the HP Prime USB-HID interface already!

So, you only create UART Write Requests and receive UART Input Reports (and Interrupt Report on an input line).

See the original post with code example, you can create a UART sending routine similar to the I2C, without the iaddr,iflag, and proper UART start opcode. ft260_recv() to receive should work.

If you want to learn about USB-HID, plug in your FT260 in a Windows10/11 and SimpleHIDWRITE utility and Wireshark are now friends to hang out with.

FYI a typial setup packet (which will be provided by the Prime) looks like this:
bmRequestType: 0x21
bRequest: SET_REPORT (0x09)
wValue: 0x02c2
ReportID: 194
ReportType: Output (2)
wIndex: 0 (or 1 depending on Windows that can reports both)
wLength: 5
Find all posts by this user
Quote this message in a reply
05-01-2023, 12:51 PM (This post was last modified: 05-01-2023 12:54 PM by matalog.)
Post: #9
RE: USBOpen(), USBSend() and USBRecv()
I will look at the HID Protocol, thanks for all the help.

Now that I have accepted that I will have to deal with multiple sized packets being received by the FT260 over UART, I tried to experiment with it. Using RealTerm on PC, if I send more than 10 bytes together, everything after the 10th is ignored by the FT260, doesn't make it to the calculator and effectively lost.

Do you know what mught cause that?
Find all posts by this user
Quote this message in a reply
05-01-2023, 01:53 PM
Post: #10
RE: USBOpen(), USBSend() and USBRecv()
It might only have a 10 byte buffer and you are overfilling it.
Find all posts by this user
Quote this message in a reply
05-01-2023, 03:37 PM
Post: #11
RE: USBOpen(), USBSend() and USBRecv()
(05-01-2023 01:53 PM)KeithB Wrote:  It might only have a 10 byte buffer and you are overfilling it.

What might only have a 10 byte buffer? The FT260 has a 64 byte (at least 60) buffer.

The FTDI232 has got a 128 byte buffer.

I can send 64 bytes from Calc to PC through the same 2 devices, and it is picked up fine.
Find all posts by this user
Quote this message in a reply
05-01-2023, 07:23 PM (This post was last modified: 05-01-2023 07:30 PM by matalog.)
Post: #12
RE: USBOpen(), USBSend() and USBRecv()
I have tested further, sending 26 bytes from 3 different Terminal programs, "abcdefghijklmono....", it only picks up 10 of them.

Then if I send from PC "abcdefghijklmono...." followed by "12" it stores 10 bytes from "abcd...." and also "12" when I have not used USBRecv() yet and will hold on to them until I use USBRecv().

[Image: 1.png?dl=1]
Find all posts by this user
Quote this message in a reply
05-01-2023, 07:41 PM
Post: #13
RE: USBOpen(), USBSend() and USBRecv()
Not familiar with your terminal program. But you could monitor the Async link data to see what side loses it.

It sounds more like a buffer overflow somewhere (sending data too fast)
But using a terminal program like YAT, one can set the output buffer to 60 bytes, buffer no more than baud rate, buffer chunks of 60 bytes, and sending max bytes / time under advanced settings and other things to play with.
Xon/Xoff also might help (I think that is on by default on the FT260 if I remember) so turn that on on your terminal program.
Find all posts by this user
Quote this message in a reply
05-01-2023, 08:43 PM (This post was last modified: 05-01-2023 10:20 PM by matalog.)
Post: #14
RE: USBOpen(), USBSend() and USBRecv()
(05-01-2023 07:41 PM)gehakte_bits Wrote:  Not familiar with your terminal program. But you could monitor the Async link data to see what side loses it.

It sounds more like a buffer overflow somewhere (sending data too fast)
But using a terminal program like YAT, one can set the output buffer to 60 bytes, buffer no more than baud rate, buffer chunks of 60 bytes, and sending max bytes / time under advanced settings and other things to play with.
Xon/Xoff also might help (I think that is on by default on the FT260 if I remember) so turn that on on your terminal program.

Xon/Xoff has fixed that. Now I get everything in all different sized packets, but at least I get it all. Thanks again.

I ordered i2c to UART devices and in the meantime, I will attempt to use an Arduino to send 60 bytes via i2c.

If I tell the arduino to Wire.begin(80) that is 50h, then should I be able to Wire.write("12345abcde") and receive it on the HP Prime, assuming I have the FT260 JP9 at 2-3 and JP 7 at 1-2. I will connect Arduino SCL-SDA-GND to FT260 SCL-SDA-GND. Is there anything else I will need to set first?
Find all posts by this user
Quote this message in a reply
05-12-2023, 09:53 PM
Post: #15
RE: USBOpen(), USBSend() and USBRecv()
Well, attempting to use i2c to communicate via the Prime and FT260 is proving difficult for me to understand.

I can see in an earlier post that you told me :
Quote:If you have a faster interface (i.e. I2C) you see it fills the full 64 bytes:
((wr) request (0xc2) to I2C-device (0x50) read (0x06) 256 bytes (0x0100)
((RD) read opcode (0xde/0xd3), size (4 * 0x3c + 0x10), actual data cropped...)

wr C2 50 06 00 01 00 00 00 00
RD DE 3C 08 30 60 00 00 A0 40
RD DE 3C 00 30 00 10 03 46 00
RD DE 3C 00 00 00 00 00 00 00
RD DE 3C 00 00 00 00 00 00 00
RD D3 10 00 00 00 00 00 00 00

I have 2 questions. I am using an arduino to communicate via i2c, if I get it to send the bytes [C2,50,06,05,00,01,02,03,04,05] via i2c, and then perform a USBRecv() on the HP Prime, should I expect the bytes[01,02,03,04,05] to be shown on the HP Prime?

The other thing is, I think the Arduino is acting as a master, is there a way to deal with a Master communicating with a master? I will also look into setting the Arduino as a slave in the mean time.

Sorry, I do not know anything about i2c, and it is a little perplexing!
Find all posts by this user
Quote this message in a reply
05-12-2023, 11:32 PM
Post: #16
RE: USBOpen(), USBSend() and USBRecv()
The FT260 is an I2C Master (and translation / forward to/from the USB HID to the Prime).

It can only talk to 'slave' devices on the bus, and as such you have to configure an Arduino as a I2C slave.

C2,50,06,05,00,01,02,03,04,05
This is a read request (0xC2) to device 0x50 (EEprom on the FT2600), I2C mode Start/Stop (0x6), of 0005 bytes. (1~5 are probably ignored)
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)