mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 14:17:51 -04:00
[sw/lib] add simple busy-wait delay function
that do not rely on any specific CPU hardware
This commit is contained in:
parent
9340394934
commit
ece8380e4f
7 changed files with 106 additions and 18 deletions
|
@ -1,7 +1,7 @@
|
|||
// ================================================================================ //
|
||||
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||
// Copyright (c) NEORV32 contributors. //
|
||||
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
|
||||
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||
// SPDX-License-Identifier: BSD-3-Clause //
|
||||
// ================================================================================ //
|
||||
|
@ -15,6 +15,16 @@
|
|||
#include <neorv32.h>
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple bus-wait helper.
|
||||
*
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void delay_ms(uint32_t time_ms) {
|
||||
neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Main function; shows an incrementing 8-bit counter on GPIO.output(7:0).
|
||||
*
|
||||
|
@ -31,7 +41,7 @@ int main() {
|
|||
|
||||
while (1) {
|
||||
neorv32_gpio_port_set(cnt++ & 0xFF); // increment counter and mask for lowest 8 bit
|
||||
neorv32_cpu_delay_ms(250); // wait 250ms using busy wait
|
||||
delay_ms(250); // wait 250ms using busy wait
|
||||
}
|
||||
|
||||
// this should never be reached
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ================================================================================ //
|
||||
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||
// Copyright (c) NEORV32 contributors. //
|
||||
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
|
||||
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||
// SPDX-License-Identifier: BSD-3-Clause //
|
||||
// ================================================================================ //
|
||||
|
@ -33,6 +33,16 @@
|
|||
uint32_t hsv2rgb(int h, int v);
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple bus-wait helper.
|
||||
*
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void delay_ms(uint32_t time_ms) {
|
||||
neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Main function
|
||||
* This demo uses a 12-LED RGB ring
|
||||
|
@ -83,7 +93,7 @@ int main() {
|
|||
for (i=0; i<NUM_LEDS_24BIT; i++) {
|
||||
neorv32_neoled_write_blocking(0);
|
||||
}
|
||||
neorv32_cpu_delay_ms(500);
|
||||
delay_ms(500);
|
||||
|
||||
|
||||
// a simple animation example: rotating rainbow
|
||||
|
@ -100,7 +110,7 @@ int main() {
|
|||
angle += 1; // rotation increment per frame
|
||||
|
||||
neorv32_neoled_strobe_blocking(); // send strobe ("RESET") command
|
||||
neorv32_cpu_delay_ms(10); // delay between frames
|
||||
delay_ms(10); // delay between frames
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ================================================================================ //
|
||||
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||
// Copyright (c) NEORV32 contributors. //
|
||||
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
|
||||
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||
// SPDX-License-Identifier: BSD-3-Clause //
|
||||
// ================================================================================ //
|
||||
|
@ -27,6 +27,15 @@
|
|||
/**@}*/
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple bus-wait helper.
|
||||
*
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void delay_ms(uint32_t time_ms) {
|
||||
neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* This program generates a simple dimming sequence for PWM channels 0 to 3.
|
||||
|
@ -115,7 +124,7 @@ int main() {
|
|||
}
|
||||
|
||||
neorv32_pwm_ch_set_duty(ch, dc); // set new duty cycle for channel
|
||||
neorv32_cpu_delay_ms(3); // wait ~3ms using busy-wait
|
||||
delay_ms(3); // wait ~3ms using busy-wait
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ================================================================================ //
|
||||
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||
// Copyright (c) NEORV32 contributors. //
|
||||
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
|
||||
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||
// SPDX-License-Identifier: BSD-3-Clause //
|
||||
// ================================================================================ //
|
||||
|
@ -33,6 +33,16 @@ void generate_histogram(void);
|
|||
void compute_rate(void);
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple bus-wait helper.
|
||||
*
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void delay_ms(uint32_t time_ms) {
|
||||
neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple true random number test/demo program.
|
||||
*
|
||||
|
@ -73,7 +83,7 @@ int main(void) {
|
|||
neorv32_uart0_printf("\nTRNG FIFO depth: %i\n", neorv32_trng_get_fifo_depth());
|
||||
neorv32_uart0_printf("Starting TRNG...\n");
|
||||
neorv32_trng_enable();
|
||||
neorv32_cpu_delay_ms(100); // TRNG "warm up"
|
||||
delay_ms(100); // TRNG "warm up"
|
||||
neorv32_trng_fifo_clear(); // discard "warm-up" data
|
||||
|
||||
while(1) {
|
||||
|
|
|
@ -26,6 +26,16 @@
|
|||
/**@}*/
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple bus-wait helper.
|
||||
*
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void delay_ms(uint32_t time_ms) {
|
||||
neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Main function
|
||||
*
|
||||
|
@ -91,7 +101,7 @@ int main() {
|
|||
neorv32_uart0_puts("Resetting WDT 5 times...\n");
|
||||
int i;
|
||||
for (i=0; i<5; i++) {
|
||||
neorv32_cpu_delay_ms(750);
|
||||
delay_ms(750);
|
||||
neorv32_wdt_feed(WDT_PASSWORD); // reset internal counter using the access password
|
||||
neorv32_uart0_puts("WDT reset.\n");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// ================================================================================ //
|
||||
// The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 //
|
||||
// Copyright (c) NEORV32 contributors. //
|
||||
// Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. //
|
||||
// Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. //
|
||||
// Licensed under the BSD-3-Clause license, see LICENSE for details. //
|
||||
// SPDX-License-Identifier: BSD-3-Clause //
|
||||
// ================================================================================ //
|
||||
|
@ -21,17 +21,17 @@
|
|||
**************************************************************************/
|
||||
/**@{*/
|
||||
/** UART BAUD rate */
|
||||
#define BAUD_RATE 19200
|
||||
#define BAUD_RATE (19200)
|
||||
/** Universe x size (has to be a multiple of 8) */
|
||||
#define NUM_CELLS_X 160
|
||||
#define NUM_CELLS_X (160)
|
||||
/** Universe y size */
|
||||
#define NUM_CELLS_Y 40
|
||||
#define NUM_CELLS_Y (40)
|
||||
/** Delay between generations in ms */
|
||||
#define GEN_DELAY 500
|
||||
#define GEN_DELAY (500)
|
||||
/** Symbol for dead cell */
|
||||
#define CELL_DEAD (' ')
|
||||
#define CELL_DEAD (' ')
|
||||
/** Symbol for alive cell */
|
||||
#define CELL_ALIVE ('#')
|
||||
#define CELL_ALIVE ('#')
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
@ -50,6 +50,16 @@ void print_universe(int u);
|
|||
int pop_count(int u);
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple bus-wait helper.
|
||||
*
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void delay_ms(uint32_t time_ms) {
|
||||
neorv32_aux_delay_ms(neorv32_sysinfo_get_clk(), time_ms);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Conway's Game of Life.
|
||||
*
|
||||
|
@ -168,7 +178,7 @@ int main(void) {
|
|||
generation++;
|
||||
|
||||
// wait GEN_DELAY ms
|
||||
neorv32_cpu_delay_ms(GEN_DELAY);
|
||||
delay_ms(GEN_DELAY);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,35 @@
|
|||
#include <neorv32.h>
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Simple delay function using busy-wait.
|
||||
*
|
||||
* @warning Timing is imprecise! Use CLINT.MTIME or CSR.[M]CYCLE[H] for precise timing.
|
||||
*
|
||||
* @param[in] clock_hz CPU clock speed in Hz.
|
||||
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
|
||||
**************************************************************************/
|
||||
void neorv32_aux_delay_ms(uint32_t clock_hz, uint32_t time_ms) {
|
||||
|
||||
// clock ticks per ms (avoid division, therefore shift by 10 instead dividing by 1000)
|
||||
uint32_t ms_ticks = clock_hz >> 10;
|
||||
uint64_t wait_cycles = ((uint64_t)ms_ticks) * ((uint64_t)time_ms);
|
||||
// divide by clock cycles per iteration of the ASM loop (16 = shift by 4)
|
||||
uint32_t iterations = (uint32_t)(wait_cycles >> 4);
|
||||
|
||||
asm volatile (
|
||||
" __neorv32_aux_delay_ms_start: \n"
|
||||
" beq %[cnt_r], zero, __neorv32_aux_delay_ms_end \n" // 3 cycles (if not taken)
|
||||
" bne zero, zero, __neorv32_aux_delay_ms_end \n" // 3 cycles (never taken)
|
||||
" addi %[cnt_w], %[cnt_r], -1 \n" // 2 cycles
|
||||
" nop \n" // 2 cycles
|
||||
" j __neorv32_aux_delay_ms_start \n" // 6 cycles
|
||||
" __neorv32_aux_delay_ms_end: \n"
|
||||
: [cnt_w] "=r" (iterations) : [cnt_r] "r" (iterations)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Convert date to Unix time stamp.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue