Menu

Creating GLCD library with HWSPI support

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

    Joseph Realmuto - 2019-10-10

    Resolved. The clock operates as expected. See later in thread for GLCD library adaption.

    edited by Anobium


    This could be a chip problem, or a problem with settings but I'm curious if anyone else experienced it. A few weeks ago in the course of solving the EEPROM issue with the K40 I noticed that the K40 wouldn't run at 64 MHz on the internal oscillator. Further testing showed 32 MHz worked just fine but 48 MHz didn't work, either. However, for my project I was using the crystal oscillator, not the internal oscillator. I originally used a 4.194304 MHz crystal and the 4xPLL for a clock speed of 16.777216 MHz. This works fine. I needed a speed boost given that I'm using a 128x128 SSD1351 color display. Substituting a 10 MHz crystal for the 4.194304 MHz works fine also. That gives me a 40 MHz clock with the 4xPLL. However, a 16 MHz crystal doesn't work. It works fine without the 4xPLL but that's only a 16 MHz clock. A 14.318 MHz crystal didn't work, either, with the 4xPLL. The 4xPLL is speced to have an input frequency range of 4 MHz to 16 MHz, so it should work.

    Given that the same problem exists whether I'm using the internal oscillator or the crystal oscillator, it looks like it's an issue with the 4xPLL. It just won't run with an input frequency over about 10 MHz. Now could this be caused by settings, or just an issue with this revision (A002) of the chip? I'm running the chip at 5V, so low voltage isn't the isssue.

    On another note, the 18F2420, which is specified only to a maximum clock frequency of 40 MHz, works just fine with a 16 MHz crystal and the 4xPLL. In fact, even a 20 MHz crystal, giving an 80 MHz clock speed, works.

     

    Last edit: Anobium 2019-10-13
  • George Towler

    George Towler - 2019-10-10

    Have you tried more than one k40?

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-10

    Yes. Same problem with all three I tried.

     
  • Anobium

    Anobium - 2019-10-10

    Let me have a proper look tomorrow. I am sure that if this is not documented in the errata then it is likely to be a config and/or an initialization issue.

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-10

    Definitely not in the errata. I already checked.

     
  • George Towler

    George Towler - 2019-10-10

    I'm pretty sure I've ran a k40 at 64Mhz but now t with an xtal. To confirm what is the symtom, does it just run slow or hang?

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-11

    I tried so many different settings. Sometimes it hangs, other times it just runs slow.

     
  • Anobium

    Anobium - 2019-10-11

    IntOsc can be 64, 48, 32, 24, 16, 8, 4, 2, 1, 0.5, 0.25, 0.125

    These frequencies are all ok using the program below. . Tested with a scope.

    #chip 18F27K40, 0.125
    
    dir porta.0 out
    do
      porta.0 = !porta.0
      wait 10 ms
    loop
    

    So, now lets look at the ext OSC using at 16mhz crystal. Seems to work here with a 16mhz crystal attached to OSC1 and OSC2. Tested with a scope.

    #chip 18F27K40, 64
    
    
        '64Mhz with 4xPLL
        #config FEXTOSC = HS            ' External Oscillator mode Selection bits->HS (crystal oscillator) above 8 MHz and PFM set to high power
        #config RSTOSC = EXTOSC_4PLL    ' Power-up default value for COSC bits->EXTOSC with 4x PLL, with EXTOSC operating per FEXTOSC bits
        #config CSWEN = ON              ' Clock Switch Enable bit->Writing to NOSC and NDIV is allowed
    
    
    
        'This is not needed but I have inclded for clarity
        ' NOSC EXTOSC   with 4x PLL and NDIV 1
        OSCCON1 = 0x20
        ' CSWHOLD may proceed and SOSCPWR Low power
        OSCCON3 = 0x00
        ' MFOEN disabled and LFOEN disabled and ADOEN disabled and SOSCEN disabled and EXTOEN disabled and HFOEN disabled and
        OSCEN = 0x00
        ' HFFRQ 4_MHz
        OSCFRQ = 0x02
        ' TUN 0
        OSCTUNE = 0x00
    
        ; Wait for PLL to stabilize
        wait while (PLLR = 0)
    
    
        dir porta.0 out
        do
          porta.0 = !porta.0
          wait 10 ms
        loop
    
     

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

    Joseph Realmuto - 2019-10-11

    None of that works at all for me unless I have CSWEN = OFF. When I have it off, it works fine with the 10 MHz crystal but not at all with the 16 MHz one. I honestly think this is an undocumented hardware issue.

     
  • Anobium

    Anobium - 2019-10-11

    Can you confirm you tried the code above? Unchanged with nothing attached to the microcontroller.

    What version of the compiler etc.? Post the top lines of your ASM file.

    The GCB compilerdoes sets the CSWEN = ON, and, this is correct. . So, I am puzzled. My guess - when you use the code above it works. So, when you set CSWEN=OFF you lockout changes with respect to NOSC and NDIV, so, your NOSC and NDIV changes in the code are ignored.

    Then, what is your config of you crystal? caps etc? distance etc.? I am sure Chris Roper will help in getting that sorted.

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-11

    The simple test program works, even with a 16 MHz crystal. PortA.0 pulses at a frequency of 50 Hz like it should. This is telling me there's definitely no issue with the crystal layout. I'm using 20 pf caps and a 330 ohm series resistor. It works with or without the series resistor.

    The problem is when I try your config with my project. At that point nothing works, or at least I'm not getting anything on the OLED display.

    Compiler version is 0.98.06 2019-06-12 (Windows 32 bit) with the new EEPROM .h you sent me a few weeks ago.

     

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

    Anobium - 2019-10-11

    OK. This tells us that the basic chip is good. Does it work at 64mhz?
    And, do have any interrupts running? and, are you still writing to the EEPROM?

     
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-11

    Yes, there are interrupts running, and I'm still writing to the EEPROM. All this works fine with the 10 MHz crystal and 4xPLL. Also, everything works fine with the 16 MHz crystal without the 4xPLL.

     
    • Anobium

      Anobium - 2019-10-11

      I am clarifying. Can you confirm that the chip and its crystal support (with nothing else attached) does not operate at 64 mhz using the code below?

      The code should toggle the port every 10 ms.

      Evan

      #chip 18F27K40, 64
      
      
          '64Mhz with 4xPLL
          #config FEXTOSC = HS            ' External Oscillator mode Selection bits->HS (crystal oscillator) above 8 MHz and PFM set to high power
          #config RSTOSC = EXTOSC_4PLL    ' Power-up default value for COSC bits->EXTOSC with 4x PLL, with EXTOSC operating per FEXTOSC bits
          #config CSWEN = ON              ' Clock Switch Enable bit->Writing to NOSC and NDIV is allowed
      
      
      
          'This is not needed but I have inclded for clarity
          ' NOSC EXTOSC   with 4x PLL and NDIV 1
          OSCCON1 = 0x20
          ' CSWHOLD may proceed and SOSCPWR Low power
          OSCCON3 = 0x00
          ' MFOEN disabled and LFOEN disabled and ADOEN disabled and SOSCEN disabled and EXTOEN disabled and HFOEN disabled and
          OSCEN = 0x00
          ' HFFRQ 4_MHz
          OSCFRQ = 0x02
          ' TUN 0
          OSCTUNE = 0x00
      
          ; Wait for PLL to stabilize
          wait while (PLLR = 0)
      
      
          dir porta.0 out
          do
            porta.0 = !porta.0
            wait 10 ms
          loop
      
       
      • Joseph Realmuto

        Joseph Realmuto - 2019-10-11

        That code with the chip and nothing but the crystal attached is working fine. The problem seems to be when the display attached. If I can sort it out with the simple test program I posted below (which just writes stuff to the display), all should be well.

         
  • Joseph Realmuto

    Joseph Realmuto - 2019-10-11

    I'm trying to run a test program which just sends stuff to the display, without any interrupts or use of the EEPROM. It doesn't work with the 16 MHz crystal and 4xPLL but works fine if I swap in a 10 MHz crystal. This is starting to look like some sort of weird interaction between the display and the chip. Here's the test program:

    ;Chip Settings
      #chip PIC18F27K40,64
      #config FEXTOSC=HS, RSTOSC=EXTOSC_4PLL, BOREN=OFF, MCLR=ON, CSWEN = OFF
      #include <glcd.h>
      #include <glcd_large_number_fonts_SSD1351.h>
    
        '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
    
    ; ----- Define Hardware settings
    
      #define GLCD_POWER PORTA.3
      #define GLCD_DC PORTC.6
      #define GLCD_CS PORTC.7
      #define GLCD_RESET PORTC.2
      #define GLCD_DO PORTC.5
      #define GLCD_DI PORTC.4
      #define GLCD_SCK PORTC.3
      #define SSD1351_HardwareSPI
    
      #define Button_1 PORTA.4
      #define Button_2 PORTA.5
    
    ; ----- Define GLCD Hardware settings
      #define GLCD_TYPE GLCD_TYPE_SSD1351
    
        Set GLCD_POWER off 'drives P-channel MOSFET off = display power on
        dir PORTA.4 in
        dir PORTA.5 in
    
    'GLCD selected OLED font set.
        #define GLCD_OLED_FONT
        '#define GLCD_PROTECTOVERRUN
        GLCDfntDefaultsize = 1
    
        GLCDCLS  ' supports GLCDBackground as default
    
        Dim CCOUNT, BYTENUMBER, OLDFONT, OLDFONT as Byte
    
        'OSCCON1 = 0x20
    
        CCount = 31
        dim longNumber as long
        longNumber = 0 ' max value = 4294967290
        dim AnobiumTableAddres, wordNumber, wordNumber2, binary16 as Word
        dim outstring as string
        wordNumber = 0
        byteNumber = 0
    
        'GLCDSetContrast ( 0x60, 0x60, 0x60  )
        'SetBrightness_SSD1351 ( 0x00 )
    
        GLCDPrintStringLN "Great Cow BASIC"
        GLCDPrintStringLN ""
        GLCDPrintStringLN "December 2018"
        GLCDPrintStringLN "SSD1351 GLCD"
        GLCDPrintStringLN ""
        GLCDPrintStringLN "by Anobium"
        wait 5 s
    
        'GLCDRotate ( Portrait )
        GLCDCLS SSD1351_TEAL
        GLCDForeground = SSD1351_YELLOW
        wordNumber =  1
        wait 1 s
        d2_last = 0
        d3_last = 0
        d4_last = 0
        d5_last = 0
        REPEAT 65535
         binary16 = wordNumber
         DisplayDigits
         GLCDDrawSize3Number ( 91, 64, d1, SSD1351_OLIVE )
         IF d2 <> d2_last THEN
          GLCDDrawSize3Number ( 74, 64, d2, SSD1351_RED )
          IF d3 <> d3_last THEN
           GLCDDrawSize3Number ( 57, 64, d3, SSD1351_YELLOW )
           IF d4 <> d4_last THEN
            GLCDDrawSize3Number ( 40, 64, d4, SSD1351_LIME )
            IF d5 <> d5_last THEN
             GLCDDrawSize3Number ( 23, 64, d5, SSD1351_PURPLE )
            END IF
           END IF
          END IF
         END IF
         d2_last = d2
         d3_last = d3
         d4_last = d4
         d5_last = d5
         wordNumber = wordNumber + 1
         IF BUTTON_1 = 1 THEN
          EXIT REPEAT
         END IF
        END REPEAT
    
        repeat 2
    
                GLCDRotate ( Landscape )
                GLCDCLS SSD1351_BLUE
    
                GLCDForeground = SSD1351_MAROON
                GLCDPrint ( 2, 2, "GLCDPrint String" )
    
                GLCDForeground = SSD1351_WHITE
                GLCDPrint ( 2, 12, "GLCDPrint String" )
    
                GLCDForeground = SSD1351_GREEN
                GLCDPrint ( 2,30, precharge )
    
    
                FilledBox 50,40,55,45,SSD1351_RED
    
                SetScrollParameters_SSD1351(1, 0, 128, 0)
                StartScroll_SSD1351
    
                wait 10 s
    
                StopScroll_SSD1351
                longNumber = 0xFFFFFFFF
                wordNumber = 0xFFFF
                byteNumber = 0xFF
    
                GLCDRotate ( Portrait )
                GLCDCLS SSD1351_GREEN
    
                GLCDForeground = SSD1351_MAROON
                GLCDPrint ( 2, 2, bytenumber )
    
    
                GLCDForeground = SSD1351_BLACK
                GLCDPrint ( 2, 12, wordNumber )
    
    
                GLCDForeground = SSD1351_CYAN
                GLCDPrint ( 2,30, longnumber )
    
                wait 2 s
    
        End Repeat
    
      'GLCDRotate ( Landscape )
      GLCDRotate ( Portrait )
      GLCDCLS SSD1351_BLUE
      GLCDForeground = SSD1351_WHITE
      ' Prepare the static components of the screen
      GLCDPrint ( 2,   2, "SSD1351 Library")                                ; Print some text
      GLCDPrint ( 2,   9, "PrintStr")                                ; Print some text
      GLCDPrint ( 64,  2, "@")                                    ; Print some more text
      GLCDPrint ( 72,  2, ChipMhz)                                   ; Print chip speed
      GLCDPrint ( 80,  2, "Mhz")                                     ; Print some text
      GLCDDrawString( 2,18,"DrawStr")                                 ; Draw some text
      box 0,0,GLCD_WIDTH-1, GLCD_HEIGHT-1                            ; Draw a box
      box GLCD_WIDTH-5, GLCD_HEIGHT-5,GLCD_WIDTH-1, GLCD_HEIGHT-1    ; Draw a box
      Circle( 32,41,10)                                              ; Draw a circle
      line 50,31,0,31                                                ; Draw a line
      CCount = 0
      byteNumber = 40
      REPEAT 10
       GLCDDrawNarrowNumber(byteNumber, 100, CCount, SSD1351_RED)
       CCount = CCount + 1
       byteNumber = byteNumber + 5
      END REPEAT
      byteNumber = 0xFF
      wordNumber2 = 0xFFFF
      bit17 = 0
    
      DO forever
         for CCount = 32 to 127
              outstring = hex(longNumber_E )
              outstring = outstring+hex(longNumber_E )
              outstring = outstring+hex(longNumber_H )
              outstring = outstring+hex(longNumber )
              outstring = outstring+"h"
    
              GLCDPrint ( 46 ,  36,  Outstring  )                        ; Print a HEX string
              GLCDPrint ( 46 ,  44, pad(str(wordNumber), 6 ) )           ; Print a padded string
              GLCDPrint ( 46 ,  52, pad(str(byteNumber), 4 ) )           ; Print a padded string
    
    
              box (46,19,56,28)                                           ; Draw a Box
              GLCDDrawChar(49, 20, CCount )                               ; Draw a character
              outString = str( CCount )                                  ; Prepare a string
              GLCDDrawString(64, 19, pad(outString,5) )                   ; Draw a string
    
              filledbox 3,43,11,51, wordNumber                           ; Draw a filled box
    
              FilledCircle( 32,41,8, longNumber )                   ; Draw a filled box
              line 0,63,50,31                                            ; Draw a line
    
                                                                         ; Do some simple maths
              longNumber = longNumber + 7 : wordNumber = wordNumber + 1 : wordNumber2 = wordNumber2 + 1 : byteNumber++
              IF wordNumber2 = 65535 THEN
               bit17 = 1
               wordNumber2 = 5535
              END IF
              binary16 = wordNumber2
              DisplayDigits
    
              IF bit17 = 1 THEN
               d5 = d5 + 6
               IF d5 = 10 THEN
                bit 17 = 0
                wordnumber2 = 0
                d5 = 0
               END IF
              END IF
    
              GLCDDrawSize3Number ( 40, 64, d5 )
              GLCDDrawSize3Number ( 57, 64, d4 )
              GLCDDrawSize3Number ( 74, 64, d3 )
              GLCDDrawSize2Number ( 91, 64, d2 )
              GLCDDrawSize2Number ( 102, 64, d1 )
    
              'GLCDForeground = SSD1351_RED
              'DrawBigChar_SSD1351 ( 20, 100, d5 + 48 )
              'DrawBigChar_SSD1351 ( 33, 100, d4 + 48 )
              'DrawBigChar_SSD1351 ( 46, 100, d3 + 48 )
              'DrawBigChar_SSD1351 ( 59, 100, d2 + 48 )
              'DrawBigChar_SSD1351 ( 72, 100, d1 + 48 )
              'GLCDForeground = SSD1351_WHITE
    
          NEXT
    
      LOOP
      end
    
    Sub DisplayDigits
      ' assembly code to convert 16-bit binary to 5-digit bcd
      SWAPF binary16_H,w
      ANDLW 0x0F
      ADDLW 0xF0
      MOVWF d4
      ADDWF d4,f
      ADDLW 0xE2
      MOVWF d3
      ADDLW 0x32
      MOVWF d1
      MOVF binary16_H,w
      ANDLW 0x0F
      ADDWF d3,f
      ADDWF d3,f
      ADDWF d1,f
      ADDLW 0xE9
      MOVWF d2
      ADDWF d2,f
      ADDWF d2,f
      SWAPF binary16,w
      ANDLW 0x0F
      ADDWF d2,f
      ADDWF d1,f
      RLCF d2,f
      RLCF d1,f
      COMF d1,f
      RLCF d1,f
      MOVF binary16,w
      ANDLW 0x0F
      ADDWF d1,f
      RLCF d4,f
      MOVLW 0x07
      MOVWF d5
      MOVLW 0x0A
    
      ' needed to modify this code section for PIC18
      Lb1:
      DECF d2,f
      ADDWF d1,f
      BTFSS STATUS, C, ACCESS
      GOTO Lb1
      Lb2:
      DECF d3,f
      ADDWF d2,f
      BTFSS STATUS, C, ACCESS
      GOTO Lb2
      Lb3:
      DECF d4,f
      ADDWF d3,f
      BTFSS STATUS, C, ACCESS
      GOTO Lb3
      Lb4:
      DECF d5,f
      ADDWF d4,f
      BTFSS STATUS, C, ACCESS
      GOTO Lb4
    End Sub
    
     
  • Anobium

    Anobium - 2019-10-11

    So, it's not the chip frequency setup. Good we have that sorted..

     
  • Anobium

    Anobium - 2019-10-11

    Your code is not correct. Remove CSWEN = OFF.

    Remove DisplayDigits was is this doing? We should have method to make the code portable.

    Add #option explicit

    Then, I would need all the code and the new library. I do not know is going on in those libraries.

     
    • Joseph Realmuto

      Joseph Realmuto - 2019-10-11

      I just made an interesting discovery. If I use the above program exactly as written it doesn't work. I tried changing CSWEN to ON. Still didn't work. However, if I change #chip PIC18F27K40,64 to #chip PIC18F27K40,32 then it works. I also tried #chip PIC18F27K40,48 but that doesn't work, either.

      Here's another interesting thing. Any delay loops should in theory run at half the speed since the program is assuming a clock speed of 32 MHz, when in reality the clock is 64 MHz. However, they don't. They run at normal speed.

      Same thing with my project. I tried #config FEXTOSC=HS, RSTOSC=EXTOSC_4PLL, BOREN=OFF, CSWEN = ON, WDTE = OFF and #chip PIC18F27K40,32. It works perfectly at 64 MHz.

      Apparently there's some issue going on with either the compiler or the chipdata file.

       
      • Anobium

        Anobium - 2019-10-11

        I am very onfused. The 'as written' is that your code or my frequency test code?

         
        • Joseph Realmuto

          Joseph Realmuto - 2019-10-11

          My code. What I just wrote above is wrong anyway. What happens for some reason when I use #chip PIC18F27K40,32 the compiler ends up having the chip running on the 32 MHz internal oscillator, not the external crystal oscillator, despite the configuration telling it to use the crystal oscillator. That explains why the delay loops work as expected.

          The bottom line is I don't think I can make my project work at 64 MHz. I'll just have to accept that 40 MHz is all I can get. I attached the SSD1351 library. Maybe you can find something that I'm missing.

           
  • Anobium

    Anobium - 2019-10-11

    I would remove SSP1SSPPS = 0x0017 'RC7 > SS1

    I will remove everything after the first circle to make this easier to test.

     
  • Anobium

    Anobium - 2019-10-11

    Finally for today.

    Wait for a few days. We are updating the compiler specifically to resolve the K40 memory issues. It may help. We are adding a cache to ensure the TABLAT and NVRAM bits are pointing at the correct part of PROGMEM and EEMEM.

     
  • Anobium

    Anobium - 2019-10-11

    I need your glcd.h and the other .

     
    • Joseph Realmuto

      Joseph Realmuto - 2019-10-11

      Attached.

       
1 2 > >> (Page 1 of 2)

Log in to post a comment.