Skip to content

[rtl872x] fixes System.ticks() #2600

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 13, 2022
Merged
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
5 changes: 5 additions & 0 deletions hal/inc/hal_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,4 +541,9 @@
#define HAL_PLATFORM_I2C_BUFFER_SIZE(x) (HAL_PLATFORM_I2C_BUFFER_SIZE_DEFAULT)
#endif // HAL_PLATFORM_I2C_BUFFER_SIZE

// hardware counter for System.ticks()
#ifndef HAL_PLATFORM_SYSTEM_HW_TICKS
#define HAL_PLATFORM_SYSTEM_HW_TICKS (0)
#endif // HAL_PLATFORM_SYSTEM_HW_TICKS

#endif /* HAL_PLATFORM_H */
3 changes: 3 additions & 0 deletions hal/src/nRF52840/hal_platform_nrf52840_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,6 @@
#define HAL_PLATFORM_ERROR_MESSAGES (1)

#define HAL_PLATFORM_PROHIBIT_XIP (1)

// hardware counter for System.ticks() supported
#define HAL_PLATFORM_SYSTEM_HW_TICKS (1)
4 changes: 2 additions & 2 deletions platform/MCU/newhal-mcu/inc/hw_ticks.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ extern "C" {
* The number of ticks per microsecond of the system counter.
* SYSTEM_TICK_COUNTER
*/
#define SYSTEM_US_TICKS 100 // cycles per microsecond
#define SYSTEM_US_TICKS (1) // cycles per microsecond

/**
* Should return a value from a system counter.
* Should return a value from a system hardware counter if supported.
*/
#define SYSTEM_TICK_COUNTER 0

Expand Down
6 changes: 2 additions & 4 deletions platform/MCU/rtl872x/inc/hw_ticks.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include "platform_config.h"
#include "system_tick_hal.h"

#define SYSTEM_US_TICKS (SystemCoreClock / 1000000) //cycles per microsecond
#define SYSTEM_TICK_COUNTER GetDwtCounter()
#define SYSTEM_US_TICKS (1) //cycles per microsecond
#define SYSTEM_TICK_COUNTER HAL_Timer_Get_Micro_Seconds()

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -62,8 +62,6 @@ uint64_t GetSystem1MsTick64();
*/
system_tick_t GetSystem1UsTick();

uint32_t GetDwtCounter();

#ifdef __cplusplus
}
#endif
5 changes: 0 additions & 5 deletions platform/MCU/rtl872x/src/hw_ticks.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include "hw_ticks.h"
#include "timer_hal.h"
#include "rtl8721d.h"

