• AVR Freaks

Hot!Strange undocumented behavior of PIC32MM MCCP/SCCP modules.

Author
willyvmm
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2019/12/12 12:59:49
  • Location: 0
  • Status: offline
2021/01/29 03:22:21 (permalink)
0

Strange undocumented behavior of PIC32MM MCCP/SCCP modules.

Hi.
 
I'm using PIC32MM0064GPM0028 in uqfn28 housing.
 
So ...
SCCP/MCCP moduels stop working when high state asserted on pin 15.
The pin is: TMS/REFCLKI/RP14/SDA1/T1CK/T1G/T2CK/T2G/U1RTS/U1BCLK/SDO1/OCM1B/INT2/RB9(1) (high drive strength pin, 5v tolerant)
 
I'm not able to tell what exactly causes that, all modules are disabled, or just clock is gated out. The SCCP/MCCP registers are not visible in debugger (!!!) 
 
I did try several different configurations, the xCCP module is activated by falling edge interrupt event on this pin. That works fine. But when later high state is asserted, the module stops. I did try dedicated interrupt(int2) and remmapable(int4).
Checked with dedicated MCCP1 and MCCP2  module as well as remapable SCCP7 and SCCP9. Every time the same behavior.
Falling edge initiates xCCP module via interrupt event and fire the interrupt, but when the high state is asserted all activity in ALL xCCP modules stop immediately. No compare event action, no compare event interrupt.  Seems like module clock stop.
If more than one xCCP module is active, same happen on all modules. 
 
Prescaller is 1:1 - as suggested in errata. Clock is system clock 24MHz. 
 
Did i miss something in the manual?? I went through whole manual several times, and can't see anything that could lead to any idea. 
I have checked the errata, silicon rev is A2 - and ... also nothing. (Except not working prescaller)
 
I spend too many hours trying to trace down this issue and have no more ideas. Hope it's my mistake not a silicone bug.

Any idea will be appreciated.
 
Best Regards
willy.
#1

