OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/sw/lib/source
    from Rev 63 to Rev 64
    Reverse comparison

Rev 63 → Rev 64

/neorv32_cfs.c
55,7 → 55,7
**************************************************************************/
int neorv32_cfs_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_CFS)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_CFS)) {
return 1;
}
else {
/neorv32_cpu.c
151,7 → 151,7
uint32_t uint32[sizeof(uint64_t)/2];
} cycles;
 
uint32_t tmp1, tmp2, tmp3;
register uint32_t tmp1, tmp2, tmp3;
while(1) {
tmp1 = neorv32_cpu_csr_read(CSR_CYCLEH);
tmp2 = neorv32_cpu_csr_read(CSR_CYCLE);
202,7 → 202,7
uint32_t uint32[sizeof(uint64_t)/2];
} cycles;
 
uint32_t tmp1, tmp2, tmp3;
register uint32_t tmp1, tmp2, tmp3;
while(1) {
tmp1 = neorv32_cpu_csr_read(CSR_INSTRETH);
tmp2 = neorv32_cpu_csr_read(CSR_INSTRET);
253,7 → 253,7
uint32_t uint32[sizeof(uint64_t)/2];
} cycles;
 
uint32_t tmp1, tmp2, tmp3;
register uint32_t tmp1, tmp2, tmp3;
while(1) {
tmp1 = neorv32_cpu_csr_read(CSR_TIMEH);
tmp2 = neorv32_cpu_csr_read(CSR_TIME);
271,36 → 271,51
 
 
/**********************************************************************//**
* Simple delay function using busy wait (simple loop).
* Delay function using busy wait.
*
* @warning This function is not really precise (especially if there is no M extension available)! Use a timer-based approach (using cycle or time CSRs) for precise timings.
* @note This function uses the time CSRs (from int./ext. MTIME). A simple ASM loop
* is used as fall back if system timer is not advancing (no MTIME available).
*
* @param[in] time_ms Time in ms to wait (max 32767ms).
* @warning Delay time might be less precise if M extensions is not available
* (especially if MTIME unit is not available).
*
* @param[in] time_ms Time in ms to wait (unsigned 32-bit).
**************************************************************************/
void neorv32_cpu_delay_ms(int16_t time_ms) {
void neorv32_cpu_delay_ms(uint32_t time_ms) {
 
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop
uint32_t clock = NEORV32_SYSINFO.CLK; // clock ticks per second
clock = clock / 1000; // clock ticks per ms
 
// check input
if (time_ms < 0) {
time_ms = -time_ms;
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms);
 
register uint64_t tmp = neorv32_cpu_get_systime();
if (neorv32_cpu_get_systime() > tmp) { // system time advancing (MTIME available and running)?
 
// use MTIME machine timer
tmp += wait_cycles;
while(1) {
if (neorv32_cpu_get_systime() >= tmp) {
break;
}
}
}
else {
// use ASM loop
// warning! not really precise (especially if M extensions is not available)!
 
uint32_t clock = SYSINFO_CLK; // clock ticks per second
clock = clock / 1000; // clock ticks per ms
const uint32_t loop_cycles_c = 16; // clock cycles per iteration of the ASM loop
uint32_t iterations = (uint32_t)(wait_cycles / loop_cycles_c);
 
uint64_t wait_cycles = ((uint64_t)clock) * ((uint64_t)time_ms);
uint32_t ticks = (uint32_t)(wait_cycles / loop_cycles_c);
 
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned
" __neorv32_cpu_delay_ms_start: \n"
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken)
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken)
" addi %[cnt_w], %[cnt_r], -1 \n" // 2 cycles
" nop \n" // 2 cycles
" j __neorv32_cpu_delay_ms_start \n" // 6 cycles
" __neorv32_cpu_delay_ms_end: "
: [cnt_w] "=r" (ticks) : [cnt_r] "r" (ticks));
asm volatile (" .balign 4 \n" // make sure this is 32-bit aligned
" __neorv32_cpu_delay_ms_start: \n"
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (not taken)
" beq %[cnt_r], zero, __neorv32_cpu_delay_ms_end \n" // 3 cycles (never taken)
" addi %[cnt_w], %[cnt_r], -1 \n" // 2 cycles
" nop \n" // 2 cycles
" j __neorv32_cpu_delay_ms_start \n" // 6 cycles
" __neorv32_cpu_delay_ms_end: "
: [cnt_w] "=r" (iterations) : [cnt_r] "r" (iterations));
}
}
 
 
332,7 → 347,7
uint32_t neorv32_cpu_pmp_get_num_regions(void) {
 
// PMP implemented at all?
if ((SYSINFO_CPU & (1<<SYSINFO_CPU_PMP)) == 0) {
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_PMP)) == 0) {
return 0;
}
 
597,7 → 612,7
uint32_t neorv32_cpu_hpm_get_counters(void) {
 
// HPMs implemented at all?
if ((SYSINFO_CPU & (1<<SYSINFO_CPU_HPM)) == 0) {
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_HPM)) == 0) {
return 0;
}
 
680,7 → 695,7
uint32_t neorv32_cpu_hpm_get_size(void) {
 
// HPMs implemented at all?
if ((SYSINFO_CPU & (1<<SYSINFO_CPU_HPM)) == 0) {
if ((NEORV32_SYSINFO.CPU & (1<<SYSINFO_CPU_HPM)) == 0) {
return 0;
}
 
/neorv32_gpio.c
52,7 → 52,7
**************************************************************************/
int neorv32_gpio_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_GPIO)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_GPIO)) {
return 1;
}
else {
71,10 → 71,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f));
 
if (pin < 32) {
GPIO_OUTPUT_LO |= mask;
NEORV32_GPIO.OUTPUT_LO |= mask;
}
else {
GPIO_OUTPUT_HI |= mask;
NEORV32_GPIO.OUTPUT_HI |= mask;
}
}
 
89,10 → 89,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f));
 
if (pin < 32) {
GPIO_OUTPUT_LO &= ~mask;
NEORV32_GPIO.OUTPUT_LO &= ~mask;
}
else {
GPIO_OUTPUT_HI &= ~mask;
NEORV32_GPIO.OUTPUT_HI &= ~mask;
}
}
 
107,10 → 107,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f));
 
if (pin < 32) {
GPIO_OUTPUT_LO ^= mask;
NEORV32_GPIO.OUTPUT_LO ^= mask;
}
else {
GPIO_OUTPUT_HI ^= mask;
NEORV32_GPIO.OUTPUT_HI ^= mask;
}
}
 
126,10 → 126,10
uint32_t mask = (uint32_t)(1 << (pin & 0x1f));
 
if (pin < 32) {
return GPIO_INPUT_LO & mask;
return NEORV32_GPIO.INPUT_LO & mask;
}
else {
return GPIO_INPUT_HI & mask;
return NEORV32_GPIO.INPUT_HI & mask;
}
}
 
141,7 → 141,14
**************************************************************************/
void neorv32_gpio_port_set(uint64_t port_data) {
 
GPIO_OUTPUT = port_data;
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} data;
 
data.uint64 = port_data;
NEORV32_GPIO.OUTPUT_LO = data.uint32[0];
NEORV32_GPIO.OUTPUT_HI = data.uint32[1];
}
 
 
152,6 → 159,14
**************************************************************************/
uint64_t neorv32_gpio_port_get(void) {
 
return GPIO_INPUT;
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} data;
 
data.uint32[0] = NEORV32_GPIO.OUTPUT_LO;
data.uint32[1] = NEORV32_GPIO.OUTPUT_HI;
 
return data.uint64;
}
 
