4.18.2 NVMCTRL with 16-bit Data Register

Non-Volatile Memory Controller with 16-bit Data Register

4.18.2.1 Introduction

The NVM module provides run-time read and write access to the Program Flash Memory (PFM), which includes the program memory and user ID space. This NVM module features up to 16-bit Data Memory registers.

4.18.2.2 Supported Device Families

PIC16F152xx PIC16(L)F188xx PIC16F171xx PIC16F181xx
PIC16(L)F191xx PIC16F180xx PIC16(L)F184xx PIC16(L)F153xx
PIC16(L)F183xx

4.18.2.3 Required header files:


#include "mcc_generated_files/nvm/nvm.h"

4.18.2.4 How to use the Memory Driver

The Memory driver can be used to access different types of memory. Click the links below to view examples on how to access the Flash and EEPROM memory.

4.18.2.5 Module Documentation

4.18.2.5.1 Non-Volatile Memory

This file contains API prototypes and other data types for the Non-Volatile Memory (NVM) driver.

Module description

This file contains API prototypes and other data types for the Non-Volatile Memory (NVM) driver.

Version: NVM Driver Version 4.0.0
Typedefs
Functions

Definition Documentation

EEPROM_SIZE[1/2]

#define EEPROM_SIZE (256U)

Contains the size of EEPROM in bytes.

EEPROM_SIZE[1/2]

#define EEPROM_SIZE (256U)

Contains the size of EEPROM in bytes.

EEPROM_START_ADDRESS[1/2]

#define EEPROM_START_ADDRESS (0xF000U)

Contains the starting address of EEPROM.

EEPROM_START_ADDRESS[1/2]

#define EEPROM_START_ADDRESS (0xF000U)

Contains the starting address of EEPROM.

PROGMEM_PAGE_SIZE[1/2]

#define PROGMEM_PAGE_SIZE (32U)

Contains the size of a Flash page/row in 14-bit words.

PROGMEM_PAGE_SIZE[1/2]

#define PROGMEM_PAGE_SIZE (32U)

Contains the size of a Flash page/row in 14-bit words.

PROGMEM_SIZE[1/2]

#define PROGMEM_SIZE (0x4000U)

Contains the size of Flash in 14-bit words.

PROGMEM_SIZE[1/2]

#define PROGMEM_SIZE (0x4000U)

Contains the size of Flash in 14-bit words.

UNLOCK_KEY[1/2]

#define UNLOCK_KEY (0xAA55U)

Contains the unlock key required for the NVM operations.

UNLOCK_KEY[1/2]

#define UNLOCK_KEY (0xAA55U)

Contains the unlock key required for the NVM operations.

Typedef Documentation

configuration_address_t[1/2]

typedef uint16_t configuration_address_t

Data type for the Configurations Settings address.

configuration_address_t[1/2]

typedef uint16_t configuration_address_t

Data type for the Configurations Settings address.

configuration_data_t[1/2]

typedef uint16_t configuration_data_t

Data type for the Configurations Settings data.

configuration_data_t[1/2]

typedef uint16_t configuration_data_t

Data type for the Configurations Settings data.

device_id_address_t[1/2]

typedef uint16_t device_id_address_t

Data type for the Device ID address.

device_id_address_t[1/2]

typedef uint16_t device_id_address_t

Data type for the Device ID address.

device_id_data_t[1/2]

typedef uint16_t device_id_data_t

Data type for the Device ID data.

device_id_data_t[1/2]

typedef uint16_t device_id_data_t

Data type for the Device ID data.

eeprom_address_t[1/2]

typedef uint16_t eeprom_address_t

Data type for the EEPROM address.

eeprom_address_t[1/2]

typedef uint16_t eeprom_address_t

Data type for the EEPROM address.

eeprom_data_t[1/2]

typedef uint8_t eeprom_data_t

Data type for the EEPROM data.

eeprom_data_t[1/2]

typedef uint8_t eeprom_data_t

Data type for the EEPROM data.

flash_address_t[1/2]

typedef uint16_t flash_address_t

Data type for the Flash address.