5 Replies Related Threads

    ric
    Super Member
    • Total Posts : 30239
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: Strange undocumented behavior of PIC32MM MCCP/SCCP modules. 2021/01/29 04:01:18 (permalink)
    2 (1)
    Is JTAG disabled in your config settings?
     

    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!
    #2
    willyvmm
    New Member
    • Total Posts : 7
    • Reward points : 0
    • Joined: 2019/12/12 12:59:49
    • Location: 0
    • Status: offline
    Re: Strange undocumented behavior of PIC32MM MCCP/SCCP modules. 2021/01/29 10:19:22 (permalink)
    0
    Hi ric
     
    Yes.
    JTAG is disabled.
     
    #pragma config JTAGEN = OFF

     
    #3
    RISC
    Super Member
    • Total Posts : 6063
    • Reward points : 0
    • Status: offline
    Re: Strange undocumented behavior of PIC32MM MCCP/SCCP modules. 2021/01/29 15:04:12 (permalink)
    4 (1)
    Hi,
    Which MPLAB X version are you using ?
    Regards
     

    For support make sure to check first here : http://microchipdeveloper.com
    There are hundreds of PIC, AVR, SAM...which one do YOU use ?
    #4
    NorthGuy
    Super Member
    • Total Posts : 6589
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Strange undocumented behavior of PIC32MM MCCP/SCCP modules. 2021/01/29 15:36:17 (permalink)
    0
    I would suspect your code doing something in response to the rising edge or otherwise, for example writing 0xffff to the PMD3 register.
    #5
    willyvmm
    New Member
    • Total Posts : 7
    • Reward points : 0
    • Joined: 2019/12/12 12:59:49
    • Location: 0
    • Status: offline
    Re: Strange undocumented behavior of PIC32MM MCCP/SCCP modules. 2021/01/30 03:51:48 (permalink)
    0
    MPLAB X 5.30
    XC32 2.41
    DFP 1.2.31
     
    Here is an essential part of my code, used to trace this issue:
     
    #include <xc.h>
    #include <sys/attribs.h>

    /** CONFIGURATION Bits **********************************************/
    // PIC32MM0064GPM028 Configuration Bit Settings

    // FDEVOPT
    #pragma config SOSCHP = OFF // Secondary Oscillator High Power Enable bit (SOSC oprerates in high power mode)
    #pragma config ALTI2C = OFF // Alternate I2C1 Pins Location Enable bit (Primary I2C1 pins are used)
    #pragma config FUSBIDIO = ON // USBID pin control (USBID pin is controlled by the port function)
    #pragma config FVBUSIO = ON // VBUS Pin Control (USBID pin is controlled by the port function) !(VBUS pin is controlled by the USB module)
    #pragma config USERID = 0xFFFF // User ID bits (User ID bits)

    // FICD
    #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)

    #ifdef __DEBUG
    #pragma config ICS = PGx3 //PGx3 //NONE // ICE/ICD Communication Channel Selection bits (Communicate on PGEC1/PGED1)
    #else
    #pragma config ICS = NONE //PGx3 //NONE // ICE/ICD Communication Channel Selection bits (Communicate on PGEC1/PGED1)
    #endif

    // FPOR
    #pragma config BOREN = BOR2 // Brown-out Reset Enable bits (Brown-out Reset enabled only while device active and disabled in Sleep; SBOREN bit disabled)
    #pragma config RETVR = ON // Retention Voltage Regulator Enable bit (Retention regulator is enabled and controlled by RETEN bit during sleep)
    #pragma config LPBOREN = ON // Downside Voltage Protection Enable bit (Low power BOR is enabled, when main BOR is disabled)

    // FWDT
    #pragma config SWDTPS = PS1024 // Sleep Mode Watchdog Timer Postscale Selection bits (1:1024 ~= 1 second)
    #pragma config FWDTWINSZ = PS75_0 // Watchdog Timer Window Size bits (Watchdog timer window size is 75%)
    #pragma config WINDIS = OFF // Windowed Watchdog Timer Disable bit (Watchdog timer is in non-window mode)
    #pragma config RWDTPS = PS512 // Run Mode Watchdog Timer Postscale Selection bits (1:512 ~= 500 ms)
    #pragma config RCLKSEL = LPRC // Run Mode Watchdog Timer Clock Source Selection bits (Clock source is LPRC (same as for sleep mode))
    #pragma config FWDTEN = OFF // Watchdog Timer Enable bit (WDT is disabled, can be enabled in software)

    // FOSCSEL
    #pragma config FNOSC = FRCDIV // Oscillator Selection bits (Primary or FRC oscillator with PLL)
    #pragma config PLLSRC = PRI // System PLL Input Clock Selection bit (FRC oscillator is selected as PLL reference input on device reset)
    //#pragma config SOSCEN = ON // Secondary Oscillator Enable bit (Secondary oscillator (SOSC) is enabled)
    #pragma config SOSCEN = OFF // Secondary Oscillator Enable bit (Secondary oscillator (SOSC) is enabled)
    #pragma config IESO = ON // Two Speed Startup Enable bit (Two speed startup is enabled)
    #pragma config POSCMOD = HS // Primary Oscillator Selection bit (HS oscillator mode is selected)
    //#pragma config OSCIOFNC = OFF // System Clock on CLKO Pin Enable bit (OSCO pin operates as a normal I/O)
    #pragma config OSCIOFNC = ON // System Clock on CLKO Pin Enable bit (OSCO pin operates as a normal I/O)
    #pragma config SOSCSEL = ON // Secondary Oscillator External Clock Enable bit (Crystal is used (RA4 and RB4 are controlled by SOSC))
    #pragma config FCKSM = CSECMD // Clock Switching and Fail-Safe Clock Monitor Enable bits (Clock switching is enabled; Fail-safe clock monitor is enabled)

    // FSEC
    #ifdef __DEBUG
    #pragma config CP = OFF // Code Protection Enable bit (Code protection is disabled)
    #else
    #pragma config CP = ON // Code Protection Enable bit (Code protection is disabled)
    #endif



    //generic pin mask, used by all macros
    #define PIN_MASK(...) __PIN_MASK(__VA_ARGS__)
    #define __PIN_MASK(P,N) _PORT##P##_R##P##N##_MASK

    //Set pin as output
    #define SET_PIN_OUT(...) __SET_PIN_OUT(__VA_ARGS__)
    #define __SET_PIN_OUT(P,N) TRIS##P##CLR=PIN_MASK(P,N)

    //set pin as input
    #define SET_PIN_IN(...) __SET_PIN_IN(__VA_ARGS__)
    #define __SET_PIN_IN(P,N) TRIS##P##SET=PIN_MASK(P,N)

    //Set pin output open drain
    #define SET_PIN_OD(...) __SET_PIN_OD(__VA_ARGS__)
    #define __SET_PIN_OD(P,N) ODC##P##SET=PIN_MASK(P,N)

    //set pin pull-up
    #define SET_PIN_PU(...) __SET_PIN_PU(__VA_ARGS__)
    #define __SET_PIN_PU(P,N) CNPU##P##SET=PIN_MASK(P,N)

    #define CLR_PIN_PU(...) __CLR_PIN_PU(__VA_ARGS__)
    #define __CLR_PIN_PU(P,N) CNPU##P##CLR=PIN_MASK(P,N)

    #define SET_PIN_PD(...) __SET_PIN_PD(__VA_ARGS__)
    #define __SET_PIN_PD(P,N) CNPD##P##SET=PIN_MASK(P,N)

    #define CLR_PIN_PD(...) __CLR_PIN_PD(__VA_ARGS__)
    #define __CLR_PIN_PD(P,N) CNPD##P##CLR=PIN_MASK(P,N)

    //Set pin digital
    #define SET_PIN_DIG(...) __SET_PIN_DIG(__VA_ARGS__)
    #define __SET_PIN_DIG(P,N) ANSEL##P##CLR=PIN_MASK(P,N)

    //set pin analog
    #define SET_PIN_ANA(...) __SET_PIN_ANA(__VA_ARGS__)
    #define __SET_PIN_ANA(P,N) ANSEL##P##SET=PIN_MASK(P,N)

    //set output high
    #define SET_PIN(...) __SET_PIN(__VA_ARGS__)
    #define __SET_PIN(P,N) LAT##P##SET=PIN_MASK(P,N)

    //set output low
    #define CLR_PIN(...) __CLR_PIN(__VA_ARGS__)
    #define __CLR_PIN(P,N) LAT##P##CLR=PIN_MASK(P,N)

    //Invert output
    #define INV_PIN(...) __INV_PIN(__VA_ARGS__)
    #define __INV_PIN(P,N) LAT##P##INV=PIN_MASK(P,N)


    //Functions to initialize pins as output and turn off analog functions
    //With Open Drain output
    #define INIT_PIN_OD(__PIN) \
                SET_PIN_OD(__PIN);\
                SET_PIN_DIG(__PIN);\
                SET_PIN_OUT(__PIN);\
                
    //Standard output
    #define INIT_PIN(__PIN) \
                SET_PIN_DIG(__PIN);\
                SET_PIN_OUT(__PIN);\

    // System clock, default 24MHz
    #define SysCLK 24000000

    #define LED_S A,0

    #define LED_E B,8

    #define POT_Y B,9

    #define POT_Y_PU B,0



    static void SYSTEM_SetOscToUSBCompatible(void);

    int main(int argc, char** argv)
    {
        
        INTCONbits.MVEC=1;
        
        SYSTEM_SetOscToUSBCompatible();

        INIT_PIN(LED_S);
        SET_PIN(LED_S);

        INIT_PIN_OD(LED_E);
        SET_PIN(LED_E);
            
        INIT_PIN_OD(POT_Y);
        
        SET_PIN_IN(POT_Y);

        SET_PIN_PU(POT_Y);
          
        INIT_PIN_OD(POT_Y_PU);
        SET_PIN_PU(POT_Y_PU);
        SET_PIN(POT_Y_PU);
        
        //map int 4
        RPINR1bits.INT4R = 0b1110; //POT_Y
        
        //setup timers and interrupts.

        //disable interrupt
        __builtin_disable_interrupts();

        PRISSbits.PRI7SS = 0b0001; //priority 7 uses shadow set 1
        IPC1bits.INT4IP = 0b111; //int4 has a priority 7, no sub-priority.
        IPC22bits.CCP9IP = 0b110; //CCP9 int has a priority of 6, no sub priority

        //############## 1 - pin interrupt on POT_Y falling edge - action
        IEC0bits.INT4IE = 0; //disable interrupt
        INTCONbits.INT4EP = 0b0; //int4 fired at falling edge
        IFS0bits.INT4IF = 0; //clear interrupt flag
        IEC0bits.INT4IE = 1; //enable interrupt


        //CCP9

        IEC2bits.CCP9IE = 0; //disable interrupt
        IFS2bits.CCP9IF = 0; //clear interrupt flag

        CCP9CON1bits.TRIGEN = 0; //
        CCP9CON1bits.SYNC = 0b1101;// int4 0b01011; //int2
        CCP9CON1bits.CLKSEL = 0b000; //SystemClock Tcy
        CCP9CON1bits.TMRPS = 0b00; //prescaller 1
        CCP9CON1bits.T32 = 0; //16 bit
        CCP9CON1bits.CCSEL = 0; //select Output Compare mode
        CCP9CON1bits.MOD = 0b0010; //drives output

        CCP9CON2bits.OCAEN = 0; //no output only interrupt source

        CCP9RA = (SysCLK / 1000000u)*380u; //delay

        CCP9CON1bits.ON = 1; //enable module
        IEC2bits.CCP9IE = 1; //enable interrupt
     

        //enable interrupts
        __builtin_enable_interrupts();



        while (1)
        {
            ;
        }

        return (EXIT_SUCCESS);
    }

    void __ISR(_EXTERNAL_4_VECTOR, IPL7SRS) int2_handler()
    {
        INV_PIN(LED_S);

        //clear int2 interrupt flag
        IFS0CLR = _IFS0_INT4IF_MASK;
                
    }

    void __ISR(_CCP9_VECTOR) ccp9_handler()
    {

        CCP9STATbits.SCEVT = 0; //clear event status bits

        INV_PIN(LED_E);

        //clear ccp9 interrupt flag
        IFS2bits.CCP9IF = 0;
    }

    static void SYSTEM_SetOscToUSBCompatible(void)
    {
        // Configure REFO to request POSC
        REFO1CONbits.ROSEL = 2; // POSC = 2
        REFO1CONbits.OE = 0; // Disable REFO pin output
        REFO1CONbits.ON = 1; // Enable REFO module to begin warming up POSC

        // Wait for POSC to warm up and reach a stable clock amplitude
        // Required delay may vary depending on different application conditions
        // such as voltage, temperature, layout, XT or HS mode and components
        {
            unsigned int start = __builtin_mfc0(_CP0_COUNT, _CP0_COUNT_SELECT);
            while ((__builtin_mfc0(_CP0_COUNT, _CP0_COUNT_SELECT)) - start < (unsigned int) (0.009 * 8000000 / 2)); // Delay ~9ms
        }
        // Unlock OSCCON to clock switch to POSC + PLL
        SYSKEY = 0;
        SYSKEY = 0xAA996655;
        SYSKEY = 0x556699AA;

        // Configure the PLL to run from the POSC (8MHz on Explorer 16/32) and output 24MHz for the CPU + Peripheral Bus (and 48MHz for USB)
        //SPLLCON = 0x02050000; // PLLODIV = /4, PLLMULT = 12x, PLL source = POSC, so: 8MHz FRC * 12x / 4 = 24MHz CPU and peripheral bus frequency.
        SPLLCON = 0x02030000; // PLLODIV = /8, PLLMULT = 12x, PLL source = POSC, so: 8MHz FRC * 12x / 4 = 24MHz CPU and peripheral bus frequency.

        // Switch to POSC = 2 (PLL)
        OSCCONCLR = _OSCCON_NOSC_MASK | _OSCCON_CLKLOCK_MASK | _OSCCON_OSWEN_MASK;
        OSCCONSET = (1 << _OSCCON_NOSC_POSITION) | _OSCCON_OSWEN_MASK;
        while (OSCCONbits.OSWEN); // Wait for switch to complete (OSWEN self clears)

        // REFO module doesn't need to request POSC anymore since CPU is requesting it. However, keeping it enabled can keep the clock warm in sleep mode, so this is commented out.
        //REFO1CONbits.ON = 0; // Enable REFO module to begin warming up POSC
    }

     
    So an external source square wave of period 500us is connected to pin POT_Y (B9, pin 15 it doesn't matter how do I configure this pin).
    The falling edge is firing interrupt 4 (tested also with dedicated int2) and SCCP9 module (tested also with dedicated MCCP1 and SCCP7)
    When the signal goes low, INT4 and SCCP9 start. The low level is present for ca 250us. and then goes high.
    If the time delay is less than the low level time (250us) it works. If the delay is longer than 250us ... it's completely gone.
     
    Best Regards
    Willy
    #6
    Jump to:
    © 2021 APG vNext Commercial Version 4.5