/neorv32_mtime.c
52,7 → 52,7
**************************************************************************/
int neorv32_mtime_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_MTIME)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_MTIME)) {
return 1;
}
else {
77,9 → 77,9
 
cycles.uint64 = time;
 
MTIME_LO = 0;
MTIME_HI = cycles.uint32[1];
MTIME_LO = cycles.uint32[0];
NEORV32_MTIME.TIME_LO = 0;
NEORV32_MTIME.TIME_HI = cycles.uint32[1];
NEORV32_MTIME.TIME_LO = cycles.uint32[0];
 
}
 
100,9 → 100,9
 
uint32_t tmp1, tmp2, tmp3;
while(1) {
tmp1 = MTIME_HI;
tmp2 = MTIME_LO;
tmp3 = MTIME_HI;
tmp1 = NEORV32_MTIME.TIME_HI;
tmp2 = NEORV32_MTIME.TIME_LO;
tmp3 = NEORV32_MTIME.TIME_HI;
if (tmp1 == tmp3) {
break;
}
132,9 → 132,9
 
cycles.uint64 = timecmp;
 
MTIMECMP_LO = -1; // prevent MTIMECMP from temporarily becoming smaller than the lesser of the old and new values
MTIMECMP_HI = cycles.uint32[1];
MTIMECMP_LO = cycles.uint32[0];
NEORV32_MTIME.TIMECMP_LO = -1; // prevent MTIMECMP from temporarily becoming smaller than the lesser of the old and new values
NEORV32_MTIME.TIMECMP_HI = cycles.uint32[1];
NEORV32_MTIME.TIMECMP_LO = cycles.uint32[0];
}
 
 
145,5 → 145,13
**************************************************************************/
uint64_t neorv32_mtime_get_timecmp(void) {
 
return MTIMECMP;
union {
uint64_t uint64;
uint32_t uint32[sizeof(uint64_t)/2];
} cycles;
 
cycles.uint32[0] = NEORV32_MTIME.TIMECMP_LO;
cycles.uint32[1] = NEORV32_MTIME.TIMECMP_HI;
 
return cycles.uint64;
}
/neorv32_neoled.c
52,7 → 52,7
**************************************************************************/
int neorv32_neoled_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_NEOLED)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_NEOLED)) {
return 1;
}
else {
62,7 → 62,7
 
 
/**********************************************************************//**
* Enable and configure NEOLED controller. The NEOLED control register bits are listed in #NEORV32_NEOLED_CT_enum.
* Enable and configure NEOLED controller. The NEOLED control register bits are listed in #NEORV32_NEOLED_CTRL_enum.
* This function performs a "raw" configuration (just configuraing the according control register bit).
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
72,25 → 72,25
**************************************************************************/
void neorv32_neoled_setup(uint32_t prsc, uint32_t t_total, uint32_t t_high_zero, uint32_t t_high_one) {
 
NEOLED_CT = 0; // reset
NEORV32_NEOLED.CTRL = 0; // reset
 
// module enable
uint32_t ct_enable = 1 << NEOLED_CT_EN;
uint32_t ct_enable = 1 << NEOLED_CTRL_EN;
 
// clock pre-scaler
uint32_t ct_prsc = (prsc & 0x7) << NEOLED_CT_PRSC0;
uint32_t ct_prsc = (prsc & 0x7) << NEOLED_CTRL_PRSC0;
 
// serial data output: total period length for one bit
uint32_t ct_t_total = (t_total & 0x1f) << NEOLED_CT_T_TOT_0;
uint32_t ct_t_total = (t_total & 0x1f) << NEOLED_CTRL_T_TOT_0;
 
// serial data output: high-time for sending a '0'
uint32_t ct_t_zero = (t_high_zero & 0x1f) << NEOLED_CT_T_ZERO_H_0;
uint32_t ct_t_zero = (t_high_zero & 0x1f) << NEOLED_CTRL_T_ZERO_H_0;
 
// serial data output: high-time for sending a '1'
uint32_t ct_t_one = (t_high_one & 0x1f) << NEOLED_CT_T_ONE_H_0;
uint32_t ct_t_one = (t_high_one & 0x1f) << NEOLED_CTRL_T_ONE_H_0;
 
// set new configuration
NEOLED_CT = ct_enable | ct_prsc | ct_t_total | ct_t_zero | ct_t_one;
NEORV32_NEOLED.CTRL = ct_enable | ct_prsc | ct_t_total | ct_t_zero | ct_t_one;
}
 
 
112,7 → 112,7
const uint32_t CLK_PRSC_FACTOR_LUT[8] = {2, 4, 8, 64, 128, 1024, 2048, 4096};
 
// get base clock period in multiples of 0.5ns
uint32_t t_clock_x500ps = (2 * 1000 * 1000 * 1000) / SYSINFO_CLK;
uint32_t t_clock_x500ps = (2 * 1000 * 1000 * 1000) / NEORV32_SYSINFO.CLK;
 
// compute LED interface timing parameters
uint32_t t_base = 0;
162,10 → 162,10
**************************************************************************/
void neorv32_neoled_set_mode(uint32_t mode) {
 
uint32_t ctrl = NEOLED_CT;
ctrl &= ~(0b1 << NEOLED_CT_MODE); // clear current mode
ctrl |= ((mode & 1) << NEOLED_CT_MODE); // set new mode
NEOLED_CT = ctrl;
uint32_t ctrl = NEORV32_NEOLED.CTRL;
ctrl &= ~(0b1 << NEOLED_CTRL_MODE); // clear current mode
ctrl |= ((mode & 1) << NEOLED_CTRL_MODE); // set new mode
NEORV32_NEOLED.CTRL = ctrl;
}
 
 
175,7 → 175,7
void neorv32_neoled_strobe_blocking(void) {
 
while(1) { // wait for FIFO full flag to clear
if ((NEOLED_CT & (1 << NEOLED_CT_TX_FULL)) == 0) {
if ((NEORV32_NEOLED.CTRL & (1 << NEOLED_CTRL_TX_FULL)) == 0) {
break;
}
}
189,12 → 189,12
**************************************************************************/
void neorv32_neoled_strobe_nonblocking(void) {
 
const uint32_t mask = 1 << NEOLED_CT_STROBE; // strobe bit
uint32_t ctrl = NEOLED_CT;
const uint32_t mask = 1 << NEOLED_CTRL_STROBE; // strobe bit
uint32_t ctrl = NEORV32_NEOLED.CTRL;
 
NEOLED_CT = ctrl | mask; // set strobe bit
NEOLED_DATA = 0; // send any data to trigger strobe command
NEOLED_CT = ctrl & (~mask); // clear strobe bit
NEORV32_NEOLED.CTRL = ctrl | mask; // set strobe bit
NEORV32_NEOLED.DATA = 0; // send any data to trigger strobe command
NEORV32_NEOLED.CTRL = ctrl & (~mask); // clear strobe bit
}
 
 
203,7 → 203,7
**************************************************************************/
void neorv32_neoled_enable(void) {
 
NEOLED_CT |= ((uint32_t)(1 << NEOLED_CT_EN));
NEORV32_NEOLED.CTRL |= ((uint32_t)(1 << NEOLED_CTRL_EN));
}
 
 
212,7 → 212,7
**************************************************************************/
void neorv32_neoled_disable(void) {
 
NEOLED_CT &= ~((uint32_t)(1 << NEOLED_CT_EN));
NEORV32_NEOLED.CTRL &= ~((uint32_t)(1 << NEOLED_CTRL_EN));
}
 
 
226,7 → 226,7
void neorv32_neoled_write_blocking(uint32_t data) {
 
while(1) { // wait for FIFO full flag to clear
if ((NEOLED_CT & (1 << NEOLED_CT_TX_FULL)) == 0) {
if ((NEORV32_NEOLED.CTRL & (1 << NEOLED_CTRL_TX_FULL)) == 0) {
break;
}
}
242,8 → 242,8
**************************************************************************/
uint32_t neorv32_neoled_get_buffer_size(void) {
 
uint32_t tmp = NEOLED_CT;
tmp = tmp >> NEOLED_CT_BUFS_0;
uint32_t tmp = NEORV32_NEOLED.CTRL;
tmp = tmp >> NEOLED_CTRL_BUFS_0;
tmp = tmp & 0xf; // isolate buffer size bits
 
return (1 << tmp); // num entries = pow(2, buffer size flags)
/neorv32_pwm.c
52,7 → 52,7
**************************************************************************/
int neorv32_pwm_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_PWM)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_PWM)) {
return 1;
}
else {
62,21 → 62,21
 
 
/**********************************************************************//**
* Enable and configure pulse width modulation controller. The PWM control register bits are listed in #NEORV32_PWM_CT_enum.
* Enable and configure pulse width modulation controller. The PWM control register bits are listed in #NEORV32_PWM_CTRL_enum.
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
**************************************************************************/
void neorv32_pwm_setup(uint8_t prsc) {
 
PWM_CT = 0; // reset
NEORV32_PWM.CTRL = 0; // reset
 
uint32_t ct_enable = 1;
ct_enable = ct_enable << PWM_CT_EN;
ct_enable = ct_enable << PWM_CTRL_EN;
 
uint32_t ct_prsc = (uint32_t)(prsc & 0x07);
ct_prsc = ct_prsc << PWM_CT_PRSC0;
ct_prsc = ct_prsc << PWM_CTRL_PRSC0;
 
PWM_CT = ct_enable | ct_prsc;
NEORV32_PWM.CTRL = ct_enable | ct_prsc;
}
 
 
85,7 → 85,7
**************************************************************************/
void neorv32_pwm_disable(void) {
 
PWM_CT &= ~((uint32_t)(1 << PWM_CT_EN));
NEORV32_PWM.CTRL &= ~((uint32_t)(1 << PWM_CTRL_EN));
}
 
 
94,7 → 94,7
**************************************************************************/
void neorv32_pwm_enable(void) {
 
PWM_CT |= ((uint32_t)(1 << PWM_CT_EN));
NEORV32_PWM.CTRL |= ((uint32_t)(1 << PWM_CTRL_EN));
}
 
 
132,23 → 132,19
return; // out-of-range
}
 
// compute duty-cycle offset
uint32_t reg_offset = (uint32_t)(channel / 4);
uint8_t byte_offset = channel % 4;
 
// read-modify-write
uint32_t duty_mask = 0xff;
uint32_t duty_new = (uint32_t)duty;
 
duty_mask = duty_mask << (byte_offset * 8);
duty_new = duty_new << (byte_offset * 8);
duty_mask = duty_mask << ((channel % 4) * 8);
duty_new = duty_new << ((channel % 4) * 8);
 
uint32_t duty_cycle = (*(IO_REG32 (&PWM_DUTY0 + reg_offset)));
uint32_t duty_cycle = NEORV32_PWM.DUTY[channel/4];
 
duty_cycle &= ~duty_mask; // clear previous duty cycle
duty_cycle |= duty_new; // set new duty cycle
 
(*(IO_REG32 (&PWM_DUTY0 + reg_offset))) = duty_cycle;
NEORV32_PWM.DUTY[channel/4] = duty_cycle;
}
 
 
164,13 → 160,7
return 0; // out-of-range
}
 
// compute duty-cycle offset
uint32_t reg_offset = (uint32_t)(channel / 4);
uint8_t byte_offset = channel % 4;
uint32_t reg_data = NEORV32_PWM.DUTY[channel/4] >> (((channel % 4) * 8));
 
// read
uint32_t tmp = (*(IO_REG32 (&PWM_DUTY0 + reg_offset)));
tmp = tmp >> ((byte_offset * 8));
 
return (uint8_t)tmp;
return (uint8_t)reg_data;
}
/neorv32_rte.c
48,9 → 48,9
static uint32_t __neorv32_rte_vector_lut[NEORV32_RTE_NUM_TRAPS] __attribute__((unused)); // trap handler vector table
 