void System1MsTick(void)
{
Expand Down Expand Up @@ -50,7 +49,3 @@ void __advance_system1MsTick(uint64_t millis, system_tick_t micros_from_rollover
{
// Unsupported
}

uint32_t GetDwtCounter() {
return DWT->CYCCNT;
}
48 changes: 48 additions & 0 deletions user/tests/wiring/no_fixture/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,51 @@ test(SYSTEM_08_hardware_info) {
}
#endif // HAL_PLATFORM_NCP
}

test(SYSTEM_09_system_ticks) {
// Serial.printlnf("ticksPerMicrosecond: %lu %lu", System.ticksPerMicrosecond(), System.ticksPerMicrosecond() * 100);
const uint32_t NUM_ITERATIONS = 100;
const uint32_t DURATION_US = 1000; // 10% higher than measured (includes for() loop overhead)
const uint32_t DURATION_TICKS = System.ticksPerMicrosecond() * DURATION_US;
const uint32_t MIN_DURATION_TICKS = DURATION_TICKS * 95 / 100; // 5% lower than measured (includes for() loop overhead)
const uint32_t MAX_DURATION_TICKS = DURATION_TICKS * 105 / 100; // 5% higher than measured (includes for() loop overhead)
uint32_t start;
uint32_t finish;
ATOMIC_BLOCK() {
start = System.ticks();
for (uint32_t i = 0; i < NUM_ITERATIONS; i++) {
HAL_Delay_Microseconds(DURATION_US);
}
finish = System.ticks();
}
uint32_t ticks = finish - start;
uint32_t expected_low = NUM_ITERATIONS * MIN_DURATION_TICKS;
uint32_t expected_high = NUM_ITERATIONS * MAX_DURATION_TICKS;
// Serial.printlnf("ticks: %lu <= %lu <= %lu", expected_low, ticks, expected_high);
assertLessOrEqual(ticks, expected_high);
assertMoreOrEqual(ticks, expected_low);
}

test(SYSTEM_10_system_ticks_delay) {
// Serial.printlnf("ticksPerMicrosecond: %lu %lu", System.ticksPerMicrosecond(), System.ticksPerMicrosecond() * 100);
const uint32_t NUM_ITERATIONS = 100;
const uint32_t DURATION_US = 1000; // 10% higher than measured (includes for() loop overhead)
const uint32_t DURATION_TICKS = System.ticksPerMicrosecond() * DURATION_US;
const uint32_t MIN_DURATION_US = DURATION_US * 95 / 100; // 5% lower than measured (includes for() loop overhead)
const uint32_t MAX_DURATION_US = DURATION_US * 105 / 100; // 5% higher than measured (includes for() loop overhead)
uint32_t start;
uint32_t finish;
ATOMIC_BLOCK() {
start = HAL_Timer_Get_Micro_Seconds();
for (uint32_t i = 0; i < NUM_ITERATIONS; i++) {
System.ticksDelay(DURATION_TICKS);
}
finish = HAL_Timer_Get_Micro_Seconds();
}
uint32_t duration = finish - start;
uint32_t expected_low = NUM_ITERATIONS * MIN_DURATION_US;
uint32_t expected_high = NUM_ITERATIONS * MAX_DURATION_US;
// Serial.printlnf("duration: %lu <= %lu <= %lu", expected_low, duration, expected_high);
assertLessOrEqual(duration, expected_high);
assertMoreOrEqual(duration, expected_low);
}
13 changes: 9 additions & 4 deletions user/tests/wiring/no_fixture_spi/spix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,12 @@ template <unsigned int clockSpeed, unsigned int transferSize, unsigned int overh
constexpr system_tick_t calculateExpectedTime() {
constexpr uint64_t microsInSecond = 1000000ULL;
constexpr uint64_t nanosInSecond = 1000000000ULL;
#if HAL_PLATFORM_RTL872X
// FIXME: SPI clock resulting in half the set speed
constexpr uint64_t spiTransferTime = (nanosInSecond * transferSize * 8 + (clockSpeed/2) - 1) / (clockSpeed/2);
#else
constexpr uint64_t spiTransferTime = (nanosInSecond * transferSize * 8 + clockSpeed - 1) / clockSpeed;
#endif
constexpr uint64_t expectedTransferTime = spiTransferTime + overheadNs;

return (expectedTransferTime * iterations) / microsInSecond;
Expand All @@ -403,12 +408,12 @@ constexpr unsigned int SPI_ITERATIONS = 10000;
constexpr unsigned int SPI_ERROR_MARGIN = 5; // 5%

#if HAL_PLATFORM_RTL872X
constexpr unsigned int SPI_CLOCK_SPEED = 6250000; // 6.25MHz
constexpr unsigned int SPI_NODMA_OVERHEAD = 15500; // 15.5us ~= 992 clock cycles @ 64MHz
constexpr unsigned int SPI_DMA_OVERHEAD = 15500;
constexpr unsigned int SPI_CLOCK_SPEED = 12500000; // 12.5MHz (FIXME: freq actually 6.25MHz)
constexpr unsigned int SPI_NODMA_OVERHEAD = 40000; // 55us (imperically measured, time between transfers on a scope, WIP set high to pass for now)
constexpr unsigned int SPI_DMA_OVERHEAD = SPI_NODMA_OVERHEAD;
#elif HAL_PLATFORM_NRF52840
constexpr unsigned int SPI_CLOCK_SPEED = 8000000; // 8MHz
constexpr unsigned int SPI_NODMA_OVERHEAD = 15500; // 15.5us ~= 992 clock cycles @ 64MHz
constexpr unsigned int SPI_NODMA_OVERHEAD = 15500; // 15.5us (imperically measured, time between transfers on a scope)
constexpr unsigned int SPI_DMA_OVERHEAD = SPI_NODMA_OVERHEAD; // Gen 3 always uses DMA underneath
#else
#error "Unsupported platform"
Expand Down
12 changes: 10 additions & 2 deletions wiring/inc/spark_wiring_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -434,20 +434,28 @@ class SystemClass {

static void enterSafeMode(SystemResetFlags flags = SystemResetFlags());

#if SYSTEM_HW_TICKS
#if HAL_PLATFORM_SYSTEM_HW_TICKS
static inline uint32_t ticksPerMicrosecond() {
return SYSTEM_US_TICKS;
}

static inline uint32_t ticks() {
return SYSTEM_TICK_COUNTER;
}
#else
static inline uint32_t ticksPerMicrosecond() {
return 1;
}

static inline uint32_t ticks() {
return HAL_Timer_Get_Micro_Seconds();
}
#endif // HAL_PLATFORM_SYSTEM_HW_TICKS

static inline void ticksDelay(uint32_t duration) {
uint32_t start = ticks();
while ((ticks() - start) < duration) {}
}
#endif

static SystemSleepResult sleep(const particle::SystemSleepConfiguration& config);
static SleepResult sleep(Spark_Sleep_TypeDef sleepMode, long seconds = 0, SleepOptionFlags flag = SLEEP_NETWORK_OFF);
Expand Down