Menu

Compiler problems with PIC18F45k42

Help
2017-11-22
2017-11-28
1 2 > >> (Page 1 of 2)
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-22

    Hi all,
    I'm trying to compile a code using I2C1 bus on PIC18F45k42.
    I have PICKIT3 and the last version of GCBASIC.

    The ASM compiler does not give errors.

    The Hex compiler gives the following errors:

    Error: GCASM: Symbol WCOL has not been defined
    Error: GCASM: Symbol SSPM3 has not been defined
    Error: GCASM: Symbol SSPM2 has not been defined
    Error: GCASM: Symbol SSPM1 has not been defined
    Error: GCASM: Symbol SSPM0 has not been defined
    Error: GCASM: Symbol SSPEN has not been defined
    Error: GCASM: Symbol P has not been defined
    Error: GCASM: Symbol MODE has not been defined
    Error: GCASM: Symbol CSTRDIS has not been defined
    Error: GCASM: Symbol 7.0 has not been defined

    At my knowledge:
    - WCOL is not a bit of any register of PIC18F45k42, (instead is a bit of SSPCON register of 16F886 f.i)
    - SSPM (3:0) are not bits of any register of PIC18F45k42 (instead are bits of the SSPCON register of 16F886 f.i)
    - SSPEN is not a bit of any register of 18F45k42 (instead is a bit of the SSPCON register of 16F886 f.i)
    - P is not a bit of any register of 18F45k42 (instead is a bit of SSPSTAT register of 16F886, f.i.)
    - MODE are bits of the I2C1CON0 register of 18F45k42 although are not recognized.
    - CSTRDIS is a bit of I2C1CON2 register of 18F45k42 although is not recognized
    - 7.0 is completely unknown to me.

    I really do not what to do because I suspect that there are errors in the compiler and that the database related to PIC18F45k42 is not complete.

    Somebody can help?

    Thank you

     
  • William Roth

    William Roth - 2017-11-22

    When having problems like this, it is important to post your GCB code for analysis and so that we can replicate the problem. It is likely a datafile problem but we still need to see your source code

    William

     
  • Anobium

    Anobium - 2017-11-22

    Starting with obvious. What version are you using?

     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-22

    Yes sure,
    I use the version 27/09/2017:v0.98.00.

    Here is the code
    (I deleted all printing instructions):

    #chip 18F45k42, 64
    #option explicit
    '_______________
    '   I2C
    ' Define I2C settings
    #define HI2C_BAUD_RATE 100
    #define HI2C_DATA PORTC.4
    #define HI2C_CLOCK PORTC.3
    'Set pin I2C directions
    Dir HI2C_DATA in
    Dir HI2C_CLOCK in
    'Now set up the I2C slave
    HI2CMode Slave
    HI2CSetAddress 0xA0 '=esadecimale 'in binario= b'10100000'
    '______________
    '   USART
    #define USART_BAUD_RATE as 9600
    #define USART_DELAY 5 ms
    #define USART_BLOCKING
    'Set pin USART directions
    Dir portC.7 IN
    Dir portC.6 OUT
    #define SerInPort PORTc.7
    #define SerOutPort PORTc.6
    
    '__Variables_________
    dim n_elm as Byte
    #define Dim_Array 10
    dim Var_Array( Dim_Array )
    dim ind as Byte
    Dim Address as Byte
    
    '============= Code ======================
    
    wait 500 ms
    
    main:
    
      for ind= 0 to Dim_Array
        Var_Array(ind)=0
      Next
    
      HI2CStart
    
      MyHI2CReceive ( n_elm )
    
      HI2CStop
    
    goto main
    
    Sub MyHI2CReceive ( n_elm )
    
      n_elm=1
    
      SET I2C1CON0.MODE=    0x0   'set Slave mode
      SET I2C1CON2.CSTRDIS  ON  'Enable GENERAL clock stretching
    '?  SET I2C1PIE.ACKTIE    ON  'Enable acknowledge clock stretching
      SET I2C1PIE.ADRIE     ON  'Enable received address clock stretching
      SET I2C1PIE.WRIE      ON  'Enable write clock stretching
      SET I2C1CON2.ACNT     ON  'Enable auto loading of I2C1CNT
    
      'Clear overflow
      SET I2C1CON1.RXO Off
      'Clear write interrupt  SET I2C1RXIF OFF
    
       'Wait for receive address
      Wait until I2C1PIR.ADRIF = 1
        ADDRESS= I2C1ADB0
        SET I2C1CON0.CSTR   OFF   'Release SCL
    
       'Wait for receive data
      do until I2C1PIR.PCIF = 1  'do until StopBit
        Wait Until I2C1RXIF.RXBF = 1 'wait until full buffer otherwise you can use  I2C1RXIF=1
        Var_Array(n_elm) = I2C1RXB
        n_elm=n_elm+1
        SET I2C1CON1.ACKDT  OFF  'Acnowledge receipt data
        SET I2C1CON0.CSTR   OFF   'Release SCL
        wait 3 us
      Loop
    
      n_elm=n_elm-1
    
    End Sub
    

    Note that if I delete the instruction HI2CMode Slave only the last four errors of my first post are returned.
    Thank you

     
  • Anobium

    Anobium - 2017-11-22

    Slave is not implement for the 18FxxK42 microcontrollers.

    I have not had time to work throught the module yet.

    So, do not initialise the HI2CMode Slave or use HI2CSetAddress 0xA0.

    You should create you own methods to support slave operations on the K42 chips. I cannot think it will be hard but the existing HI2C slave command are not supported yet.

    If you have the time and willingness to update the library that would be really helpful.

     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-22

    I have found that if a substitute the instruction HI2CMode Slave with the #Define HI2CMode Slave only the last four errors of my first post are returned.
    Accordingly, HI2CMode Slave, working with 16F886, seem to not work with 18F45k42

     
  • Anobium

    Anobium - 2017-11-22

    That would be correct. As the Slave capability is not yet implement for the 18FxxK42 microcontrollers.

     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-22

    OK, thank you.

    I will try to do it.

    However I suppose I will need more help from you

    I figure that I should start with the I2c port setting and properly understand and modify the PIC database.

    At the moment I substitute the instruction
    SET I2C1CON0.MODE= 0x0
    with
    SET I2C1CON0.MODE0= 0 'set Slave mode, four bit address
    SET I2C1CON0.MODE1= 0
    SET I2C1CON0.MODE2= 0
    and the error
    Error: GCASM: Symbol MODE has not been defined
    is not more returned.

    However, this was obtained from reading the PIC database and it was simple to understand what to do.

     
    • Anobium

      Anobium - 2017-11-22

      Yes, I am think you will.

      This is completely new I2C module. I have an open ticket with Microchip with respect to a silicon error. This open ticket is with engineering for resolution - so, if we hit that you need to know that you may have to change your chip.

      That said. I get started but after the horrors of getting the Master module working - I took a gap from it.

      This is the start - it is still missing the I2C1_StatusCallback method. This is not tested, at all. This is the library function that would be needed. This is prototype and the init part would need to be moved into the appropiate method later. The honors for this go to Microchip - they are helping me with the K42 implementation of I2C.

      '  address 18  
          I2C1ADR0 = 0x12 
          I2C1ADR1 = 0x00 
          I2C1ADR2 = 0x00 
          I2C1ADR3 = 0x00 
          I2C1CON1 = 0x00 
          I2C1CON2 = 0x00 
          I2C1CLK = 0x00 
          I2C1CNT = 0x50 
          I2C1CON0 = 0x80 
      
          I2C1RXIF=0 
          I2C1TXIF=0 
          I2C1EIF=0 
          NACKIF=0 
          I2C1IF=0 
          PCIF=0 
          ADRIF=0 
      
          I2C1RXIE=1 ' enable I2C RX interrupt
          I2C1TXIE=1 ' enable I2C TX interrupt
          I2C1EIE=1 ' enable I2C error interrupt
          NACKIE=1 ' enable I2C error interrupt for NACK
          I2C1IE=1 ' enable I2C  interrupt
          PCIE=1 ' enable I2C interrupt for stop condition
          ADRIE=1 ' enable I2C interrupt for I2C address match condition
      
          I2C1PIR = 0 '      Clear all the error flags
          I2C1ERR = 0 
      
      
      
          On Interrupt I2C1ErrorInterrupt call I2C1_ISR
          On Interrupt I2C1Interrupt call I2C1_ISR
          On Interrupt I2C1ReceiveInterrupt call I2C1_ISR
          On Interrupt I2C1Transmit terrupt call I2C1_ISR
          On Interrupt I2C2ErrorInterupt call I2C1_ISR
          On Interrupt I2C2Interrupt call I2C1_ISR
          On Interrupt I2C2ReceiveInterrupt call I2C1_ISR
      
          do
      
          loop
      
      
      sub I2C1_ISR
          dim I2C1_data as byte
          I2C1_data = 0x55
      
          if ( RXBF or I2C1RXIF ) then
      
              I2C1RXIF=0
              I2C1_data = I2C1RXB
          end if
      
          if( I2C1STAT0.R = 1 ) then
      
      
              if (I2C1PIR.PCIF = 1 ) then
                  I2C1PIR.PCIF=0
                  PIR3.I2C1IF=0
                  I2C1STAT1.CLRBF=1   'clear I2C1TXB and TXBE
              end if
              if (NACKIF = 1 ) then
      
                  I2C1ERRNACKIF=0
                  PIR3.I2C1EIF=0
                  I2C1STAT1.CLRBF=1  'clear I2C1TXB and TXBE
                  ' I2C1_SLAVE_READ_COMPLETED.. set some flag?
      
              else if ( PIR3.I2C1TXIF = 1 ) then 
      
                  PIR3.I2C1TXIF=0
                  'a callback routine should write data into I2C1TXB
                  I2C1_StatusCallback(I2C1_SLAVE_READ_REQUEST);
              end if
      
              if (  I2C1PIR.ADRIF = 1) then
      
                  I2C1PIR.ADRIF=0
                  PIR3.I2C1IF=0
              end if
      
          else if ( I2C1PIR.ADRIF = 1) then
      
              I2C1PIR.ADRIF=0
              PIR3.I2C1IF=0
              'callback routine should prepare to receive data from the master
              I2C1_StatusCallback(I2C1_SLAVE_WRITE_REQUEST);
          end if
          else
      
              I2C1_slaveWriteData   = I2C1_data
      
              'callback routine should process I2C1_slaveWriteData from the master
              I2C1_StatusCallback(I2C1_SLAVE_WRITE_COMPLETED)
          end if
          I2C1CON0.CSTR=0 
      
      sub
      
      sub I2C1_StatusCallback(     )
      
      end sub '  address 18  
          I2C1ADR0 = 0x12 
          '  address 0  
          I2C1ADR1 = 0x00 
          '  address 0  
          I2C1ADR2 = 0x00 
          '  address 0  
          I2C1ADR3 = 0x00 
          '  TXU 0  CSD Clock Stretching enabled  ACKT 0  RXO 0  ACKDT Acknowledge  ACKSTAT ACK received  ACKCNT Acknowledge  
          I2C1CON1 = 0x00 
          '  ABD enabled  GCEN disabled  ACNT disabled  SDAHT 300 ns hold time  BFRET 8 I2C Clock pulses  FME disabled  
          I2C1CON2 = 0x00 
          '  CLK Fosc/4  
          I2C1CLK = 0x00 
          '  CNT 0  
          I2C1CNT = 0x50 
          '  CSTR Enable clocking  S Cleared by hardware after Start  MODE four 7-bit address  EN enabled  RSEN disabled  
          I2C1CON0 = 0x80 
      
          I2C1RXIF=0 
          I2C1TXIF=0 
          I2C1EIF=0 
          NACKIF=0 
          I2C1IF=0 
          PCIF=0 
          ADRIF=0 
      
          I2C1RXIE=1 ' enable I2C RX interrupt
          I2C1TXIE=1 ' enable I2C TX interrupt
          I2C1EIE=1 ' enable I2C error interrupt
          NACKIE=1 ' enable I2C error interrupt for NACK
          I2C1IE=1 ' enable I2C  interrupt
          PCIE=1 ' enable I2C interrupt for stop condition
          ADRIE=1 ' enable I2C interrupt for I2C address match condition
      
          I2C1PIR = 0 '      Clear all the error flags
          I2C1ERR = 0 
      
      
      
          On Interrupt I2C1ErrorInterrupt call I2C1_ISR
          On Interrupt I2C1Interrupt call I2C1_ISR
          On Interrupt I2C1ReceiveInterrupt call I2C1_ISR
          On Interrupt I2C1Transmit terrupt call I2C1_ISR
          On Interrupt I2C2ErrorInterupt call I2C1_ISR
          On Interrupt I2C2Interrupt call I2C1_ISR
          On Interrupt I2C2ReceiveInterrupt call I2C1_ISR
      
          do
      
          loop
      
      
      sub I2C1_ISR
          dim I2C1_data as byte
          I2C1_data = 0x55
      
          if ( RXBF or I2C1RXIF ) then
      
              I2C1RXIF=0
              I2C1_data = I2C1RXB
          end if
      
          if( I2C1STAT0.R = 1 ) then
      
      
              if (I2C1PIR.PCIF = 1 ) then
                  I2C1PIR.PCIF=0
                  PIR3.I2C1IF=0
                  I2C1STAT1.CLRBF=1   'clear I2C1TXB and TXBE
              end if
              if (NACKIF = 1 ) then
      
                  I2C1ERRNACKIF=0
                  PIR3.I2C1EIF=0
                  I2C1STAT1.CLRBF=1  'clear I2C1TXB and TXBE
                  ' I2C1_SLAVE_READ_COMPLETED.. set some flag?
      
              else if ( PIR3.I2C1TXIF = 1 ) then 
      
                  PIR3.I2C1TXIF=0
                  'a callback routine should write data into I2C1TXB
                  I2C1_StatusCallback(I2C1_SLAVE_READ_REQUEST);
              end if
      
              if (  I2C1PIR.ADRIF = 1) then
      
                  I2C1PIR.ADRIF=0
                  PIR3.I2C1IF=0
              end if
      
          else if ( I2C1PIR.ADRIF = 1) then
      
              I2C1PIR.ADRIF=0
              PIR3.I2C1IF=0
              'callback routine should prepare to receive data from the master
              I2C1_StatusCallback(I2C1_SLAVE_WRITE_REQUEST);
          end if
          else
      
              I2C1_slaveWriteData   = I2C1_data
      
              'callback routine should process I2C1_slaveWriteData from the master
              I2C1_StatusCallback(I2C1_SLAVE_WRITE_COMPLETED)
          end if
          I2C1CON0.CSTR=0 
      
      sub
      
      sub I2C1_StatusCallback(     )
      
      end sub
      
       
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-23

    Hi Anobium,
    thanks for the news.

    Not so good, I bought five of that chips.

    I need time to read and understand the library you sent.

    Anyway, as you can understand, at the moment I do not need a full management of I2C. I have not enough experience to do it.

    A slave 7 bit reception management is enought for me now, also avoiding slave writing and master operations.

    As a matter of fact I need to use the PIC in a "real time" control system wherein a RPI zero manage the main task and the PIC just repeatedly receive data to execute "real time" operations.

    Now I suspect that also USART commands does not work.
    In fact the following simple code

    #chip 18F45k42, 64
    #option explicit
    
    '   USART
    #define USART_BAUD_RATE  9600
    #define USART_DELAY 5 ms
    #define USART_BLOCKING
    'Set pin USART directions
    Dir portC.7 IN
    Dir portC.6 OUT
    #define SerInPort PORTc.7
    #define SerOutPort PORTc.6
    
    '__Variables_________
    dim n_elm as Byte
    
    
    '============= Code ======================
    
    wait 500 ms
    
    HSerPrintCRLF
    

    give the ASM errors:

    usart.h (372): Error: Incorrect parameters in Set, expected: Set
    variable.bit status
    usart.h (375): Error: Incorrect parameters in Set, expected: Set
    variable.bit status

    that I still does not understand.

    Finally, I made the following set of instructions that are compiled, both for ASM and HEX ,without error.
    However I had not the time to test them on the PIC, because the above difficulties with USART:

    #chip 18F45k42, 64
    #option explicit
    '   I2C
    ' Define I2C settings
    #define HI2C_BAUD_RATE 100
    #define HI2C_DATA PORTC.4
    #define HI2C_CLOCK PORTC.3
    'Set pin I2C directions
    Dir HI2C_DATA in
    Dir HI2C_CLOCK in
    'Now set up the I2C slave
    SET I2C1CON0.MODE0=    1   'set Slave mode, two bit address
    SET I2C1CON0.MODE1=    0
    SET I2C1CON0.MODE2=    0
    'Set Address
    SET I2C1ADR1=   0XA0        '=esadecimale 'in binario= b'10100000'
    
    '__Variables_________
    dim n_elm as Byte
    Dim Address as Byte
    #define Dim_Array 10
    dim Var_Array( Dim_Array )
    
    '============= Code ======================
    main:
    
      for ind= 0 to Dim_Array
        Var_Array(ind)=0
      Next
    
      SET I2C1PIE.SCIE = 1
      wait until I2C1PIR.SCIF = 1   'Start I2C slave
    
      MyHI2CReceive ( n_elm )
    
    
      wait until I2C1PIR.PCIF = 1   'Stop I2C slave, maybe not needed
    
    goto main
    
    Sub MyHI2CReceive ( n_elm )
    
      n_elm=1
    
      SET I2C1CON2.CSTR     ON  'Enable GENERAL clock stretching
    '?  SET I2C1PIE.ACKTIE    ON  'Enable acknowledge clock stretching
      SET I2C1PIE.ADRIE     ON  'Enable received address clock stretching
      SET I2C1PIE.WRIE      ON  'Enable write clock stretching
      SET I2C1CON2.ACNT     ON  'Enable auto loading of I2C1CNT
      SET I2C1PIE.PCIE      ON  'Enable STOP condition interrupt
      'Clear overflow
      SET I2C1CON1.RXO Off
      'Clear write interrupt  SET I2C1RXIF OFF
    
       'Wait for receive address
      Wait until I2C1PIR.ADRIF = 1
        ADDRESS= I2C1ADB0
        SET I2C1CON0.CSTR   OFF   'Release SCL
    
       'Wait for receive data
      do until I2C1PIR.PCIF = 1  'do until StopBit
        Wait Until I2C1STAT1.RXBF = 1 'wait until full buffer 
        Var_Array(n_elm) = I2C1RXB
        n_elm=n_elm+1
        SET I2C1CON1.ACKDT  OFF  'Acnowledge receipt data
        SET I2C1CON0.CSTR   OFF   'Release SCL
        wait 3 us
      Loop
    
      n_elm=n_elm-1
    
    End Sub
    

    Anyway really many thanks for your help and attention.

     
  • William Roth

    William Roth - 2017-11-23

    @Giuseppe

    1. If your version of Great Cow Basic is 27/09/2017 then you are not using the latest release. The latest release is 0.98.01 2017-10-27. This version has updated compiler and datafiles.

    2. Your code is not setting up PPS ( Peripheral Pin Select) for the USART pins or for I2C pins. This must be set up for 18FxxK42 chips or else there will be no pins assigned to Serial TX or to SCL and SDA.

    3. In regards to the USART code, it unnecessarily defines SerinPin and SeroutPin. These are not needed.

    4. The error messages that you see in regards to USART.h suggest either a corrupted USART.H file or a corrupted/old datafile.

    You need to update your GCB installation to 98.01.

    The code below demonstrates how to setup and do a simple test using Serial Usart . It runs without error on PIC18F25K42 and should run well on your 18F45K42. Just change the chipname.
    Please load this into GCB then compile and program the chip. Use a serial terminal to view the serial output. Please let us know your result.

    #chip 18F25k42, 32
    #config MCLRE = ON
    #option explicit
    #startup InitPPS, 85 '//Call InitPPS
    

    'USART
    #define USART_BAUD_RATE 9600
    #define USART_DELAY 1 ms
    #define USART_BLOCKING

    'Set pin USART directions ( not really necessary with USART Pins)
    Dir portC.7 IN
    Dir portC.6 OUT
    
    Dim AsciiChar as Byte
    
     wait 1 s
     HSerPrintCRLF
    
    Hserprint "Great Cow Basic"
    HSerPrintCRLF
    HSerprint "Serial Send Test"
    HSerPrintCRLF
    HserPrint ChipNameStr
    HSerPrintCRLF 2
    Wait 2 sec
    
    Repeat 5
          For AsciiChar = 48 to 90
              HSersend AsciiChar : Hsersend " "
         Next
         HserprintCRLF
         Wait 1 sec
    End Repeat
    
    HserprintCRLF 3
    Hserprint "*** Press Reset to repeat test ***"
    Do
    
    Loop
    
    Sub InitPPS
        '//sets up pins for USART
    
        UNLOCKPPS
            'Module: UART1
            U1RXPPS = 0x0017    'RC7 > RX1
            RC6PPS = 0x0013     'TX1 > RC6
    
        LOCKPPS
     End Sub
    
     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-23

    @William,
    thank you.
    I will do it as soon as possible and I will send a feedback.

     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-23

    Hi William,

    I added the USART instruction you suggested. At beginning the terminal (the Cool Terminal) didn’t received anything.

    I lost a lot of time on this. At the end I discovered that disconnecting the PicKit3 anything works fine. So, thank you for your suggestions. They work on PIC18F45k42 too.

    I do not understand why I must disconnect PicKit3. It is normal? With 16F886 I never found this problem.

    I suspected it was necessary to clear the ANSEL appropriate bits but still didn’t work (I used a SET command, although I suspected a CRLF one could be more appropriate).

    Obviously, the need of disconnecting the PicKit3 is annoying when many PIC programming steps are required during debugging phase.

    I modified your InitPPS Sub by introducing the I2C1 PPS commands as shown in the following:

    Sub InitPPS
        '//sets up pins for USART
    
        UNLOCKPPS
            'Module: UART1
            U1RXPPS = 0x0017    'RC7 > RX1
            RC6PPS = 0x0013     'TX1 > RC6
    '       'Module: I2C1
              'input
            I2C1SCLPPS = 0x0013
            I2C1SDAPPS = 0x0014
              'Output
            RC3PPS = 0x0021
            RC4PPS = 0x0022 
    
        LOCKPPS
     End Sub
    

    However, I had not time to check them also because i think in this case the ANSEL and TRIS registers must be set. to use I2C module

    I will work on this and will give you an update.

    Thank you again

     
    • Anobium

      Anobium - 2017-11-24

      @Guiseppe.

      :Please look at the I2C demonstration for this chip. They are in your installation, they are also here in GitHub: https://github.com/Anobium/Great-Cow-BASIC-Demonstration-Sources/tree/master/Vendor%20Boards/Great%20Cow%20Basic%20Demo%20Board/18F25K42%20ChipRange%20Demonstrations

      The demonstrations are what we use to test chips - so, if they are incorrect with respect to ANSEL and/or TRIS I would like to ensure we 1) correct the compiler 2) correct the demos (test programs). So, with you help we can improve Great Cow BASIC.

      With respect to I2C. Please review the page on information show in the GitHub folder - this details the differences between 'legacy i2C mode' and the new 'K i2C mode' see https://github.com/Anobium/Great-Cow-BASIC-Demonstration-Sources/tree/master/Vendor%20Boards/Great%20Cow%20Basic%20Demo%20Board/18F25K42%20ChipRange%20Demonstrations. A piece of that document - this document also shows the current issues I am working on with Microchip Engineering.

      Setting the Ports in 'K Mode'

      The I2C module provides a synchronous interface between the microcontroller and other I2C-compatible devices using the two-wire I2C serial bus. Devices communicate in a master/slave environment. The I2C bus specifies two signal connections which are bidirectional open-drain lines, each requiring pull-up resistors to the supply voltage.
      **
      Specific pins are configured for I2C and SMB 3.0/2.0 logic levels. The SCLx/SDAx signals may be assigned to any of the RB1/RB2/RC3/RC4 pins. PPS assignments to the other pins (e.g., RA5) will operate, but, input logic levels will be standard TTL/ST as selected by the INLVL register, instead of the I2C specific or SMBUS input buffer thresholds.
      **
      I/O pins assigned to these signals must be configured as such through the ANSELx and ODCONx registers, and PPS, respectively. The PPS enables these pins to function as peripheral inputs (I2CxSCLPPS and I2CxSDAPPS) and outputs (RxyPPS). Input threshold, slew rate and internal pull-up settings are configured in the RxyI2C Control registers.
      **
      Essentially, setting the ports requires the SCL and SDA pins to be open-drain, and the these pins MUST programmed as OUTPUTS by setting the appropriate TRISC bits which is very different from the 'legacy mode'.**

       
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-23

    @William,
    for the sake of completeness, by deleting the instruction

    config MCLRE = ON

    now the PIC works also when connected to PicKit3.

     
    • Anobium

      Anobium - 2017-11-24

      My guess, as I am not sure what software/programmer combination you are using, is the when using MPLAB-IPE you need to select 'Release from Hold' in the IPE UI.

       
  • William Roth

    William Roth - 2017-11-24

    The reason you must set MCLRE = OFF is becaue your programmer is not releasing the MCLRE line.

    What are you using as a programming application?

    I will assume that you are using MPLABX IPE since that is the only thing I am aware of that supports K42 chips. You must configure IPE to "Release from Reset".

    If you are using the IPE command line utiliity (IPECMD) you must add the -OL switch.

    If you are using PK3CMD then you must add the -L switch.

    If you are importing the hex into the IPE GUI application then you must click on "settings" then select "Release from reset"

     
  • William Roth

    William Roth - 2017-11-24

    The K42 I2C module is different from all others. This module reqiires that the IC2 Pins defined in PPSINIT both be set as OUTPUTS not inputs. This can be done in at the start of your source code before any I2C function are called. Or optionally it can be done in the PPSINIT sub routine.

    Dir PortC.3 Out
    Dir PortC.4 Out
    

    You will also need to configure the I2C Pins as open-drain

       ODCC4=1        ' Configure Open Drain Bit for I2C Pin C.4
       ODCC3=1        ' Configure Open Drain Bit for I2C Pin C.3
    

    Here is my working setup for 18F25K42 where both USART and I2C Modules are known to work correctly.

    I2C 3k3 Pullup resistors on I2C Pins
    Compiler: GCB 98.01 - 2017-10-27.
    Programmer: PiCKIT3
    Programmer Application: ipecmd (IPE command line) from MPLAB IPE Ver4.05

    Copy and paste the line below in your FlashPic.bat file and make this the active line.

    java -jar "C:\Program Files (x86)\Microchip\MPLABX\v4.05\mplab_ipe\ipecmd.jar" -TPPK3 -P%2 -M -F%1 -OL
    

    If you have installed IPE into a different location than what is in the line above then edit as necessary. The IPE version must be either 4.01 or 4.05. If you are using IPE 3.xx then you must update to either 4.01 or 4.05 ... Recommend 4.05 as it is the latest.

    Here is the working code: (Change chip to 18F45K22)

    '''Test Program For 18F25K42
    
    'Chip Settings.
    #chip 18f25k42, 32
    #option Explicit
    #config MCLRE=EXTMCLR, LVP=ON
    
    #startup InitPPS, 85
    
     'Configure USART
    #define USART_BAUD_RATE 9600
    #define USART_DELAY 1 ms
    #define USART_BLOCKING
    
    'Set pin USART directions ( not really necessary with USART Pins)
    Dir portC.7 IN
    Dir portC.6 OUT
    
    ' Define I2C settings
    #define HI2C_BAUD_RATE 125
    #define HI2C_DATA PORTC.4
    #define HI2C_CLOCK PORTC.3
    
    HI2CMode Master
    
    'Initialise I2C - For the I2C module the ports need to be set to Output.
    Dir HI2C_DATA out
    Dir HI2C_CLOCK out
    ODCC4=1        ' Configure Open Drain Bit for I2C
    ODCC3=1        ' Configure Open Drain Bit for I2C
    
    '''Set up LCD
    #define LCD_IO 10
    #define LCD_I2C_Address_1 0x7E
    #define LCD_SPEED slow
    #define LCD_Backlight_On_State  1
    #define LCD_Backlight_Off_State 0
    CLS
    Wait 1 s
    
    '***********MAIN LOOP ********************
    DO
        DIM AsciiChar as Byte
    
        CLS  '// Clear LCD
        Wait 1 s
        'Print to I2C LCD
        Print "Great Cow BASIC"
        Locate 1,0
        Print "Ver 0.98.01"
    
        'Print to terminal
        HSerPrintCRLF 2
        HserPrint "Great Cow BASIC"
        HSerprintCRLF
        HserPrint "Ver 0.98.01"
        HserprintCRLF
    
        For AsciiChar = 48 to 90
          Hsersend AsciiChar '// To Terminal
          Hsersend " "
        Next
        Wait 1 s
    LOOP
    '****************End MAIN LOOP *******************
    
    Sub InitPPS
          'Module: UART1
          U1RXPPS = 0x0017    'RC7 > RX1
          RC6PPS = 0x0013    'TX1 > RC6
    
          'Module: I2C1
          RC3PPS = 0x0021        'SCL1 > RC3
          I2C1SCLPPS = 0x0013    'RC3 > SCL1 (bi-directional)
          RC4PPS = 0x0022        'SDA1 > RC4
          I2C1SDAPPS = 0x0014    'RC4 > SDA1 (bi-directional)
    
    End Sub
    

    Edit: Fixed Typo

     

    Last edit: William Roth 2017-11-24
    • Anobium

      Anobium - 2017-11-24

      @Giuseppe

      More examples for this code are in your installation at

      ..Demos\Vendor Boards\Great Cow Basic Demo Board\18F25K42 ChipRange Demonstrations

      If you have about an hour to work throught the demonstrations. I would be very grateful for a set of demonstrations proven to work in the PIC18F45k42 chip. :-)

       
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-24

    Hi Anobium and William,

    many thanks for the lot of information you give me.

    My working setup is the following:

    I2C 4k7 Pullup resistors on I2C Pins
    Compiler: GCB 98.01 - 2017-10-27.
    Programmer: PiCKIT3
    Programmer Application: IPE V4.01, gui interface

    I will update IPE to V4.05 as soon as possible.

    I re-introduced the command #config MCLRE = ON and I set "Release from Reset" in the IPE and now the terminal works also with PicKit3 connected, as you said. I do not need anymore to disconnect PicKit3 or to delete the MCLRE=ON line. Thank you.

    Till now I added these lines for I2C1 setting, by accounting for open drain and analog off.

    '_____________
    '   I2C
    
    SET ANSELC.ANSELC4 off
    SET ANSELC.ANSELC3 off
    SET ODCONC.ODCC4 on
    SET ODCONC.ODCC3 on
    
    ' Define I2C settings
    #define HI2C_BAUD_RATE 100
    #define HI2C_DATA PORTC.4
    #define HI2C_CLOCK PORTC.3
    
    'Set pin I2C directions
    Dir HI2C_DATA in
    Dir HI2C_CLOCK in
    
    'Now set up the I2C slave
    SET I2C1CON0.MODE0=    1   'set Slave mode, two bit address
    SET I2C1CON0.MODE1=    0
    SET I2C1CON0.MODE2=    0
    
    'Set Address
    SET I2C1ADR1=   0XA0        '=esadecimale 'in binario= b'10100000'
    '______________
    

    that essentially agree with the one you suggest, but for setting I2cDATA and I2cSCL as Input instead than Output as you said.
    Now I changed them.

    Concerning this point, it was not clear to me how to set the TRIS register because the I2C ports works both as input and output ports and (from the data sheet) any TRIs setting is a choice between input or output. You solved my doubt.

    Concerning the PPS setting, from your code I see that my setting are right. I’m happy.

    I changed I2C1 ports to OUT but the I2C slave still does not detect the incoming data.

    Concerning my ADDRESS setting still I’m not fully sure of my setting (SET I2C1ADR1= 0XA0 ) and your code is for MASTER so you do not need an I2C address setting.
    Analogously, I’m not sure that the instructions

    SET I2C1CON0.MODE0=    1   'set Slave mode, two bit address
    SET I2C1CON0.MODE1=    0
    SET I2C1CON0.MODE2=    0
    

    are enough for device slave setting.

    Provided this is OK and address setting is OK, I think that now my I2C slave problems involves the I2C managing commands.

    Essentially I wait until I2C1PIR.ADRIF = 1, i.e. ADDR Interrupt Flag is set. I previously set ADRIE ON.
    At the moment the code stay on this wait command.

    @ William
    I have not an LCD here and I cannot run your code.
    However in the weekend, at home, I can try to use an old LCD I already managed in the past with I2C commands.

    @Anobium
    Certainly I will check the demonstration codes on PIC18F45k42 as you suggest

    Many thanks for your help

     
  • Anobium

    Anobium - 2017-11-24

    @ Giuseppe

    As a rule and as this a new chip we need to resolve why you would need the following.

    SET ANSELC.ANSELC4 off
    SET ANSELC.ANSELC3 off
    

    I do no think these are needed as we do not have this in the demomstration/test programs. I may be incorrect but if they are required then we need to resolve in the compiler for these chips.

    I have started a new thread on the slave functionality as a fully functional slave library is needed. See https://sourceforge.net/p/gcbasic/discussion/579125/thread/945046fe/ Let us sort the Slave issues out in that thread.

     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-24

    @Anobium

    in the PIC18F45k42 data sheet, PPS section, page 272, 17.1 Section, PPS Inputs, I read that when a Pin has also analog function associated, the ANSEL pin for that pin must be cleared to enable the digital input buffer.

    Furthermore, on page 217, down on the first column of Section 16.0, I read:

    Ports that support analog inputs have an associated ANSELx register. When an ANSELx bit is set, the digital input buffer associated with that bit is disabled. 


    On page 258, subsection 16.2.3, first note they say:

    The ANSELx bits default to the Analog mode after Reset. To use any pins as digital general purpose or peripheral inputs, the corresponding ANSEL bits must be initialized to ‘0’ by user software.

    On the same page, in the example 16-1 PORTA is initialized, ANSELA is cleared and a comment say: digital I/O

    The same is said for TX UART on page 474, Sect.31.2.1.1 just before the Note. and for Receiver on page 476 subsection 32.2.2.1.

    I agree that nothing is said about I2C (Section 33).

    However, from the 40/44 pin allocation table, page 11 I see that pinsRC3 and RC4 (the I2C1 pins) share ADC functions (ANC3 and ANC4) that I suppose are analog functions.

    I do not know if I’m right.

    Please let me know about.

     
  • Anobium

    Anobium - 2017-11-24

    Yes. Agree.

    The compiler is intended to do this heavy lifting for you. Compile without those statement. Examine the ASM. What is the compiler producing?

     
  • Giuseppe D'Elia

    Giuseppe D'Elia - 2017-11-24

    Yes, I agree, ASM compiler clears all ANSELA/B... registers.

    On the contrary the open-drain control command are required.

    I understund that all I2C slave commands were not usable for PIC18F45k42.
    Now I try to define address and slave following the GCBASIC commands.

    Thank you

     
  • William Roth

    William Roth - 2017-11-26

    @Guiseppe & All

    Attached is a program I created to ease troubleshooting/debugging of PIC 18FxxK42 chips... Specifically for I2C. However it can be easily adapted to display the contents of any register or group of registers. The registers contents are displayed in binary, hex and decimal.

    This program uses CoolTerm as the debug display. CoolTerm must be configured to handle the Form Feed character (DEC 12) to clear the entire screen with one command.
    To Configure:

    OPTIONS > TERMINAL > Handle Form Feed Character.
    

    So to clear the entire screen use > Hsersend 12

    There are 2 main subroutines. View_Registers & View_Config_Registers

    View_registers can be modified to show the contents of any register. For this program I have it set up to View the contents of all I2C related regsiters.

    View_Config_Registers displays the contents of all config registers in binary, hex and decimal.

    Place your code in the MAIN routine. You can call "View_Registers" at any time in your code. You may want to remark out some registers that are not likely to change like ANSELx and TRISx.

    The program is attached as as well as some screenshots of what the terminal should look like.

    Have Fun

    William

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.