flash_address_t[1/2]

typedef uint16_t flash_address_t

Data type for the Flash address.

flash_data_t[1/2]

typedef uint16_t flash_data_t

Data type for the Flash data.

flash_data_t[1/2]

typedef uint16_t flash_data_t

Data type for the Flash data.

Function Documentation

CONFIGURATION_Read()

configuration_data_t CONFIGURATION_Read (configuration_address_t address)

Reads one Configuration Word.

Parameters:
in address

- Configuration Word address to be read.

Returns:

Configuration Word data.

CONFIGURATION_Write()

void CONFIGURATION_Write (configuration_address_t address, configuration_data_t data)

Writes one Configuration Word. Use the NVM_StatusGet() API to see the result of the write operation.

Precondition:

Set the unlock key using the NVM_UnlockKeySet() API, if the key has been cleared before.

Parameters:
in address

- Configuration Word address to be written.

in data

- Configuration Word to be written.

Returns:

None.

DeviceID_Read()

device_id_data_t DeviceID_Read (device_id_address_t address)

Reads the Device ID.

Parameters:
in address

- Starting address of the Device ID.

Returns:

Device ID.

EEPROM_Read()

eeprom_data_t EEPROM_Read (eeprom_address_t address)

Reads one byte from the given EEPROM address.

Parameters:
in address

- Address of the EEPROM location to be read.

Returns:

Byte read from the given EEPROM address.

EEPROM_Write()

void EEPROM_Write (eeprom_address_t address, eeprom_data_t data)

Writes one byte to the given EEPROM address. Use the NVM_StatusGet() API to see the result of the write operation.

Precondition:

Set the unlock key using the NVM_UnlockKeySet() API, if the key has been cleared before.

Parameters:
in address

- Address of the EEPROM location to be written.

in data

- Byte to be written to the given EEPROM location.

Returns:

None.

FLASH_PageAddressGet()

flash_address_t FLASH_PageAddressGet (flash_address_t address)

Returns the starting address of the page/row (the first word location) containing the given Flash address.

Parameters:
in address

- Flash address for which the page starting address will be obtained.

Returns:

Starting address of the page containing the given Flash address.

FLASH_PageErase()

nvm_status_t FLASH_PageErase (flash_address_t address)

Erases one Flash page/row containing the given address.

Precondition:

Set the unlock key using the NVM_UnlockKeySet() API, if the key has been cleared before.

Parameters:
in address

- Any address in the Flash page to be erased.

Returns:

Status of the Flash page erase operation as described in nvm_status_t.

FLASH_PageOffsetGet()

uint16_t FLASH_PageOffsetGet (flash_address_t address)

Returns the offset from the starting address of the page/row (the first word location).

Parameters:
in address

- Flash address for which the offset from the starting address of the page will be obtained.

Returns:

Offset of the given address from the starting address of the page.

FLASH_Read()

flash_data_t FLASH_Read (flash_address_t address)

Reads a 14-bit word from the given Flash address.

Parameters:
in address

- Address of the Flash location from which data is to be read.

Returns:

14-bit word read from the given Flash address.

FLASH_RowWrite()

nvm_status_t FLASH_RowWrite (flash_address_t address, flash_data_t * dataBuffer)

Writes one entire Flash row from the given starting address of the row (the first word location). The size of the input buffer must be one Flash row and the address must be aligned with the row boundary. Use FLASH_PageAddressGet() to obtain the starting address of the row.

Precondition:

Erase Flash row before calling this function. Set the unlock key using the NVM_UnlockKeySet() API, if the key has been cleared before.

Parameters:
in address

- Starting address of the Flash row to be written.

in *data

- Pointer to a buffer which holds the data to be written.

Returns:

Status of the Flash row write operation as described in nvm_status_t.

NVM_CallbackRegister()

void NVM_CallbackRegister (void(*)(void) CallbackHandler)

Setter function for the NVM interrupt callback.

Parameters:
in CallbackHandler

- Pointer to a custom callback.

Returns:

None.

NVM_Initialize()

void NVM_Initialize (void )

Initializes the NVM driver.