// private functions
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused));
static void __neorv32_rte_debug_exc_handler(void) __attribute__((unused));
static void __neorv32_rte_print_true_false(int state) __attribute__((unused));
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16)));
static void __neorv32_rte_debug_exc_handler(void);
static void __neorv32_rte_print_true_false(int state);
static void __neorv32_rte_print_hex_word(uint32_t num);
 
 
162,7 → 162,6
case TRAP_CODE_S_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
case TRAP_CODE_UENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_UENV_CALL]; break;
case TRAP_CODE_MENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
case TRAP_CODE_NMI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_NMI]; break;
case TRAP_CODE_MSI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
case TRAP_CODE_MTI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
case TRAP_CODE_MEI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MEI]; break;
277,16 → 276,16
 
// Processor - general stuff
neorv32_uart0_printf("\n=== << General >> ===\n"
"Clock speed: %u Hz\n", SYSINFO_CLK);
neorv32_uart0_printf("Full HW reset: "); __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_HW_RESET));
"Clock speed: %u Hz\n", NEORV32_SYSINFO.CLK);
neorv32_uart0_printf("Full HW reset: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_HW_RESET));
neorv32_uart0_printf("Boot Config.: Boot ");
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_BOOTLOADER)) {
neorv32_uart0_printf("via Bootloader\n");
}
else {
neorv32_uart0_printf("from memory (@ 0x%x)\n", SYSINFO_ISPACE_BASE);
neorv32_uart0_printf("from memory (@ 0x%x)\n", NEORV32_SYSINFO.ISPACE_BASE);
}
neorv32_uart0_printf("On-chip debug: "); __neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_OCD));
neorv32_uart0_printf("On-chip debug: "); __neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_OCD));
 
 
// CPU configuration
330,7 → 329,7
}
// Z* CPU extensions
tmp = SYSINFO_CPU;
tmp = NEORV32_SYSINFO.CPU;
if (tmp & (1<<SYSINFO_CPU_ZICSR)) {
neorv32_uart0_printf("Zicsr ");
}
381,12 → 380,12
// Memory configuration
neorv32_uart0_printf("\n=== << Memory Configuration >> ===\n");
 
neorv32_uart0_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE);
neorv32_uart0_printf("Instr. base address: 0x%x\n", NEORV32_SYSINFO.ISPACE_BASE);
 
// IMEM
neorv32_uart0_printf("Internal IMEM: ");
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM)) {
neorv32_uart0_printf("yes, %u bytes\n", SYSINFO_IMEM_SIZE);
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_IMEM)) {
neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.IMEM_SIZE);
}
else {
neorv32_uart0_printf("no\n");
393,18 → 392,18
}
 
// DMEM
neorv32_uart0_printf("Data base address: 0x%x\n", SYSINFO_DSPACE_BASE);
neorv32_uart0_printf("Data base address: 0x%x\n", NEORV32_SYSINFO.DSPACE_BASE);
neorv32_uart0_printf("Internal DMEM: ");
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM)) { neorv32_uart0_printf("yes, %u bytes\n", SYSINFO_DMEM_SIZE); }
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_INT_DMEM)) { neorv32_uart0_printf("yes, %u bytes\n", NEORV32_SYSINFO.DMEM_SIZE); }
else { neorv32_uart0_printf("no\n"); }
 
// i-cache
neorv32_uart0_printf("Internal i-cache: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE));
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_ICACHE)) {
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE));
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)) {
neorv32_uart0_printf("- ");
 
uint32_t ic_block_size = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F;
uint32_t ic_block_size = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_BLOCK_SIZE_0) & 0x0F;
if (ic_block_size) {
ic_block_size = 1 << ic_block_size;
}
412,7 → 411,7
ic_block_size = 0;
}
 
uint32_t ic_num_blocks = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_NUM_BLOCKS_0) & 0x0F;
uint32_t ic_num_blocks = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_NUM_BLOCKS_0) & 0x0F;
if (ic_num_blocks) {
ic_num_blocks = 1 << ic_num_blocks;
}
420,7 → 419,7
ic_num_blocks = 0;
}
 
