Getting display working for SN80

Posted on
Page
of 2
/ 2
Next
  • I guess this is really for @fanoush, but I'll welcome any input.

    I've flashed Espruino to an SN80 (nrf52832, DaFit, 240x240 round ST7899). The pinouts are identical to the P8, so I used a prebuilt P8 (fanoush's espruino_2v08.5_p8_SDK12_SD30_SPIFLASH.z­ip) I used ATC's init code, replacing the default in the ST7789 Espruino module. I'm getting odd results. In the video, I start at reset(), then load the driver (sets up SPI, runs the init) then draw "Espruino" after 2 secs, then a white rectangle (full screen) after 2 seconds. you can see the draws happening, but everything is a vertical line. And more, in the still picture, you can see what happens after a minute, the screen dims in a doughnut shape! I have the ST7789V datasheet, so I'm prepared to do some homework, but any direction would be greatly appeciated!

    (I checked in with ATC and he doesn't remember what he did exactly... there are two versions of the hardware so he's not sure if he's mixed them up. I also tried his code in ATCwatch and get the same result).

    thanks to anyone for any help!

  • Those from the USA will (should) get this with all the nonsense going on. Comment on video:

    As our politicians would like you to believe, 'Everything is fine and you are content with what you have'

    I couldn't help myself after viewing the video @yngv126399 I feel you pain after investing all the hours you have.

    'I guess this is really for fanoush, but I'll welcome any input.'   holds true

  • The circular dimming thing looks a lot like the LCD itself is not updating the screen.

    That could be a configuration thing, but it's also possible that in the hardware there's a specific pin which provides power to the LCD driver. If that wasn't enabled then maybe the LCD is powered parasitically from the IO pins, which would give it some power but maybe not enough to update the screen correctly?

  • work great as a sundial! So, sure... it's "fine!"

  • init commands are here
    https://gist.github.com/atc1441/925fabbf­d5d5b7986c8848a823914599
    arduino https://gist.github.com/atc1441/667fe0ee­4d64007766876b1a18b097a7
    original code https://gist.github.com/atc1441/fd76ea66­d62a5be1b56ee3e48e35264d
    if these do not work then you are out of luck. You can guess but without having original firmware matching your watch chances are low.

  • That's what I tried (both Arduino & Espruino) with similar results. I was hoping the effect may have been something that looked familiar to you, to help me look in the right spot. I was assuming that this code WAS from the original firmware, but ATC mentioned he wasn't certain as there are two versions of the watch.

    It was a long shot... thanks anyway.

    @Gordon Thank you for that input.. that makes sense. I've tried toggling all the undocumented pins with no luck; it may be a setting in the init as well.

    If I get it, I'll share.

  • Thank you @Robin! I've only invested a little time so far, as I assumed that sample code I had would work! I have Espruino running fine: buzzer and button work (probably touch panel and accel too!) since it's a pinout identical to P8! So close....

    The real work now begins... digesting the nuances of the ST7789.

  • 'Thank you @Robin! I've only invested a little time so far, I assumed that sample code I had would work!'

    While I won't let the thanks of gratitude inflate my ego, shouldn't the credit go to fanoush instead?

    P.S. the sundial response was a hoot!!

  • I'll gladly thank @fanoush for all his work in this project, and have many times. I wear his code on my wrist every day (currently an F07)! I was thanking YOU @Robin for your empathy in my situation. I am currently chatting with ATC1441 to see if anything can be done further, or if I simply have a $35 beacon now. It's difficult to get this far and have to give up.

    And a very huge THANK YOU to @Gordon and all other contributors here... I haven't had this much fun in tech in a long time (yes, a bit of pain and frustration too... all part of the process).

    @Gordon, have you had anyone else express desire for a ROUND watch Espruino (I mean truly round, not Bangle 1: square in a round frame)? I could (easily) be in the minority, but having a more dressy Espruino has appeal. Just curious...

  • Yes, there definitely has been some interest in a circular watch. In fact I've got someone (annoyingly I can't say who) that's shipping thousands of proper round watches running Espruino.

    It does mean that you've got to rewrite pretty much all your apps though, and IMO maybe it makes more sense on nRF52840 hardware where you can have an offscreen buffer so can do some more fancy things.

  • In fact I've got someone (annoyingly I can't say who) that's shipping thousands of proper round watches running Espruino

    wait... what? I guess something related to a NDA? Would a regular person be able to purchase such watch if he ever found out who is selling them?

  • Umm, well, if you you check board files or git history , there is one board file with gc9a01 controller.

  • You reverse engineered @Gordon's remark! Brilliant!! That board looks VERY interesting indeed. It's resisting my attempts to Google more info though... and we don't want to get Gordon in any trouble, so I'll shut up now. But intriguing....

  • Yes, it will be available to buy - although maybe only in a year's time as it releases alongside something else... And sadly, yes - NDA.

    Hopefully I'll actually be able to say more nearer the time

  • Well I'm looking forward to that! Glad to hear it won't be secret for long...

    Another Q... this SN80 is an interesting beast; it seems to be nearly identical to the P8s in the wild (same pinouts, samed shared SPI for display / ext flash). I'm using @jeffmer 's code for the shared SPI (basically his P8 build untouched except for the name), and I'm getting an SPI error during display initialization.

    Uncaught InternalError: Timeout on SPI0-lock
     at line 19 col 28
                spi.write(c, ce);
                               ^
    in function "cmd" called from line 32 col 9
    cmd(0x11); //SLPOUT
            ^
    in function called from system
    >
    

    When I was running the firmware without shared SPI (no ext flash) I didn't get this. I assumed that this code would be safe regardless if it's shared or not (it errs on the side of caution by pausing the other device). My impression is that this is saying "SPI is in use or not ready". Am i interpreting that correctly? (BTW: the external flash works, I'm able to save files and read them back.. but this started as soon as I began working with both display AND spi flash).

    Any insights or thoughts welcome...

  • Are you using the command function built into my version of lcd_spi_unbuf
    as in var cmd = lcd_spi_unbuf.command? If you are using SPI write directly as it looks like you might be you would get this error. Another thing to try is to not set double buffering on in the board file.

  • that is likely it... thank you. I'll try shortly, but that sounds right. I'm glad it's me being absent minded and not something really wrong with the watch!

  • @jeffmer Thanks, that was it of course... however I'm running into some more weirdness now.. I have a test pattern I'm writing to screen (bitmap font, vector font, lines, filled/unfilled shapes and an image. When I use the JS-only method to drive the display, everything displays, albeit very slowly.
    pure JS version
    When I use lcd_spi_unbuf (with proper command), filled shapes and drawRect work..every other horizontal line seems to work, and drawCircle/drawPoly do NOT seem to work at all.
    lcd_spi_unbuf version
    I must be missing an initialization of something.?

  • Pure JS:

    /* Copyright (c) 2020 Akos Lukacs, based on code by Gordon Williams and https://github.com/Bodmer/TFT_eSPI. See the file LICENSE for copying permission. */
    /*
    Module for the ST7789 135x240 LCD controller
    
    Just:
    */
    
    
    var spi = new SPI();
    spi.setup({sck:D2,mosi:D3,mode:0}); //spi.send([0xab],D5); 
    
    const LCD_WIDTH = 240;
    const LCD_HEIGHT = 240;
    const COLSTART = 0;
    const ROWSTART = 0;
    
    
    function init(spi, dc, ce, rst, callback) {
      function cmd(c, d) {
          dc.reset();
          spi.write(c, ce);
          if (d !== undefined) {
              dc.set();
              spi.write(d, ce);
          }
      }
    
      if (rst) {
          digitalPulse(rst, 0, 10);
      } else {
          cmd(0x01); //Software reset
      }
      
      /* SN80 specific */
      const ST7789_INIT_CODE = [
      [0xFE],
      [0xEF],
      [0xEB,0x14],
      [0x84,0x40],
      [0x85,0xF1],
      [0x86,0x98],
      [0x87,0x28],
      [0x88,0xA],
      [0x8A,0],
      [0x8B,0x80],
      [0x8C,1],
      [0x8D,0],
      [0x8E,0xDF],
      [0x8F,82],
      [0xB6,0x20],
      [0x36,0x48],
      [0x3A,5],
      [0x90,[8,8,8,8]],
      [0xBD,6],
      [0xA6,0x74],
      [0xBF,0x1C],
      [0xA7,0x45],
      [0xA9,0xBB],
      [0xB8,0x63],
      [0xBC,0],
      [0xFF,[0x60,1,4]],
      [0xC3,0x17],
      [0xC4,0x17],
      [0xC9,0x25],
      [0xBE,0x11],
      [0xE1,[0x10,0xE]],
      [0xDF,[0x21,0x10,2]],
      [0xF0,[0x45,9,8,8,0x26,0x2A]],
      [0xF1,[0x43,0x70,0x72,0x36,0x37,0x6F]],
      [0xF2,[0x45,9,8,8,0x26,0x2A]],
      [0xF3,[0x43,0x70,0x72,0x36,0x37,0x6F]],
      [0xED,[0x1B,0xB]],
      [0xAC,0x47],
      [0xAE,0x77],
      [0xCB,2],
      [0xCD,0x63],
      [0x70,[7,9,4,0xE,0xF,9,7,8,3]],
      [0xE8,0x34],
      [0x62,[0x18,0xD,0x71,0xED,0x70,0x70,0x18­,0x0F,0x71,0xEF,0x70,0x70]],
      [0x63,[0x18,0x11,0x71,0xF1,0x70,0x70,0x1­8,0x13,0x71,0xF3,0x70,0x70]],
      [0x64,[0x28,0x29,1,0xF1,0,7,0xF1]],
      [0x66,[0x3C,0,0xCD,0x67,0x45,0x45,0x10,0­,0,0]],
      [0x67,[0,0x3C,0,0,0,1,0x54,0x10,0x32,0x9­8]],
      [0x74,[0x10,0x80,0x80,0,0,0x4E,0]],
      [0x35,0],
      [0x21],
        ];
    
        setTimeout(function () {
            //cmd(0x11); //Exit Sleep
            setTimeout(function () {
                ST7789_INIT_CODE.forEach(function (e) {
                    cmd(e[0], e[1]);
                });
                setTimeout(()=>{  //delay_0(120);
                  cmd(0x11); }, 120);
                setTimeout(()=>{    //delay_0(120);
                  cmd(0x29);}, 240);
                setTimeout(()=>{  //delay_0(120);
                  cmd(0x2A,[0,0,0,0xEF]);
                  cmd(0x2B,[0,0,0,0xEF]);
                  cmd(0x2C);}, 360);
    
                if (callback) setTimeout(callback, 500);
            }, 20);
        }, 120);
       /**/
    }
    
    
    let connect = function (spi, dc, ce, rst, callback) {
        var g = Graphics.createCallback(LCD_WIDTH, LCD_HEIGHT, 16, {
            setPixel: function (x, y, c) {
                ce.reset();
                spi.write(0x2A, dc);
                spi.write((COLSTART + x) >> 8, COLSTART + x, (COLSTART + x) >> 8, COLSTART + x);
                spi.write(0x2B, dc);
                spi.write((ROWSTART + y) >> 8, ROWSTART + y, (ROWSTART + y) >> 8, (ROWSTART + y));
                spi.write(0x2C, dc);
                spi.write(c >> 8, c);
                ce.set();
            },
            fillRect: function (x1, y1, x2, y2, c) {
                ce.reset();
                spi.write(0x2A, dc);
                spi.write((COLSTART + x1) >> 8, COLSTART + x1, (COLSTART + x2) >> 8, COLSTART + x2);
                spi.write(0x2B, dc);
                spi.write((ROWSTART + y1) >> 8, ROWSTART + y1, (ROWSTART + y2) >> 8, (ROWSTART + y2));
                spi.write(0x2C, dc);
                spi.write({ data: String.fromCharCode(c >> 8, c), count: (x2 - x1 + 1) * (y2 - y1 + 1) });
                ce.set();
            }
        });
        init(spi, dc, ce, rst, callback);
        return g;
    };
    
    var img = {
      width : 206, height : 96, bpp : 2,
      transparent : -1,
      palette : new Uint16Array([0,65535,6339,61277]),
      buffer : require("heatshrink").decompress(atob("A­E8LqoAD8AyrgXVGQdWM1ktMwlwM2NXwBmxvBm/M3­4ASgYyEM1s1GYlYGVcLGQlVM1m1GQlcM2XgM2NeM­35m/ACUJMwtgGdeVGQlWGVcNM2MC6oyEq+AGdUlM­wt4GVUDGQtV4Azq2ouBr/1AYNcGVULZAP+1W/aQP­gEzuoBZUC6tf1QFB1X1q+ABgWqAAIGDACUJXJQyB­vwlDgQzB3AFBh////+Ga2cZhdeEggzBrqbCagNVv­xmhlqSEAAMK6oICg6ZB394M0ELGQwzCrwEBF4WtN­oRmdZgIiHhdVuBmBH4W3M0G1RJEtqxmEgXYMz8tR­4QAE0A9DMwctdRRmUgXXZg0uBQhzD7xmf2rMGhYH­BhpxBMwcJbw5mXhtcBA24HwVwMwmeMzyZIl4HBBY­RmDhrNfmtgHYyPCTQRmCgXcMz0LEwKZIbIRmDOAR­mdTJBqDqxmDhbTBMzsteQYACgaZCBgRmChXeGShm­JLISZJOYV61Wq+54DhWu1EC0ABBBoIWD1XqwEqMw­kq/+oBwU1LwaZGSgNYgv///1vQyD/tf9G+CgOv//­6DYf1/+C+BmDlfVCoKRCrxuGHQm14FfGYP9vwOC7­46B9fggV9v/9XIUvv//72nMwcLv/r+onCEoKZKhd­e06LB1W9EwW31Eq+5mBkv+BgIjBhd+0Grv1wMwUC­72gCoK3BRgKZGYQanBv4uCIwImBloCBNIJmBr2Ag­Q4BFIIbBlt3Mwe3BAMK7wfCFYiZGgVVq4ODDQMLH­QRzBMwIVBgYJBm4TClpmDJAQVBBAMJK4YAClAFEk­tVBwcC/BZBAwQhBgQNCk+AhIpCgXXMwQODIAeXMw­oyFMwwsBloGDG4IvBCQPYA4RdEMwO3EQYPBhpmFh­egMxUA3xQEhZmBFAI/BwDoEm5mChPq1QAB1rUB65­mF3RmLgdgEII5DMwJWDVAIZD+BmCy//AAR0BZo0C­aYpmGmw0BMx8vMwdVAAbbBZow0B1BmLmwSDnxmGI­wZmEzyZC1QnBhdYZouA3/oMy8nMxBhBAAm1Mws4l­2qBAUDq/3ZreeGQsLrgGEgeCIQm19RmE3yNEZphE­BMwIQBGYs1A4s4DAhABg4GDhvgRohmGgHeDIY9BM­wO2GQsDrwGFZoIlDU4LtE/ECEwctMwzEEy5mCgYc­DlzzCMw0C3wzCht4Mwm3KoIdChZNBMws3CYUtMwZ­EBCoVgCQPXEgZmCgG4D4QMBJIetDQOnAQMC6pmGO­Ycru5mCgCKCBgZZBMwo/BCQJzCMwevCQJJD2/+Mw­0LvwCB75mDgQIBgX3EAW1TQkDxWA3jaEr////9Sw­fX9X19ZmGAQN/1/f05mDhdf1f3FwQmCMwku1Y/Cy­vAgtVAAP6B4Ur6tV/G+Mw0A3tVr+iMwcAl4cB9Ac­ClqaEgeC34/CBYWqAAQQDlf//UKMwLxDVYf/0A9B­hQIC1f/GQcAW4RmDgWoDwVXOQgATgakCABELTQkD­HAjZFACk2BhaaFnAKJACCACLIJNLgXVBoZmETK0J­EAfeCJYoBFwcoHolgGam+AYUvXQiaIZwjMEMysCv­RYCWhu1Bw8tqqyLABMvvWq1aZMSAX4DQ1VJZoAI3­v///fTJh1BqvoA4krqpLNKhO9qtX0ASNltXSIkr6­trJZoAJlf+DJ7FB/QSBgWvTC4AU2tV/2q1X9qteG­VUDqtVr//+oEBTC4ATmouBAAdYGVUCGQtXM1ctGY­twGVUA6oyEqwyrhJmFsAzryoyErwyrhZmF8Azr2p­m/M1dcM2WAM2NYGVcDGQlXM1k1GYl4GVcC6pmxlp­m/M1dwM2QyrMw1gGdm1GQdeBQg="))
    };
    /**/
    var g = connect(spi, D18, D25, D26, function() {
      digitalWrite(D23,0);
      g.clear();
      //g.setRotation(1);
     // g.drawString("Hello",0,0);
      //g.setFontVector(20);
      
      g.setColor(0.5,1,1);
      g.setFont("6x8",1);
      
      g.setFontAlign(0,0);
      g.drawString("Espruino",120,20);
      g.setFontVector(12);
      g.drawString("Espruino",120,40);
      
      g.drawCircle(60,40,20);
      g.fillCircle(180,40,20);
      g.setColor(1,0,1);
      g.drawRect(40,75,80,100);
      g.fillRect(160,75,200,100);
      g.setColor(1,1,0);
      g.drawPoly([70,130,80,110,90,130,100,110­,110,130, 110,140,70,140], true);
      g.fillPoly([130,130,140,110,150,130,160,­110,170,130, 170,140,130,140], true);
      g.setColor(0.5,0.5,1);
      for(let x = 90; x < 120; x+=5) {
        g.drawLine(x, 60, x, 90);
      }
      for(let y = 60; y < 90; y+=5) {
        g.drawLine(125, y, 155, y);
      }
      g.drawImage(img,20,144);
      });
    

    lcd_spi_unbuf version:

    const logD = console.log;
    
    let batV=() => {
      return 7.1 * analogRead(D31);
    };
    
    //var spi = new SPI();
    SPI1.setup({sck:D2,mosi:D3,baud:8000000,­mode:0}); //spi.send([0xab],D5); 
    
    const LCD_WIDTH = 240;
    const LCD_HEIGHT = 240;
    const COLSTART = 0;
    const ROWSTART = 0;
    const INVERSE = 0;
    
    
      /* SN80 specific */
    const ST7789_INIT_CODE = [
      [0xFE],
      [0xEF],
      [0xEB,0x14],
      [0x84,0x40],
      [0x85,0xF1],
      [0x86,0x98],
      [0x87,0x28],
      [0x88,0xA],
      [0x8A,0],
      [0x8B,0x80],
      [0x8C,1],
      [0x8D,0],
      [0x8E,0xDF],
      [0x8F,82],
      [0xB6,0x20],
      [0x36,0x48],
      [0x3A,5],
      [0x90,[8,8,8,8]],
      [0xBD,6],
      [0xA6,0x74],
      [0xBF,0x1C],
      [0xA7,0x45],
      [0xA9,0xBB],
      [0xB8,0x63],
      [0xBC,0],
      [0xFF,[0x60,1,4]],
      [0xC3,0x17],
      [0xC4,0x17],
      [0xC9,0x25],
      [0xBE,0x11],
      [0xE1,[0x10,0xE]],
      [0xDF,[0x21,0x10,2]],
      [0xF0,[0x45,9,8,8,0x26,0x2A]],
      [0xF1,[0x43,0x70,0x72,0x36,0x37,0x6F]],
      [0xF2,[0x45,9,8,8,0x26,0x2A]],
      [0xF3,[0x43,0x70,0x72,0x36,0x37,0x6F]],
      [0xED,[0x1B,0xB]],
      [0xAC,0x47],
      [0xAE,0x77],
      [0xCB,2],
      [0xCD,0x63],
      [0x70,[7,9,4,0xE,0xF,9,7,8,3]],
      [0xE8,0x34],
      [0x62,[0x18,0xD,0x71,0xED,0x70,0x70,0x18­,0x0F,0x71,0xEF,0x70,0x70]],
      [0x63,[0x18,0x11,0x71,0xF1,0x70,0x70,0x1­8,0x13,0x71,0xF3,0x70,0x70]],
      [0x64,[0x28,0x29,1,0xF1,0,7,0xF1]],
      [0x66,[0x3C,0,0xCD,0x67,0x45,0x45,0x10,0­,0,0]],
      [0x67,[0,0x3C,0,0,0,1,0x54,0x10,0x32,0x9­8]],
      [0x74,[0x10,0x80,0x80,0,0,0x4E,0]],
      [0x35,0],
      [0x21],
      [0x29],
        ];
    
    function ST7789() {
        var LCD_WIDTH = 240;
        var LCD_HEIGHT = 240;
        var XOFF = 0;
        var YOFF = 0;
        var INVERSE = 1;
        var cmd = lcd_spi_unbuf.command;
      
        function dispinit(spi, dc, ce, rst, fn) {
    
          if (rst) {
              digitalPulse(rst,0,10);
          } else {
              cmd(0x01); //ST7789_SWRESET: Software reset, 0 args, w/delay: 150 ms delay
          }
          setTimeout(function() {
            cmd(0x11); //SLPOUT
            setTimeout(function () {
                ST7789_INIT_CODE.forEach(function (e) {
                    cmd(e[0], e[1]);
                });
    
                if (fn) setTimeout(fn, 500);
                
            }, 20);
          }, 120);
          return cmd;
        }
    
        function connect(options , callback) {
            var spi=options.spi, dc=options.dc, ce=options.cs, rst=options.rst;
            var g = lcd_spi_unbuf.connect(options.spi, {
                dc: options.dc,
                cs: options.cs,
                height: LCD_HEIGHT,
                width: LCD_WIDTH,
                colstart: XOFF,
                rowstart: YOFF
            });
            g.lcd_sleep = function(){cmd(0x10);cmd(0x28);};
            g.lcd_wake = function(){cmd(0x29);cmd(0x11);};
            dispinit(spi, dc, ce, rst);
            //g.cmd = cmd;
            return g;
        }
    
        //var spi = new SPI();
        SPI1.setup({sck:D2, mosi:D3, baud: 8000000});
    
        return connect({spi:SPI1, dc:D18, cs:D25, rst:D26});
    }
    
    //screen brightness function
    function brightness(v) {
        v=v>7?1:v;
    digitalWrite([D23,D22,D14],7-v);
    }
    
    let g = ST7789();
    brightness(7);
    
    
    
    var img = {
      width : 206, height : 96, bpp : 2,
      transparent : -1,
      palette : new Uint16Array([0,65535,6339,61277]),
      buffer : require("heatshrink").decompress(atob("A­E8LqoAD8AyrgXVGQdWM1ktMwlwM2NXwBmxvBm/M3­4ASgYyEM1s1GYlYGVcLGQlVM1m1GQlcM2XgM2NeM­35m/ACUJMwtgGdeVGQlWGVcNM2MC6oyEq+AGdUlM­wt4GVUDGQtV4Azq2ouBr/1AYNcGVULZAP+1W/aQP­gEzuoBZUC6tf1QFB1X1q+ABgWqAAIGDACUJXJQyB­vwlDgQzB3AFBh////+Ga2cZhdeEggzBrqbCagNVv­xmhlqSEAAMK6oICg6ZB394M0ELGQwzCrwEBF4WtN­oRmdZgIiHhdVuBmBH4W3M0G1RJEtqxmEgXYMz8tR­4QAE0A9DMwctdRRmUgXXZg0uBQhzD7xmf2rMGhYH­BhpxBMwcJbw5mXhtcBA24HwVwMwmeMzyZIl4HBBY­RmDhrNfmtgHYyPCTQRmCgXcMz0LEwKZIbIRmDOAR­mdTJBqDqxmDhbTBMzsteQYACgaZCBgRmChXeGShm­JLISZJOYV61Wq+54DhWu1EC0ABBBoIWD1XqwEqMw­kq/+oBwU1LwaZGSgNYgv///1vQyD/tf9G+CgOv//­6DYf1/+C+BmDlfVCoKRCrxuGHQm14FfGYP9vwOC7­46B9fggV9v/9XIUvv//72nMwcLv/r+onCEoKZKhd­e06LB1W9EwW31Eq+5mBkv+BgIjBhd+0Grv1wMwUC­72gCoK3BRgKZGYQanBv4uCIwImBloCBNIJmBr2Ag­Q4BFIIbBlt3Mwe3BAMK7wfCFYiZGgVVq4ODDQMLH­QRzBMwIVBgYJBm4TClpmDJAQVBBAMJK4YAClAFEk­tVBwcC/BZBAwQhBgQNCk+AhIpCgXXMwQODIAeXMw­oyFMwwsBloGDG4IvBCQPYA4RdEMwO3EQYPBhpmFh­egMxUA3xQEhZmBFAI/BwDoEm5mChPq1QAB1rUB65­mF3RmLgdgEII5DMwJWDVAIZD+BmCy//AAR0BZo0C­aYpmGmw0BMx8vMwdVAAbbBZow0B1BmLmwSDnxmGI­wZmEzyZC1QnBhdYZouA3/oMy8nMxBhBAAm1Mws4l­2qBAUDq/3ZreeGQsLrgGEgeCIQm19RmE3yNEZphE­BMwIQBGYs1A4s4DAhABg4GDhvgRohmGgHeDIY9BM­wO2GQsDrwGFZoIlDU4LtE/ECEwctMwzEEy5mCgYc­DlzzCMw0C3wzCht4Mwm3KoIdChZNBMws3CYUtMwZ­EBCoVgCQPXEgZmCgG4D4QMBJIetDQOnAQMC6pmGO­Ycru5mCgCKCBgZZBMwo/BCQJzCMwevCQJJD2/+Mw­0LvwCB75mDgQIBgX3EAW1TQkDxWA3jaEr////9Sw­fX9X19ZmGAQN/1/f05mDhdf1f3FwQmCMwku1Y/Cy­vAgtVAAP6B4Ur6tV/G+Mw0A3tVr+iMwcAl4cB9Ac­ClqaEgeC34/CBYWqAAQQDlf//UKMwLxDVYf/0A9B­hQIC1f/GQcAW4RmDgWoDwVXOQgATgakCABELTQkD­HAjZFACk2BhaaFnAKJACCACLIJNLgXVBoZmETK0J­EAfeCJYoBFwcoHolgGam+AYUvXQiaIZwjMEMysCv­RYCWhu1Bw8tqqyLABMvvWq1aZMSAX4DQ1VJZoAI3­v///fTJh1BqvoA4krqpLNKhO9qtX0ASNltXSIkr6­trJZoAJlf+DJ7FB/QSBgWvTC4AU2tV/2q1X9qteG­VUDqtVr//+oEBTC4ATmouBAAdYGVUCGQtXM1ctGY­twGVUA6oyEqwyrhJmFsAzryoyErwyrhZmF8Azr2p­m/M1dcM2WAM2NYGVcDGQlXM1k1GYl4GVcC6pmxlp­m/M1dwM2QyrMw1gGdm1GQdeBQg="))
    };
    /**/
    
    setTimeout(()=>{
      g.clear();
      g.setColor(0.5,1,1);
      g.setFont("6x8",1);
      
      g.setFontAlign(0,0);
      g.drawString("Espruino",120,20);
      g.setFontVector(12);
      g.drawString("Espruino",120,40);
      
      g.drawCircle(60,40,20);
      g.fillCircle(180,40,20);
      g.setColor(1,0,1);
      g.drawRect(40,75,80,100);
      g.fillRect(160,75,200,100);
      g.setColor(1,1,0);
      g.drawPoly([70,130,80,110,90,130,100,110­,110,130, 110,140,70,140], true);
      g.fillPoly([130,130,140,110,150,130,160,­110,170,130, 170,140,130,140], true);
      g.setColor(0.5,0.5,1);
      for(let x = 90; x < 120; x+=5) {
        g.drawLine(x, 60, x, 90);
      }
      for(let y = 60; y < 90; y+=5) {
        g.drawLine(125, y, 155, y);
      }
      g.drawImage(img,20,144);
    
     },500);
    
  • lcd_spi_unbuf implements both a setPixel and a fillRect function. From what you describe, it is the setPixel that is not working correctly. I would suggest that if you have double buffering set in the BOARD file you try unsetting it and vice-versa as only setPixel makes use of double buffering.

  • well, it's definitely the setPixel f().. I wrote a super simple one (chunk-less) and the screen now displays fine. No idea why the chunk_buffer is not working for me (it works on this code base with the P8). I'll investigate further, for now, I have a working screen. Thanks to all!

  • @yngv126399 I got hold of an SN80 recently to play with circular displays and I have now fixed the lcd_spi_unbuf driver. The problem was that for some reason, no pixels are displayed if the address window you set up is not completely filled. This means that double buffering does not work, so I have fixed the problem for single buffering - just remove the -DLCD_SPI_DOUBLEBUF=1 declaration in the board file. I have left a firmware build with the revised driver here . I have got most of the P8 bangle emulation environment to run on the SN80 including accelerometer, touch screen and heart rate sensor- see picture below.

    .

    I have made the widgets moveable, so you can specify the location of the widget panel. The clock face above moves the panel top or bottom to minimse it being obscure by the hour hand.

    The only remaining problem is the physical button which should be on D13 or D17, however, I have tried these and other unallocated pins with no success. I would be interested to know if you have got the button to work as I suspect that I may have a hardware fault. I am currently using long touch to replace the button - which works OK.

  • That's great! I actually am running with my own driver for the moment... not as good, but for setPixel, I just set the color and go.. I don't buffer even the one line; so it's slower but I got it to work. I tried taking out double buffering but it didn't work for me... but I'll try your version for sure.

    As for the button, I did get it to work.. According to atc1441's notes, btn1 is D9, and that works as long as you pull D17 high. I'm sure there's a less hacky way, but I defined two buttons, the second one being D17, and pull it high:

     'BTN1' : { 'pin' : 'D9'} ,
     'BTN2' : { 'pin' : 'D17', 'pinstate' : 'IN_PULLUP'} ,
    
  • Thanks - that's about the only pin combination that I did not try:-( I have updated the firmware in the WatchApps repository with your BTN1 hack. Really like the SN80 as it has a nice bright large screen - the 1.3 inch spec for the lcd is deceptive as it is equivalent to a 1.8 inch square lcd.

  • It really is a nice screen isn't it? and yes, much bigger looking than its spec. I just bought another SN80 recently, with DaFit firmware from AE, and just ran through the full process:

    • Used DaFlasher to upload DaFitBootloader23Hacked.bin
    • Used nrfConnect to upload FitBootloaderDFU2.0.1.zip
    • Used nrfConnect to upload fanoush's p8-sdk11-to-sdk12.zip
    • Used nrfConnect to upload jeffmer's image (github.com/jeffmer/WatchApps/firmware) espruino_2v11.1.5.4_SN80.zip

    I used my own driver set for now, but all works perfectly. Nice work, @jeffmer!

    A caution for anyone wanting to get an SN80 though.. my "new" one has a slightly misaligned LCD ( a vertical line from 12:00 to 6:00 is tilted a few degrees). Nothing tragic, but unfortunate as analog watches won't align to the tick marks on the bezel! Could be selling off QA rejections?

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Getting display working for SN80

Posted by Avatar for yngv126399 @yngv126399

Actions