Author Topic: Cover Display Subforum?  (Read 1467 times)

Jujuyeh

  • Newbie
  • *
  • Posts: 6
    • View Profile
Cover Display Subforum?
« on: January 21, 2020, 07:04:50 am »
Hi,

I believe that there is a lot of potential in the Cover Display hardware. (I'll call it CoDi from now on)

What do we know at the moment?

- It can be manually flashed with the Cover Assistant app. That would help us to run custom firmware.
- It's based on a STM32 microcontroller (as pointed out in https://wuffs.org/blog/pulling-apart-the-co...emfota-updater)
- There's a well-defined protocol, so the main OS can communicate with the microcontroller.

Questions for the future:

- Will PC publish any information on the CoDi?
- Which protocols is CoDi using? (I suspect it could be SWD for flashing, and SPI for real-time data).
- Which model of communication is CoDi using with the vanilla firmware? Is the microcontroller pulling the data, or is the main OS pushing data? (This is relevant on how it would behave with other OS than Android)
- Has anyone done any experiment? Any working custom code?

I think there are lots of topics regarding CoDi, I just can't help wanting to know more about it.

It depends on the openness of PC with CoDi but the hardware nerd inside me wants to play with it, make some tweaks, run custom code...  

That's why I bring this topic to hopefully build some community around it. It would be nice to have a CoDi subforum, so other subforums don't get spammed with CoDi specific topics. Also, currently, is difficult to tell where CoDi topics belong.

Dickon Hood

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
    • http://
Cover Display Subforum?
« Reply #1 on: January 21, 2020, 08:09:57 am »
I'll be surprised if it's anything more complicated than a UART, frankly.  I've had a Raspberry Pi talking to an Armada 370 at 1.5Mb/s or so over a bog-standard serial port, which goes to show you can get some serious bandwidth out of these things -- a tad quicker than the usual 9600 or 115200 baud.

iusethis

  • Newbie
  • *
  • Posts: 20
    • View Profile
Cover Display Subforum?
« Reply #2 on: January 21, 2020, 09:49:58 am »
PC should just open source the code for the cover display and the community might come up with a better way to update it. It's a mess now tbh. Mine's currently dead, and others on Indiegogo have reported that it takes 10-20 tries with a voodoo combination of factors to finally succeed.

Dickon Hood

  • Jr. Member
  • **
  • Posts: 51
    • View Profile
    • http://
Cover Display Subforum?
« Reply #3 on: January 21, 2020, 09:53:44 am »
Mine updated first time, but then I'd put it in aeroplane mode, and didn't have any alarms scheduled.

I'm not convinced it's helped.  Battery life isn't looking great.

NormMonkey

  • Full Member
  • ***
  • Posts: 110
    • View Profile
Cover Display Subforum?
« Reply #4 on: January 21, 2020, 10:36:33 am »
I seem to recall from one of the videos that PC intends to release some API access to CoDi, presumably so that the linux community can take advantage of it.

I suspect that's much of the reason why they went with FreeRTOS on STM32 instead of a more low-level interface.  Makes it easier for the linux community to interface with it, which makes it easier for PC to support the linux community and not have to build and manage drivers.

gymbo

  • Full Member
  • ***
  • Posts: 221
    • View Profile
Cover Display Subforum?
« Reply #5 on: January 21, 2020, 05:58:40 pm »
Quote from: iusethis
PC should just open source the code for the cover display and the community might come up with a better way to update it. It's a mess now tbh. Mine's currently dead, and others on Indiegogo have reported that it takes 10-20 tries with a voodoo combination of factors to finally succeed.
Probably not worthy of an entire subforum, but a thread with "voodoo" practices needed to make the Cosmo (or Gemini) work, could be interesting: To get function/app X work, I needed to stand on my head, while reciting "Cosmo/Gemini is great" backwards three times....

There really seems to be som "magic" involved in getting certain things working in the Gemini (and probably Cosmo too)      

Jujuyeh

  • Newbie
  • *
  • Posts: 6
    • View Profile
Cover Display Subforum?
« Reply #6 on: January 21, 2020, 06:15:34 pm »
I agree. But if the main reason they would release such API specification is to get Linux support... They are better going to release the source code for CoDi.

The community would give more and more value to the Cosmo with all the software and tweaks they would build on top. This is for me the ACTUAL value for the Cosmo. Without that it's just an android phone for those that have a fetish on keyboards (sorry, no offense).

The Cosmo has the potential to become something beyond PC's capability on developing (at least currently). If getting CoDi to work on Linux is too hard for them... Give us anything that could be helpful.

I want to play around with my CoDi. And then, and only then, if I'm happy with the experience I got making something for it, I'll invest my knowledge into creating something useful. This would give the Cosmo a little bit of more value, but if PC ensures a good experience working on CoDi I don't think I would be the only one tempted to create new functionality.

Ninji

  • Newbie
  • *
  • Posts: 32
    • View Profile
Cover Display Subforum?
« Reply #7 on: January 21, 2020, 09:07:50 pm »
The CoDi is exposed to the main OS via a UART on /dev/ttyS1 for general communication and files in /proc/ that map to certain bits of functionality (wake up, reset, enter-FW-update-mode button). Updates are handled via the same UART - the CoDi bootloader detects whether the update "button" is being "pressed" (obviously not a real button ) and if so, loads into an updater mode which accepts a file via a YModem transfer. Like most of the CoDi code it's heavily based off STM32 SDK samples.

I've been trying to write custom firmware for it, and I've gotten to the point where I have a binary I can flash that boots up, sends debug information over the UART and displays an image on the screen, but there's an issue with the display interface that I've not figured out yet.

My current code for this is here, if you're curious: https://github.com/Treeki/OpenCodi
And, an example of what it's doing right now: https://twitter.com/_Ninji/status/1219362735378530306
« Last Edit: January 21, 2020, 09:09:10 pm by Ninji »

spook

  • Jr. Member
  • **
  • Posts: 87
    • View Profile
Cover Display Subforum?
« Reply #8 on: January 21, 2020, 10:04:32 pm »
Quote from: Ninji
The CoDi is exposed to the main OS via a UART on /dev/ttyS1 for general communication and files in /proc/ that map to certain bits of functionality (wake up, reset, enter-FW-update-mode button). Updates are handled via the same UART - the CoDi bootloader detects whether the update "button" is being "pressed" (obviously not a real button ) and if so, loads into an updater mode which accepts a file via a YModem transfer. Like most of the CoDi code it's heavily based off STM32 SDK samples.

I've been trying to write custom firmware for it, and I've gotten to the point where I have a binary I can flash that boots up, sends debug information over the UART and displays an image on the screen, but there's an issue with the display interface that I've not figured out yet.

My current code for this is here, if you're curious: https://github.com/Treeki/OpenCodi
And, an example of what it's doing right now: https://twitter.com/_Ninji/status/1219362735378530306

For %@#! sake Ninji - when are PC going to employ you already!!! How good would the software be if they just paid you full time to write it

shuntcap

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Cover Display Subforum?
« Reply #9 on: January 22, 2020, 03:08:39 am »
Quote from: Ninji
I've been trying to write custom firmware for it, and I've gotten to the point where I have a binary I can flash that boots up, sends debug information over the UART and displays an image on the screen, but there's an issue with the display interface that I've not figured out yet.
Nice work! I took a quick look at your main.c and your twitter GIF of the screen issue.  Without my spending too much time studying the code, it looks possibly like an issue with your img.h data array or your blit not being matched to the screen's pixel format and/or width.  The LCD layer appears to be initialized with a size of 240x536 with RGB888 pixels: that's three bytes per pixel.  screen_buffer[] is the right size, but make sure your img[] array is of the same RGB888 format and that it's exactly 240 pixels wide (240*3=720 bytes per row).  One more thing to watch out for is rotation. If it's really a 536x240 display rotated 90 or 270 degrees, you'll want to rotate your img[] array first before blitting.  And a real pain of a problem is if the LCD timing is mismatched to the actual panel (ltdcHandle.Init.* parameters). It's a pain if you don't have docs for the panel you're stuck debugging!  This can cause odd sliding or flashing effects. Finally, if 240x536 or RGB888 isn't the real size or pixel depth of the panel used, your blit might jump all over the place if it's not static on the screen (or if it doesn't move, it'll be badly warped or discolored).

Jujuyeh

  • Newbie
  • *
  • Posts: 6
    • View Profile
Cover Display Subforum?
« Reply #10 on: January 22, 2020, 05:47:51 am »
Quote from: Ninji
The CoDi is exposed to the main OS via a UART on /dev/ttyS1 for general communication and files in /proc/ that map to certain bits of functionality (wake up, reset, enter-FW-update-mode button). Updates are handled via the same UART - the CoDi bootloader detects whether the update "button" is being "pressed" (obviously not a real button ) and if so, loads into an updater mode which accepts a file via a YModem transfer. Like most of the CoDi code it's heavily based off STM32 SDK samples.

I've been trying to write custom firmware for it, and I've gotten to the point where I have a binary I can flash that boots up, sends debug information over the UART and displays an image on the screen, but there's an issue with the display interface that I've not figured out yet.

My current code for this is here, if you're curious: https://github.com/Treeki/OpenCodi
And, an example of what it's doing right now: https://twitter.com/_Ninji/status/1219362735378530306

Wow! That's great news! Thank you Ninji for your hard work

I'd like to test it, could you please give some instructions on how to reproduce what you were trying?

I do have some experience working with ARM microcontrollers with C and assembly. It would be nice to combine that with your advancements.

Thank you again for your work!  

Ninji

  • Newbie
  • *
  • Posts: 32
    • View Profile
Cover Display Subforum?
« Reply #11 on: January 22, 2020, 10:02:22 am »
Quote from: shuntcap
Nice work! I took a quick look at your main.c and your twitter GIF of the screen issue.  Without my spending too much time studying the code, it looks possibly like an issue with your img.h data array or your blit not being matched to the screen's pixel format and/or width.  The LCD layer appears to be initialized with a size of 240x536 with RGB888 pixels: that's three bytes per pixel.  screen_buffer[] is the right size, but make sure your img[] array is of the same RGB888 format and that it's exactly 240 pixels wide (240*3=720 bytes per row).  One more thing to watch out for is rotation. If it's really a 536x240 display rotated 90 or 270 degrees, you'll want to rotate your img[] array first before blitting.  And a real pain of a problem is if the LCD timing is mismatched to the actual panel (ltdcHandle.Init.* parameters). It's a pain if you don't have docs for the panel you're stuck debugging!  This can cause odd sliding or flashing effects. Finally, if 240x536 or RGB888 isn't the real size or pixel depth of the panel used, your blit might jump all over the place if it's not static on the screen (or if it doesn't move, it'll be badly warped or discolored).
All of these are things I've tested already. The values I'm using for the LCD timing, DSI commands, etc are all taken from my disassembly of the CoDi firmware - I tried to replicate what they are doing as closely as possible, seeing as I don't have actual info on the CoDi hardware. I'm also not doing any blitting using the hardware yet; I'm keeping it simple by just telling it to draw a static framebuffer from 0x20000000, and that's still messing up.

I have a couple of thoughts on what to try next but haven't had the time to. I dumped the registers from all the peripheral memory regions while running the official CoDi FW so I could compare them to the values they have while running mine, but haven't gotten round to the latter yet. I also want to disassemble my resulting binary and compare it to the original one, just in case there's some discrepancy I've overlooked because of STM32 HAL changes between my version and whatever Planet used.

Quote from: Jujuyeh
I'd like to test it, could you please give some instructions on how to reproduce what you were trying?

I do have some experience working with ARM microcontrollers with C and assembly. It would be nice to combine that with your advancements.
You will need:
- A copy of https://github.com/STMicroelectronics/STM32CubeL4
- The GNU ARM toolchain: https://developer.arm.com/tools-and-softwar...nu-rm/downloads (I used the latest version at the time of posting, 9-2019-q4-major)
- ADB and a rooted Cosmo (for debugging)

You will probably need to adjust the SDK_DIR in the Makefile to point to the STM32CubeL4 checkout (I should take that out of the Makefile when I get round to poking at this again) and then run as follows:
Code: [Select]
$ make GCC_PATH=/Users/ash/src/cosmo/gcc-arm-none-eabi-9-2019-q4-major/bin
$ adb push build/OpenCodi.bin /sdcard/Cosmo_firmware_custtest.bin

Then, flash the binary via the manual option in the Cover Display Assistant. You will want to keep a couple of adb shells open so you can send commands:
Code: [Select]
$ su
# cat /dev/ttyS1
# echo -n 1 > /proc/AEON_RESET_STM32; sleep 2; echo -n 0 > /proc/AEON_RESET_STM32
Upgrading via the Assistant usually seems to terminate the 'cat' (probably because it changes the baud rate on the TTY) so you will have to re-run it. You'll probably miss some of the initial output that way so if I need to view something I will update it, run the 'cat' command and then do a reset in another terminal.

I've not yet implemented anything to let the CoDi go to sleep or turn off the screen while running this, so after flashing it will just stay in that mode until you flash the original firmware back. It does seem to reboot every so often, I'm not sure if this is some kind of watchdog mechanism in the STM32 that I'm not handling properly, or if this is the Android code forcing it to reboot because it doesn't reply to ping commands.

Jujuyeh

  • Newbie
  • *
  • Posts: 6
    • View Profile
Cover Display Subforum?
« Reply #12 on: January 22, 2020, 11:01:19 am »
Thanks, Ninji.

I was afraid I had to root my Cosmo. I'm not sure if rooting the cosmo would leave me without the dual-boot update. I want to run GNU/Linux on my cosmo, so I'll think I'll wait until the update.

Then I'll root my cosmo. Even so, I think by then it will be easier to work with CoDi from Linux.

On the meanwhile, I can still flash custom firmware with the assistant and then just reboot the device, right?

Also, once I want to go back to the original firmware, will the assistant just download it as an update or I have to manually download it?



shuntcap

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Cover Display Subforum?
« Reply #13 on: January 22, 2020, 04:27:36 pm »
Quote from: Ninji
All of these are things I've tested already. The values I'm using for the LCD timing, DSI commands, etc are all taken from my disassembly of the CoDi firmware - I tried to replicate what they are doing as closely as possible, seeing as I don't have actual info on the CoDi hardware. I'm also not doing any blitting using the hardware yet; I'm keeping it simple by just telling it to draw a static framebuffer from 0x20000000, and that's still messing up.
What happens if you simply try painting one quadrant of the screen (width/2 x height/2) a certain color?

Judging from how slowly the LCD redraws during a "swipe" gesture, my guess is the CoDi hardware doesn't even support a hardware blit (or at least isn't using it), probably just buffer swapping.

