CMSIS-Driver_PIC32CZ-CA70  
Peripheral Library (PLIB) Documentation
 
Loading...
Searching...
No Matches
SMC Interface

Driver API for SMC (plib_smc.h) More...

Data Structures

struct  SMC_TIMING
 SMC Timing Parameters for one chip select. Field widths match the real SMC_SETUP/PULSE/CYCLE bitfields: setup = 6 bits (0-63), pulse = 7 bits (0-127), cycle = 9 bits (0-511). More...
 
struct  SMC_MODE
 SMC Mode Parameters for one chip select. More...
 
struct  SMC_CHIP_SELECT_CONFIG
 SMC Mode and Timing configuration for one chip select. More...
 

Macros

#define SMC_CHIP_SELECT_MAX   (4U)
 Number of SMC chip selects (0..3).
 
#define SMC_READ_MODE_NCS_CTRL   0U
 SMC Read Mode. No _Val enum exists in the real header for this field (SMC_MODE_READ_MODE is a plain 1-bit field) - values below are defined per datasheet semantics, not derived from a macro.
 
#define SMC_READ_MODE_NRD_CTRL   1U
 
#define SMC_WRITE_MODE_NCS_CTRL   0U
 SMC Write Mode. Same caveat as SMC_READ_MODE_* - no real _Val enum.
 
#define SMC_WRITE_MODE_NWE_CTRL   1U
 
#define SMC_PAGE_MODE_DISABLE   0U
 
#define SMC_PAGE_MODE_ENABLE   1U
 
#define SMC_TDF_MODE_DISABLE   0U
 
#define SMC_TDF_MODE_ENABLE   1U
 

Functions

bool SMC_SetupTiming (uint8_t chip_select, const SMC_TIMING *timing)
 Configures the NRD/NCS_RD/NWE/NCS_WR setup lengths for a chip select (SMC_SETUP register).
 
bool SMC_PulseTiming (uint8_t chip_select, const SMC_TIMING *timing)
 Configures the NRD/NCS_RD/NWE/NCS_WR pulse lengths for a chip select (SMC_PULSE register).
 
bool SMC_CycleTiming (uint8_t chip_select, const SMC_TIMING *timing)
 Configures the NRD/NWE total cycle lengths for a chip select (SMC_CYCLE register).
 
bool SMC_SetMode (uint8_t chip_select, const SMC_MODE *mode)
 Configures the mode parameters for a chip select (SMC_MODE register).
 
bool SMC_SetScramblingKeys (uint32_t key1, uint32_t key2, uint8_t chip_select, bool enable)
 Sets the OCMS scrambling keys and enables/disables scrambling for one chip select. The global SMSE bit is kept consistent: it is set whenever any chip select has scrambling enabled, and cleared when none do.
 
void SMC_EnableWriteProtection (void)
 Enables SMC write protection by writing SMC_WPMR with WPEN set and the correct WPKEY password.
 
void SMC_DisableWriteProtection (void)
 Disables SMC write protection by writing SMC_WPMR with WPEN cleared and the correct WPKEY password.
 
bool SMC_Read (uint8_t chip_select, uint32_t offset, void *buffer, size_t size)
 Reads bytes from external memory on a chip select.
 
bool SMC_Write (uint8_t chip_select, uint32_t offset, const void *buffer, size_t size)
 Writes bytes to external memory on a chip select.
 
bool SMC_ReloadConfig (uint8_t chip_select)
 Triggers a reload of timing/mode configuration for a chip select by re-writing its SMC_MODE register.
 
bool SMC_GetWriteProtectionStatus (uint32_t *source)
 Reads and decodes the SMC_WPSR (Write Protection Status) register.
 
bool SMC_ChipSelectConfigIsValid (uint8_t chip_select, const SMC_CHIP_SELECT_CONFIG *cs_config)
 Returns true if the given chip-select configuration is valid, i.e. no pulse parameter is null, and setup+pulse does not exceed cycle length for both the NRD/NCS-read path and the NWE/NCS-write path.
 
void SMC_Reset (void)
 Resets all SMC chip selects (via SMC_ResetChipSelect()) and clears the OCMS scrambling configuration (SMC_OCMS = 0).
 
bool SMC_ResetChipSelect (uint8_t chip_select)
 Restores SMC_SETUP, SMC_PULSE, SMC_CYCLE, and SMC_MODE for the given chip select to their datasheet-documented hardware reset defaults (Table 33-5, "Reset Values of Timing Parameters"): SMC_SETUP = 0x01010101, SMC_PULSE = 0x01010101, SMC_CYCLE = 0x00030003, and SMC_MODE.READ_MODE = SMC_MODE.WRITE_MODE = 1.
 

