• AVR Freaks

Hot!18F27K42 any conflict between I2C1 and SPI1?

Author
Doubletop
Starting Member
  • Total Posts : 46
  • Reward points : 0
  • Joined: 2019/03/07 21:46:09
  • Location: New Zealand
  • Status: offline
2021/01/02 17:32:09 (permalink)
0

18F27K42 any conflict between I2C1 and SPI1?

I have been using a simple bit bang (See AN1488) implementation of I2C on an 18F27K42, along with MCC generated SPI1 for an SD card. Both worked fine but it was about time I moved the I2C over to the chip  as I'm doing for the other on chip devices. I'm using MPLAB 5.45 with MCC 4.0.2 and XC8 2.31. Both I2C and SPI in master mode without interrupts.
 
The SPI1 implementation has always worked using on RC2-5, SS on RC2. The bit banged I2C was on pins RC0 and RC1 and those pins retained for the MCC generated code. The problem I having is the I2C1 works fine but SPI1 has stopped working.
 
I've checked and rechecked the pin configurations. Confirmed that the SPI modules from MCC have not changed at all. Traced the SPI code all the way through to the SD_SPI_MediaInitialize function in sd_spi.c to the point where the SS line is toggled and the SPI registers show the same values in the old and new code versions. However, the pre MCC I2C version the clock and data lines are active but in the new version nothing happens.
 
sd_spi.c
       //Toggle chip select, to make media abandon whatever it may have been doing
        //before. This ensures the CMD0 is sent freshly after CS is asserted low,
        //minimizing risk of SPI clock pulse master/slave synchronization problems,
        //due to possible application noise on the SCK line.
        SD_SPI_ChipDeselect();
        (void)SD_SPI_exchangeByte(0xFF); //Send some "extraneous" clock pulses. If a previous
                                          //command was terminated before it completed normally,
                                          //the card might not have received the required clocking
                                          //following the transfer.
        SD_SPI_ChipSelect();
        timeout--;

pin_manager.c
void PIN_MANAGER_Initialize(void)
{
    /**
    LATx registers
    */
    LATA = 0xFC;
    LATB = 0x00;
    LATC = 0x06;

    /**
    TRISx registers
    */
    TRISA = 0x03;
    TRISB = 0x83;
    TRISC = 0x90;
   
    /**
    ANSELx registers
    */
    ANSELC = 0x00;
    ANSELB = 0x00;
    ANSELA = 0x03;

    /**
    WPUx registers
    */
    WPUE = 0x00;
    WPUB = 0x03;
    WPUA = 0x00;
    WPUC = 0x00;

    /**
    RxyI2C registers
    */
    RB1I2C = 0x00;
    RB2I2C = 0x00;
    RC3I2C = 0x00;
    RC4I2C = 0x00;

    /**
    ODx registers
    */
    ODCONA = 0x00;
    ODCONB = 0x00;
    ODCONC = 0x03;

    /**
    SLRCONx registers
    */
    SLRCONA = 0xFF;
    SLRCONB = 0xFF;
    SLRCONC = 0xFF;

    /**
    INLVLx registers
    */
    INLVLA = 0xFF;
    INLVLB = 0xFF;
    INLVLC = 0xFF;
    INLVLE = 0x08;


    /**
    IOCx registers
    */
    //interrupt on change for group IOCBF - flag
    IOCBFbits.IOCBF0 = 0;
    //interrupt on change for group IOCBF - flag
    IOCBFbits.IOCBF1 = 0;
    //interrupt on change for group IOCBN - negative
    IOCBNbits.IOCBN0 = 0;
    //interrupt on change for group IOCBN - negative
    IOCBNbits.IOCBN1 = 0;
    //interrupt on change for group IOCBP - positive
    IOCBPbits.IOCBP0 = 0;
    //interrupt on change for group IOCBP - positive
    IOCBPbits.IOCBP1 = 0;



    // register default IOC callback functions at runtime; use these methods to register a custom function
    IOCBF0_SetInterruptHandler(IOCBF0_DefaultInterruptHandler);
    IOCBF1_SetInterruptHandler(IOCBF1_DefaultInterruptHandler);
   
    // disable IOCI interrupt
    PIE0bits.IOCIE = 0;
    
    //UART1
    U1RXPPS = 0x17; //RC7->UART1:RX1;
    RC6PPS = 0x13; //RC6->UART1:TX1;
    
    //UART2
    U2RXPPS = 0x0F; //RB7->UART2:RX2;
    RB6PPS = 0x16; //RB6->UART2:TX2;
    
    //I2C1
    RC0PPS = 0x21; //RC0->I2C1:SCL1;
    I2C1SDAPPS = 0x11; //RC1->I2C1:SDA1;
    RC1PPS = 0x22; //RC1->I2C1:SDA1;
    I2C1SCLPPS = 0x10; //RC0->I2C1:SCL1;
    
    //SPI1
    SPI1SCKPPS = 0x13; //RC3->SPI1:SCK1;
    RC3PPS = 0x1E; //RC3->SPI1:SCK1;
    RC5PPS = 0x1F; //RC5->SPI1:SDO1;
    SPI1SDIPPS = 0x14; //RC4->SPI1:SDI1;
    //SPI1SSPPS = 0x12; //RC2->SS1
    RC2PPS = 0x20; //RC2->SS1
}

 
 