Ninji

  • Newbie
  • *
  • Posts: 32
    • View Profile
Cover Display Subforum?
« Reply #14 on: January 22, 2020, 06:58:49 pm »
Quote from: Jujuyeh
I was afraid I had to root my Cosmo. I'm not sure if rooting the cosmo would leave me without the dual-boot update. I want to run GNU/Linux on my cosmo, so I'll think I'll wait until the update.
You can always flash the original boot image back and use the OTA updater that way, or you can just flash the partitions manually (which is the approach I take as I've been rooted since I got my Cosmo).

Quote from: Jujuyeh
Then I'll root my cosmo. Even so, I think by then it will be easier to work with CoDi from Linux.
Sort of - there is no way to flash the CoDi from Linux right now. There's no technical limitations to it, mind you, it just needs code to be written...

Quote from: Jujuyeh
On the meanwhile, I can still flash custom firmware with the assistant and then just reboot the device, right?
No need to reboot, it loads up immediately after flashing.

Quote from: Jujuyeh
Also, once I want to go back to the original firmware, will the assistant just download it as an update or I have to manually download it?
Yep, the assistant will happily re-flash the original firmware as an update.

Quote from: shuntcap
What happens if you simply try painting one quadrant of the screen (width/2 x height/2) a certain color?

Judging from how slowly the LCD redraws during a "swipe" gesture, my guess is the CoDi hardware doesn't even support a hardware blit (or at least isn't using it), probably just buffer swapping.
I don't know if it's possible to update just part of the screen, with the way the APIs work, but there might have been something I missed. The chip does seem to have some accelerated blitting features but I've not looked into these just yet as I've been trying to just get a simple framebuffer up and running.



edit: After a bunch of faffing about I managed to fix the issues. The code needs a lot of cleanup but it's now in a state where you could feasibly implement some initial stuff, it now accepts packets from the Android service (albeit almost all of them are ignored) and tells the CoDi assistant what version number it is. More soon, hopefully...
« Last Edit: January 23, 2020, 12:44:56 am by Ninji »