Description

Driver API for SMC (plib_smc.h)

Usage Example

The following example demonstrates typical usage of the SMC peripheral:

/*******************************************************************************
* Copyright © 2026 Microchip Technology Inc. and its subsidiaries.
*
* Subject to your compliance with these terms, you may use Microchip software
* and any derivatives exclusively with Microchip products. It is your
* responsibility to comply with third party license terms applicable to your
* use of third party software (including open source software) that may
* accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*******************************************************************************/
/*******************************************************************************
* @file configure_smc.c
*
* @brief SMC Configuration Template
*
* @details Enables the SMC peripheral clock and configures its chip selects by
* calling the plib_smc PLIB APIs. Edit SMC_CONFIGURED_CHIP_SELECT_COUNT
* and the smc_cs<n>_config tables below to match the target design.
*******************************************************************************/
#include "plib_smc.h"
#define SMC_CONFIGURED_CHIP_SELECT_COUNT (1U)
typedef struct
{
uint8_t chip_select_count;
const SMC_CHIP_SELECT_CONFIG *chip_select_config[SMC_CHIP_SELECT_MAX];
} SMC_ConfigSet_t;
static const SMC_CHIP_SELECT_CONFIG smc_cs0_config =
{
.mode =
{
.byte_access_type = 0U,
.read_mode = SMC_READ_MODE_NRD_CTRL,
.write_mode = SMC_WRITE_MODE_NWE_CTRL,
.page_mode_enable = SMC_PAGE_MODE_DISABLE,
.page_size = 0U,
.tdf_cycles = 0U,
.tdf_mode = SMC_TDF_MODE_DISABLE,
.exnw_mode = 0U
},
.timing =
{
.nrd_setup = 1U,
.ncs_rd_setup = 1U,
.nwe_setup = 1U,
.ncs_wr_setup = 1U,
.nrd_pulse = 3U,
.ncs_rd_pulse = 3U,
.nwe_pulse = 3U,
.ncs_wr_pulse = 3U,
.nrd_cycle = 5U,
.nwe_cycle = 5U
}
};
static const SMC_ConfigSet_t smc_config_set =
{
.chip_select_count = SMC_CONFIGURED_CHIP_SELECT_COUNT,
.chip_select_config = { &smc_cs0_config, NULL, NULL, NULL }
};
int32_t configure_smc(void)
{
uint8_t cs;
PMC_REGS->PMC_PCR = PMC_PCR_PID(ID_SMC) | PMC_PCR_CMD_Msk | PMC_PCR_EN_Msk;
for (cs = 0U; cs < smc_config_set.chip_select_count; cs++)
{
const SMC_CHIP_SELECT_CONFIG *cs_config = smc_config_set.chip_select_config[cs];
bool ok;
ok = SMC_SetupTiming(cs, &cs_config->timing);
if (ok)
{
ok = SMC_PulseTiming(cs, &cs_config->timing);
}
if (ok)
{
ok = SMC_CycleTiming(cs, &cs_config->timing);
}
if (ok)
{
ok = SMC_SetMode(cs, &cs_config->mode);
}
if (!ok)
{
return -1;
}
}
return 0;
}
#define SMC_READ_MODE_NRD_CTRL
Definition plib_smc.h:68
#define SMC_TDF_MODE_DISABLE
Definition plib_smc.h:79
bool SMC_SetMode(uint8_t chip_select, const SMC_MODE *mode)
Configures the mode parameters for a chip select (SMC_MODE register).
#define SMC_PAGE_MODE_DISABLE
Definition plib_smc.h:76
#define SMC_WRITE_MODE_NWE_CTRL
Definition plib_smc.h:74
#define SMC_CHIP_SELECT_MAX
Number of SMC chip selects (0..3).
Definition plib_smc.h:60
bool SMC_PulseTiming(uint8_t chip_select, const SMC_TIMING *timing)
Configures the NRD/NCS_RD/NWE/NCS_WR pulse lengths for a chip select (SMC_PULSE register).
bool SMC_SetupTiming(uint8_t chip_select, const SMC_TIMING *timing)
Configures the NRD/NCS_RD/NWE/NCS_WR setup lengths for a chip select (SMC_SETUP register).
bool SMC_CycleTiming(uint8_t chip_select, const SMC_TIMING *timing)
Configures the NRD/NWE total cycle lengths for a chip select (SMC_CYCLE register).
SMC Mode and Timing configuration for one chip select.
Definition plib_smc.h:121
SMC_TIMING timing
Definition plib_smc.h:123
SMC_MODE mode
Definition plib_smc.h:122
uint8_t data_bus_width
Definition plib_smc.h:106

