Menu

Creating GLCD library with HWSPI support

2019-10-10
2019-10-13
<< < 1 2 (Page 2 of 2)
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-11

    I found a partial workaround. It looks like the SPI data rate to the display is too fast at 64 MHz for some reason. I tried starting the chip with #config FEXTOSC=HS, RSTOSC=EXTOSC, BOREN=OFF, CSWEN = ON, WDTE = OFF and writing to the display. That write was successful. I then put OSCCON1=0x20 to turn on the 4x PLL before trying another write to the display. That write failed.

    The problem seems to be with the initPPS. Here is what I've been using:

        'Generated by PIC PPS Tool for Great Cow Basic
        'PPS Tool version: 0.0.5.15
        'PinManager data: v1.65.1
        '
        'Template comment at the start of the config file
        '
        #startup InitPPS, 85
    
        Sub InitPPS
    
                'Module: MSSP1
                RC5PPS = 0x0010    'SDO1 > RC5
                RC4PPS = 0x0010    'SDA1 > RC4
                SSP1DATPPS = 0x0014    'RC4 > SDA1 (bi-directional)
                RC3PPS = 0x000F    'SCL1 > RC3
                SSP1CLKPPS = 0x0013    'RC3 > SCL1 (bi-directional)
                'SSP1SSPPS = 0x0017    'RC7 > SS1
    
    
        End Sub
        'Template comment at the end of the config file
    

    If I comment out #startup InitPPS, 85, and also comment out #define SSD1351_HardwareSPI in the section where I define my SPI pins, everything is fine at 64 MHz.

    I accidently discovered all this while running my project. I did as above, starting the chip at 16 MHz, writing something, using OSCCON1 = 0x20 to go to 64 MHz, then updating the display again. The second update didn't work. However, the chip is supposed to go into sleep mode after 2 minutes, turning the display off. That part worked, even though the second display update didn't work. Moreover, my constants and timers were still set for a 40 MHz clock. The chip went into sleep mode after about 75 seconds, as would be expected if it was running with a faster 64 MHz clock. This was telling me the chip is running fine at 64 MHz, only it's unable to update the display, perhaps because the SPI data rate is too fast. The above changes fixed the problem entirely, although it's admittedly a hack. I don't know how the compiler uses the clock speed to figure SPI data rates so that part of a real fix is beyond me. At least we know where to look now.

    EDIT: Thinking about this some more, I don't think it's an SPI data rate problem. I remember just dropping a 16 MHz crystal in place of a 4.194304 MHz one on a 18F2420 running basically the same program, without modifying any code. The display still ran, and presumably the SPI data rates were almost 4 times as fast. What I think is happening here is specifying a 48 or 64 MHz clock with the 18F27K40 is breaking the hardware SPI in some manner.

    EDIT#2: It looks like there's some stuff in the hwspi.h file for the K42 chips but not the K40s. That might be the source of the problem.

     

    Last edit: Joseph Realmuto 2019-10-11
  • Anobium

    Anobium - 2019-10-12

    Your latest insights got me looking into the files you posted.


    This is simply the SPI bus speed error. You are overclocking the GLCD. So, the data is not being received correctly.

    I am not sure where you started the library but I am thinking is was a library that was dated prior to 10/02/2019. Why? All the GLCD libraries were updated to ensure operations with 64mhz frequencies.

    See change #598 in the release notes for Great Cow BASIC. GLCD : ILI9430 and ILI9431 new capability to set the hardware SPI speed to MasterSlow, Master, or MasterFast. Now defaults to MasterFast when ChipMhz is not 64mhz, as the MasterFast at 64mhz will not operate as expected s the ILI934x chip can operate at this SPI frequency.

    This change was applied to the ILI9340, ILI9341, ILI9486L, SSD1331 and the ST7735 GLCD libraries.


    So, in your new .h you need to change the init as follows:

    #ifdef SSD1351_HardwareSPI
      ' harware SPI mode
      asm showdebug SPI constant used equates to HWSPIMODESCRIPT
      SPIMode HWSPIMODESCRIPT, 0
    #endif
    

    How does this work?

    The Help shows how to use HWSPIMode. Essentially, HWSPIMode controls the HPSPI speed. The default for < 64 is MasterFast and > 32 is Master. See the latest HWSPI.h for the script that supports all this.


    So, if you make the change shown in this post. Then, all should be good. As adding the code above you will get the following ASM. Note that ;spi constant used equates to 12 is the code produced -where 12 equates to SPI MASTER - which should work.

    ;harware SPI mode
    ;asm showdebug SPI constant used equates to HWSPIMODESCRIPT
    ;spi constant used equates to 12
    ;SPIMode HWSPIMODESCRIPT, 0
      movlw 12
      movwf SPICURRENTMODE,ACCESS
      clrf  SPICLOCKMODE,ACCESS
      call  SPIMODE588
    
     

    Last edit: Anobium 2019-10-12
  • Anobium

    Anobium - 2019-10-12

    Jo - I have not done a full code review but I know this already. :-)

    #define GLCD_TYPE_ST7735R 25

    Constant 25 was used in May 2019, so, your new device should use 26.

    #define GLCD_TYPE_SSD1351 26

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-12

    I made that change in the glcd_ssd1351.h (attached), uncommented the lines I mentioned, and all is well. :) Thanks!

    Interestingly, it's also possible to tweak the SPI speed further. SPI Master mode uses Fosc/16 instead of Fosc/4 like MasterFast. The K40 chips have an SPI master mode which uses SSP1ADD to tweak the SPI speed. You need to set SSPM(3:0] in SSP1CON1 to 1010. The chip then uses an SPI clock of Fosc/(4x(SSP1ADD+1). It was just a matter then of trying several SSP1ADD values to see what works. SSP1ADD = 0 didn't, SSP1ADD = 1 does. That gives an SPI clock of Fosc/8, which should give the same SPI speeds at 64 MHz as MasterFast gives at 32 MHz.

    Therefore, I just added the following code right at the beginning of my program:

    Set SSP1CON1.3 on
    Set SSP1CON1.2 off
    Set SSP1CON1.1 on
    Set SSP1CON1.0 off
    SSP1ADD = 1

    That noticably speeds up the display writes over using Master mode.

    I'm aware that you're adding glcds all the time to the library, so the number I used might have been out of date.

     

    Last edit: Joseph Realmuto 2019-10-12
  • Anobium

    Anobium - 2019-10-12

    Sounds like you are getting it sorted.

    Can you send me the code segments from glcd.h that I need to add to the master glcd.h?

    Let me look at the fast SPI option. I think this is already implemented. I need to look at the libraries.

    And, are you willing to let me include your stock demos? If I can advise - do this after these last few changes and you have a new glcd.h from me.

     
  • Anobium

    Anobium - 2019-10-12

    Very good spot!!

    Try the attached HWSPI library updated with your SSP1ADD idea.

    In your code simply add (the define was already there... I have added a new option!)

    #chip 18f27k40
    
    #define HWSPIMode MasterSSPADDMode
    
    '.....
    

    This should set the new SSPADDmode. It will set the two bits that are needed and then set SSP1ADD =1. This way all the SPI libraries can use the feature.

    And, if the user does not add the HWSPIMode constant it will work as before.

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-12

    That works for me. I get a warning:16 from the compiler, but it makes the hex file just fine, and the display writes are at the same speed as when I manually put the SSP1ADD code in.

     
  • Anobium

    Anobium - 2019-10-12

    silly me. remove the 'warning' line in the .h file.

     
  • Anobium

    Anobium - 2019-10-13

    Here are the baseline libaries.

    I have included your changes in GLCD.h and HWSPI.h - please confirm these are ok by testing with these.

    You will need all three GLCD files and you should use the new HPSPI.H to make sure this is good to release.

    For the glcd_ssd1351.h please use the supplied .h. I have updated the license etc etc but more importantly the attached version contains my code review. Please search for 'erv - you do not need to tell me your resolution to the queries - just make the changes and send back to me as the new master library. Please update the change log with 'formal release' when you have completed the changes.

    Great job!

     

    Last edit: Anobium 2019-10-13
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-13

    I completed the testing and made my changes to glcd_ssd1351.h. I removed the SendMultipleCommand_SSD1351 and SendMultipleData_SSD1351 subs as there doesn't seem to really be any need for them. I also removed the SetBrightness_SSD1351 sub as it doesn't work, even though it should according to the data sheet. It was redundant anyway. The SetContrast_SSD1351 sub works just fine for the purposes of setting display brightness, as well as the relative brightness of the colors.

    On the rotation, I set it up so you just need to swap the x and y values, without going through the addition calculation of GLCDY = SSD1351_GLCD_WIDTH - GLCDY - 1.

    Attached is the revised glcd_ssd1351.h, as well as an SSD1351 demo program.

     

    Last edit: Joseph Realmuto 2019-10-13
    • Anobium

      Anobium - 2019-10-13

      Regarding the demo. We don't need to be using the external osc - do we?

       
      • Joseph Realmuto

        Joseph Realmuto - 2019-10-13

        No, the demo could use the internal oscillator.

         
        • Anobium

          Anobium - 2019-10-13
           

          Last edit: Anobium 2019-10-13
          • Joseph Realmuto

            Joseph Realmuto - 2019-10-13

            Yes, please comment it out. The more portable the demo is the better.

            Minor correction to your comments in the demo:

            "It is a nice graphical TFT LCD, suitable for a lot of various projects."

            It's actually an OLED display, not an LCD.

             

            Last edit: Joseph Realmuto 2019-10-13
            • Anobium

              Anobium - 2019-10-13

              Help: Created. I took the 1331 and adapated to 1351.

              https://github.com/Anobium/Great-Cow-BASIC-Help/blob/master/source/ssd1351controllers.adoc

              Can you review and edit please.

               

              Last edit: Anobium 2019-10-13
              • Joseph Realmuto

                Joseph Realmuto - 2019-10-13

                That looks fine to me. Only thing I might add here is that GCB only supports 65K colors, even though the controller supports 262K colors.

                 
                • Anobium

                  Anobium - 2019-10-13

                  I will update all the GLCDs. It is correct to state 65k-colors not 262k-colors.

                   
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-13

    Actually, the SetBrightness_SSD1351 sub didn't work because I set up a few things wrong. Here's the final revised glcd_ssd1351.h with the SetBrightness_SSD1351 sub working correctly.

     
    • Anobium

      Anobium - 2019-10-13

      Ok. I will move all these files into the release code SVN.

      Great job.

      Evan

       
<< < 1 2 (Page 2 of 2)

Log in to post a comment.