Posté le 29/01/2021 23:35
Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 156 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 29/01/2021 23:58 | #
Hello !
It seems to be interesting, have you ever heard of P7?
It's a tool develop a while ago to replace FA-124 on Linux.
It contains also P7screen to replicate the current screen, but it only works with mono calc
I'll try out with my cg-50
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C
Citer : Posté le 30/01/2021 00:01 | #
Wow, this looks quite impressive! I don't know how to program a kernel module for Linux or the v4l2 API, but I've actually implemented the protocol used for the kind of models you're describing and checked the protocol part, described through cgscreen_recv(), for what I've found.
There are at least two “projector” protocols on what we call Graph calculators in France, and they are radically different:
- the one used on monochrome models, for which the first model was the fx-9860G known as the Graph 85 in France and published around 2004 (if I remember correctly). This is the protocol you've implemented, it uses the VID/PID couple 07CF/6101, and we refer to it as “protocol 7” as it is an extension of the protocol used for exchanging files and information in the other communication modes.
- the one used on the colour models, for which the first model was the fx-CG20 or “Prizm” and which the latest in France is the fx-CG50 known as Graph 90+E, hence the affirmation I told you earlier about not all Graph calculators in France using one protocol. This one uses the VID/PID couple 07CF/6102, and actually shares its screen using vendor-specific SCSI commands documented here by members of the Cemetech community (which no longer covers Prizm calculators as a community), and the payload has this format; notice the similarities with the frames you've encountered, with TYPZ1 or TYPZ2 replacing TYP01 and it having a subheader where the one you've encountered on the fx-9860G does not.
Notice that this means you might want to modify your driver description; the current one is misleading and could lead people (like Tituya
For this protocol, there is a problem I've encountered during my implementation which is the calculator skipping a few bytes occasionnally. I guess you've either encountered or anticipated the problem because you've added the “Got non-image packet type, ignoring” and “Got partial frame, ignoring” errors. What I've done differently, but I don't know if this is possible to add without headaches in your driver, is being able to read from multiple URB blocks as a stream, and being able to wait for the "\x0BTY" three-byte block which is a good-enough method to recalibrate easily; but for this I guess waiting for the next URB can be ok too.
Also, the calculator uses the same parameter for projector and other interactions such as main memory and storage memory manipulation, so I have a question: is it still possible for any tool using libusb to still interact directly with the USB device when your driver is active? Because otherwise this could be unpractical…
I don't really understand the rest of the code as it uses APIs I don't know, but again, impressive work! Maybe you can check out if you're interested looking for the
For reference, my protocol 7 receiving function is here, it uses a custom stream implementation over libusb basically; this is a protocol I've never finished reworking so it won't compile, you can find an older version of this project here. If you're using Archlinux you can try it out using yay -S p7screen.
Mon blog ⋅ Mes autres projets
Citer : Posté le 30/01/2021 00:27 | #
I have tried p7screen, and I've based my code on it and some pdf I found. I didn't know about the other protocol, but if you send me some specification for it, it shouldn't be too hard to add support for it. I haven't actually encountered dropping bytes, but according to that pdf, if screen updates are happening very quickly, the calculator will simply interrupt the current transmission and start transmitting the new frame. After sending a complete frame the calcualtor seems to send some kind of end of transmission signal (not sure what it's called), but the urb will always stop receiving after the screen ended. Currently the driver doesn't handle this too well, but I will try to fix this soon.
When the calculator is in screen receiver mode, I don't think it's possible to do anything else with it anyway, so that's not a problem. But if you choose a different mode when plugging in the cable, the device registers itself with a different idProduct, so my driver will not get associated with it.
I'll also make an AUR package for fellow archlinux users, that should make testing it out a lot easier
Ajouté le 30/01/2021 à 00:59 :
Also, I'm not sure if it's different with other calculators, but my fx-9750GIII shows up as a mountable device if I select "USB Flash" after plugging in the cable, so I only needed p7 for the screen receiving. I've tested it just in case, and p7screen appears to take precedence over my driver. On the driver side it's as if it disconnected. So I guess it's possible to use p7, but you need to reconnect it after using p7 to regain video functionality.
Citer : Posté le 30/01/2021 01:08 | #
the device registers itself with a different idProduct
I am not sure what you mean by that, for what I've seen until now idProduct is always 0x6101 for the fx-9860G, in projector or other modes (even the OS Update mode, if you already tried updating the fx-9860G derivative you've used for testing). For reference, here's an lsusb output I have for a Graph 35+USB (fx-9750GII-2 french model):
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.01
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x07cf Casio Computer Co., Ltd
idProduct 0x6101 fx-9750gII
bcdDevice 1.00
iManufacturer 1 CESG502
iProduct 2 CESG502
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 39
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 0
bInterfaceProtocol 255
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 2
Device Status: 0x0001
Self Powered
Which should be the same as what you have in Projector mode?
The PDF you have found is very probably this one, by Simon Lothar, which has worked towards reverse engineering CASIO calculators with Andreas Bertheussen (one of the authors of FiXOS, an alternative UNIX-like OS project that's been abandoned for years now). Both these people have stopped working actively on reverse engineering CASIO calculators for quite some time (although SimonLothar is still able to answer questions on Casiopeia if you wish to ask him questions directly). p7screen is one of my projects from back in 2017, and is actually what I tried to improve with libcasio (which I've sourced) but never finished doing so. History is important for small communities like us, it is what makes us so special <3
For the fx-CG50 model, it is of course better if you are able to test on a real model, although it is expensive so I don't really know how this can be arranged
It basically uses USB-attached SCSI (UAS), i.e. USB Mass Storage, using Bulk-Only Transport (maybe Linux has utilities for this already, which you can use vendor-specific commands with). It is coherent: the same way fx-9860G derivatives use protocol 7 over serial and bulk-only USB connections (although screenstreaming / projector mode only works over USB for speed constraints), the Prizm uses the same protocol for exchanging file (standard USB Mass Storage, which it names “Clé USB” in french) and projector mode. There are three custom SCSI commands documented here as linked above, where instead of sending data spontaneously, the Prizm waits for the host device to come and take it though these vendor-specific commands.
The format of every packet is the following:
* The projector packet identifier in one byte, 11 (hex. 0x0B).
Simon Lothar uses the “OHP” letters for “Overhead Projector”, but
“Projector” or “Screenstreaming” work just as good.
* The five-letter picture type. For fx-CG50 it is usually TYPZ1 or TYPZ2.
* The subheader, which in my programs I've limited to be read only if
the five-letter type is TYPZ1 or TYPZ2. It is composed of the following:
* The size of the picture, as big-endian unsigned integer stored either
on 6 bytes if type is TYPZ1, or on 8 bytes if type is TYPZ2.
* The height, as a big-endian 4-byte unsigned integer.
* The width, as a big-endian 4-byte unsigned integer.
* The encoding, as a 4-letter code, representing the encoding of the
picture data:
* 1RC2: 16-bit mode (set of 2-bytes big endian integers ordered by
height then width, as R5G6B5, i.e. 5 highest bits for red, 6 bits
for green and 5 bits for blue).
* 1RC3: 3-bit mode, where every nibble (4 bits) is a pixel, where the
bits represent, ordered from highest to lowest: red, green, blue, trash.
* 1RM2: 2-bit mode? (in my own documentation but no description, so i
guess i found that referenced somewhere but never digged further)
* The payload, of the size indicated above.
* The checksum, as a 2-byte big-endian unsigned integer from the
projector packet identifier (0x0B) to the byte right before the checksum
using sum complement on 1-byte but by substracting instead of adding
(which is why the function in my code is called “checksub8”).
Also, I sometimes have CALxxxx values before packets (7 bytes), where xxxx
seems to represent a 2-byte value represented as 4 hex digits represented
in ASCII. It can appear zero, one or more times, and I don't know what
purpose this fulfills.
This is already a lot of information to take in, I'm sorry for the long message and for the wait as I had to compile all of this from various sources and code excerpts (understanding myself from 2017/2018 can be tricky sometimes).
Mon blog ⋅ Mes autres projets
Citer : Posté le 30/01/2021 09:12 | #
Just woke up to this really cool news. Thanks a lot Baltazar!
English is fine here, as you've seen they aren't that many active forums unfortunately. This is the first time we've had contributions from Hungary though! May I ask (if you don't mind) what kind of background led you here?
Also, I'm not sure if it's different with other calculators, but my fx-9750GIII shows up as a mountable device if I select "USB Flash" after plugging in the cable, so I only needed p7 for the screen receiving.
The fx-CG series (2011) and the GIII series (2020) do that; they show up as SCSI Mass Storage devices for easier data transfer. This seems to coincide with their use of the Fugue FAT-12-like filesystem. Earlier black-and-while models until 2020 (everything but the GIII series) used protocol 7 for file transfer, and (because?) they had a different, homemade, terribly bad filesystem that a computer wouldn't be able to work with.
I am not sure what you mean by that, for what I've seen until now idProduct is always 0x6101 for the fx-9860G, in projector or other modes (even the OS Update mode, if you already tried updating the fx-9860G derivative you've used for testing).
That too changed with the GIII series. Essentially every mode that uses p7 is 07cf:6101, and the SCSI Mass Storage mode is 07cf:6102.
Bus 001 Device 051: ID 07cf:6101 Casio Computer Co., Ltd fx-9750gII
# Graph 75+E (~ fx-9750G II), Projector
Bus 001 Device 052: ID 07cf:6101 Casio Computer Co., Ltd fx-9750gII
# Graph 35+E II (~ fx-9750G III or fx-9860G III), USB transfer
Bus 001 Device 054: ID 07cf:6102 Casio Computer Co., Ltd fx-CP400
# Graph 35+E II (~ fx-9750G III or fx-9860G III), Projector
Bus 001 Device 055: ID 07cf:6101 Casio Computer Co., Ltd fx-9750gII
As you can see the model IDs just separate these two behaviors. Even the Prizm series and the ClassPad series use 0x7c:6102.
In the end Cake's correct, ideally you would need to not control the device in other modes in order to support older models (which are still the most common). I can help with the testing if needed.
Also, that may not be of help as much as the documentation Cake linked, but I made Wireshark captures of the projector protocol over a virtual machine a couple years ago. If there are occasional skipping frames of irregularities, you might be able to find instances of that.
So I ran your module and it worked mostly out-of-the-box, I got /dev/video2 ready to read from. The device also shows up in "Video Capture" in VLC.
I used the following ffmpeg command:
The image is inverted (white-on-black) but it otherwise works fine. I first tested with -r 30 and there were timing issues, a 20-second capture got output as an extremely slowed-down 2-hour long video. In VLC the image seems to freeze after the first frame, but I assume that's just the same problem, as the video info popup says "Framerate: 30.303030".
Other than that, it's really well done, thank you.
Citer : Posté le 30/01/2021 10:59 | #
Yeah... the framerate setting was kind of an afterthought. At first I had it only send frames when the calculator sent new frames, but that didn't work quite well for some use cases. If you only wanted to record your screen, it was great: a lot of video codecs support holding frames, so you could get fairly compact videos, as no frames would get stored if nothing was happening. But I also wanted to be able to overlay my calculator onto my camera for online classes to show what I'm doing, but this would act funky, so I added some basic fixed-framerate functionality. Not very accurate, but it did work for me. I haven't figured out yet how it would be best to allow the user to switch between these modes. I'm not sure what the problem could be for you. This is the command I've used for recording:
I haven't tried with vlc, but ffplay works fine for previewing, and you can also add the -vf from the previous command to it so you can make it a little larger.
I'm not sure if it's possible to allow p7 and my module to work in parallel, but again, p7 seems to kick my module off the device so it's possible to use p7 while my module is loaded. To get my module working, you have to reconnect the device it seems.
However, it might be possible to create a virtual filesystem from my module but that sounds like quite a project, especially given that I don't have a calculator I can test it on. Same problem with the other screen streaming protocol, but I'll try to implement that so you can test it out.
Citer : Posté le 30/01/2021 11:00 | #
The fx-CG series (2011) and the GIII series (2020) do that; they show up as SCSI Mass Storage devices for easier data transfer.
I completely forgot for the newest monochrome models (GIII) that have a Prizm-like “USB key” mode, that's true! Which explains why Baltazar was talking about this mode while saying they had a monochrome model.
EDIT: For your problem of p7 kicking out your module, it may be because, per documentation, the library uses libusb_claim_interface() when using a device.
EDIT 2: Plus, the VFS is indeed quite the project seing how I never finished doing it in my library. Protocol 7 is a reqrep protocol at its core (whereas it's a simple unidirectional pipe for screenstreaming), with roleswapping between host and guest from time to time; e.g. if you want to list files on a storage memory, you send a list request, then roleswap, and the calculator sends file information commands with information until it asks for another roleswap, setting your PC as the host again.
Protocol 7 transfer mode supports two filesystems and multiple commands, which are documented in the fxReverse documentation for the most part, but just to give you an idea of what's in it:
* 0x20 - 0x33: manipulation of the main memory, a 64 KiB custom format filesystem (its inner workings are actually complicated) which the “USB key” mode emulates using the @MAINMEM folder, by copying “file attributes” on the filesystem level to the file itself using the g1m / g1r / g3m format.
* 0x40 - 0x51: manipulation of the storage memories. Basic monochrome models don't have any (although not sure for the newer models, I haven't been very up to date recently), more advanced models use the last 2,5 MiB of their rewritable 4 MiB flash memory as a Fugue filesystem (named fls0), some older models also support SD cards (not SDHC, so at most 2 GB) named crd0.
* 0x2F, 0x30: RAM backup commands, which probably don't work since 2.04 (although haven't experimented a lot on them).
* 0x4F-0x55: ROM backup commands, which don't work since 2.04 (see this).
* 0x56: the infamous “OS Update” command, which allows the host to upload and execute any correctly formatted payload. This is used for executing some OS update code from the RAM, which opens the USB connection and flashes the memory with what it receives.
Notice that there are other custom commands depending on which OS Update payload you transfer to the calculator. Simon Lothar for example, in its custom OS Update used in fxRemote, uses commands in the 0x70 - 0x7F command (see my implementation of this flow).
So as you said, quite the project.
Mon blog ⋅ Mes autres projets
Citer : Posté le 30/01/2021 11:37 | #
I'm just realizing what you're saying. Does this mean it uses those vendor specific scsi commands for the screen receive? Because if it works similarly to my calculator, I just have to add support for TYPZ1 and TYPZ2 screens, but I'm not sure how I would work with the scsi commands while still allowing it to be mounted as usb mass storage.
Citer : Posté le 30/01/2021 11:49 | #
It absolutely does. As you have a newer model, you might run into another encoding I don't know representing 1bpp pictures (or it might just use the TYP01 format, without subheader). Maybe Lephenixnoir has this model to test with, to check what encoding the projector mode uses, so you only have to worry about the Linux-side of things? (haven't bought a CASIO calculator since 2018 I think)
Ajouté le 30/01/2021 à 11:54 :
… wait, I just made the link. From what I've understood you have a GIII, and it still uses protocol 7 style for screenstreaming so it obviously won't use UAS with TYPZ subheaders. Sorry for having confused you >_>
Mon blog ⋅ Mes autres projets
Citer : Posté le 30/01/2021 12:01 | #
Oh yes that's a really cool thing to have! So far I've usually recorded animations as MP4 then ran mpdecimate to obtain the same effect when converting to GIF:
But that's really not as good, especially because of compression artifacts that I've not manager to get rid of in wf-recorder.
I'm not sure if it's possible to allow p7 and my module to work in parallel, but again, p7 seems to kick my module off the device so it's possible to use p7 while my module is loaded.
If you assume the user runs a certain command before starting the capture, would it be possible to reclaim the device from p7 without trying to share it?
Does this mean it uses those vendor specific scsi commands for the screen receive? Because if it works similarly to my calculator, I just have to add support for TYPZ1 and TYPZ2 screens (...)
I have a Graph 90+E (fx-CG 50) to test with, and a couple of Wireshark captures (linked earlier) so I would be able to help with that
Citer : Posté le 30/01/2021 12:16 | #
Do you think there's a chance the GIII supports the scsi commands for screen receiving? If so, I could do at least some testing myself.
Yes, it's possible to claim the device manually by writing the usb device's identifier to /sys/bus/usb/drivers/cgscreen/bind. e.g:
Also, how can I turn off email notifications from this thread? I've turned it on when first posting, but I'm receiving way too many emails.
Citer : Posté le 30/01/2021 12:21 | #
For SCSI support in the GIII, I wouldn't know. If you're the one initiating the communication, you might have luck, but otherwise the calculator might just always use protocol 7 without an option to switch.
Yes, it's possible to claim the device manually by writing the usb device's identifier to /sys/bus/usb/drivers/cgscreen/bind. e.g:
I would personally consider that good enough, since I'd wrap the watching/recording in a command anyway.
I'd assume unchecking the box would work. In any case I've unsubscribed you from this topic for now.
Citer : Posté le 01/02/2021 19:44 | #
On the calculators which use the scsi vendor-specific commands, is there a different mode on the calculator if you want to use the screen receiver or you should be able to view the screen while it's mountable as a disk as well? My GIII has three options when the usb cable is plugged in: USB Flash, Projector, ScreenRecv. In USB Flash, it shows up as a mountable mass storage device. In Projector, I can use protocol 7 to receive its screen. In ScreenRecv, it again shows up as a scsi removable disk, but there's nothing to be mounted. I assume in this mode I should be able to use the vendor specific commands. I have yet to test this out, but if the other calculators you mentioned work the same way, I should be able to make this work. However, if they don't have different modes for screen receiving and file transfer, I'm not sure it's possible to make them work in parallel. Also, I must come up with something to differentiate these modes, as (at least my model) shows up with the same IdVendor / IdProduct combination in both modes.
Also, I've pushed a few commits, now the screen is not inverted, and I shouldn't be getting overflow / partial frame warnings anymore, and those frames are also parsed correctly now. (previously, I couldn't make out any frames when an animation was playing in the geometry addon)
Citer : Posté le 01/02/2021 22:39 | #
I am slightly confused - the GIII indeed has an SCSI-based Screen Receiver mode, so how did you implement support for the Screen Receiver mode on your GIII using protocol 7 ?
Other than that, yes, there is probably only one SCSI-based Screen Receiver protocol, so if you can make it work for your GIII, you'll very likely be just a couple of color frames formats away from supporting the fx-CG series.
Citer : Posté le 01/02/2021 23:03 | #
the GIII seems to have support for both protocols: it has a Projector and a ScreenRecv mode. Projector uses protocol 7, ScreenRecv presumably uses scsi. What I was asking is whether the other calculators separate the screen receiving and the file transferring modes. The problem is that it might not be possible to allow screen recording while the device is mountable.
Citer : Posté le 01/02/2021 23:06 | #
Projector mode is used mostly for CASIO projectors, which I assume continue to use protocol 7 because there doesn't seem to be any incentive to update that code. I realize after testing that's what you implemented instead of the SCSI-based screen receiver.
As for dual-tasking with projector and filesystem access, I'm 95% confident the calculator doesn't support it anyway.
Citer : Posté le 01/02/2021 23:16 | #
Yeah, I didn't really have any resources on the scsi version and p7screen seemed to be working well enough to be worth implementing to a video device. It appears that the scsi protocol is now more widespread than protocol 7 so I guess that's what I'll try to do now.
Another important question is whether the calculator can switch between the 16-bit and 3-bit color modes during screen receiving. If not, it should be enough to read the first frame to decide the size of the buffers to be allocated. Another option might be just to always create large buffers and translate the 3-bit pixels to 16-bit.
Citer : Posté le 01/02/2021 23:27 | #
I think it can't really change without the device reconnecting, but we're dealing with proprietary software here, and not amongst the best ones, so I reckon the latter solution (big buffers with 3-bit to 16-bit translation) is the best one.
Mon blog ⋅ Mes autres projets
Citer : Posté le 01/02/2021 23:31 | #
Now that I think about it, nothing would understand that weird 3-bit packed encoding, so I would have to translate it to something sensible anyway.