Macro Definition Documentation

◆ SMC_CHIP_SELECT_MAX

#define SMC_CHIP_SELECT_MAX   (4U)

Number of SMC chip selects (0..3).

◆ SMC_PAGE_MODE_DISABLE

#define SMC_PAGE_MODE_DISABLE   0U

◆ SMC_PAGE_MODE_ENABLE

#define SMC_PAGE_MODE_ENABLE   1U

◆ SMC_READ_MODE_NCS_CTRL

#define SMC_READ_MODE_NCS_CTRL   0U

SMC Read Mode. No _Val enum exists in the real header for this field (SMC_MODE_READ_MODE is a plain 1-bit field) - values below are defined per datasheet semantics, not derived from a macro.

◆ SMC_READ_MODE_NRD_CTRL

#define SMC_READ_MODE_NRD_CTRL   1U

◆ SMC_TDF_MODE_DISABLE

#define SMC_TDF_MODE_DISABLE   0U

◆ SMC_TDF_MODE_ENABLE

#define SMC_TDF_MODE_ENABLE   1U

◆ SMC_WRITE_MODE_NCS_CTRL

#define SMC_WRITE_MODE_NCS_CTRL   0U

SMC Write Mode. Same caveat as SMC_READ_MODE_* - no real _Val enum.

◆ SMC_WRITE_MODE_NWE_CTRL

#define SMC_WRITE_MODE_NWE_CTRL   1U

Function Documentation

◆ SMC_ChipSelectConfigIsValid()

bool SMC_ChipSelectConfigIsValid ( uint8_t chip_select,
const SMC_CHIP_SELECT_CONFIG * cs_config )

Returns true if the given chip-select configuration is valid, i.e. no pulse parameter is null, and setup+pulse does not exceed cycle length for both the NRD/NCS-read path and the NWE/NCS-write path.

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]cs_configMode and timing configuration to validate.
Returns
true if cs_config is valid for chip_select; false if chip_select is out of range, cs_config is NULL, any pulse parameter (nrd_pulse/nwe_pulse/ncs_rd_pulse/ncs_wr_pulse) is 0 (forbidden per datasheet 33.9.8 "Usage Restriction"), or any setup+pulse exceeds its corresponding cycle length.

◆ SMC_CycleTiming()

bool SMC_CycleTiming ( uint8_t chip_select,
const SMC_TIMING * timing )

Configures the NRD/NWE total cycle lengths for a chip select (SMC_CYCLE register).

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]timingTiming configuration providing the cycle fields.
Returns
true on success; false if chip_select is out of range or timing is NULL.

◆ SMC_DisableWriteProtection()

void SMC_DisableWriteProtection ( void )

Disables SMC write protection by writing SMC_WPMR with WPEN cleared and the correct WPKEY password.

◆ SMC_EnableWriteProtection()

void SMC_EnableWriteProtection ( void )

Enables SMC write protection by writing SMC_WPMR with WPEN set and the correct WPKEY password.

◆ SMC_GetWriteProtectionStatus()

bool SMC_GetWriteProtectionStatus ( uint32_t * source)

Reads and decodes the SMC_WPSR (Write Protection Status) register.

Parameters
[out]sourceOffset of the register where the violation occurred (SMC_WPSR.WPVSRC). Written only when the return value is true; may be NULL if the caller doesn't need it.
Returns
true if a write-protection violation has occurred since the last read of SMC_WPSR (SMC_WPSR.WPVS); false otherwise.

◆ SMC_PulseTiming()

bool SMC_PulseTiming ( uint8_t chip_select,
const SMC_TIMING * timing )

Configures the NRD/NCS_RD/NWE/NCS_WR pulse lengths for a chip select (SMC_PULSE register).

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]timingTiming configuration providing the pulse fields.
Returns
true on success; false if chip_select is out of range or timing is NULL.

◆ SMC_Read()

bool SMC_Read ( uint8_t chip_select,
uint32_t offset,
void * buffer,
size_t size )

