Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Libraries/PeriphDrivers/Include/MAX32657/mxc_pins.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,7 @@ extern const mxc_gpio_cfg_t gpio_cfg_spi_ts0;
extern const mxc_gpio_cfg_t gpio_cfg_spi_ts1;
extern const mxc_gpio_cfg_t gpio_cfg_spi_ts2;

// RTC square wave output
extern const mxc_gpio_cfg_t gpio_cfg_rtcsqw;

#endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32657_MXC_PINS_H_
7 changes: 7 additions & 0 deletions Libraries/PeriphDrivers/Include/MAX32657/mxc_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ void MXC_SYS_StartClockMeasure(mxc_sys_compare_clock_t clock, uint32_t compareCl
*/
uint32_t MXC_SYS_GetClockMeasure(void);

/**
* @brief Calibrate the specified system clock. Check the microcontroller's UG for more details.
* @param clock Clock source to calibrate. Note usually only the IPO supports calibration.
* @returns E_NO_ERROR if everything is successful.
*/
int MXC_SYS_ClockCalibrate(mxc_sys_system_clock_t clock);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion Libraries/PeriphDrivers/Source/RTC/rtc_me30.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ int MXC_RTC_Init(uint32_t sec, uint16_t ssec)

int MXC_RTC_SquareWaveStart(mxc_rtc_freq_sel_t ft)
{
// TODO(RTC): Use MCR registers for GPIO Port 1 configuration.
MXC_GPIO_Config(&gpio_cfg_rtcsqw);

MXC_MCR->outen |= MXC_F_MCR_OUTEN_SQWOUT_EN;

Expand Down
5 changes: 5 additions & 0 deletions Libraries/PeriphDrivers/Source/SYS/pins_me30.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@ const mxc_gpio_cfg_t gpio_cfg_spi_ts1 = { MXC_GPIO0, MXC_GPIO_PIN_7, MXC_GPIO_FU
MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 };
const mxc_gpio_cfg_t gpio_cfg_spi_ts2 = { MXC_GPIO0, MXC_GPIO_PIN_8, MXC_GPIO_FUNC_ALT1,
MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 };

// RTC square wave output
const mxc_gpio_cfg_t gpio_cfg_rtcsqw = { MXC_GPIO0, MXC_GPIO_PIN_13, MXC_GPIO_FUNC_ALT1,
MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0};

40 changes: 40 additions & 0 deletions Libraries/PeriphDrivers/Source/SYS/sys_me30.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,4 +580,44 @@ uint32_t MXC_SYS_ClockMeasure(mxc_sys_compare_clock_t clock, uint32_t compareClo
return MXC_SYS_GetClockMeasure();
}

/* ************************************************************************** */
int MXC_SYS_ClockCalibrate(mxc_sys_system_clock_t clock)
{
static const int CAL_MS = 10;
/* IPO_FREQ / ERTCOCC_FREQ, integer divide, rounded */
static const int AUTOCAL2_DIV = (IPO_FREQ + (ERTCO_FREQ - 1)) / ERTCO_FREQ;
Copy link

@anubiradar-adi anubiradar-adi Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comes out to 1526 if my math is correct, should it not be 3662? Even if 1526 was left shifted it would come out to 3052.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3662 and 3051 are based on different IPO frequencies. There is a typo in the documentation. 1526 = 50 MHz / 32768

image

int err;

/* Only the IPO supports calibration */
if (clock != MXC_SYS_CLOCK_IPO) {
return E_BAD_PARAM;
}

/* Make sure the ERTCO is enabled */
if ((err = MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_ERTCO))) {
return err;
}

/* The following section implements section 4.1.2.1 of the MAX32657 UG */
MXC_FCR->autocal0 &= ~(MXC_F_FCR_AUTOCAL0_EN);
MXC_SETFIELD(MXC_FCR->autocal2, MXC_F_FCR_AUTOCAL2_DIV,
AUTOCAL2_DIV << MXC_F_FCR_AUTOCAL2_DIV_POS);
MXC_SETFIELD(MXC_FCR->autocal2, MXC_F_FCR_AUTOCAL2_RUNTIME,
CAL_MS << MXC_F_FCR_AUTOCAL2_RUNTIME_POS);
MXC_SETFIELD(MXC_FCR->autocal1, MXC_F_FCR_AUTOCAL1_INIT_TRIM,
0x64 << MXC_F_FCR_AUTOCAL1_INIT_TRIM_POS);
MXC_SETFIELD(MXC_FCR->autocal0, MXC_F_FCR_AUTOCAL0_MU, 4 << MXC_F_FCR_AUTOCAL0_MU_POS);
MXC_FCR->autocal0 |= MXC_F_FCR_AUTOCAL0_LOAD_TRIM | MXC_F_FCR_AUTOCAL0_EN |
MXC_F_FCR_AUTOCAL0_RUN;

MXC_Delay(MXC_DELAY_MSEC(CAL_MS));

/* Leaving the calibration hardware running will result in a more accurate frequency on average.
* Trim trim settings will oscillate around the ideal frequency.
*/
MXC_FCR->autocal0 &= ~(MXC_F_FCR_AUTOCAL0_RUN);
Comment on lines +615 to +618
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any scenario where we might want a one-shot calibration and then shutdown the hardware, e.g. for power efficiency? If we want to leave the calibration hardware running, then should at least be documented in the header file for consumers, IMHO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clearing the run bit here makes this a one-shot calibration.


return E_NO_ERROR;
}

/**@} end of mxc_sys */