How do you enable the code protection bit during run time in PIC32MX devices?
Usually, the code protection bit is enabled via configuration bits during startup. However, for some applications, the code protection bit needs to be enabled in the application code during runtime. Refer to the following code using NVM operations:
// Microcontroller: PIC32MX795F512L
// Compiler: XC32 v1.33
// IDE: MPLABX IDE v2.20
//
// NOTES: Test Code showing the Enabling of Code Protection bit ONLY inside the
// main application. Note that once enabled, it can only be disabled via
// bulk erase only.
// Code Tested on: Explorer16 Development Board - Device: PIC32MX795F512L device (100-pin TQFP)
// Date: 10.30.2014 //
// ****************************************************************************
// PIC32MX795F512L Configuration Bit Settings
// DEVCFG3
// USERID = No Setting
#pragma config FSRSSEL = PRIORITY_7 // SRS Select (SRS Priority 7)
#pragma config FMIIEN = ON // Ethernet RMII/MII Enable (MII Enabled)
#pragma config FETHIO = ON // Ethernet I/O Pin Select (Default Ethernet I/O)
#pragma config FUSBIDIO = ON // USB USID Selection (Controlled by the USB Module)
#pragma config FVBUSONIO = ON // USB VBUS ON Selection (Controlled by USB Module)
// DEVCFG2
#pragma config FPLLIDIV = DIV_12 // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_24 // PLL Multiplier (24x Multiplier)
#pragma config UPLLIDIV = DIV_12 // USB PLL Input Divider (12x Divider)
#pragma config UPLLEN = OFF // USB PLL Enable (Disabled and Bypassed)
#pragma config FPLLODIV = DIV_256 // System PLL Output Clock Divider (PLL Divide by 256)
// DEVCFG1
#pragma config FNOSC = FRC // Oscillator Selection Bits (Fast RC Osc (FRC))
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Disabled)
#pragma config IESO = OFF // Internal/External Switch Over (Disabled)
#pragma config POSCMOD = HS // Primary Oscillator Configuration (HS osc mode)
#pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSDCMD // Clock Switch Disable, FSCM Disabled
#pragma config WDTPS = PS8192 // Watchdog Timer Postscaler (1:8192)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config ICESEL = ICS_PGx2 // ICE EMUC2/EMUD2 pins shared with PGC2/PGD2
#pragma config PWP = OFF // Program Flash Write Protect (Disable)
#pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF // Code Protect (Protection Disabled)
#define NVMOP_WORD_PGM 0x4001 // Word program operation
extern unsigned int _NVMOperation(unsigned int nvmop);
int main(void)
{
unsigned int res, delay;
// JTAG port must be disabled.
mJTAGPortEnable(DEBUG_JTAGPORT_OFF);
mPORTASetPinsDigitalOut(BIT_0); //Set RA0 as output
// Set NVMADDR to Address of row to program
NVMADDR = 0x1FC02FFC; //point to DEVCFG0 address
// Load data into NVMDATA register
NVMDATA = 0x6FFFFFFF; //Set CP bit to 0 to enable code protection bit
// Unlock and Write Word
res = _NVMOperation(NVMOP_WORD_PGM);
while (1)
{
LATAINV = 1; //Toggle RA0 to indicate that code is running
delay = 0xffff;
while(delay--);
}
}
From the example code, note that the code protection bit was enabled inside the main application code and not in the configuration bits. Also, note that in order to disable the code protection bit, a bulk erase is required to set the bit to 1.