Reads bytes from external memory on a chip select.

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]offsetByte offset within the chip select's address window (bounds-checked against the real 16MB EBI_CSx_SIZE).
[out]bufferDestination buffer for the read bytes.
[in]sizeNumber of bytes to read.
Returns
true on success; false if chip_select is out of range, buffer is NULL, size is 0, or offset+size exceeds the chip select's address window.

◆ SMC_ReloadConfig()

bool SMC_ReloadConfig ( uint8_t chip_select)

Triggers a reload of timing/mode configuration for a chip select by re-writing its SMC_MODE register.

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
Returns
true on success; false if chip_select is out of range.

◆ SMC_Reset()

void SMC_Reset ( void )

Resets all SMC chip selects (via SMC_ResetChipSelect()) and clears the OCMS scrambling configuration (SMC_OCMS = 0).

Note
Restores SMC_SETUP/SMC_PULSE/SMC_CYCLE/SMC_MODE to the hardware reset defaults documented in the datasheet (Table 33-5, "Reset Values of Timing Parameters") for every chip select: SMC_SETUP = 0x01010101, SMC_PULSE = 0x01010101, SMC_CYCLE = 0x00030003, and SMC_MODE.READ_MODE = SMC_MODE.WRITE_MODE = 1.

◆ SMC_ResetChipSelect()

bool SMC_ResetChipSelect ( uint8_t chip_select)

Restores SMC_SETUP, SMC_PULSE, SMC_CYCLE, and SMC_MODE for the given chip select to their datasheet-documented hardware reset defaults (Table 33-5, "Reset Values of Timing Parameters"): SMC_SETUP = 0x01010101, SMC_PULSE = 0x01010101, SMC_CYCLE = 0x00030003, and SMC_MODE.READ_MODE = SMC_MODE.WRITE_MODE = 1.

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
Returns
true on success; false if chip_select is out of range.
Note
A null SMC_PULSE sub-field is a documented hardware usage violation (datasheet sections 33.9.1.5 / 33.9.3.5), which is why this restores 0x01010101 rather than zeroing the register.

◆ SMC_SetMode()

bool SMC_SetMode ( uint8_t chip_select,
const SMC_MODE * mode )

Configures the mode parameters for a chip select (SMC_MODE register).

Note
Per datasheet 33.11.3.1, writing SMC_MODE is what validates/loads the SMC_SETUP/PULSE/CYCLE values for this chip select, even if the mode parameters themselves are unchanged. Call this function last, after SMC_SetupTiming/SMC_PulseTiming/SMC_CycleTiming, to latch any timing changes.
Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]modeMode configuration to apply.
Returns
true on success; false if chip_select is out of range or mode is NULL.

◆ SMC_SetScramblingKeys()

bool SMC_SetScramblingKeys ( uint32_t key1,
uint32_t key2,
uint8_t chip_select,
bool enable )

Sets the OCMS scrambling keys and enables/disables scrambling for one chip select. The global SMSE bit is kept consistent: it is set whenever any chip select has scrambling enabled, and cleared when none do.

Parameters
[in]key1SMC_KEY1 scrambling key. Only written when enable is true.
[in]key2SMC_KEY2 scrambling key. Only written when enable is true.
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]enabletrue to (re)program key1/key2 and enable scrambling on chip_select, false to disable it without touching key1/key2.
Returns
true on success; false if chip_select is out of range.
Note
SMC_KEY1/SMC_KEY2 are write-once after reset per the datasheet (section 33.10); key1/key2 are only written when enable is true so a disable-only call never risks permanently latching in a key.

◆ SMC_SetupTiming()

bool SMC_SetupTiming ( uint8_t chip_select,
const SMC_TIMING * timing )

Configures the NRD/NCS_RD/NWE/NCS_WR setup lengths for a chip select (SMC_SETUP register).

Precondition
The SMC peripheral clock must already be enabled and PIO lines for the SMC must already be muxed to their peripheral function by the application/board (no PIO PLIB exists in this repo yet to do this automatically).
Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]timingTiming configuration providing the setup fields.
Returns
true on success; false if chip_select is out of range or timing is NULL.

◆ SMC_Write()

bool SMC_Write ( uint8_t chip_select,
uint32_t offset,
const void * buffer,
size_t size )

Writes bytes to external memory on a chip select.

Parameters
[in]chip_selectChip select index (0..SMC_CHIP_SELECT_MAX-1).
[in]offsetByte offset within the chip select's address window.
[in]bufferSource buffer of bytes to write.
[in]sizeNumber of bytes to write.
Returns
true on success; false if chip_select is out of range, buffer is NULL, size is 0, or offset+size exceeds the chip select's address window.