Skip to content

Commit

Permalink
feat(PeriphDrivers): Add Clock Setter APIs for MAX32690 & MAX78002 Pe…
Browse files Browse the repository at this point in the history
…ripherals, Add Dual Mode TMR Support, Add MAX32690 Clock Calibration API for IPO, Add MAX32690 RISCV Clock Setter, CFS Support Functions (#1108)
  • Loading branch information
Jake-Carter committed Aug 9, 2024
1 parent cac32a7 commit 3f96590
Show file tree
Hide file tree
Showing 26 changed files with 1,037 additions and 320 deletions.
17 changes: 17 additions & 0 deletions Libraries/CMSIS/Device/Maxim/MAX32690/Include/max32690.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ typedef enum {
#define MXC_BASE_WDT1 ((uint32_t)0x40080800UL)
#define MXC_WDT1 ((mxc_wdt_regs_t *)MXC_BASE_WDT1)

#define MXC_WDT_GET_IDX(p) ((p) == MXC_WDT0 ? 0 : (p) == MXC_WDT1 ? 1 : -1)

/******************************************************************************/
/* AES Keys */
#define MXC_BASE_AESKEYS ((uint32_t)0x40005000UL)
Expand Down Expand Up @@ -834,6 +836,21 @@ typedef enum {
#define MXC_USBHS_NUM_DMA 8 /* HW must have at least this many DMA channels */
#define MXC_USBHS_MAX_PACKET 512

/** @brief USB clock source options */
typedef enum {
MXC_USB_CLOCK_SYS_DIV_10 = 0, ///< SYS_CLK divded by 10
MXC_USB_CLOCK_EXTCLK = 1, ///< External clock input
MXC_USB_CLOCK_ERFO = 2 ///< External RF Oscillator input
} _mxc_usb_clock_t;

/**
* @brief USB clock source options macro
* @note (Developers): "mxc_usb_clock_t" should be defined as a macro in the top-level
file here so that the pre-processor can check for its existence when the USB
library is built. The macro should pass through to the actual enum
*/
#define mxc_usb_clock_t _mxc_usb_clock_t

/******************************************************************************/
/* Low Power General control */
#define MXC_BASE_LPGCR ((uint32_t)0x40080000UL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ __weak void PinInit(void)
/* Do nothing */
}

__weak int ClockInit(void)
{
/* Do nothing */
return E_NO_ERROR;
}

/* This function can be implemented by the application to initialize the board */
__weak int Board_Init(void)
{
Expand Down Expand Up @@ -162,6 +168,7 @@ __weak void SystemInit(void)
PalSysInit();

PinInit();
ClockInit();
Board_Init();

__enable_irq();
Expand Down
9 changes: 9 additions & 0 deletions Libraries/CMSIS/Device/Maxim/MAX78002/Include/max78002.h
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,15 @@ typedef enum {
#define MXC_USBHS_NUM_DMA 8 /* HW must have at least this many DMA channels */
#define MXC_USBHS_MAX_PACKET 512

/** @brief USB clock source options */
typedef enum {
MXC_USB_CLOCK_SYS_DIV_10 = 0, ///< SYS_CLK divded by 10
MXC_USB_CLOCK_EXTCLK = 1, ///< External clock input
MXC_USB_CLOCK_ERFO = 2 ///< External RF Oscillator input
} _mxc_usb_clock_t;

#define mxc_usb_clock_t _mxc_usb_clock_t

/******************************************************************************/
/* SDHC */
#define MXC_BASE_SDHC ((uint32_t)0x400B6000UL)
Expand Down
43 changes: 43 additions & 0 deletions Libraries/MAXUSB/include/core/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef LIBRARIES_MAXUSB_INCLUDE_CORE_USB_H_
#define LIBRARIES_MAXUSB_INCLUDE_CORE_USB_H_

#include <stdbool.h>
#include "usb_hwopt.h"
#include "usb_protocol.h"

Expand Down Expand Up @@ -135,6 +136,48 @@ typedef struct {
*/
int MXC_USB_Init(maxusb_cfg_options_t *options);

#ifdef MAX32690
// Clock setter mux APIs are currently only supported on the MAX32690. It does not exist
// on earlier hardware revisions such as the MAX32650

#ifndef mxc_usb_clock_t
#warning "mxc_usb_clock_t" not implemented. See note in usb.h on "MXC_USB_SetClockSource"
typedef enum {
MXC_USB_CLOCK_0 = 0,
MXC_USB_CLOCK_1 = 1,
MXC_USB_CLOCK_2 = 2
} mxc_usb_clock_t;
#endif

/**
* @brief Set the input clock source to the USB peripheral.
*
* @param clock_source Input clock source
* @note (Developers): "mxc_usb_clock_t" should be defined as a macro in the top-level "max32xxx.h" file
* so that the pre-processor can check for its existence. Ex:
*
* #define mxc_usb_clock_t _mxc_usb_clock_t
*
* where "_mxc_usb_clock_t" is the actual "typedef enum".
* See "max32690.h" for reference.
*
* @return This function returns zero (0) for success, non-zero for failure
*
*/
int MXC_USB_SetClockSource(mxc_usb_clock_t clock_source);

/**
* @brief Lock the input clock source to the USB peripheral.
*
* @param lock Whether to lock the clock source. Set to true to lock, false to unlock.
*
* @return This function returns zero (0) for success, non-zero for failure
*
*/
int MXC_USB_LockClockSource(bool lock);

#endif

/**
* @brief Shut down the USB peripheral block
*
Expand Down
40 changes: 40 additions & 0 deletions Libraries/MAXUSB/src/core/musbhsfc/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
#include "usbhs_regs.h"
#include "usb.h"

#ifdef MAX32690
#include "fcr_regs.h"
static bool g_is_clock_locked = false;
#endif

#define USBHS_M31_CLOCK_RECOVERY

typedef enum {
Expand Down Expand Up @@ -173,6 +178,41 @@ int MXC_USB_Init(maxusb_cfg_options_t *options)
return 0;
}

#ifdef MAX32690

int MXC_USB_LockClockSource(bool lock)
{
g_is_clock_locked = lock;
return E_NO_ERROR;
}

int MXC_USB_SetClockSource(mxc_usb_clock_t clock_source)
{
if (g_is_clock_locked) {
return E_BAD_STATE; // Clock source must be unlocked to set it.
}

// The USB peripheral's clock source is set in the FCR register bank.
// The actual clock source selected by each field value may vary between
// microcontrollers, so it is the responsibility of the implementer to define
// mxc_usb_clock_t correctly in the top-level "max32xxx.h" file. The enum values
// should match the field values when type-casted to an unsigned int.
if ((unsigned int)clock_source < 0 || (unsigned int)clock_source >= 3) {
return E_BAD_PARAM;
}

mxc_sys_system_clock_t current_sys_clk = (mxc_sys_system_clock_t)(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_SYSCLK_SEL);
if (current_sys_clk != MXC_SYS_CLOCK_IPO && clock_source == MXC_USB_CLOCK_SYS_DIV_10) {
return E_BAD_STATE; // System clock must be set to the IPO for the USB PHY to use the internal clock
}

MXC_SETFIELD(MXC_FCR->fctrl0, MXC_F_FCR_FCTRL0_USBCLKSEL, ((unsigned int)clock_source) << MXC_F_FCR_FCTRL0_USBCLKSEL_POS);

return E_NO_ERROR;
}

#endif

int MXC_USB_Shutdown(void)
{
/* Disconnect and disable HS, too. */
Expand Down
40 changes: 36 additions & 4 deletions Libraries/PeriphDrivers/Include/MAX32690/adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_ADC_H_

/* **** Includes **** */
#include <stdbool.h>
#include <stdint.h>
#include "adc_regs.h"
#include "mcr_regs.h"
Expand Down Expand Up @@ -98,10 +99,16 @@ typedef enum {
* @brief Clock settings
*/
typedef enum {
MXC_ADC_HCLK = 0, ///< HCLK CLock
MXC_ADC_CLK_ADC0, ///< ADC0 Clock
MXC_ADC_CLK_ADC1, ///< ADC1 Clock
MXC_ADC_CLK_ADC2, ///< ADC2 Clock
MXC_ADC_CLK_SYS_OSC = 0,
MXC_ADC_CLK_EXT = 1,
MXC_ADC_CLK_IBRO = 2,
MXC_ADC_CLK_ERFO = 3,

// Legacy names
MXC_ADC_HCLK = MXC_ADC_CLK_SYS_OSC, ///< HCLK CLock
MXC_ADC_CLK_ADC0 = MXC_ADC_CLK_EXT, ///< ADC0 Clock
MXC_ADC_CLK_ADC1 = MXC_ADC_CLK_IBRO, ///< ADC1 Clock
MXC_ADC_CLK_ADC2 = MXC_ADC_CLK_ERFO, ///< ADC2 Clock
} mxc_adc_clock_t;

/**
Expand Down Expand Up @@ -235,6 +242,31 @@ typedef struct {
*/
int MXC_ADC_Init(mxc_adc_req_t *req);

/**
* @brief Set the input clock source for the ADC peripheral
*
* @param clock_source Input clock source
* @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
*/
int MXC_ADC_SetClockSource(mxc_adc_clock_t clock_source);

/**
* @brief Lock the input clock source for the ADC peripheral. The clock source
* must be unlocked for it to be set.
*
* @param lock Whether to lock the clock source. Set to true to lock, false, to unlock.
* @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
*/
int MXC_ADC_LockClockSource(bool lock);

/**
* @brief Set the clock divider the ADC peripheral's input clock
*
* @param div Clock divider
* @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
*/
int MXC_ADC_SetClockDiv(mxc_adc_clkdiv_t div);

/**
* @brief Shuts down the ADC
*
Expand Down
78 changes: 78 additions & 0 deletions Libraries/PeriphDrivers/Include/MAX32690/mxc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/******************************************************************************
*
* Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
* Analog Devices, Inc.),
* Copyright (C) 2023-2024 Analog Devices, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/

#ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_MXC_H_
#define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_MXC_H_

#ifdef __riscv
// TODO(JC): This is a somewhat ugly hack added to avoid
// implicit function warnings on RISC-V projects
// when LIB_BOARD was added to libs.mk. When the
// RISC-V build system is improved to use libs.mk
// this should be removed.
#ifndef LIB_BOARD
#define LIB_BOARD
#endif
#endif

#include "mxc_device.h"
#include "mxc_delay.h"
#include "mxc_assert.h"
#include "mxc_errors.h"
#include "mxc_lock.h"
#include "mxc_pins.h"
#include "mxc_sys.h"
#include "nvic_table.h"
#ifdef LIB_BOARD
#include "board.h"
#endif

/*
* Peripheral Driver Includes
*/
#include "adc.h"
// #include "aes.h" // TODO(JC): AES drivers not implemented for ME18 (?)
#include "can.h"
#include "crc.h"
#include "ctb.h"
#include "dma.h"
#include "emcc.h"
#include "flc.h"
#include "gpio.h"
#include "hpb.h"
#include "i2c.h"
#include "i2s.h"
#include "icc.h"
#include "lp.h"
#include "lpcmp.h"
#include "owm.h"
#include "pt.h"
#include "rtc.h"
#include "sema.h"
#include "spi.h"
#include "spixf.h"
#include "spixr.h"
#include "tmr.h"
#include "trng.h"
#include "uart.h"
#include "wdt.h"
#include "wut.h"

#endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_MXC_H_
34 changes: 34 additions & 0 deletions Libraries/PeriphDrivers/Include/MAX32690/mxc_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_MXC_SYS_H_
#define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_MXC_SYS_H_

#include <stdbool.h>
#include "mxc_device.h"
#include "lpgcr_regs.h"
#include "gcr_regs.h"
Expand Down Expand Up @@ -203,6 +204,11 @@ typedef enum {
MXC_V_GCR_CLKCTRL_SYSCLK_SEL_EXTCLK /**< Use the external system clock input */
} mxc_sys_system_clock_t;

typedef enum {
MXC_SYS_RISCV_CLOCK_ISO, /**< Select the Internal Secondary Oscillator (ISO) as the RISCV clock source */
MXC_SYS_RISCV_CLOCK_PCLK /**< Select the Advanced Peripheral Bus (APB) clock as the RISCV clock source */
} mxc_sys_riscv_clock_t;

typedef enum {
MXC_SYS_CLOCK_DIV_1 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV1,
MXC_SYS_CLOCK_DIV_2 = MXC_S_GCR_CLKCTRL_SYSCLK_DIV_DIV2,
Expand Down Expand Up @@ -394,6 +400,14 @@ void MXC_SYS_SetClockDiv(mxc_sys_system_clock_div_t div);
*/
mxc_sys_system_clock_div_t MXC_SYS_GetClockDiv(void);

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

/**
* @brief Wait for a clock to enable with timeout
* @param ready The clock to wait for
Expand All @@ -416,6 +430,14 @@ void MXC_SYS_RISCVRun(void);
*/
void MXC_SYS_RISCVShutdown(void);

/**
* @brief Set the clock source for the RISC-V core.
*
* @param clock The clock source to set
* @returns 0 if successful, @ref MXC_Error_Codes on errors
*/
int MXC_SYS_RISCVClockSelect(mxc_sys_riscv_clock_t clock);

/**
* @brief Returns the clock rate (in Hz) of the Risc-V core.
*/
Expand All @@ -429,6 +451,18 @@ uint32_t MXC_SYS_RiscVClockRate(void);
*/
int MXC_SYS_LockDAP_Permanent(void);

/**
* @brief Bypass the crystal oscillator driver circuit for the specified clock. Some clock sources
* support this option, allowing an external square wave input signal to be fed directly to the
* clock's input pin. Refer to the microcontroller's User Guide for more details.
*
* @param clock The clock source target
* @param bypass Bypass the oscillator circuit or not. Set to true to bypass, false to disable the bypass
*
* @return @ref MXC_Error_Codes
*/
int MXC_SYS_SetBypass(mxc_sys_system_clock_t clock, bool bypass);

#ifdef __cplusplus
}
#endif
Expand Down
Loading

0 comments on commit 3f96590

Please sign in to comment.