Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 5 additions & 3 deletions hal/include/hal/lp_ticker_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ void lp_ticker_free(void);
*/
uint32_t lp_ticker_read(void);

/** Set interrupt for specified timestamp
/**
* @brief Set interrupt for specified timestamp
*
* @param timestamp The time in ticks to be set. Guaranteed to be between 0 and 2^bits-1, where bits is
* the number of bits returned by ::lp_ticker_get_info
Expand All @@ -199,6 +200,7 @@ uint32_t lp_ticker_read(void);
* @code
* void lp_ticker_set_interrupt(timestamp_t timestamp)
* {
* lp_ticker_clear_interrupt();
* LPTMR_COMPARE = timestamp;
* LPTMR_CTRL |= LPTMR_CTRL_COMPARE_ENABLE_Msk;
* }
Expand All @@ -222,8 +224,8 @@ void lp_ticker_disable_interrupt(void);
/**
* @brief Clear the low power ticker interrupt.
*
* This is required to be called from the interrupt handler to stop the interrupt handler
* from being executed again after it returns. This does not do anything if called before the interrupt
* This is called from Mbed's interrupt handler and should clear the interrupt flag in the peripheral to stop
* the interrupt from being executed again after it returns. This does not do anything if called before the interrupt
* fires (e.g. it doesn't cancel the interrupt if it's set in the future).
*
* Pseudo Code:
Expand Down
10 changes: 6 additions & 4 deletions hal/include/hal/us_ticker_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ void us_ticker_free(void);
// note: parenthesis around the function name make sure this isn't replaced by the us_ticker_read() macro version.
uint32_t (us_ticker_read)(void);

/** Set interrupt for specified timestamp
/**
* @brief Set interrupt to fire at specified timestamp.
*
* @param timestamp The time in ticks to be set. Guaranteed to be between 0 and 2^bits-1, where bits is
* the number of bits returned by us_ticker_get_info()
Expand All @@ -247,7 +248,7 @@ uint32_t (us_ticker_read)(void);
* in the future, then reschedule the timer for the correct time.
*
* Calling this function with timestamp of more than the supported
* number of bits returned by ::lp_ticker_get_info results in undefined
* number of bits returned by ::us_ticker_get_info results in undefined
* behavior.
*
* If the timer interrupt is pending when this function is called (e.g. due to the ticker being set,
Expand All @@ -258,6 +259,7 @@ uint32_t (us_ticker_read)(void);
* @code
* void us_ticker_set_interrupt(timestamp_t timestamp)
* {
* us_ticker_clear_interrupt();
* TIMER_COMPARE = timestamp;
* TIMER_CTRL |= TIMER_CTRL_COMPARE_ENABLE_Msk;
* }
Expand All @@ -281,8 +283,8 @@ void us_ticker_disable_interrupt(void);
/**
* @brief Clear the us ticker interrupt.
*
* This is required to be called from the interrupt handler to stop the interrupt handler
* from being executed again after it returns. This does not do anything if called before the interrupt
* This is called from Mbed's interrupt handler and should clear the interrupt flag in the peripheral to stop
* the interrupt from being executed again after it returns. This does not do anything if called before the interrupt
* fires (e.g. it doesn't cancel the interrupt if it's set in the future).
*
* Pseudo Code:
Expand Down
15 changes: 7 additions & 8 deletions hal/tests/TESTS/mbed_hal/common_tickers/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,30 +271,29 @@ void ticker_interrupt_test(void)
void ticker_disable_test()
{
intFlag = 0;
const uint32_t ticksFor1ms = lroundf(intf->get_info()->frequency * .001f);

const uint32_t ticksFor100us = lroundf(intf->get_info()->frequency * .0001f);

// Set an interrupt for 100us in the future, then disable it immediately
intf->set_interrupt(intf->read() + ticksFor100us);
// Set an interrupt for 1ms in the future, then disable it immediately
intf->set_interrupt(intf->read() + ticksFor1ms);
intf->disable_interrupt();

// Verify that it does not fire. Note that we cannot use wait_us here as it uses the us ticker
// which is currently suspended.
wait_ns(200000);
wait_ns(2000000);
TEST_ASSERT_EQUAL_INT(0, intFlag);

// Now reset the interrupt again.
intf->set_interrupt(intf->read() + ticksFor100us);
intf->set_interrupt(intf->read() + ticksFor1ms);

// Should not have fired yet
TEST_ASSERT_EQUAL_INT_MESSAGE(0, intFlag, "Ticker fired during set_interrupt() while disabled! Check that set_interrupt() function clears pending timer compare.");

// Still not yet
wait_ns(20000);
wait_ns(200000);
TEST_ASSERT_EQUAL_INT(0, intFlag);

// NOW it should have fired
wait_ns(170000);
wait_ns(1700000);
TEST_ASSERT_EQUAL_INT(1, intFlag);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,13 @@ SECTIONS

#if MBED_CONF_PLATFORM_CRASH_CAPTURE_ENABLED
/* Stick the crash data ram at the start of sram_l */
.crash_data_ram : ALIGN(8)
.crash_data_ram (NOLOAD): ALIGN(8)
{
__CRASH_DATA_RAM__ = .;
__CRASH_DATA_RAM_START__ = .; /* Create a global symbol at data start */
KEEP(*(.keep.crash_data_ram))
*(.m_crash_data_ram) /* This is a user defined section */
. += M_CRASH_DATA_RAM_SIZE;
*(.m_crash_data_ram) /* This is a user defined section */
. = ALIGN(8);
__CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
} > m_sram_l :sram_l
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,14 @@
#endif