So before I try to go any further are there any known limitations to using SPI1 an I2C1?
 
Pete
#1

18 Replies Related Threads

    mbrowning
    USNA79
    • Total Posts : 1887
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/02 17:52:05 (permalink)
    +2 (2)
    No. I use both I2C in state Mach, interrupt, and DMA versions and SPI slave interrupt and master DMA in various combos depending on need. There are no interdependencies. I’ve never used MCC but based on the awful MCC code others have posted I would be surprised if MCC isn’t the culprit.
    #2
    ric
    Super Member
    • Total Posts : 30239
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/02 18:33:08 (permalink)
    +1 (1)
    Can we see your bit bang code?
    I'm suspecting there might be some read-modify-write type code in there corrupting the CS pin used by SPI.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    Doubletop
    Starting Member
    • Total Posts : 46
    • Reward points : 0
    • Joined: 2019/03/07 21:46:09
    • Location: New Zealand
    • Status: offline
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/02 22:25:19 (permalink)
    0
    ric
    Can we see your bit bang code?
    I'm suspecting there might be some read-modify-write type code in there corrupting the CS pin used by SPI.
     


    Ric
    The I2C bitbang code can be found here. I had been sucessfully using it alongside the MCC generated SPI code, which worked.
    https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en560799
     
    However, I have replaced it with the MCC generated I2C code on the same pins (RC0,RC1). I doing that the SPI code failed to work and nothing I've tried to get it going again seems to work.
     
    Pete
     
    #4
    ric
    Super Member
    • Total Posts : 30239
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/02 22:32:44 (permalink)
    +1 (1)
    That is not the actual code you are running in your device, you must have edited it to suit your PIC18F27K42 PIC.
    In particular, it was originally written for PIC12F and PIC16F devices without LAT registers, so it is doing writes to PORTx rather than LATx registers. That is a sure way to trigger read-modify-write problems.
    That is why I want to see the ACTUAL code you are using, not what it was based on.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #5
    ric
    Super Member
    • Total Posts : 30239
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/02 22:45:04 (permalink)
    0
    Sorry, scrub that.
    I thought you were still using the bit bang code. You're lucky it did work ok without RMW interfering.
    I now see you are having the problem with MCC versions of both I2C and SPI. Can't help with that, MCC is a mysterious black box to me, which I've left well alone. It appears to be over-engineered for simple peripherals like I2C and SPI.
     
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    Doubletop
    Starting Member
    • Total Posts : 46
    • Reward points : 0
    • Joined: 2019/03/07 21:46:09
    • Location: New Zealand
    • Status: offline
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/02 22:49:53 (permalink)
    0
    mbrowning
    No. I use both I2C in state Mach, interrupt, and DMA versions and SPI slave interrupt and master DMA in various combos depending on need. There are no interdependencies. I’ve never used MCC but based on the awful MCC code others have posted I would be surprised if MCC isn’t the culprit.



    I agree with you the SPI code from the MCC is a bit of a convaluted mess. This exercise was an attempt to tidy things up and consolidate the mish mash of code that has evolved over time. The various SPI and SD interfaces that seem to repeat each other and depending how the functions are called decides which gets used (SPI_, SPI1_, or spi_). Likewise the bitbang code had seperate interface modules for each device. After you pointed out I2C example code I now have one I2C module.
     
    As you have confirmed that there aren't any chip issues using I2C1 and SPI1 side by side would it be possible to get an example of the pin_manager and SPI config parameters you have used successfully? No interrupts are neccesary
     
    The SPI for an SD card. But an exampleof what works for you would be apprecited.  Hopefully it will highlight something I've missed. The pins I'm using
     
    RC0 - I2C1 SCL
    RC1 - I2C1 SDA
    RC2 - SPI1 SS
    RC3 - SPI1 CLK
    RC4 - SPI1 SDO
    RC5 - SPI1 SDI
     
    Pete
    #7
    Mysil
    Super Member
    • Total Posts : 4130
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/03 11:16:44 (permalink)
    0
    Hi,
    I am trying to reproduce your setup, partly because I have some code running on various other devices,
    that I want to port to PIC18F46K42.  But it is taking some time.
     
    There may be some discrepancy between what you say, and what MCC do!
    In message #7:  RC5 is SPI1 SDI,
    but code in message #1:  RC5PPS = 0x1F; //RC5->SPI1:SDO1; /* SPI1:SDO1 -> RC5  which is MCC default. */
    0x1F is SDO signal
     
    Similarly in message #7:  RC4 - SPI1 SDO1
    but code in message #1:  SPI1SDIPPS = 0x14; // RC4 -> SPI1:SDI1;
    0x14 is RC4 input.   /* This is same as hardware default. */
     
        Mysil
    post edited by Mysil - 2021/01/03 11:19:28
    #8
    mbrowning
    USNA79
    • Total Posts : 1887
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/03 13:27:22 (permalink)
    0
    Probably not much use to you, but here's a portion of my code from one project using LF57K42 that uses SCL1/SDA1=RB1/RB2, SCL2/SDA2=RD0/RD1 (non-blocking state machines) and SPI1 with DMA as MDIO interface to an ethernet PHY (SCLK=RC2, SDO/SDI=RC3).
    void init_gpio (void) {
    // Port B init=>PGD(modprs1),PGC(modprs2),ANB5,ANB4,LPBK_IO1, SDA1, SCL1, RSTB_3316
        LATB    = 0b00000111;
        TRISB   = 0b11110000;
        ANSELB  = 0b00110000;
        ODCONB  = 0b00000111;
        RB1I2C  = 0x00;            // default setting for I2C1
        RB2I2C  = 0x00;            // default setting for I2C1

    // Port C init=>LED, RSTn_IO, LTXD, LRXD, MDIO, MDC, EN_SMB, PIC_10M  (MDC,MDIO = SPI1 SCLK,SDO/SDI)
        LATC    = 0b00000000;
        TRISC   = 0b00100001;
        ANSELC  = 0b00000000;
        ODCONC  = 0b00001000;     // SDO open drain as MDIO
        INLVLC  = 0b00000000;     // ensure MDIO has TTL theshold (1.6V)
        SLRCONC = 0b11110011;     // MDC, MDIO slew rate set high

    // Port D init=>CFG_3316, STAT1_3316, STAT0_3316, EN_MGTHLPBK, AND3,AND2,SDA2,SCL2
        LATD    = 0b10000011;
        TRISD   = 0b01101100;
        ANSELD  = 0b00001100;
        WPUD    = 0b00001000;
        ODCOND  = 0b10000011;
        RD0I2C  = 0x00;           // default setting for I2C2
        RD1I2C  = 0x00;           // default setting for I2C2
    }
    void init_pps (void) {
    // unlock PPS
        . . .
    // I2C1
        RB1PPS        = 0x21;                //RB1->I2C1:SCL1;
        I2C1SCLPPS    = 0x09;                //RB1->I2C1:SCL1;
        RB2PPS        = 0x22;                //RB2->I2C1:SDA1;
        I2C1SDAPPS    = 0x0a;                //RB2->I2C1:SDA1;
    // I2C2
        RD0PPS        = 0x23;                //RD0->I2C2:SCL2;
        I2C2SCLPPS    = 0x18;                //RD0->I2C2:SCL2;
        RD1PPS        = 0x24;                //RD1->I2C2:SDA2;
        I2C2SDAPPS    = 0x19;                //RD1->I2C2:SDA2;
    // SPI1
        SPI1SDIPPS    = 0x13;                //RC3->SPI1:SDI1
        RC3PPS        = 0x1f;                //RC3->SPI1:SDO1;    SDI and SDO on same pin
        RC2PPS        = 0x1e;                //RC2->SPI1:SCK1
    // relock PPS
        . . . .
    }       
    // init for SPI/DMA operation
    void mdio_init_spidma (void) {
    // init SPI1 for mdio interface
        SPI1CLK     = 0x00;  // SPI Clock Source Fosc (64MHz)
        SPI1BAUD    = 31;    // SPI Clock = 64MHz / (2*(BAUD+1)) = 1MHz;
        SPI1TWIDTH  = 0x00;  // 8b wide

        SPI1CON1    = 0b11000000;    // SMP=1, CKE=1, CKP=0, FST=0, SS/SDI/SDO act hi
        SPI1CON2    = 0x03;  // SS don't care, TXR=1, RXR=1 (legacy mode)
        SPI1CON0    = 0x83;  // En SPI1, MSB, Master, BMODE=1
    // SPI1 init done

    // DMA init
        // Lock priority to grant memory access
        // Use default priority level
         . . .
    // transmit DMA source
        DMA1SSA = (uint24_t) mdio_tbfr;    // set source start address
        DMA1CON1bits.SMR    = 0;    // SFR/GPR space as source memory
        DMA1CON1bits.SMODE  = 1;    // Increment source address each transaction
        DMA1SSZ             = 8;    // source size 8 bytes
        DMA1CON1bits.SSTP   = 1;    // SIRQEN cleared after sending 8 bytes
    // transmit DMA dest    
        DMA1DSA = (uint16_t) &SPI1TXB;    // destination start address to SPI1TXB
        DMA1CON1bits.DMODE  = 0;    // destination address fixed
        DMA1DSZ             = 1;    // destination size 1 byte
        DMA1CON1bits.DSTP   = 0;    // No destination reload stop bit
        DMA1SIRQ            = 21;   // SPI1TX as Transfer Trigger Source

    // receive DMA source
        DMA2SSA = (uint16_t) &SPI1RXB;    // set source start address to RXB
        DMA2CON1bits.SMR    = 0;    // SFR/GPR space as source memory
        DMA2CON1bits.SMODE  = 0;    // source address fixed
        DMA2SSZ             = 1;    // source size 1 byte
        DMA2CON1bits.SSTP   = 0;    // No source reload stop bit
    // received DMA dest
        DMA2DSA = (uint24_t) mdio_rbfr;    // set dest start address
        DMA2CON1bits.DMODE  = 1;    // destination address increment
        DMA2DSZ             = 8;    // destination size 8 byte
        DMA2CON1bits.DSTP   = 1;    // SIRQEN cleared after rcving 8 bytes
        DMA2SIRQ            = 20;   // SPI1RX as Transfer Trigger Source

        DMA1CON0bits.DMA1EN = 1;
        DMA2CON0bits.DMA2EN = 1;
    }

    In an earlier version of this code I set RxxI2C = 0x41 for "I2C specific slew" and "thresholds", but I found that above 320KHz, I2C1 went crazy and continuously transmitted the same few bits. I submitted a support ticket and Microchip was able to duplicate my finding. I found that if both RB1I2C and RB2I2C had the "SLEW" bit set, this happened. Any other settings and I2C1 worked fine up to at least 500KHz.
     
    #9
    Doubletop
    Starting Member
    • Total Posts : 46
    • Reward points : 0
    • Joined: 2019/03/07 21:46:09
    • Location: New Zealand
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/03 23:04:50 (permalink)
    +1 (1)
    [SOLVED]
    I believe I've found the problem. Rather than chase the problem with SPI not working I realised that I just needed to  comment out all the I2C changes, confirm that SPI still worked and then progressively uncomment the I2C code until SPI stopped again. Everything worked fine until the FATFS request for date/time which called for the RTC (on I2C) to provide the data, which was actually a redundant call anyway. Removing the call had the SPI and I2C behaving....
     
    ... that was until the system got overloaded and the bloated I2C code from the MCC caused everthing to lock up.
     
    Next thing is to find a lightweight I2C library that uses the PIC I2C hardware rather than bitbang the ports.
     
    Pete
    post edited by Doubletop - 2021/01/03 23:08:41
    #10
    NKurzman
    A Guy on the Net
    • Total Posts : 19189
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 00:04:53 (permalink)
    +1 (1)
    The I2C Peripheral is not that complicated.
    You probably can find some code in the data sheets or older app notes.
    One thing to make sure you do is to create a time out when you’re waiting for operations to finish. Otherwise a locked up bus can lock up your chip. After you have it working the only thing you may want to add is a way to deal with locked up for peripherals
    The SPI master is even easier to code.
    #11
    Doubletop
    Starting Member
    • Total Posts : 46
    • Reward points : 0
    • Joined: 2019/03/07 21:46:09
    • Location: New Zealand
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 00:15:39 (permalink)
    0
    NKurzman
    The I2C Peripheral is not that complicated.
    You probably can find some code in the data sheets or older app notes.
    One thing to make sure you do is to create a time out when you’re waiting for operations to finish. Otherwise a locked up bus can lock up your chip. After you have it working the only thing you may want to add is a way to deal with locked up for peripherals
    The SPI master is even easier to code.



    Thanks, To be frank I'm just being lazy rather than knuckling down and doing it. However, just prior to your post, I had picked up the data sheet ready to make a start. As you say it can't be hard, the bitbang version was quite simple and when using the chip it does the hard stuff.
     
    The SPI code from the MCC is OK and I've been using it with FATFS for some time now.
     
    Pete
    #12
    Mysil
    Super Member
    • Total Posts : 4130
    • Reward points : 0
    • Joined: 2012/07/01 04:19:50
    • Location: Norway
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 10:14:32 (permalink)
    +1 (1)
    Hi,
    This thread is about PIC18___K42 that have the new I2C peripheral,
    that so far is used only in _K42, _K83, and _Q43  family devices.
    I2C hardware in these devices is very different from MSSP peripheral used in all earlier 8-bit PIC microcontrollers.
     
    The I2C hardware in these chips seem to be designed with Interrupt and DMA in mind,
    and is rather awkward to use for non-interrupt, byte by byte transfer.
     
    There are not many alternative code examples around for this device, anything written for MSSP peripheral,
    or using PLIB primitives is completely unsuitable.
    Code provided with older app notes will completely miss the target.
     
    Of code examples, I know about MPLAB Xpress Demo code by Chris Best:
    https://mplabxpress.microchip.com/mplabcloud/example/details/519 
    Code is strongly related to code generated by MCC,
    derived from or used as reference code for MCC code generating scripts.
    There is Application Note TB3191 about master mode:
    https://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en605150 
    and TB2669     about Slave mode:
    https://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en605165
    TB3159 
    https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en594547
     
    Then there is mbrowning that prefer to make code that fit the features of the hardware,
    instead of trying to use a model that was suitable for a previous generation of hardware.
    https://www.microchip.com/forums/FindPost/1127343
     
        Mysil
    #13
    NKurzman
    A Guy on the Net
    • Total Posts : 19189
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 11:13:51 (permalink)
    0
    oh....
    Well Never mind then.
    #14
    Doubletop
    Starting Member
    • Total Posts : 46
    • Reward points : 0
    • Joined: 2019/03/07 21:46:09
    • Location: New Zealand
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 13:01:44 (permalink)
    0
    Mysil
    Hi,
    This thread is about PIC18___K42 that have the new I2C peripheral,
    that so far is used only in _K42, _K83, and _Q43  family devices.
    I2C hardware in these devices is very different from MSSP peripheral used in all earlier 8-bit PIC microcontrollers.
     
    The I2C hardware in these chips seem to be designed with Interrupt and DMA in mind,
    and is rather awkward to use for non-interrupt, byte by byte transfer.
     
    There are not many alternative code examples around for this device, anything written for MSSP peripheral,
    or using PLIB primitives is completely unsuitable.
    Code provided with older app notes will completely miss the target.
     
    Of code examples, I know about MPLAB Xpress Demo code by Chris Best:
    https://mplabxpress.microchip.com/mplabcloud/example/details/519 
    Code is strongly related to code generated by MCC,
    derived from or used as reference code for MCC code generating scripts.
    There is Application Note TB3191 about master mode:
    https://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en605150 
    and TB2669     about Slave mode:
    https://www.microchip.com//wwwAppNotes/AppNotes.aspx?appnote=en605165
    TB3159 
    https://www.microchip.com/wwwAppNotes/AppNotes.aspx?appnote=en594547
     
    Then there is mbrowning that prefer to make code that fit the features of the hardware,
    instead of trying to use a model that was suitable for a previous generation of hardware.
    https://www.microchip.com/forums/FindPost/1127343
     
        Mysil




    Mysil
    Thank you. The reason I'm in this situation is because I had been using an 18F26K80 with a single MSSP that I had used for SPI. This meant I couldn't use the I2C so resorted to bitbang. I was then running out of space and ported to 18F27K42. The time came when I really needed to tidy thing up and dump the bitbang I2C.
     
    Thanks again. this is now my reading for the morning.
     
    Pete
    #15
    mbrowning
    USNA79
    • Total Posts : 1887
    • Reward points : 0
    • Joined: 2005/03/16 14:32:56
    • Location: Melbourne, FL
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 13:08:23 (permalink)
    0
    Mysil
    Then there is mbrowning that prefer to make code that fit the features of the hardware,
    instead of trying to use a model that was suitable for a previous generation of hardware.
    I never used I2C on a PIC before, so I had no preconceptions or old code :)  Obviously a non-universal perspective.
     
    #16
    Jerry Messina
    Super Member
    • Total Posts : 705
    • Reward points : 0
    • Joined: 2003/11/07 12:35:12
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/04 13:31:35 (permalink)
    +1 (1)
    The time came when I really needed to tidy thing up and dump the bitbang I2C

    The old MSSP peripheral was a piece of cake.
     
    By the time you get done jumping through hoops for the I2C peripheral in the K42, you might just want to use that bit-bang code.
     
    #17
    Doubletop
    Starting Member
    • Total Posts : 46
    • Reward points : 0
    • Joined: 2019/03/07 21:46:09
    • Location: New Zealand
    • Status: offline
    Re: [SOLVED] 18F27K42 any conflict between I2C1 and SPI1? 2021/01/07 20:03:32 (permalink)
    0
    Thanks to Mysil pointing me to the appropriate application notes and code example from Chris Best. I've created I2C1_simple_master_interface.c, based on the MCC generated i2c_simple_master.c but with additional bitwise functions so bit can be read and set in 8 bit and 16 bit registers.

    I've used Chris Best's master/slave example and extended the test harness to use the devices I had available - PCF8574 LCD interface, PCF8570 EPROM, DS3231 RTC and MPU6050 gyro/accelerometer

    My system has I2C1 mapped to RC0 and RC1, not the standard RC2, RC3. It just needs some PPS changes to move them back or elsewhere.

    I did find a couple of bugs in the Chris's code, so I may well have intruduced some other myslef :-)

    From the header
    * ***************************************************************************
     *
     * I2C Simple Master Interface (No Multi Master)
     *
     * Only for PIC18___K42 that have the new I2C peripheral, that so far is used only in _K42, _K83, and _Q43  family devices.
     
     * Pete T "Doubletop" Jan 2021
     *
     * Reference Application Notes
     *  TB3191 - Master mode: https://www.microchip.com....aspx?appnote=en605150
      * TB2669 - Slave mode:  https://www.microchip.com....aspx?appnote=en605165
     *
     * Code Based on
     *
     *  i2c1_simple_master.c from MCC
     *
     *  Example 12c1.c provided by Chris Best https://mplabxpress.micro...ud/example/details/519
     *  
     *   bitwise functions from I2Cdev.c device library code for MPU6050 placed under the MIT license
     *   Copyright (c) 2012 Jeff Rowberg
     *   Copyright (c) 2014 Marton Sebok
     *
     * ***************************************************************************

    Functions

    uint8_t  I2C1_Read1ByteRegister(uint8_t address, uint8_t reg);
    uint16_t I2C1_Read2ByteRegister(uint8_t address, uint8_t reg);
    void I2C1_Write1ByteRegister(uint8_t address, uint8_t reg, uint8_t data);
    void I2C1_Write2ByteRegister(uint8_t address, uint8_t reg, uint16_t data);
    void I2C1_WriteNBytesRegister(uint8_t address, uint8_t reg, void* data, uint8_t len);
    void I2C1_WriteNBytes(uint8_t address, uint8_t *data, size_t len);
    void I2C1_ReadNBytes(uint8_t address, uint8_t *data, size_t len);
    void I2C1_ReadDataBlock(uint8_t address, uint8_t reg, uint8_t *data, size_t len);

    void I2C1_ReadBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t *data);
    void I2C1_ReadBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t *data);
    void I2C1_ReadBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data);
    void I2C1_ReadBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t *data);

    void I2C1_WriteBit(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data);
    void I2C1_WriteBitW(uint8_t devAddr, uint8_t regAddr, uint8_t bitNum, uint16_t data);
    void I2C1_WriteBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t data);
    void I2C1_WriteBitsW(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint16_t data);

    void I2C1_Initialize(void);


    post edited by Doubletop - 2021/01/07 20:06:15
    #18
    ishkabum
    Starting Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2020/09/24 07:42:09
    • Location: Washington DC
    • Status: offline
    Re: 18F27K42 any conflict between I2C1 and SPI1? 2021/01/08 07:45:18 (permalink)
    +1 (1)
    ric
    Sorry, scrub that.
    I thought you were still using the bit bang code. You're lucky it did work ok without RMW interfering.
    I now see you are having the problem with MCC versions of both I2C and SPI. Can't help with that, MCC is a mysterious black box to me, which I've left well alone. It appears to be over-engineered for simple peripherals like I2C and SPI.

    You must have seen a million like me on these forums trying to figure out how to use the MCC generated I2C routines.
     
    OP, I spent a good two weeks trying to figure out how to use those routines. Microchip support doesn't know either. I'm not even sure if they actually work or not. All they can do is show me presentations on how I2C works in theory, which I studied at length and I get. I couldn't bitbang it either but I didn't have a logic analyzer, that's where they left it off. Buy this $700 piece of equipment to see what is happening or you're SOL because we don't know what's happening. THANKS. I just switched to UART and thank god it's just pretty easy to use.
     
    Edit: People on this forum have claimed it works and they've used the MCC functions, but last time I ditched the project, this person here reviewed my code and didn't notice anything wrong so I have no idea.
    post edited by ishkabum - 2021/01/08 08:07:24
    #19
    Jump to:
    © 2021 APG vNext Commercial Version 4.5