Parameters:
None.
Returns:

None.

NVM_InterruptDisable()

void NVM_InterruptDisable (void )[inline]

Disables the NVM interrupt.

Parameters:
None.
Returns:

None.

NVM_InterruptEnable()

void NVM_InterruptEnable (void )[inline]

Enables the NVM interrupt.

Precondition:

Enable the global interrupt.

Parameters:
None.
Returns:

None.

NVM_IsBusy()

bool NVM_IsBusy (void )

Checks if the NVM is busy with the read/write/erase commands.

Parameters:
None.
Return values:
True

- The NVM operation is being performed.

False

- The NVM operation is not being performed.

NVM_ISR()

void NVM_ISR (void )

NVM Interrupt Service Routine (ISR) function.

Parameters:
None.
Returns:

None.

NVM_StatusClear()

void NVM_StatusClear (void )

Clears the NVM error status.

Parameters:
None.
Returns:

None.

NVM_StatusGet()

nvm_status_t NVM_StatusGet (void )

Returns the status of the last NVM operation.

Parameters:
None.
Return values:
NVM_OK

- The NVM operation succeeded.

NVM_ERROR

- The NVM operation failed.

NVM_UnlockKeyClear()

void NVM_UnlockKeyClear (void )

Clears the previously configured unlock keys.

Parameters:
None.
Returns:

None.

NVM_UnlockKeySet()

void NVM_UnlockKeySet (uint16_t unlockKey)

Sets the unlock keys required to perform any erase or write operations on Flash and EEPROM.

Parameters:
in unlockKey

- Unlock key value as specified in the device data sheet.

Returns:

None.

Enumeration Type Documentation

nvm_status_t

enum nvm_status_t

Contains the return codes for the NVM driver APIs.

NVM_OK

0 - The NVM operation succeeded.

NVM_ERROR

1 - The NVM operation failed.

NVM_OK

0 - The NVM operation succeeded.

NVM_ERROR

1 - The NVM operation failed.

4.18.2.5.2 Nvm_example

Flash Examples

This example shows how to overwrite an entire Flash page/row with the new data using the row write feature:
#include "../mcc_generated_files/system/system.h"

#define FLASH_ADDRESS (PROGMEM_SIZE - 5) //Flash address at which data to is be written

void FLASH_Example_PageErase_RowWrite_Read(void)
{
    flash_address_t flashStartPageAddress;
    uint16_t index;
    flash_data_t flashWriteData[PROGMEM_PAGE_SIZE];
    nvm_status_t errorStatus = NVM_OK;
    bool readError = false;

    //Get the starting address of the page containing the given address
    flashStartPageAddress = FLASH_PageAddressGet(FLASH_ADDRESS);
  
    //Erase entire page
    NVM_UnlockKeySet(UNLOCK_KEY);     
    errorStatus = FLASH_PageErase(flashStartPageAddress);
    NVM_UnlockKeyClear();
    if (errorStatus == NVM_OK)
    {
        printf("FLASH_PageErase passed \r\n");
    }
    else
    {
        printf("FLASH_PageErase failed \r\n");
        NVM_StatusClear();
    }

    //Prepare row data
    for (index = 0; index < PROGMEM_PAGE_SIZE; index++)
    {
        flashWriteData[index] = (flash_data_t) index;
    }

    //Write data to Flash row   
    NVM_UnlockKeySet(UNLOCK_KEY); 
    errorStatus = FLASH_RowWrite(flashStartPageAddress, flashWriteData);
    NVM_UnlockKeyClear();
    if (errorStatus == NVM_OK)
    {
        printf("FLASH_RowWrite passed \r\n");
    }
    else
    {
        printf("FLASH_RowWrite failed \r\n");
        NVM_StatusClear();
    }

    //Read and verify row data
    for (index = 0; index < PROGMEM_PAGE_SIZE; index++)
    {
        if (FLASH_Read(flashStartPageAddress + index) != flashWriteData[index])
        {
            readError = true;
            break;
        }
    }

    if (readError == false)
    {
        printf("FLASH_Read passed \r\n");
    }
    else
    {
        printf("FLASH_Read failed \r\n");
    }
}
This example shows how to update the specific locations in a given Flash page/row without disturbing the other locations:
#include "../mcc_generated_files/system/system.h"

