-
Hi, no plans to merge at the moment as I also had to add non-standard Espruino fns to disable and enable SPI to switch between lcd driver and storage access. Gordon rightly thinks this is a bit of a hack. It is unique to the P8 as in shares SPI. I will update the build to current Espruino in the next few weeks when I get a chance.
-
It may be that you have a version of the P8 with a different accelerometer.
accel.js
only works with the SC7A20 while your P8 may have a BMA421. Search here for more information. -
There is a very neat online build facility for NodeMCU for the ESP8266 https://nodemcu-build.com/ which lets users select the modules they want and it then builds a custom firmware. Something like that for Espruino might be a solution - but a lot of implementation effort:-(
-
With regards to Swipe, I have just extended the existing Bangle swipe event to add UP and DOWN. I use the events for navigation - specifically swipe down to look at old notifications - swipe up to return to the clock. These are just gestures recognised by the CST816 touch chip as is “click”. Smooth scrolling is quite ambitious given the display and might it be possible that the stream of touch events makes other activities unresponsive? In fact, in my prototype, I have made the `E.touchˋ event the “click” rather than the stream of touch coordinates as a quick hack. The “click” makes it easy to implement buttons.
-
Tried out
Bangle.setLCDMode("240x240")
- it works well although Vector fonts do look - just perceptibly - a little more ragged. I found the simulated buttons to be unresponsive at times and Clock apps tend to stop after a few seconds when they get thelcdPower
off event. So - I suppose in general - multi-platform apps will need to query the type of the underlying watch. -
I have also been thinking of how to have only one version of apps. It should be possible with the a bit of discipline and the ability to detect the capabilities of the underlying hardware - in most cases, I lazily hard coded in new screen coordinates. The screen size and color palette is probably the major issue but there is also the touch interface which it would be nice if apps could exploit. For example, the SMAQ3 version of my desktop style launcher allows you to click on the icon.
Related to touch, it would be nice to have swipe up and swipe down as well as a click event with x, y coordinates. These are easy to do, however, not sure how best to combine these with the current Bangle event. My version of the firmware implemented these instead of the existing touch events, however, I would prefer to,return to the standard build.
Having different versions of menu, prompt and message for the SMAQ3 was really flexible and means that you can have touch friendly versions without changing the app at all.
I got a sample SMAQ3 delivered in 10days, so as you say, it looks like they are now willing to supply the watches. I think a lot of people would be interested in getting an SMAQ3 with Espruino preloaded or at least with the DFU boot loader to avoid having to deal with SWD.
I tried emailing the VC31 manufacturer requesting a datasheet - sadly no response.
-
I have been spending some time adapting Bangle applications to the SMAQ3. You can see some of the results in the pictures below.
The flash memory, magnetometer, barometer and touch now all work reliably and reasonably efficiently thanks to Gordon's work to which I have contributed a few bug fixes. The heart monitor VC31 chip remains a mystery.Once you do the initial flash of the watch using the SWD interface, subsequent firmware updates can now be done using bluetooth which is a great convenience as the DFU loader for the NRF52840 seems to be much faster than that used for Espruino on NRF52832 devices.
When compared with the Bangle, the always on reflective display is great in daylight, but at night, the backlight tends to wash out colours and the Bangle display looks much crisper.
Battery life is nowhere near as good as the Bangle - I get 4 days and I am sure this can be improved, however, the battery at 175mah is smaller than the Bangle.js battery. It is also worth mentioning that the charging cable attaches very insecurely due to having 4 pogo style pins rather than only two on the Bangle. In fact overall, the SMA Q3 is a much less robust watch than the Bangle.
The GPS works OK, however, it loses signal in places where the Bangle does not - I think the Bangle has a much better antenna.
You can see the adapted SMA Q3 apps here together with a version of the firmware necessary to run them.
Some Bangle Apps will run without modification on the SMA Q3, especially using the standard Espruino build for the SMA Q3 which has simulated buttons. However, most apps need to be modified to deals with the different screen size and limited colour palette and to take full advantage of the touch interface.
Lastly, the additional RAM on the NRF52840 is liberating - you can run as many widgets as you want:)
Screenshots
Some pictures of apps running on the SMAQ3:
Launcher App
Multiclock App - Clock face
Multiclock App - BMP280 face
GPS Recorder App - Menu
GPS Recorder App - Track display
Note that the red padlock icon means that the screen is locked i.e. touch disabled. On the Bangle this would be display off, however, with an always on display, we simply disable touch to save power. Enabling is controlled by the usual LCD Power On settings e.g. button press.
-
@hungryforcodes - I did exactly as you suggest - actually I removed the BLUETOOTH module entirely - for Espruino on the TWATCH. See
https://github.com/jeffmer/Twatch_Espruino
. -
A small update - I have now got double buffering to work with SPI flash. The solution is to introduce a simple spin lock which blocks any attempt to do a flash read until the DMA transfer has finished. I used the existing macro WAIT_UNTIL for the spin lock so that it can timeout if a DMA interrupt goes missing.
-
-
Having thought about it, I think the current implementation is probably the best you can do as for the reasons below, it is difficult/impossible to use double buffering. In addition, I think enabling and disabling the HW SPI is quite legitimate - it already happens to switch from DMA SPI to normal SPI to read single bytes. For some graphics screens, you have to do something similar to adjust to lower the bus speed for the touch controller if shares the display bus.
Double Buffering
My attempt at this - which works well when not using SPI flash - failed with a SPI timeout for - I think - the following reason. The driver starts a DMA operation to flush a buffer full of pixels and then returns to drawImage which accesses SPI flash to read the color palette. This read stops the DMA transfer with no completion interrupt so when it comes to try and flush the next buffer you get the SPI timeout.
I do not think that there is a general solution- other than synchronous single buffering - to stopping the CPU accessing the SPI flash in the time available during the DMA transfer. I tried blocking the SPI flash read while the DMA is in operation but this causes a sort of deadlock - #
drawImage
cannot fill the next buffer because it is waiting for a spi flash read which cannot complete because it is waiting for the bus to be released.I have persevered with the driver as I would like to run different apps with different graphics requirements - you can see the result in the video below.
@fanoush - Many thanks for your invaluable help with this - looking forward to softdevice+bootloader upgrade package to move to SDK12 as I need the secure connection to connect my phone.
-
-
Thanks for your advice. After a little bit of a struggle, I have got my driver to work with the SPIFLASH board description. I added an enable/disable function:
/** enable/disable SPI - needed for shared SPI pins between flash and device */ void jshSPIEnable(IOEventFlags device, bool enable);
to
jshardware.c
. You can see it here]: (https://github.com/jeffmer/Espruino/blob/master/targets/nrf5x/jshardware.c) . I also put a weak implementation injshardware_common.c
. I am not sure if @Gordon will think this is something that might be included in the main repository. It would seem to be needed if you want to share SPI pins.Your board description only allocates 96 pages of the 4 Megabyte spi flash - is there any reason why we cannot use the whole 4M as with the Bangle?
-
The performance when I rebuilt with DMA enabled was:
P8:
fillRect
81ms,drawImage
154ms.which is much more reasonable. However, I have now implemented double buffering which with two 60 pixel (120 byte ) buffers gives:
P8:
fillRect
85ms,drawImage
111ms.There is a tradeoff in that smaller buffers allow more overlap but increase the time to draw the rectangle - important for fast
g.clear()
.I would now like to get the driver to work with SPI Flash which I guess requires some care with the chip select pins?
-
-
Thanks to the clear instructions, I had no problem building the P8 package. I also tested your driver which gives an impressive result of 73ms for the fill rectangle test -
fill_time()
. Admittedly, this is 12-bit but it would still be less than 100ms for 16-bit while the best that mylcd_spi_unbuf
driver can do is 237ms.I accept your arguments about single pixel operations, however this performance difference is not caused by pixel operations, since both drivers are sending large buffers via EasyDMA. The difference seems to be caused by the fact that you have used a direct implementation of EasyDMA while the Espruino
jshSPISendMany
uses SoftDevice routines - including interrupt handling. Your implementation - similar to @atc1441's ATCWatchfastspi
module does not use either the SoftDevice or interrupts. I am surprised that the Nordic routines seem to incur such a large overhead.BTW. Both Espruino and the ATCwatch module have workarounds for the 1 byte EasyDMA transfer bug while your implementation does not - yet it seems to work OK?
-
Did you test also g.flip of my driver? should be below 100ms for full 240x240 screen.
I did not get around to testing it as I realised it was faster which makes me believe that it should be possible to speed up
lcd_spi_unbuf
which has the advantage of flexibility in terms of screen buffering.Many thanks for the information on building - I will have a go and get back to you. Look forward to SDK12 as I think the Apple ANCS widget requires secure connections.
-
Thanks, I managed to get my P8 flashed with Espruino with no problems. I did the following measurements for the
Lcd_spi_unbuf
driver.I compared the time taken to fill a 240 x 160 pixel rectangle with the time to draw a 240 x 160 1 bit image. I include the results for Bangle and ESP32 (T-watch for comparison.
RESULTS
Bangle:
fillRect
11ms,drawImage
66ms.ESP32:
fillRect
44ms,drawImage
82ms.P8:
fillRect
256ms,drawImage
331ms.The speed is not great, however, its is worth noting that the issue is not rendering palleted images but it is simply getting pixels sent to the driver. There are at least two improvements I can think of:
1) The buffer at 128 (256 bytes) is nearly exactly the wrong size as the implementation of
spiSendMany
uses EasyDMA with a maximum transfer size of 255 bytes i.e. the current buffer size causes two transfers, the second of 1 byte. I would like to try a buffer size of 240 (480 bytes).2)
spiSendMany
is currently used synchronously inspiSendMany
so it would be interesting to try double buffering to speed things up.I would really like to be able to build the firmware to test this and also to add a Bluetooth hack to support my ANCS widget. I see that you have made the board description public but I would guess that you also need the other files (bootloader etc) to build it?
Thanks agian for making the package available - the P8 has a bright display and its good to experiment with the touchscreen. I found it really easy to transfer the apps I have been running on the T-watch to the P8. Will share when I clean things up.
function time_fill(){ g.setColor(0x07E0); var time= Date.now(); g.fillRect(0,40,239,199); g.flip(); time = Math.floor(Date.now()-time); console.log("Time to Draw Rectangle: "+time+"ms"); } var pal1color = new Uint16Array([0x0000,0xF100]); var buf = Graphics.createArrayBuffer(240,160,1,{msb:true}); buf.setColor(1); buf.fillRect(0,0,239,159); function time_image(){ var time= Date.now(); g.drawImage({width:240,height:160,bpp:1,buffer:buf.buffer, palette:pal1color},0,40); g.flip(); time = Math.floor(Date.now()-time); console.log("Time to Draw Image: "+time+"ms"); }
-
With reference to your recent post - congratulations on getting execution from SPI working.
Does the new build include
lcd_spi_unbuf
? I would be interested in how it performs in comparison with the driver you describe here and I would like to try it now my P8 has arrived. -
I completely agree that the ESP32 Bluetooth consumes a lot of power. I noted above that it seemed to require 40ma even if not active and so I removed it completely. This post https://github.com/espressif/esp-idf/issues/947#issuecomment-500312453 would seem to indicate that Bluetooth on current ESP32 hardware is a lost cause as you need an external 32.768Khz crystal to get effective low-power performance (yes, it uses 1 second advertising!).
Overall, I think the T-watch is great as it has a large bright touchscreen but it would be of much more practical use as a smartwatch if it was based on low-power Bluetooth SoC such as an NRF52840. (I have a P8 - NRF52832 - on order! )
-
Yes, I have made now made the repository public -jeffmer/Twatch_Espruino. My changes to the Espruino firmware are at jeffmer/Espruino.
I noticed that current partitions for the ESP32 allocate only 256K to Storage. In addition, the configuration is for 4Mb of flash. The T-watch has 16Mb of flash - I would grateful for any guidance as to how to build a version of Espruino with different partitions?
-
I had a go at porting the App Manager from the Bangle and managed to run it unchanged by implementing a version of
E.showMenu()
with emulated buttons as shown below:
I think the buttons are better at the bottom of the screen as otherwise your fingers obscure a lot of the screen when you use them. The implementation uses a 2-bit
ArrayBuffer
to eliminate screen flicker. -
The ESP32 power saving design is fine, its the board designers that let it down. For example, the light sleep current of the ESP32 itself is 20-40 microamps, however, the T-watch only manages to reduce to 2.5ma. The active current can be reduced by introducing sleep in the idle loops, but this is not currently supported in the Espruino port. However, turning on the Wifi drains the battery fairly quickly! Using it simply as a watch with on time between 5 and 30 seconds, I get about three days battery life which is OK.
-
Thanks for the kind words. Loading apps direct from Github is a great idea.
I am not sure about button emulations - there are a lot more possibilities on a touch screen swipe up/down as well as left/right,long-touch and double touch. It might be less intrusive visually to map BTN’s to some if these. In addition, for some apps - for example the calculator - it is more natural to use the full facilities of touch. With reference to your post on a unified interface , I think it would be equally important to manage variants of the same app for different targets in a general purpose Espruino App loader.
Actually, for the P8, I did not use jswrap_ bangle.c as I found it easier to develop drivers in Espruino. I intended to put these into C afterwards but the Espruino driver performance seemed quite useable so I did not bother. I plan to look at using the new Layout and touch UI stuff in the coming weeks as it should then be possible to run standard Bangle apps on the P8.