uint32_t ic_associativity = (SYSINFO_CACHE >> SYSINFO_CACHE_IC_ASSOCIATIVITY_0) & 0x0F;
uint32_t ic_associativity = (NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_ASSOCIATIVITY_0) & 0x0F;
ic_associativity = 1 << ic_associativity;
 
neorv32_uart0_printf("%u bytes: %u set(s), %u block(s) per set, %u bytes per block", ic_associativity*ic_num_blocks*ic_block_size, ic_associativity, ic_num_blocks, ic_block_size);
427,7 → 426,7
if (ic_associativity == 1) {
neorv32_uart0_printf(" (direct-mapped)\n");
}
else if (((SYSINFO_CACHE >> SYSINFO_CACHE_IC_REPLACEMENT_0) & 0x0F) == 1) {
else if (((NEORV32_SYSINFO.CACHE >> SYSINFO_CACHE_IC_REPLACEMENT_0) & 0x0F) == 1) {
neorv32_uart0_printf(" (LRU replacement policy)\n");
}
else {
436,9 → 435,9
}
 
neorv32_uart0_printf("Ext. bus interface: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
__neorv32_rte_print_true_false(NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT));
neorv32_uart0_printf("Ext. bus Endianness: ");
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_MEM_EXT_ENDIAN)) {
neorv32_uart0_printf("big\n");
}
else {
448,20 → 447,20
// peripherals
neorv32_uart0_printf("\n=== << Peripherals >> ===\n");
 
tmp = SYSINFO_FEATURES;
neorv32_uart0_printf("GPIO - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_GPIO));
neorv32_uart0_printf("MTIME - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_MTIME));
neorv32_uart0_printf("UART0 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART0));
neorv32_uart0_printf("UART1 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_UART1));
neorv32_uart0_printf("SPI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SPI));
neorv32_uart0_printf("TWI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TWI));
neorv32_uart0_printf("PWM - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_PWM));
neorv32_uart0_printf("WDT - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_WDT));
neorv32_uart0_printf("TRNG - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_TRNG));
neorv32_uart0_printf("CFS - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_CFS));
neorv32_uart0_printf("SLINK - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_SLINK));
neorv32_uart0_printf("NEOLED - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_NEOLED));
neorv32_uart0_printf("XIRQ - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_FEATURES_IO_XIRQ));
tmp = NEORV32_SYSINFO.SOC;
neorv32_uart0_printf("GPIO - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_GPIO));
neorv32_uart0_printf("MTIME - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_MTIME));
neorv32_uart0_printf("UART0 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_UART0));
neorv32_uart0_printf("UART1 - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_UART1));
neorv32_uart0_printf("SPI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_SPI));
neorv32_uart0_printf("TWI - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_TWI));
neorv32_uart0_printf("PWM - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_PWM));
neorv32_uart0_printf("WDT - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_WDT));
neorv32_uart0_printf("TRNG - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_TRNG));
neorv32_uart0_printf("CFS - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_CFS));
neorv32_uart0_printf("SLINK - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_SLINK));
neorv32_uart0_printf("NEOLED - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_NEOLED));
neorv32_uart0_printf("XIRQ - "); __neorv32_rte_print_true_false(tmp & (1 << SYSINFO_SOC_IO_XIRQ));
}
 
 
546,7 → 545,7
}
 
neorv32_uart0_print("The NEORV32 RISC-V Processor\n"
"(c) Stephan Nolting\n"
"(c) 2021, Stephan Nolting\n"
"BSD 3-Clause License\n"
"https://github.com/stnolting/neorv32\n\n");
}
/neorv32_slink.c
50,7 → 50,7
**************************************************************************/
int neorv32_slink_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_SLINK)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_SLINK)) {
return 1;
}
else {
64,7 → 64,7
**************************************************************************/
void neorv32_slink_enable(void) {
 
SLINK_CT |= (uint32_t)(1 << SLINK_CT_EN);
NEORV32_SLINK.CTRL |= (uint32_t)(1 << SLINK_CTRL_EN);
}
 
 
75,7 → 75,7
**************************************************************************/
void neorv32_slink_disable(void) {
 
SLINK_CT &= ~(uint32_t)(1 << SLINK_CT_EN);
NEORV32_SLINK.CTRL &= ~(uint32_t)(1 << SLINK_CTRL_EN);
}
 
 
87,7 → 87,7
int neorv32_slink_get_rx_num(void) {
 
if (neorv32_slink_available()) {
return (int)((SLINK_CT >> SLINK_CT_RX_NUM0) & 0xf);
return (int)((NEORV32_SLINK.CTRL >> SLINK_CTRL_RX_NUM0) & 0xf);
}
else {
return 0;
103,7 → 103,7
int neorv32_slink_get_tx_num(void) {
 
if (neorv32_slink_available()) {
return (int)((SLINK_CT >> SLINK_CT_TX_NUM0) & 0xf);
return (int)((NEORV32_SLINK.CTRL >> SLINK_CTRL_TX_NUM0) & 0xf);
}
else {
return 0;
119,7 → 119,7
int neorv32_slink_get_rx_depth(void) {
 
if (neorv32_slink_available()) {
uint32_t tmp = (SLINK_CT >> SLINK_CT_RX_FIFO_S0) & 0x0f;
uint32_t tmp = (NEORV32_SLINK.CTRL >> SLINK_CTRL_RX_FIFO_S0) & 0x0f;
return (int)(1 << tmp);
}
else {
136,7 → 136,7
int neorv32_slink_get_tx_depth(void) {
 
if (neorv32_slink_available()) {
uint32_t tmp = (SLINK_CT >> SLINK_CT_TX_FIFO_S0) & 0x0f;
uint32_t tmp = (NEORV32_SLINK.CTRL >> SLINK_CTRL_TX_FIFO_S0) & 0x0f;
return (int)(1 << tmp);
}
else {
155,7 → 155,7
 
const uint32_t mask = 1 << SLINK_STATUS_RX0_HALF;
 
if (SLINK_STATUS & (mask << (link_id & 0x7))) {
if (NEORV32_SLINK.STATUS & (mask << (link_id & 0x7))) {
return 1;
}
else {
174,7 → 174,7
 
const uint32_t mask = 1 << SLINK_STATUS_TX0_HALF;
 
if (SLINK_STATUS & (mask << (link_id & 0x7))) {
if (NEORV32_SLINK.STATUS & (mask << (link_id & 0x7))) {
return 1;
}
else {
191,8 → 191,8
**************************************************************************/
int neorv32_slink_tx0_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX0_FREE)) {
SLINK_CH0 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX0_FREE)) {
NEORV32_SLINK.DATA[0] = tx_data;
return 0;
}
return 1;
207,8 → 207,8
**************************************************************************/
int neorv32_slink_tx1_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX1_FREE)) {
SLINK_CH1 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX1_FREE)) {
NEORV32_SLINK.DATA[1] = tx_data;
return 0;
}
return 1;
223,8 → 223,8
**************************************************************************/
int neorv32_slink_tx2_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX2_FREE)) {
SLINK_CH2 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX2_FREE)) {
NEORV32_SLINK.DATA[2] = tx_data;
return 0;
}
return 1;
239,8 → 239,8
**************************************************************************/
int neorv32_slink_tx3_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX3_FREE)) {
SLINK_CH3 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX3_FREE)) {
NEORV32_SLINK.DATA[3] = tx_data;
return 0;
}
return 1;
255,8 → 255,8
**************************************************************************/
int neorv32_slink_tx4_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX4_FREE)) {
SLINK_CH4 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX4_FREE)) {
NEORV32_SLINK.DATA[4] = tx_data;
return 0;
}
return 1;
271,8 → 271,8
**************************************************************************/
int neorv32_slink_tx5_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX5_FREE)) {
SLINK_CH5 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX5_FREE)) {
NEORV32_SLINK.DATA[5] = tx_data;
return 0;
}
return 1;
287,8 → 287,8
**************************************************************************/
int neorv32_slink_tx6_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX6_FREE)) {
SLINK_CH6 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX6_FREE)) {
NEORV32_SLINK.DATA[6] = tx_data;
return 0;
}
return 1;
303,8 → 303,8
**************************************************************************/
int neorv32_slink_tx7_nonblocking(uint32_t tx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_TX7_FREE)) {
SLINK_CH7 = tx_data;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_TX7_FREE)) {
NEORV32_SLINK.DATA[7] = tx_data;
return 0;
}
return 1;
319,8 → 319,8
**************************************************************************/
int neorv32_slink_rx0_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX0_AVAIL)) {
*rx_data = SLINK_CH0;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX0_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[0];
return 0;
}
return 1;
335,8 → 335,8
**************************************************************************/
int neorv32_slink_rx1_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX1_AVAIL)) {
*rx_data = SLINK_CH1;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX1_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[1];
return 0;
}
return 1;
351,8 → 351,8
**************************************************************************/
int neorv32_slink_rx2_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX2_AVAIL)) {
*rx_data = SLINK_CH2;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX2_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[2];
return 0;
}
return 1;
367,8 → 367,8
**************************************************************************/
int neorv32_slink_rx3_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX3_AVAIL)) {
*rx_data = SLINK_CH3;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX3_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[3];
return 0;
}
return 1;
383,8 → 383,8
**************************************************************************/
int neorv32_slink_rx4_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX4_AVAIL)) {
*rx_data = SLINK_CH4;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX4_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[4];
return 0;
}
return 1;
399,8 → 399,8
**************************************************************************/
int neorv32_slink_rx5_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX5_AVAIL)) {
*rx_data = SLINK_CH5;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX5_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[5];
return 0;
}
return 1;
415,8 → 415,8
**************************************************************************/
int neorv32_slink_rx6_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX6_AVAIL)) {
*rx_data = SLINK_CH6;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX6_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[6];
return 0;
}
return 1;
431,8 → 431,8
**************************************************************************/
int neorv32_slink_rx7_nonblocking(uint32_t *rx_data) {
 
if (SLINK_STATUS & (1 << SLINK_STATUS_RX7_AVAIL)) {
*rx_data = SLINK_CH7;
if (NEORV32_SLINK.STATUS & (1 << SLINK_STATUS_RX7_AVAIL)) {
*rx_data = NEORV32_SLINK.DATA[7];
return 0;
}
return 1;
/neorv32_spi.c
52,7 → 52,7
**************************************************************************/
int neorv32_spi_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_SPI)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_SPI)) {
return 1;
}
else {
62,7 → 62,7
 
 
/**********************************************************************//**
* Enable and configure SPI controller. The SPI control register bits are listed in #NEORV32_SPI_CT_enum.
* Enable and configure SPI controller. The SPI control register bits are listed in #NEORV32_SPI_CTRL_enum.
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] clk_polarity Idle clock polarity (0, 1).
70,21 → 70,21
**************************************************************************/
void neorv32_spi_setup(uint8_t prsc, uint8_t clk_polarity, uint8_t data_size) {
 
SPI_CT = 0; // reset
NEORV32_SPI.CTRL = 0; // reset
 
uint32_t ct_enable = 1;
ct_enable = ct_enable << SPI_CT_EN;
ct_enable = ct_enable << SPI_CTRL_EN;
 
uint32_t ct_prsc = (uint32_t)(prsc & 0x07);
ct_prsc = ct_prsc << SPI_CT_PRSC0;
ct_prsc = ct_prsc << SPI_CTRL_PRSC0;
 
uint32_t ct_polarity = (uint32_t)(clk_polarity & 0x01);
ct_polarity = ct_polarity << SPI_CT_CPHA;
ct_polarity = ct_polarity << SPI_CTRL_CPHA;
 
uint32_t ct_size = (uint32_t)(data_size & 0x03);
ct_size = ct_size << SPI_CT_SIZE0;
ct_size = ct_size << SPI_CTRL_SIZE0;
 
SPI_CT = ct_enable | ct_prsc | ct_polarity | ct_size;
NEORV32_SPI.CTRL = ct_enable | ct_prsc | ct_polarity | ct_size;
}
 
 
93,7 → 93,7
**************************************************************************/
void neorv32_spi_disable(void) {
 
SPI_CT &= ~((uint32_t)(1 << SPI_CT_EN));
NEORV32_SPI.CTRL &= ~((uint32_t)(1 << SPI_CTRL_EN));
}
 
 
102,7 → 102,7
**************************************************************************/
void neorv32_spi_enable(void) {
 
SPI_CT |= ((uint32_t)(1 << SPI_CT_EN));
NEORV32_SPI.CTRL |= ((uint32_t)(1 << SPI_CTRL_EN));
}
 
 
116,8 → 116,8
void neorv32_spi_cs_en(uint8_t cs) {
 
uint32_t cs_mask = (uint32_t)(1 << (cs & 0x07));
cs_mask = cs_mask << SPI_CT_CS0;
SPI_CT |= cs_mask;
cs_mask = cs_mask << SPI_CTRL_CS0;
NEORV32_SPI.CTRL |= cs_mask;
}
 
 
131,8 → 131,8
void neorv32_spi_cs_dis(uint8_t cs) {
 
uint32_t cs_mask = (uint32_t)(1 << (cs & 0x07));
cs_mask = cs_mask << SPI_CT_CS0;
SPI_CT &= ~cs_mask;
cs_mask = cs_mask << SPI_CTRL_CS0;
NEORV32_SPI.CTRL &= ~cs_mask;
}
 
 
148,10 → 148,10
**************************************************************************/
uint32_t neorv32_spi_trans(uint32_t tx_data) {
 
SPI_DATA = tx_data; // trigger transfer
while((SPI_CT & (1<<SPI_CT_BUSY)) != 0); // wait for current transfer to finish
NEORV32_SPI.DATA = tx_data; // trigger transfer
while((NEORV32_SPI.CTRL & (1<<SPI_CTRL_BUSY)) != 0); // wait for current transfer to finish
 
return SPI_DATA;
return NEORV32_SPI.DATA;
}
 
 
164,7 → 164,7
**************************************************************************/
int neorv32_spi_busy(void) {
 
if ((SPI_CT & (1<<SPI_CT_BUSY)) != 0) {
if ((NEORV32_SPI.CTRL & (1<<SPI_CTRL_BUSY)) != 0) {
return 1;
}
return 0;
/neorv32_trng.c
52,7 → 52,7
**************************************************************************/
int neorv32_trng_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_TRNG)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_TRNG)) {
return 1;
}
else {
62,19 → 62,19
 
 
/**********************************************************************//**
* Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CT_enum.
* Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CTRL_enum.
**************************************************************************/
void neorv32_trng_enable(void) {
 
int i;
 
TRNG_CT = 0; // reset
NEORV32_TRNG.CTRL = 0; // reset
 
for (i=0; i<256; i++) {
asm volatile ("nop");
}
 
TRNG_CT = 1 << TRNG_CT_EN; // activate
NEORV32_TRNG.CTRL = 1 << TRNG_CTRL_EN; // activate
 
for (i=0; i<256; i++) {
asm volatile ("nop");
87,7 → 87,7
**************************************************************************/
void neorv32_trng_disable(void) {
 
TRNG_CT = 0;
NEORV32_TRNG.CTRL = 0;
}
 
 
104,13 → 104,13
uint32_t ct_reg;
 
for (i=0; i<retries; i++) {
ct_reg = TRNG_CT;
ct_reg = NEORV32_TRNG.CTRL;
 
if ((ct_reg & (1<<TRNG_CT_VALID)) == 0) { // output data valid?
if ((ct_reg & (1<<TRNG_CTRL_VALID)) == 0) { // output data valid?
continue;
}
 
*data = (uint8_t)(ct_reg >> TRNG_CT_DATA_LSB);
*data = (uint8_t)(ct_reg >> TRNG_CTRL_DATA_LSB);
return 0; // valid data
}
 
/neorv32_twi.c
52,7 → 52,7
**************************************************************************/
int neorv32_twi_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_TWI)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_TWI)) {
return 1;
}
else {
62,7 → 62,7
 
 
/**********************************************************************//**
* Enable and configure TWI controller. The TWI control register bits are listed in #NEORV32_TWI_CT_enum.
* Enable and configure TWI controller. The TWI control register bits are listed in #NEORV32_TWI_CTRL_enum.
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] ckst_en Enable clock-stretching by peripherals when 1.
69,18 → 69,18
**************************************************************************/
void neorv32_twi_setup(uint8_t prsc, uint8_t ckst_en) {
 
TWI_CT = 0; // reset
NEORV32_TWI.CTRL = 0; // reset
 
uint32_t ct_enable = 1;
ct_enable = ct_enable << TWI_CT_EN;
ct_enable = ct_enable << TWI_CTRL_EN;
 
uint32_t ct_prsc = (uint32_t)(prsc & 0x07);
ct_prsc = ct_prsc << TWI_CT_PRSC0;
ct_prsc = ct_prsc << TWI_CTRL_PRSC0;
 
uint32_t ct_cksten = (uint32_t)(ckst_en & 0x01);
ct_cksten = ct_cksten << TWI_CT_CKSTEN;
ct_cksten = ct_cksten << TWI_CTRL_CKSTEN;
 
TWI_CT = ct_enable | ct_prsc | ct_cksten;
NEORV32_TWI.CTRL = ct_enable | ct_prsc | ct_cksten;
}
 
 
89,7 → 89,7
**************************************************************************/
void neorv32_twi_disable(void) {
 
TWI_CT &= ~((uint32_t)(1 << TWI_CT_EN));
NEORV32_TWI.CTRL &= ~((uint32_t)(1 << TWI_CTRL_EN));
}
 
 
98,7 → 98,7
**************************************************************************/
void neorv32_twi_enable(void) {
 
TWI_CT |= (uint32_t)(1 << TWI_CT_EN);
NEORV32_TWI.CTRL |= (uint32_t)(1 << TWI_CTRL_EN);
}
 
 
107,7 → 107,7
**************************************************************************/
void neorv32_twi_mack_enable(void) {
 
TWI_CT |= ((uint32_t)(1 << TWI_CT_MACK));
NEORV32_TWI.CTRL |= ((uint32_t)(1 << TWI_CTRL_MACK));
}
 
 
116,7 → 116,7
**************************************************************************/
void neorv32_twi_mack_disable(void) {
 
TWI_CT &= ~((uint32_t)(1 << TWI_CT_MACK));
NEORV32_TWI.CTRL &= ~((uint32_t)(1 << TWI_CTRL_MACK));
}
 
 
129,7 → 129,7
**************************************************************************/
int neorv32_twi_busy(void) {
 
if (TWI_CT & (1 << TWI_CT_BUSY)) {
if (NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)) {
return 1;
}
return 0;
148,11 → 148,11
 
neorv32_twi_generate_start(); // generate START condition
 
TWI_DATA = (uint32_t)a; // send address
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again
NEORV32_TWI.DATA = (uint32_t)a; // send address
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again
 
// check for ACK/NACK
if (TWI_CT & (1 << TWI_CT_ACK))
if (NEORV32_TWI.CTRL & (1 << TWI_CTRL_ACK))
return 0; // ACK received
else
return 1; // NACK received
169,11 → 169,11
**************************************************************************/
int neorv32_twi_trans(uint8_t d) {
 
TWI_DATA = (uint32_t)d; // send data
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again
NEORV32_TWI.DATA = (uint32_t)d; // send data
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again
 
// check for ACK/NACK
if (TWI_CT & (1 << TWI_CT_ACK))
if (NEORV32_TWI.CTRL & (1 << TWI_CTRL_ACK))
return 0; // ACK received
else
return 1; // NACK received
187,7 → 187,7
**************************************************************************/
uint8_t neorv32_twi_get_data(void) {
 
return (uint8_t)TWI_DATA; // get RX data from previous transmission
return (uint8_t)NEORV32_TWI.DATA; // get RX data from previous transmission
}
 
 
198,8 → 198,8
**************************************************************************/
void neorv32_twi_generate_stop(void) {
 
TWI_CT |= (uint32_t)(1 << TWI_CT_STOP); // generate STOP condition
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again
NEORV32_TWI.CTRL |= (uint32_t)(1 << TWI_CTRL_STOP); // generate STOP condition
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again
}
 
 
210,6 → 210,6
**************************************************************************/
void neorv32_twi_generate_start(void) {
 
TWI_CT |= (1 << TWI_CT_START); // generate START condition
while(TWI_CT & (1 << TWI_CT_BUSY)); // wait until idle again
NEORV32_TWI.CTRL |= (1 << TWI_CTRL_START); // generate START condition
while(NEORV32_TWI.CTRL & (1 << TWI_CTRL_BUSY)); // wait until idle again
}
/neorv32_uart.c
226,7 → 226,7
**************************************************************************/
int neorv32_uart0_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_UART0)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_UART0)) {
return 1;
}
else {
249,9 → 249,9
**************************************************************************/
void neorv32_uart0_setup(uint32_t baudrate, uint8_t parity, uint8_t flow_con) {
 
UART0_CT = 0; // reset
NEORV32_UART0.CTRL = 0; // reset
 
uint32_t clock = SYSINFO_CLK;
uint32_t clock = NEORV32_SYSINFO.CLK;
uint16_t i = 0; // BAUD rate divisor
uint8_t p = 0; // initial prsc = CLK/2
 
277,20 → 277,20
}
 
uint32_t clk_prsc = (uint32_t)p;
clk_prsc = clk_prsc << UART_CT_PRSC0;
clk_prsc = clk_prsc << UART_CTRL_PRSC0;
 
uint32_t baud_prsc = (uint32_t)i;
baud_prsc = baud_prsc - 1;
baud_prsc = baud_prsc << UART_CT_BAUD00;
baud_prsc = baud_prsc << UART_CTRL_BAUD00;
 
uint32_t uart_en = 1;
uart_en = uart_en << UART_CT_EN;
uart_en = uart_en << UART_CTRL_EN;
 
uint32_t parity_config = (uint32_t)(parity & 3);
parity_config = parity_config << UART_CT_PMODE0;
parity_config = parity_config << UART_CTRL_PMODE0;
 
uint32_t flow_control = (uint32_t)(flow_con & 3);
flow_control = flow_control << UART_CT_RTS_EN;
flow_control = flow_control << UART_CTRL_RTS_EN;
 
/* Enable UART0 for SIM mode. */
/* USE THIS ONLY FOR SIMULATION! */
299,12 → 299,12
#endif
#if defined UART0_SIM_MODE || defined UART_SIM_MODE
#warning UART0_SIM_MODE (primary UART) enabled! Sending all UART0.TX data to text.io simulation output instead of real UART0 transmitter. Use this for simulations only!
uint32_t sim_mode = 1 << UART_CT_SIM_MODE;
uint32_t sim_mode = 1 << UART_CTRL_SIM_MODE;
#else
uint32_t sim_mode = 0;
#endif
 
UART0_CT = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control;
NEORV32_UART0.CTRL = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control;
}
 
 
313,7 → 313,7
**************************************************************************/
void neorv32_uart0_disable(void) {
 
UART0_CT &= ~((uint32_t)(1 << UART_CT_EN));
NEORV32_UART0.CTRL &= ~((uint32_t)(1 << UART_CTRL_EN));
}
 
 
322,7 → 322,7
**************************************************************************/
void neorv32_uart0_enable(void) {
 
UART0_CT = ((uint32_t)(1 << UART_CT_EN));
NEORV32_UART0.CTRL = ((uint32_t)(1 << UART_CTRL_EN));
}
 
 
336,8 → 336,8
void neorv32_uart0_putc(char c) {
 
// wait for previous transfer to finish
while ((UART0_CT & (1<<UART_CT_TX_BUSY)) != 0);
UART0_DATA = ((uint32_t)c) << UART_DATA_LSB;
while ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0);
NEORV32_UART0.DATA = ((uint32_t)c) << UART_DATA_LSB;
}
 
 
350,7 → 350,7
**************************************************************************/
int neorv32_uart0_tx_busy(void) {
 
if ((UART0_CT & (1<<UART_CT_TX_BUSY)) != 0) {
if ((NEORV32_UART0.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0) {
return 1;
}
return 0;
368,7 → 368,7
 
uint32_t d = 0;
while (1) {
d = UART0_DATA;
d = NEORV32_UART0.DATA;
if ((d & (1<<UART_DATA_AVAIL)) != 0) { // char received?
return (char)d;
}
386,7 → 386,7
**************************************************************************/
int neorv32_uart0_getc_safe(char *data) {
 
uint32_t uart_rx = UART0_DATA;
uint32_t uart_rx = NEORV32_UART0.DATA;
if (uart_rx & (1<<UART_DATA_AVAIL)) { // char available at all?
 
int status = 0;
426,7 → 426,7
**************************************************************************/
int neorv32_uart0_char_received(void) {
 
if ((UART0_DATA & (1<<UART_DATA_AVAIL)) != 0) {
if ((NEORV32_UART0.DATA & (1<<UART_DATA_AVAIL)) != 0) {
return 1;
}
else {
445,7 → 445,7
**************************************************************************/
char neorv32_uart0_char_received_get(void) {
 
return (char)UART0_DATA;
return (char)NEORV32_UART0.DATA;
}
 
 
589,7 → 589,7
**************************************************************************/
int neorv32_uart1_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_UART1)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_UART1)) {
return 1;
}
else {
612,9 → 612,9
**************************************************************************/
void neorv32_uart1_setup(uint32_t baudrate, uint8_t parity, uint8_t flow_con) {
 
UART1_CT = 0; // reset
NEORV32_UART1.CTRL = 0; // reset
 
uint32_t clock = SYSINFO_CLK;
uint32_t clock = NEORV32_SYSINFO.CLK;
uint16_t i = 0; // BAUD rate divisor
uint8_t p = 0; // initial prsc = CLK/2
 
640,31 → 640,31
}
 
uint32_t clk_prsc = (uint32_t)p;
clk_prsc = clk_prsc << UART_CT_PRSC0;
clk_prsc = clk_prsc << UART_CTRL_PRSC0;
 
uint32_t baud_prsc = (uint32_t)i;
baud_prsc = baud_prsc - 1;
baud_prsc = baud_prsc << UART_CT_BAUD00;
baud_prsc = baud_prsc << UART_CTRL_BAUD00;
 
uint32_t uart_en = 1;
uart_en = uart_en << UART_CT_EN;
uart_en = uart_en << UART_CTRL_EN;
 
uint32_t parity_config = (uint32_t)(parity & 3);
parity_config = parity_config << UART_CT_PMODE0;
parity_config = parity_config << UART_CTRL_PMODE0;
 
uint32_t flow_control = (uint32_t)(flow_con & 3);
flow_control = flow_control << UART_CT_RTS_EN;
flow_control = flow_control << UART_CTRL_RTS_EN;
 
/* Enable UART1 for SIM mode. */
/* USE THIS ONLY FOR SIMULATION! */
#ifdef UART1_SIM_MODE
#warning UART1_SIM_MODE (secondary UART) enabled! Sending all UART1.TX data to text.io simulation output instead of real UART1 transmitter. Use this for simulations only!
uint32_t sim_mode = 1 << UART_CT_SIM_MODE;
uint32_t sim_mode = 1 << UART_CTRL_SIM_MODE;
#else
uint32_t sim_mode = 0;
#endif
 
UART1_CT = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control;
NEORV32_UART1.CTRL = clk_prsc | baud_prsc | uart_en | parity_config | sim_mode | flow_control;
}
 
 
673,7 → 673,7
**************************************************************************/
void neorv32_uart1_disable(void) {
 
UART1_CT &= ~((uint32_t)(1 << UART_CT_EN));
NEORV32_UART1.CTRL &= ~((uint32_t)(1 << UART_CTRL_EN));
}
 
 
682,7 → 682,7
**************************************************************************/
void neorv32_uart1_enable(void) {
 
UART1_CT |= ((uint32_t)(1 << UART_CT_EN));
NEORV32_UART1.CTRL |= ((uint32_t)(1 << UART_CTRL_EN));
}
 
 
696,8 → 696,8
void neorv32_uart1_putc(char c) {
 
// wait for previous transfer to finish
while ((UART1_CT & (1<<UART_CT_TX_BUSY)) != 0);
UART1_DATA = ((uint32_t)c) << UART_DATA_LSB;
while ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0);
NEORV32_UART1.DATA = ((uint32_t)c) << UART_DATA_LSB;
}
 
 
710,7 → 710,7
**************************************************************************/
int neorv32_uart1_tx_busy(void) {
 
if ((UART1_CT & (1<<UART_CT_TX_BUSY)) != 0) {
if ((NEORV32_UART1.CTRL & (1<<UART_CTRL_TX_BUSY)) != 0) {
return 1;
}
return 0;
728,7 → 728,7
 
uint32_t d = 0;
while (1) {
d = UART1_DATA;
d = NEORV32_UART1.DATA;
if ((d & (1<<UART_DATA_AVAIL)) != 0) { // char received?
return (char)d;
}
746,7 → 746,7
**************************************************************************/
int neorv32_uart1_getc_safe(char *data) {
 
uint32_t uart_rx = UART1_DATA;
uint32_t uart_rx = NEORV32_UART1.DATA;
if (uart_rx & (1<<UART_DATA_AVAIL)) { // char available at all?
 
int status = 0;
786,7 → 786,7
**************************************************************************/
int neorv32_uart1_char_received(void) {
 
if ((UART1_DATA & (1<<UART_DATA_AVAIL)) != 0) {
if ((NEORV32_UART1.DATA & (1<<UART_DATA_AVAIL)) != 0) {
return 1;
}
else {
805,7 → 805,7
**************************************************************************/
char neorv32_uart1_char_received_get(void) {
 
return (char)UART1_DATA;
return (char)NEORV32_UART1.DATA;
}
 
 
/neorv32_wdt.c
52,7 → 52,7
**************************************************************************/
int neorv32_wdt_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_WDT)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_WDT)) {
return 1;
}
else {
62,7 → 62,7
 
 
/**********************************************************************//**
* Configure and enable watchdog timer. The WDT control register bits are listed in #NEORV32_WDT_CT_enum.
* Configure and enable watchdog timer. The WDT control register bits are listed in #NEORV32_WDT_CTRL_enum.
*
* @param[in] prsc Clock prescaler to select timeout interval. See #NEORV32_CLOCK_PRSC_enum.
* @param[in] mode Trigger system reset on timeout when 1, trigger interrupt on timeout when 0.
70,21 → 70,21
**************************************************************************/
void neorv32_wdt_setup(uint8_t prsc, uint8_t mode, uint8_t lock) {
 
WDT_CT = (1 << WDT_CT_RESET); // reset WDT counter
NEORV32_WDT.CTRL = (1 << WDT_CTRL_RESET); // reset WDT counter
 
uint32_t prsc_int = (uint32_t)(prsc & 0x07);
prsc_int = prsc_int << WDT_CT_CLK_SEL0;
prsc_int = prsc_int << WDT_CTRL_CLK_SEL0;
 
uint32_t mode_int = (uint32_t)(mode & 0x01);
mode_int = mode_int << WDT_CT_MODE;
mode_int = mode_int << WDT_CTRL_MODE;
 
uint32_t lock_int = (uint32_t)(lock & 0x01);
lock_int = lock_int << WDT_CT_LOCK;
lock_int = lock_int << WDT_CTRL_LOCK;
 
const uint32_t enable = (uint32_t)(1 << WDT_CT_EN);
const uint32_t enable = (uint32_t)(1 << WDT_CTRL_EN);
 
// update WDT control register
WDT_CT = enable | mode_int | prsc_int | lock_int;
NEORV32_WDT.CTRL = enable | mode_int | prsc_int | lock_int;
}
 
 
95,10 → 95,10
**************************************************************************/
int neorv32_wdt_disable(void) {
WDT_CT = 0;
NEORV32_WDT.CTRL = 0;
 
// check if wdt is really off
if (WDT_CT & (1 << WDT_CT_EN)) {
if (NEORV32_WDT.CTRL & (1 << WDT_CTRL_EN)) {
return -1; // WDT still active
}
else {
112,7 → 112,7
**************************************************************************/
void neorv32_wdt_reset(void) {
 
WDT_CT = WDT_CT | (1 << WDT_CT_RESET);
NEORV32_WDT.CTRL = NEORV32_WDT.CTRL | (1 << WDT_CTRL_RESET);
}
 
 
123,7 → 123,7
**************************************************************************/
int neorv32_wdt_get_cause(void) {
 
if (WDT_CT & (1 << WDT_CT_RCAUSE)) { // reset caused by watchdog
if (NEORV32_WDT.CTRL & (1 << WDT_CTRL_RCAUSE)) { // reset caused by watchdog
return 1;
}
else { // external reset
137,5 → 137,5
**************************************************************************/
void neorv32_wdt_force(void) {
 
WDT_CT = WDT_CT | (1 << WDT_CT_FORCE);
NEORV32_WDT.CTRL = NEORV32_WDT.CTRL | (1 << WDT_CTRL_FORCE);
}
/neorv32_xirq.c
49,8 → 49,8
static uint32_t __neorv32_xirq_vector_lut[32] __attribute__((unused)); // trap handler vector table
 
// private functions
static void __attribute__((aligned(16))) __attribute__((unused)) __neorv32_xirq_core(void);
static void __attribute__((unused)) __neorv32_xirq_dummy_handler(void);
static void __attribute__((aligned(16))) __neorv32_xirq_core(void);
static void __neorv32_xirq_dummy_handler(void);
 
 
/**********************************************************************//**
60,7 → 60,7
**************************************************************************/
int neorv32_xirq_available(void) {
 
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_IO_XIRQ)) {
if (NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_IO_XIRQ)) {
return 1;
}
else {
78,8 → 78,8
**************************************************************************/
int neorv32_xirq_setup(void) {
 
XIRQ_IER = 0; // disable all input channels
XIRQ_IPR = 0xffffffff; // clear/ack all pending IRQs
NEORV32_XIRQ.IER = 0; // disable all input channels
NEORV32_XIRQ.IPR = 0; // clear all pending IRQs
 
int i;
for (i=0; i<32; i++) {
86,7 → 86,7
__neorv32_xirq_vector_lut[i] = (uint32_t)(&__neorv32_xirq_dummy_handler);
}
 
// register XIRQ handler in RTE
// register XIRQ handler in NEORV32 RTE
return neorv32_rte_exception_install(XIRQ_RTE_ID, __neorv32_xirq_core);
}
 
124,8 → 124,8
if (neorv32_xirq_available()) {
 
neorv32_cpu_irq_disable(XIRQ_FIRQ_ENABLE); // make sure XIRQ cannot fire
XIRQ_IER = 0xffffffff; // try to set all enable flags
enable = XIRQ_IER; // read back actually set flags
NEORV32_XIRQ.IER = 0xffffffff; // try to set all enable flags
enable = NEORV32_XIRQ.IER; // read back actually set flags
 
// count set bits in enable
cnt = 0;
144,6 → 144,45
 
 
/**********************************************************************//**
* Clear pending interrupt.
*
* @param[in] ch XIRQ interrupt channel (0..31).
**************************************************************************/
void neorv32_xirq_clear_pending(uint8_t ch) {
 
if (ch < 32) { // channel valid?
NEORV32_XIRQ.IPR = ~(1 << ch);
}
}
 
 
/**********************************************************************//**
* Enable IRQ channel.
*
* @param[in] ch XIRQ interrupt channel (0..31).
**************************************************************************/
void neorv32_xirq_channel_enable(uint8_t ch) {
 
if (ch < 32) { // channel valid?
NEORV32_XIRQ.IER |= 1 << ch;
}
}
 
 
/**********************************************************************//**
* Disable IRQ channel.
*
* @param[in] ch XIRQ interrupt channel (0..31).
**************************************************************************/
void neorv32_xirq_channel_disable(uint8_t ch) {
 
if (ch < 32) { // channel valid?
NEORV32_XIRQ.IER &= ~(1 << ch);
}
}
 
 
/**********************************************************************//**
* Install exception handler function for XIRQ channel.
*
* @note This will also activate the according XIRQ channel and clear a pending IRQ at this channel.
158,8 → 197,8
if (ch < 32) {
__neorv32_xirq_vector_lut[ch] = (uint32_t)handler; // install handler
uint32_t mask = 1 << ch;
XIRQ_IPR = mask; // clear if pending
XIRQ_IER |= mask; // enable channel
NEORV32_XIRQ.IPR = ~mask; // clear if pending
NEORV32_XIRQ.IER |= mask; // enable channel
return 0;
}
return 1;
180,8 → 219,8
if (ch < 32) {
__neorv32_xirq_vector_lut[ch] = (uint32_t)(&__neorv32_xirq_dummy_handler); // override using dummy handler
uint32_t mask = 1 << ch;
XIRQ_IER &= ~mask; // disable channel
XIRQ_IPR = mask; // clear if pending
NEORV32_XIRQ.IER &= ~mask; // disable channel
NEORV32_XIRQ.IPR = ~mask; // clear if pending
return 0;
}
return 1;
189,17 → 228,16
 
 
/**********************************************************************//**
* This is the actual second-level IRQ handler for the XIRQ. It will call the previously installed handler
* if an XIRQ fires.
*
* @note This function must no be used by the user.
* This is the actual second-level (F)IRQ handler for the XIRQ. It will
* call the previously installed handler if an XIRQ fires.
**************************************************************************/
static void __attribute__((aligned(16))) __attribute__((unused)) __neorv32_xirq_core(void) {
static void __attribute__((aligned(16))) __neorv32_xirq_core(void) {
 
register uint32_t src = XIRQ_SCR; // get IRQ source (with highest priority)
src &= 0x1f;
register uint32_t src = NEORV32_XIRQ.SCR; // get IRQ source (with highest priority)
 
XIRQ_IPR = (uint32_t)(1 << src); // acknowledge pending interrupt
uint32_t mask = 1 << src;
NEORV32_XIRQ.IPR = ~mask; // clear current pending interrupt
NEORV32_XIRQ.SCR = 0; // acknowledge current interrupt (CPU FIRQ)
 
// execute handler
register uint32_t xirq_handler = __neorv32_xirq_vector_lut[src];
212,7 → 250,7
/**********************************************************************//**
* XIRQ dummy handler.
**************************************************************************/
static void __attribute__((unused)) __neorv32_xirq_dummy_handler(void) {
static void __neorv32_xirq_dummy_handler(void) {
 
asm volatile ("nop");
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.