#define FLASH_ADDRESS (PROGMEM_SIZE - 5) //Flash address at which data is to be written

void FLASH_Example_UpdateSelectiveLocations(void)
{
    flash_address_t flashStartPageAddress;
    uint16_t flashAddressOffset;
    nvm_status_t errorStatus = NVM_OK;
    bool readError = false;    
    flash_data_t flashWriteData[PROGMEM_PAGE_SIZE];

    //Get the starting address of the page containing the given address
    flashStartPageAddress = FLASH_PageAddressGet(FLASH_ADDRESS);

    //Read entire row in buffer RAM
    for (flashAddressOffset = 0; flashAddressOffset < PROGMEM_PAGE_SIZE; flashAddressOffset++)
    {
        flashWriteData[flashAddressOffset] = FLASH_Read(flashStartPageAddress + flashAddressOffset);
    }

    //Get offset from the starting address of the page
    flashAddressOffset = FLASH_PageOffsetGet(FLASH_ADDRESS);

    //Update 4 words 
    flashWriteData[flashAddressOffset] = 0x0A;
    flashWriteData[flashAddressOffset + 1] = 0x1A;
    flashWriteData[flashAddressOffset + 2] = 0x2A;
    flashWriteData[flashAddressOffset + 3] = 0x3A;

    //Erase entire Flash page   
    NVM_UnlockKeySet(UNLOCK_KEY);   
    errorStatus = FLASH_PageErase(flashStartPageAddress);
    NVM_UnlockKeyClear();
    if (errorStatus == NVM_OK)
    {
        printf("FLASH_PageErase passed \r\n");
    }
    else
    {
        printf("FLASH_PageErase failed \r\n");
        NVM_StatusClear();
    }

    //Write data to Flash row   
    NVM_UnlockKeySet(UNLOCK_KEY);
    errorStatus = FLASH_RowWrite(flashStartPageAddress, flashWriteData);
    NVM_UnlockKeyClear();
    if (errorStatus == NVM_OK)
    {
        printf("FLASH_RowWrite passed \r\n");
    }
    else
    {
        printf("FLASH_RowWrite failed \r\n");
        NVM_StatusClear();
    }

    //Read and verify row data
    for (flashAddressOffset = 0; flashAddressOffset < PROGMEM_PAGE_SIZE; flashAddressOffset++)
    {
        if (FLASH_Read(flashStartPageAddress + flashAddressOffset) != flashWriteData[flashAddressOffset])
        {
            readError = true;
            break;
        }
    }

    if (readError == false)
    {
        printf("FLASH_Read passed \r\n");
    }
    else
    {
        printf("FLASH_Read failed \r\n");
    }
}

EEPROM Examples

This example shows how to perform the write and read operations on EEPROM:
#include "../mcc_generated_files/system/system.h"

#define EEPROM_ADDRESS (EEPROM_START_ADDRESS) //EEPROM address at which data is to be written

void EEPROM_Write_Read(void)
{
    eeprom_data_t eepromWriteData[8];
    uint8_t count;
    bool readError = false;

    //Prepare data
    for (count = 0; count < 8; count++)
    {
        eepromWriteData[count] = 0xA1 + count;
    }

    for (count = 0; count < 8; count++)
    {
        //Write EEPROM byte    
        NVM_UnlockKeySet(UNLOCK_KEY); 
        EEPROM_Write(EEPROM_ADDRESS + count, eepromWriteData[count]);
        NVM_UnlockKeyClear();
        if (NVM_StatusGet() == NVM_OK)
        {
            printf("EEPROM_Write passed \r\n");
        }
        else
        {
            printf("EEPROM_Write failed \r\n");
            NVM_StatusClear();
        }
    }

    //Read and verify
    for (count = 0; count < 8; count++)
    {
        if (EEPROM_Read(EEPROM_ADDRESS + count) != eepromWriteData[count])
        {
            readError = true;
            break;
        }
    }

    if (readError == false)
    {
        printf("EEPROM_Read passed \r\n");
    }
    else
    {
        printf("EEPROM_Read failed \r\n");
    }
}
Exceptions:
1.