STACK_SIZE = MBED_CONF_TARGET_BOOT_STACK_SIZE;
M_CRASH_DATA_RAM_SIZE = 0x100;

#define VECTORS_SIZE (((NVIC_NUM_VECTORS * 4) + 7) & 0xFFFFFFF8)

MEMORY
{
FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
RAM (rwx) : ORIGIN = (MBED_RAM_START + VECTORS_SIZE), LENGTH = MBED_RAM_SIZE - VECTORS_SIZE
RAM_0 (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000
RAM_1 (rwx) : ORIGIN = 0x20004000, LENGTH = 0x4000
RAM_2 (rwx) : ORIGIN = 0x20008000, LENGTH = 0x8000
RAM_3 (rwx) : ORIGIN = 0x20010000, LENGTH = 0x8000
FLASH (rx) : ORIGIN = MBED_CONFIGURED_ROM_START, LENGTH = MBED_CONFIGURED_ROM_SIZE
RAM (rwx) : ORIGIN = MBED_RAM_BANK_IRAM1_START, LENGTH = MBED_RAM_BANK_IRAM1_SIZE
}


Expand Down Expand Up @@ -82,6 +79,12 @@ ENTRY(Reset_Handler)

SECTIONS
{
/* Space for interrupt vectors in RAM */
.ram_vector (NOLOAD):
{
. += VECTORS_SIZE;
} > RAM

.text :
{
KEEP(*(.isr_vector))
Expand Down
32 changes: 19 additions & 13 deletions targets/TARGET_Maxim/TARGET_MAX32670/lp_ticker.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,12 @@ const ticker_info_t *lp_ticker_get_info(void)
#define LP_TIMER_WIDTH 32

//******************************************************************************

static bool already_initialized = false;

void lp_ticker_init(void)
{
mxc_tmr_cfg_t cfg;
unsigned int count;

cfg.pres = LP_TIMER_PRESCALE;
cfg.mode = TMR_MODE_COMPARE;
Expand All @@ -177,36 +179,38 @@ void lp_ticker_init(void)
cfg.pol = 0;

// Disable and deconfigure
MXC_TMR_Shutdown(LP_TIMER);
MXC_TMR_ClearFlags(LP_TIMER);
uint32_t prevCount = 0;
if (already_initialized) {
MXC_TMR_Shutdown(LP_TIMER);
MXC_TMR_ClearFlags(LP_TIMER);

count = MXC_TMR_GetCount(LP_TIMER);
prevCount = MXC_TMR_GetCount(LP_TIMER);
}

// Configure and enable
MXC_TMR_Init(LP_TIMER, &cfg, 0);
MXC_TMR_EnableWakeup(LP_TIMER, &cfg);
MXC_TMR_SetCount(LP_TIMER, count);
MXC_TMR_SetCount(LP_TIMER, prevCount);

// Enable interrupts
MXC_TMR_EnableInt(LP_TIMER);
NVIC_SetVector(LP_TIMER_IRQn, (uint32_t)lp_ticker_irq_handler);
NVIC_EnableIRQ(LP_TIMER_IRQn);

#if MBED_CONF_TARGET_LP_TICKER_TIMER == 0
MXC_GCR->pm |= MXC_F_GCR_PM_LPTMR0_WE;
#elif MBED_CONF_TARGET_LP_TICKER_TIMER == 1
MXC_GCR->pm |= MXC_F_GCR_PM_LPTMR1_WE;
#endif

// Make sure ERTCO oscillator stays enabled in low-power mode
MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_ERTCO_EN;

// Enable wakeup from sleep via LP timer
MXC_LP_EnableTimerWakeup(LP_TIMER);

MXC_TMR_Start(LP_TIMER);

already_initialized = true;
}

//******************************************************************************
void lp_ticker_free(void)
{
NVIC_DisableIRQ(LP_TIMER_IRQn);
MXC_TMR_Shutdown(LP_TIMER);
}

Expand All @@ -227,13 +231,15 @@ uint32_t lp_ticker_read(void)
void lp_ticker_set_interrupt(timestamp_t timestamp)
{
//MXC_TMR_SetCompare(LP_TIMER, (timestamp) ? timestamp : 1);
lp_ticker_clear_interrupt();
MXC_TMR_EnableInt(LP_TIMER);
LP_TIMER->cmp = timestamp ? timestamp : 1;
}

//******************************************************************************
void lp_ticker_disable_interrupt(void)
{
NVIC_DisableIRQ(LP_TIMER_IRQn);
MXC_TMR_DisableInt(LP_TIMER);
}

//******************************************************************************
Expand Down
29 changes: 19 additions & 10 deletions targets/TARGET_Maxim/TARGET_MAX32670/us_ticker.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,40 +57,47 @@


//******************************************************************************

static bool already_initialized = false;

void us_ticker_init(void)
{
mxc_tmr_cfg_t cfg;
unsigned int count;

cfg.pres = US_TIMER_PRESCALE;
cfg.mode = TMR_MODE_COMPARE;
cfg.bitMode = TMR_BIT_MODE_32;
cfg.clock = MXC_TMR_APB_CLK;
cfg.cmp_cnt = 0;//MXC_TMR_GetCompare(US_TIMER);
cfg.pol = 0;
cfg.pol = 0;

// Disable and deconfigure
MXC_TMR_Shutdown(US_TIMER);
MXC_TMR_ClearFlags(US_TIMER);
uint32_t prevCount = 0;
if (already_initialized) {
// Disable and deconfigure
MXC_TMR_DisableInt(US_TIMER);
MXC_TMR_Shutdown(US_TIMER);
MXC_TMR_ClearFlags(US_TIMER);

count = MXC_TMR_GetCount(US_TIMER);
prevCount = MXC_TMR_GetCount(US_TIMER);
}

// Configure and enable
MXC_TMR_Init(US_TIMER, &cfg, 0);
MXC_TMR_SetCount(US_TIMER, count);
MXC_TMR_SetCount(US_TIMER, prevCount);
MXC_TMR_Start(US_TIMER);

MXC_TMR_EnableInt(US_TIMER);

// Enable interrupts
NVIC_SetVector(US_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
NVIC_EnableIRQ(US_TIMER_IRQn);

already_initialized = true;
}

//******************************************************************************
void us_ticker_free(void)
{
MXC_TMR_Shutdown(US_TIMER);
NVIC_DisableIRQ(US_TIMER_IRQn);
}

//******************************************************************************
Expand All @@ -103,7 +110,9 @@ uint32_t us_ticker_read(void)
//******************************************************************************
void us_ticker_set_interrupt(timestamp_t timestamp)
{
us_ticker_clear_interrupt();
MXC_TMR_SetCompare(US_TIMER, (timestamp) ? timestamp : 1);
MXC_TMR_EnableInt(US_TIMER);
}

//******************************************************************************
Expand All @@ -115,7 +124,7 @@ void us_ticker_fire_interrupt(void)
//******************************************************************************
void us_ticker_disable_interrupt(void)
{
NVIC_DisableIRQ(US_TIMER_IRQn);
MXC_TMR_DisableInt(US_TIMER);
}

//******************************************************************************
Expand Down
3 changes: 2 additions & 1 deletion targets/targets.json5
Original file line number Diff line number Diff line change
Expand Up @@ -6937,7 +6937,8 @@ mode is recommended for target MCUs with small amounts of flash and RAM.",
"small"
]
},
"device_name": "MAX32670"
"device_name": "MAX32670",
"is_mcu_family_target": true
},
"MAX32670EVKIT": {
"inherits": [
Expand Down
41 changes: 41 additions & 0 deletions targets/upload_method_cfg/MAX32670EVKIT.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Mbed OS upload method configuration file for target MAX32670EVKIT.
# To change any of these parameters from their default values, set them in your build script between where you
# include app.cmake and where you add mbed os as a subdirectory.

# Notes:
# 1. For the MBED upload method to work, you may need to update the DAPLink firmware as described here:
# https://github.com/analogdevicesinc/max32625pico-firmware-images
# My board shipped with firmware that claimed it was an MAX32630FTHR, causing
# "ERROR: The target board you compiled for is not connected to your system"
# 2. MAX32670 support did not land in upstream OpenOCD until Aug 2025. As of this writing, you need to compile
# it yourself from the git version (or use the OpenOCD that is distributed with the Maxim SDK).
# However, this should be resolved with the release of OpenOCD 1.0, which is imminent.
# 3. PyOCD does not work as of Sep 2025:
# 0000691 I DAP is not accessible after reset; attempting reconnect [dap]
# 0000795 E Error during board uninit: [session]
# 0000805 C No ACK received [__main__]

# General config parameters
# -------------------------------------------------------------
set(UPLOAD_METHOD_DEFAULT MBED)

# Config options for MBED
# -------------------------------------------------------------

set(MBED_UPLOAD_ENABLED TRUE)
set(MBED_RESET_BAUDRATE 115200)

# Config options for OPENOCD
# -------------------------------------------------------------

set(OPENOCD_UPLOAD_ENABLED TRUE)
set(OPENOCD_CHIP_CONFIG_COMMANDS
-f interface/cmsis-dap.cfg
-s ${CMAKE_CURRENT_LIST_DIR}/openocd_cfgs/max32xxx
-f target/max32670.cfg)

# Config options for PYOCD
# -------------------------------------------------------------
set(PYOCD_UPLOAD_ENABLED FALSE)
set(PYOCD_TARGET_NAME max32670)
set(PYOCD_CLOCK_SPEED 4000k)