This example is not applicable for the PIC16F152xx family of devices, as it does not have EEPROM.

Device ID Examples

This example shows how to read the Device ID:
#include "mcc_generated_files/system/system.h"

#define DEVICE_ID_ADDRESS (0x8006U) //Compare with the device data sheet to see if the address is correct

void NVM_Example_DeviceID_Read(void)
{
    printf("Device ID : 0x%X \r\n", DeviceID_Read(DEVICE_ID_ADDRESS));
}

Configuration Settings Examples

This example shows how to update the specific Configuration setting without disturbing the other settings:
#include "mcc_generated_files/system/system.h"

#define CONFIG_TO_BE_UPDATED_ADDRESS (0x8007U) //CONFIG1 address (Compare with the device data sheet to see if the address is correct)

#if defined(_16F152XX_FAMILY_) //Define _16F152XX_FAMILY_ macro for all the PIC16F152xx family of devices 
    #define _CONFIG1_FEXTOSC_MASK (0b11)
#else
    #define _CONFIG1_FEXTOSC_MASK (0b111)
#endif

void NVM_Example_Configuration_UpdateSpecifcSetting(void)
{
    configuration_address_t configurationToBeUpdatedAddress = CONFIG_TO_BE_UPDATED_ADDRESS;   
    configuration_data_t configurationValueToBeUpdated;
        
    //Read
    configurationValueToBeUpdated = CONFIGURATION_Read(configurationToBeUpdatedAddress);
    
    //Modify
    configurationValueToBeUpdated &= (~((configuration_data_t)_CONFIG1_FEXTOSC_MASK)); //Clear External Oscillator Mode Selection bits
    
    //Write
    NVM_UnlockKeySet(UNLOCK_KEY);
    CONFIGURATION_Write(configurationToBeUpdatedAddress, configurationValueToBeUpdated);
    NVM_UnlockKeyClear();   
    if (NVM_StatusGet() == NVM_OK)
    {
        printf("CONFIGURATION_Write passed \r\n");
    }
    else
    {
        printf("CONFIGURATION_Write failed \r\n");
        NVM_StatusClear();
    }
    
    //Read again to verify
    if(configurationValueToBeUpdated == CONFIGURATION_Read(configurationToBeUpdatedAddress))
    {
        printf("CONFIGURATION_Read passed \r\n");
    }
    else
    {
        printf("CONFIGURATION_Read failed \r\n");
    }
}
Exceptions:
1.

This example is not applicable for the PIC16(L)F188xx family of devices, as the run-time write of Configuration settings is not supported in that case.

4.18.2.6 File Documentation

4.18.2.6.1 source/nvm_example.dox File Reference

4.18.2.6.2 source/nvm_interrupt.c File Reference

#include "../nvm.h"

Functions

Variable Documentation

NVM_Callback

void(* NVM_Callback) (void) = NULL[static]

unlockKeyHigh

volatile uint8_t unlockKeyHigh[static]

unlockKeyLow

volatile uint8_t unlockKeyLow[static]

4.18.2.6.3 source/nvm_interrupt.h File Reference

#include <xc.h>
#include <stdbool.h>

Functions

Typedefs

4.18.2.6.4 source/nvm_polling.c File Reference

#include "../nvm.h"

Functions

Variable Documentation

unlockKeyHigh

volatile uint8_t unlockKeyHigh[static]

unlockKeyLow

volatile uint8_t unlockKeyLow[static]

4.18.2.6.5 source/nvm_polling.h File Reference

#include <xc.h>
#include <stdbool.h>

Functions

Typedefs

Enumeration Type Documentation

nvm_status_t

enum nvm_status_t

NVM_OK

0 - The NVM operation succeeded.

NVM_ERROR

1 - The NVM operation failed.

NVM_OK

0 - The NVM operation succeeded.

NVM_ERROR

1 - The NVM operation failed.